APE Price: $0.51 (+2.78%)

Contract

0xBf98E89c279E7b7e74C6b13179DD0bfE4E54Ae5d

Overview

APE Balance

Apechain LogoApechain LogoApechain Logo0 APE

APE Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
StatValidation

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
shanghai EvmVersion
File 1 of 2 : StatValidation.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "../interfaces/ICollectionRegistry.sol";

/// @title StatValidation
/// @notice Library for validating stat ranges and class-specific requirements
library StatValidation {
    // ------------------------- Constants -------------------------
    uint64 private constant MIN_STAT_VALUE = 50;
    uint64 private constant MAX_STAT_VALUE = 200;
    uint64 private constant MAX_STAT_INCREASE = 50;
    uint8 private constant MAX_COMPLEXITY = 3;

    // Gas limits by complexity tier
    uint256 private constant TIER1_GAS_LIMIT = 30000;
    uint256 private constant TIER2_GAS_LIMIT = 50000;
    uint256 private constant TIER3_GAS_LIMIT = 80000;

    // ------------------------- Errors -------------------------
    error InvalidStatRange(uint64 value, uint64 min, uint64 max);
    error InvalidStatIncrease(
        uint64 oldValue,
        uint64 newValue,
        uint64 maxIncrease
    );
    error InvalidClassStats(uint8 classType, string reason);
    error InvalidComplexity(uint8 complexity, uint256 gasUsed);

    // ------------------------- Core validation -------------------------
    /// @notice Validate a stat value is within acceptable range
    /// @param value Stat value to check
    /// @param min Minimum allowed value
    /// @param max Maximum allowed value
    function validateStatRange(
        uint64 value,
        uint64 min,
        uint64 max
    ) public pure {
        if (value < min || value > max) {
            revert InvalidStatRange(value, min, max);
        }
    }

    /// @notice Validate a stat increase is within acceptable range
    /// @param oldValue Previous stat value
    /// @param newValue New stat value
    /// @param maxIncrease Maximum allowed increase
    function validateStatIncrease(
        uint64 oldValue,
        uint64 newValue,
        uint64 maxIncrease
    ) public pure {
        if (newValue < oldValue || newValue > oldValue + maxIncrease) {
            revert InvalidStatIncrease(oldValue, newValue, maxIncrease);
        }
    }

    // ------------------------- Class validation -------------------------
    /// @notice Validate stats are appropriate for class type
    /// @param classType The class archetype
    /// @param stats Array of stats [vitality, strength, agility, defense]
    function validateClassStats(
        uint8 classType,
        uint64[4] memory stats
    ) public pure {
        ICollectionRegistry.ClassArchetype archetype = ICollectionRegistry
            .ClassArchetype(classType);

        // Validate base requirements for each class
        if (archetype == ICollectionRegistry.ClassArchetype.WARRIOR) {
            if (stats[1] < 80 || stats[3] < 80) {
                // strength and defense
                revert InvalidClassStats(
                    classType,
                    "Warrior requires high strength and defense"
                );
            }
        } else if (archetype == ICollectionRegistry.ClassArchetype.ROGUE) {
            if (stats[2] < 80) {
                // agility
                revert InvalidClassStats(
                    classType,
                    "Rogue requires high agility"
                );
            }
        } else if (archetype == ICollectionRegistry.ClassArchetype.PALADIN) {
            if (stats[0] < 80 || stats[3] < 70) {
                // vitality and defense
                revert InvalidClassStats(
                    classType,
                    "Paladin requires high vitality and defense"
                );
            }
        } else if (archetype == ICollectionRegistry.ClassArchetype.BERSERKER) {
            if (stats[1] < 90) {
                // strength
                revert InvalidClassStats(
                    classType,
                    "Berserker requires very high strength"
                );
            }
        }

        // Validate all stats are within global range
        for (uint256 i = 0; i < 4; i++) {
            validateStatRange(stats[i], MIN_STAT_VALUE, MAX_STAT_VALUE);
        }
    }

    // ------------------------- Complexity validation -------------------------
    /// @notice Validate gas usage against complexity tier
    /// @param complexity Complexity tier (1-3)
    /// @param gasUsed Amount of gas used
    function validateComplexityRequirements(
        uint8 complexity,
        uint256 gasUsed
    ) public pure {
        if (complexity == 0 || complexity > MAX_COMPLEXITY) {
            revert InvalidComplexity(complexity, gasUsed);
        }

        uint256 gasLimit = complexity == 1
            ? TIER1_GAS_LIMIT
            : complexity == 2
                ? TIER2_GAS_LIMIT
                : TIER3_GAS_LIMIT;

        if (gasUsed > gasLimit) {
            revert InvalidComplexity(complexity, gasUsed);
        }
    }

    // ------------------------- Utility functions -------------------------
    /// @notice Get the gas limit for a complexity tier
    /// @param complexity Complexity tier (1-3)
    /// @return uint256 Gas limit for the tier
    function getGasLimitForComplexity(
        uint8 complexity
    ) public pure returns (uint256) {
        return
            complexity == 1
                ? TIER1_GAS_LIMIT
                : complexity == 2
                    ? TIER2_GAS_LIMIT
                    : complexity == 3
                        ? TIER3_GAS_LIMIT
                        : 0;
    }
}

File 2 of 2 : ICollectionRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/// @title ICollectionRegistry
/// @notice Interface for managing whitelisted NFT collections and their base stats
interface ICollectionRegistry {
    // ------------------------- Type definitions -------------------------
    /// @notice Enum for different class archetypes
    enum ClassArchetype {
        WARRIOR, // High strength/defense
        ROGUE, // High agility/critical
        PALADIN, // Balanced with healing
        BERSERKER // High damage/risk
    }

    /// @notice Stats structure for NFT collections
    struct CollectionStats {
        uint64 baseVitality;
        uint64 baseStrength;
        uint64 baseAgility;
        uint64 baseDefense;
        uint8 classType; // ClassArchetype
        uint8 complexity; // For gas limit determination
        bool isWhitelisted;
    }

    // ------------------------- Events -------------------------
    /// @notice Event emitted when a collection is whitelisted
    event CollectionWhitelisted(
        address indexed collection,
        uint64 baseVitality,
        uint64 baseStrength,
        uint64 baseAgility,
        uint64 baseDefense,
        ClassArchetype classType,
        uint8 complexity
    );

    /// @notice Event emitted when a collection's stats are updated
    event CollectionStatsUpdated(
        address indexed collection,
        uint64 baseVitality,
        uint64 baseStrength,
        uint64 baseAgility,
        uint64 baseDefense,
        ClassArchetype classType,
        uint8 complexity
    );

    /// @notice Event emitted when a collection is removed from whitelist
    event CollectionRemoved(address indexed collection);

    // ------------------------- Admin functions -------------------------
    /// @notice Whitelist a new NFT collection with base stats
    /// @param collection Address of the NFT collection
    /// @param baseVitality Initial vitality for NFTs from this collection
    /// @param baseStrength Initial strength for NFTs from this collection
    /// @param baseAgility Initial agility for NFTs from this collection
    /// @param baseDefense Initial defense for NFTs from this collection
    /// @param classType Class archetype for this collection
    /// @param complexity Gas complexity tier (1-3)
    function whitelistCollection(
        address collection,
        uint64 baseVitality,
        uint64 baseStrength,
        uint64 baseAgility,
        uint64 baseDefense,
        ClassArchetype classType,
        uint8 complexity
    ) external;

    /// @notice Update base stats for a whitelisted collection
    /// @param collection Address of the NFT collection
    /// @param baseVitality New base vitality
    /// @param baseStrength New base strength
    /// @param baseAgility New base agility
    /// @param baseDefense New base defense
    /// @param classType New class archetype
    /// @param complexity New complexity tier
    function updateCollectionStats(
        address collection,
        uint64 baseVitality,
        uint64 baseStrength,
        uint64 baseAgility,
        uint64 baseDefense,
        ClassArchetype classType,
        uint8 complexity
    ) external;

    /// @notice Remove a collection from the whitelist
    /// @param collection Address of the NFT collection to remove
    function removeCollection(address collection) external;

    // ------------------------- View functions -------------------------
    /// @notice Check if a collection is whitelisted
    /// @param collection Address of the NFT collection to check
    /// @return bool True if collection is whitelisted
    function isWhitelisted(address collection) external view returns (bool);

    /// @notice Get base stats for a collection
    /// @param collection Address of the NFT collection
    /// @return CollectionStats struct containing base stats
    function getCollectionStats(
        address collection
    ) external view returns (CollectionStats memory);
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@pythnetwork/entropy-sdk-solidity/=../node_modules/@pythnetwork/entropy-sdk-solidity/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "pyth-sdk-solidity/=lib/pyth-sdk-solidity/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "shanghai",
  "libraries": {
    "src/libraries/StatValidation.sol": {
      "StatValidation": "0xbf98e89c279e7b7e74c6b13179dd0bfe4e54ae5d"
    },
    "src/libraries/StatsCalculator.sol": {
      "StatsCalculator": "0x78758a734b9e2045728d179f1f5b180c7e948095"
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"uint8","name":"classType","type":"uint8"},{"internalType":"string","name":"reason","type":"string"}],"name":"InvalidClassStats","type":"error"},{"inputs":[{"internalType":"uint8","name":"complexity","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"name":"InvalidComplexity","type":"error"},{"inputs":[{"internalType":"uint64","name":"oldValue","type":"uint64"},{"internalType":"uint64","name":"newValue","type":"uint64"},{"internalType":"uint64","name":"maxIncrease","type":"uint64"}],"name":"InvalidStatIncrease","type":"error"},{"inputs":[{"internalType":"uint64","name":"value","type":"uint64"},{"internalType":"uint64","name":"min","type":"uint64"},{"internalType":"uint64","name":"max","type":"uint64"}],"name":"InvalidStatRange","type":"error"},{"inputs":[{"internalType":"uint8","name":"complexity","type":"uint8"}],"name":"getGasLimitForComplexity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint8","name":"classType","type":"uint8"},{"internalType":"uint64[4]","name":"stats","type":"uint64[4]"}],"name":"validateClassStats","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint8","name":"complexity","type":"uint8"},{"internalType":"uint256","name":"gasUsed","type":"uint256"}],"name":"validateComplexityRequirements","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64","name":"oldValue","type":"uint64"},{"internalType":"uint64","name":"newValue","type":"uint64"},{"internalType":"uint64","name":"maxIncrease","type":"uint64"}],"name":"validateStatIncrease","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint64","name":"value","type":"uint64"},{"internalType":"uint64","name":"min","type":"uint64"},{"internalType":"uint64","name":"max","type":"uint64"}],"name":"validateStatRange","outputs":[],"stateMutability":"pure","type":"function"}]

610784610035600b8282823980515f1a60731461002957634e487b7160e01b5f525f60045260245ffd5b305f52607381538281f3fe7300000000000000000000000000000000000000003014608060405260043610610060575f3560e01c80631271ee3f1461006457806313914bbd14610079578063baae97e51461008c578063e43fe79a1461009f578063fa465e34146100c4575b5f80fd5b610077610072366004610594565b6100d7565b005b6100776100873660046105e4565b61014b565b61007761009a366004610620565b6101e3565b6100b26100ad3660046106b3565b6104c3565b60405190815260200160405180910390f35b6100776100d2366004610594565b610506565b816001600160401b0316836001600160401b031610806101085750806001600160401b0316836001600160401b0316115b1561014657604051632fb882ad60e01b81526001600160401b0380851660048301528084166024830152821660448201526064015b60405180910390fd5b505050565b60ff8216158061015e5750600360ff8316115b156101885760405163b82ffb9960e01b815260ff831660048201526024810182905260440161013d565b5f8260ff166001146101b0578260ff166002146101a857620138806101b4565b61c3506101b4565b6175305b9050808211156101465760405163b82ffb9960e01b815260ff841660048201526024810183905260440161013d565b5f8260ff1660038111156101f9576101f96106d3565b90505f81600381111561020e5761020e6106d3565b036102b357605082600160200201516001600160401b031610806102425750605082600360200201516001600160401b0316105b156102ae576040805163019d632960e71b815260ff851660048201526024810191909152602a60448201527f57617272696f72207265717569726573206869676820737472656e67746820616064820152696e6420646566656e736560b01b608482015260a40161013d565b61047d565b60018160038111156102c7576102c76106d3565b0361033957605082600260200201516001600160401b031610156102ae576040805163019d632960e71b815260ff851660048201526024810191909152601b60448201527f526f6775652072657175697265732068696768206167696c6974790000000000606482015260840161013d565b600281600381111561034d5761034d6106d3565b036103e957815160506001600160401b03909116108061037d5750604682600360200201516001600160401b0316105b156102ae576040805163019d632960e71b815260ff851660048201526024810191909152602a60448201527f50616c6164696e207265717569726573206869676820766974616c69747920616064820152696e6420646566656e736560b01b608482015260a40161013d565b60038160038111156103fd576103fd6106d3565b0361047d57605a82600160200201516001600160401b0316101561047d576040805163019d632960e71b815260ff851660048201526024810191909152602560448201527f4265727365726b657220726571756972657320766572792068696768207374726064820152640cadccee8d60db1b608482015260a40161013d565b5f5b60048110156104bd576104ab83826004811061049d5761049d6106e7565b6020020151603260c86100d7565b806104b58161070f565b91505061047f565b50505050565b5f8160ff166001146104fc578160ff166002146104f4578160ff166003146104eb575f610500565b62013880610500565b61c350610500565b6175305b92915050565b826001600160401b0316826001600160401b03161080610540575061052b8184610727565b6001600160401b0316826001600160401b0316115b156101465760405163fda3a0f760e01b81526001600160401b03808516600483015280841660248301528216604482015260640161013d565b80356001600160401b038116811461058f575f80fd5b919050565b5f805f606084860312156105a6575f80fd5b6105af84610579565b92506105bd60208501610579565b91506105cb60408501610579565b90509250925092565b803560ff8116811461058f575f80fd5b5f80604083850312156105f5575f80fd5b6105fe836105d4565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b5f8060a08385031215610631575f80fd5b61063a836105d4565b9150602084603f85011261064c575f80fd5b604051608081018181106001600160401b038211171561066e5761066e61060c565b6040528060a0860187811115610682575f80fd5b8387015b818110156106a45761069781610579565b8352918401918401610686565b50505080925050509250929050565b5f602082840312156106c3575f80fd5b6106cc826105d4565b9392505050565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201610720576107206106fb565b5060010190565b6001600160401b03818116838216019080821115610747576107476106fb565b509291505056fea2646970667358221220b5b38f89a07d0a545dda9e96a2a7cdeaf2469bc8386af1e326c7741c0e582d1664736f6c63430008140033

Deployed Bytecode

0x73bf98e89c279e7b7e74c6b13179dd0bfe4e54ae5d3014608060405260043610610060575f3560e01c80631271ee3f1461006457806313914bbd14610079578063baae97e51461008c578063e43fe79a1461009f578063fa465e34146100c4575b5f80fd5b610077610072366004610594565b6100d7565b005b6100776100873660046105e4565b61014b565b61007761009a366004610620565b6101e3565b6100b26100ad3660046106b3565b6104c3565b60405190815260200160405180910390f35b6100776100d2366004610594565b610506565b816001600160401b0316836001600160401b031610806101085750806001600160401b0316836001600160401b0316115b1561014657604051632fb882ad60e01b81526001600160401b0380851660048301528084166024830152821660448201526064015b60405180910390fd5b505050565b60ff8216158061015e5750600360ff8316115b156101885760405163b82ffb9960e01b815260ff831660048201526024810182905260440161013d565b5f8260ff166001146101b0578260ff166002146101a857620138806101b4565b61c3506101b4565b6175305b9050808211156101465760405163b82ffb9960e01b815260ff841660048201526024810183905260440161013d565b5f8260ff1660038111156101f9576101f96106d3565b90505f81600381111561020e5761020e6106d3565b036102b357605082600160200201516001600160401b031610806102425750605082600360200201516001600160401b0316105b156102ae576040805163019d632960e71b815260ff851660048201526024810191909152602a60448201527f57617272696f72207265717569726573206869676820737472656e67746820616064820152696e6420646566656e736560b01b608482015260a40161013d565b61047d565b60018160038111156102c7576102c76106d3565b0361033957605082600260200201516001600160401b031610156102ae576040805163019d632960e71b815260ff851660048201526024810191909152601b60448201527f526f6775652072657175697265732068696768206167696c6974790000000000606482015260840161013d565b600281600381111561034d5761034d6106d3565b036103e957815160506001600160401b03909116108061037d5750604682600360200201516001600160401b0316105b156102ae576040805163019d632960e71b815260ff851660048201526024810191909152602a60448201527f50616c6164696e207265717569726573206869676820766974616c69747920616064820152696e6420646566656e736560b01b608482015260a40161013d565b60038160038111156103fd576103fd6106d3565b0361047d57605a82600160200201516001600160401b0316101561047d576040805163019d632960e71b815260ff851660048201526024810191909152602560448201527f4265727365726b657220726571756972657320766572792068696768207374726064820152640cadccee8d60db1b608482015260a40161013d565b5f5b60048110156104bd576104ab83826004811061049d5761049d6106e7565b6020020151603260c86100d7565b806104b58161070f565b91505061047f565b50505050565b5f8160ff166001146104fc578160ff166002146104f4578160ff166003146104eb575f610500565b62013880610500565b61c350610500565b6175305b92915050565b826001600160401b0316826001600160401b03161080610540575061052b8184610727565b6001600160401b0316826001600160401b0316115b156101465760405163fda3a0f760e01b81526001600160401b03808516600483015280841660248301528216604482015260640161013d565b80356001600160401b038116811461058f575f80fd5b919050565b5f805f606084860312156105a6575f80fd5b6105af84610579565b92506105bd60208501610579565b91506105cb60408501610579565b90509250925092565b803560ff8116811461058f575f80fd5b5f80604083850312156105f5575f80fd5b6105fe836105d4565b946020939093013593505050565b634e487b7160e01b5f52604160045260245ffd5b5f8060a08385031215610631575f80fd5b61063a836105d4565b9150602084603f85011261064c575f80fd5b604051608081018181106001600160401b038211171561066e5761066e61060c565b6040528060a0860187811115610682575f80fd5b8387015b818110156106a45761069781610579565b8352918401918401610686565b50505080925050509250929050565b5f602082840312156106c3575f80fd5b6106cc826105d4565b9392505050565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f60018201610720576107206106fb565b5060010190565b6001600160401b03818116838216019080821115610747576107476106fb565b509291505056fea2646970667358221220b5b38f89a07d0a545dda9e96a2a7cdeaf2469bc8386af1e326c7741c0e582d1664736f6c63430008140033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.