APE Price: $0.51 (-2.00%)

Contract Diff Checker

Contract Name:
StatValidation

Contract Source Code:

// 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;
    }
}

// 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);
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):