{"sources":{"AgentGoldMiner.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\ninterface IAgentId {\n    function balanceOf(address owner) external view returns (uint256);\n}\n\ninterface IERC165 {\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n\ninterface IERC721 is IERC165 {\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    function balanceOf(address owner) external view returns (uint256 balance);\n    function ownerOf(uint256 tokenId) external view returns (address owner);\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\n    function safeTransferFrom(address from, address to, uint256 tokenId) external;\n    function transferFrom(address from, address to, uint256 tokenId) external;\n    function approve(address to, uint256 tokenId) external;\n    function setApprovalForAll(address operator, bool approved) external;\n    function getApproved(uint256 tokenId) external view returns (address operator);\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n}\n\ninterface IERC721Metadata is IERC721 {\n    function name() external view returns (string memory);\n    function symbol() external view returns (string memory);\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n\ninterface IERC721Receiver {\n    function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\n}\n\ninterface IPancakeFactory {\n    function getPair(address tokenA, address tokenB) external view returns (address pair);\n}\n\ninterface IPancakePair {\n    function token0() external view returns (address);\n    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);\n}\n\ninterface IPancakeRouter02 {\n    function swapExactETHForTokensSupportingFeeOnTransferTokens(\n        uint256 amountOutMin,\n        address[] calldata path,\n        address to,\n        uint256 deadline\n    ) external payable;\n}\n\ninterface IChainlinkAggregator {\n    function latestRoundData()\n        external\n        view\n        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\n}\n\n/// @title Agent Gold Miner Token ($AGM)\n/// @notice Official mining & ecosystem token for Agent Gold Miner (.ai).\n///         Fixed 1,000,000,000 (1B) max supply:\n///         - 20% (200,000,000 $AGM) Ecosystem & LP Reserve minted at genesis to CREATOR.\n///         - 80% (800,000,000 $AGM) Mining Pool supply, minted exclusively by the AgentGoldMiner contract as cards mine.\ncontract AgentGoldMinerToken {\n    string public constant name = \"Agent Gold Miner Token\";\n    string public constant symbol = \"AGM\";\n    uint8 public constant decimals = 18;\n\n    uint256 public constant MAX_SUPPLY = 1_000_000_000 ether;\n    uint256 public constant LP_RESERVE_SUPPLY = 200_000_000 ether;\n    uint256 public constant INITIAL_LP_SEED = 15_000 ether;\n    uint256 public constant GENESIS_BURN_SUPPLY = 199_985_000 ether;\n    uint256 public constant MAX_MINING_SUPPLY = 800_000_000 ether;\n    address public constant DEAD_ADDRESS = 0x000000000000000000000000000000000000dEaD;\n\n    address public immutable CREATOR;\n    address public immutable MINING_POOL;\n\n    uint256 public totalSupply;\n    uint256 public totalMinedSupply;\n\n    mapping(address => uint256) public balanceOf;\n    mapping(address => mapping(address => uint256)) public allowance;\n\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    error OnlyMiningPool();\n    error InsufficientBalance();\n    error InsufficientAllowance();\n    error ZeroAddress();\n\n    constructor(address creator_, address miningPool_) {\n        if (creator_ == address(0) || miningPool_ == address(0)) revert ZeroAddress();\n        CREATOR = creator_;\n        MINING_POOL = miningPool_;\n        totalSupply = LP_RESERVE_SUPPLY;\n        balanceOf[creator_] = INITIAL_LP_SEED;\n        balanceOf[DEAD_ADDRESS] = GENESIS_BURN_SUPPLY;\n        emit Transfer(address(0), creator_, INITIAL_LP_SEED);\n        emit Transfer(address(0), DEAD_ADDRESS, GENESIS_BURN_SUPPLY);\n    }\n\n    function transfer(address to, uint256 value) external returns (bool) {\n        _transfer(msg.sender, to, value);\n        return true;\n    }\n\n    function approve(address spender, uint256 value) external returns (bool) {\n        allowance[msg.sender][spender] = value;\n        emit Approval(msg.sender, spender, value);\n        return true;\n    }\n\n    function transferFrom(address from, address to, uint256 value) external returns (bool) {\n        uint256 allowed = allowance[from][msg.sender];\n        if (allowed != type(uint256).max) {\n            if (allowed < value) revert InsufficientAllowance();\n            unchecked {\n                allowance[from][msg.sender] = allowed - value;\n            }\n        }\n        _transfer(from, to, value);\n        return true;\n    }\n\n    function mintReward(address to, uint256 amount) external returns (uint256 minted) {\n        if (msg.sender != MINING_POOL) revert OnlyMiningPool();\n        uint256 remaining = MAX_MINING_SUPPLY - totalMinedSupply;\n        if (remaining == 0 || amount == 0) return 0;\n        minted = amount > remaining ? remaining : amount;\n        totalMinedSupply += minted;\n        totalSupply += minted;\n        balanceOf[to] += minted;\n        emit Transfer(address(0), to, minted);\n    }\n\n    function _transfer(address from, address to, uint256 value) internal {\n        if (to == address(0)) revert ZeroAddress();\n        uint256 bal = balanceOf[from];\n        if (bal < value) revert InsufficientBalance();\n        unchecked {\n            balanceOf[from] = bal - value;\n            balanceOf[to] += value;\n        }\n        emit Transfer(from, to, value);\n    }\n}\n\n/// @title Agent Gold Miner (AGM-CARD)\n/// @notice BNB Chain .ai Agent ID exclusive blind-box mining card game, approval-free mining pool & auto-buyback engine.\n///         - First 3,000 unique .ai wallets get their 1st card FREE (0 BNB, 5-day mining validity).\n///         - Paid mints cost 0.0068 BNB (~$5 USD, 15-day mining validity).\n///         - Revenue split on paid mints & renewals:\n///           * 80% transferred directly to CREATOR\n///           * 20% Token Buyback Reserve: automatically buys back $AGM on PancakeSwap and burns to 0x...dEaD\n///             (or forwards to CREATOR buyback reserve before LP is seeded).\n///         - Dynamic Renewal Pricing (`getRenewalPrice`):\n///           * Priced at 10% (`renewalDiscountBps = 1000`) of the card's 15-day $AGM output market value in BNB\n///             when $AGM/WBNB LP is active (with 0.0014 BNB floor), or $5 USD via Chainlink BNB/USD before LP.\n///         - 4 Card Tiers drawn on-chain (4:3:2:1 ratio):\n///           * Gold Card (5%):   0.4 $AGM / min (24 $AGM / hr, 8,640 $AGM / 15D)\n///           * Silver Card (10%): 0.3 $AGM / min (18 $AGM / hr, 6,480 $AGM / 15D)\n///           * Bronze Card (20%): 0.2 $AGM / min (12 $AGM / hr, 4,320 $AGM / 15D)\n///           * Iron Card (65%):   0.1 $AGM / min (6 $AGM / hr,  2,160 $AGM / 15D)\n///         - Built-in approval-free staking pool: deploy cards in-place without NFT approvals.\n///         - Claiming mined $AGM requires a 0.00015 BNB (~$0.11) claim fee.\ncontract AgentGoldMiner is IERC721Metadata {\n    string public constant override name = \"Agent Gold Miner\";\n    string public constant override symbol = \"AGM-CARD\";\n\n    uint256 public constant MAX_SUPPLY = 50_000;\n    uint256 public constant FREE_QUOTA = 3_000;\n    uint256 public constant MAX_PER_TX = 20;\n\n    uint256 public constant MINT_PRICE = 0.0068 ether;\n    uint256 public constant CLAIM_FEE = 0.00015 ether;\n\n    uint40 public constant FREE_DURATION = 5 days;\n    uint40 public constant PAID_DURATION = 15 days;\n\n    /// @notice Base unit rate per tier weight: 0.1 $AGM per minute (6 $AGM / hour, 2,160 $AGM per 15 days) per weight (1..4).\n    uint256 public constant RATE_PER_WEIGHT_PER_MIN = 0.1 ether;\n\n    IAgentId public constant AGENT_ID = IAgentId(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    address public constant WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;\n    address public constant PANCAKE_FACTORY = 0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73;\n    address public constant PANCAKE_ROUTER = 0x10ED43C718714eb63d5aA57B78B54704E256024E;\n    address public constant BNB_USD_FEED = 0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE;\n    address public constant DEAD_ADDRESS = 0x000000000000000000000000000000000000dEaD;\n\n    address payable public immutable CREATOR;\n    AgentGoldMinerToken public immutable agmToken;\n\n    address public lpPair;\n    uint256 public renewalDiscountBps = 1000; // 10% of 15-day mined $AGM market value\n    uint256 public minRenewalPrice = 0.0014 ether; // ~$1 floor\n    uint256 public baseRenewalPrice = 0.0068 ether; // ~$5 fallback\n    bool public autoBuyback = true;\n\n    uint256 public totalSupply;\n    uint256 public freeMinted;\n    uint256 public totalStakedCards;\n    uint256 public totalCreatorRevenueBNB;\n    uint256 public totalBuybackReserveBNB;\n    uint256 public totalAgmBoughtBack;\n    uint256 public totalClaimFeeBNB;\n\n    uint256[5] public tierMintedCount; // index 1=Iron, 2=Bronze, 3=Silver, 4=Gold\n\n    struct CardInfo {\n        uint8 tier;          // 1 = Iron (0.1/min), 2 = Bronze (0.2/min), 3 = Silver (0.3/min), 4 = Gold (0.4/min)\n        bool isPaid;         // false = Free Card (5D), true = Paid/Renewed Card (15D)\n        bool isStaked;       // true = Deployed in Mining Pool\n        uint40 mintedAt;     // timestamp minted\n        uint40 expiresAt;    // mining validity expiration timestamp\n        uint40 lastSettledAt;// last timestamp rewards were settled\n    }\n\n    mapping(uint256 => CardInfo) public cards;\n    mapping(address => bool) public claimedFree;\n    mapping(address => uint256) public mintedBy;\n    mapping(address => uint256) public unclaimedRewards;\n\n    mapping(uint256 => address) private _owners;\n    mapping(address => uint256) private _balances;\n    mapping(uint256 => address) private _tokenApprovals;\n    mapping(address => mapping(address => bool)) private _operatorApprovals;\n\n    mapping(address => uint256[]) private _ownedTokens;\n    mapping(uint256 => uint256) private _ownedTokensIndex;\n\n    event CardMinted(address indexed minter, uint256 indexed tokenId, uint8 tier, bool isPaid, uint40 expiresAt, bool autoStaked);\n    event CardDeployedToPool(address indexed owner, uint256 indexed tokenId, uint8 tier);\n    event CardWithdrawnFromPool(address indexed owner, uint256 indexed tokenId);\n    event CardRenewed(address indexed payer, uint256 indexed tokenId, uint40 newExpiresAt, uint256 pricePaid);\n    event RewardsClaimed(address indexed user, uint256 amount, uint256 feePaid);\n    event RevenueSplit(address indexed payer, uint256 creatorShare, uint256 buybackShare);\n    event BuybackExecuted(uint256 bnbSpent, uint256 agmBurned);\n    event PricingParamsUpdated(address lpPair, uint256 renewalDiscountBps, uint256 minRenewalPrice, uint256 baseRenewalPrice, bool autoBuyback);\n\n    error NotAgentIdHolder();\n    error InvalidQuantity();\n    error MaxSupplyReached();\n    error WrongPayment();\n    error NonexistentToken();\n    error NotCardOwner();\n    error CardStakedInPool();\n    error CardAlreadyStaked();\n    error CardNotStaked();\n    error CardExpired();\n    error NothingToClaim();\n    error TransferFailed();\n    error ZeroAddress();\n    error NotAuthorized();\n    error OnlyCreator();\n\n    constructor(address payable creator_) {\n        if (creator_ == address(0)) revert ZeroAddress();\n        CREATOR = creator_;\n        agmToken = new AgentGoldMinerToken(creator_, address(this));\n    }\n\n    // ---------------- Pricing, Buyback & Eligibility Views ----------------\n\n    function totalLpReserveBNB() external view returns (uint256) {\n        return totalBuybackReserveBNB;\n    }\n\n    function isAgent(address account) public view returns (bool) {\n        return AGENT_ID.balanceOf(account) > 0;\n    }\n\n    function canClaimFree(address minter) public view returns (bool) {\n        return freeMinted < FREE_QUOTA && !claimedFree[minter];\n    }\n\n    /// @notice Returns total BNB cost in wei for `minter` to mint `quantity` cards right now.\n    function quote(address minter, uint256 quantity) public view returns (uint256) {\n        if (quantity == 0) return 0;\n        uint256 free = canClaimFree(minter) ? 1 : 0;\n        return (quantity - free) * MINT_PRICE;\n    }\n\n    function priceFor(address minter, uint256 quantity) external view returns (uint256) {\n        return quote(minter, quantity);\n    }\n\n    /// @notice Resolves the active PancakeSwap V2 pair for $AGM / WBNB.\n    function resolveLpPair() public view returns (address pair) {\n        pair = lpPair;\n        if (pair == address(0)) {\n            try IPancakeFactory(PANCAKE_FACTORY).getPair(address(agmToken), WBNB) returns (address p) {\n                pair = p;\n            } catch {}\n        }\n    }\n\n    /// @notice Returns the current reserves (reserveAGM, reserveBNB) in the PancakeSwap V2 pair.\n    function getPoolReserves() public view returns (uint256 reserveAGM, uint256 reserveBNB) {\n        address pair = resolveLpPair();\n        if (pair == address(0)) return (0, 0);\n        try IPancakePair(pair).getReserves() returns (uint112 r0, uint112 r1, uint32) {\n            try IPancakePair(pair).token0() returns (address t0) {\n                if (t0 == address(agmToken)) {\n                    return (uint256(r0), uint256(r1));\n                } else {\n                    return (uint256(r1), uint256(r0));\n                }\n            } catch {}\n        } catch {}\n    }\n\n    /// @notice Dynamic renewal price for `tokenId` based on live $AGM token price (10% of 15-day output value),\n    ///         or $5 USD via Chainlink BNB/USD feed before the $AGM/WBNB LP pool is live.\n    function getRenewalPrice(uint256 tokenId) public view returns (uint256) {\n        uint8 tier = cards[tokenId].tier;\n        if (tier == 0) tier = 1;\n        return getRenewalPriceByTier(tier);\n    }\n\n    function getRenewalPriceByTier(uint8 tier) public view returns (uint256) {\n        if (tier == 0 || tier > 4) tier = 1;\n        (uint256 reserveAGM, uint256 reserveBNB) = getPoolReserves();\n        if (reserveAGM > 0 && reserveBNB > 0) {\n            uint256 card15DayAGM = uint256(tier) * 2160 ether;\n            uint256 fullOutputValueBNB = (card15DayAGM * reserveBNB) / reserveAGM;\n            uint256 discounted = (fullOutputValueBNB * renewalDiscountBps) / 10000;\n            return discounted > minRenewalPrice ? discounted : minRenewalPrice;\n        }\n        try IChainlinkAggregator(BNB_USD_FEED).latestRoundData() returns (\n            uint80,\n            int256 answer,\n            uint256,\n            uint256,\n            uint80\n        ) {\n            if (answer > 0) {\n                uint256 oraclePrice = (5 * 1e8 * 1e18) / uint256(answer);\n                return oraclePrice > minRenewalPrice ? oraclePrice : minRenewalPrice;\n            }\n        } catch {}\n        return baseRenewalPrice;\n    }\n\n    function setPricingParams(\n        address _lpPair,\n        uint256 _renewalDiscountBps,\n        uint256 _minRenewalPrice,\n        uint256 _baseRenewalPrice,\n        bool _autoBuyback\n    ) external {\n        if (msg.sender != CREATOR) revert OnlyCreator();\n        if (_renewalDiscountBps == 0 || _renewalDiscountBps > 10000) revert WrongPayment();\n        lpPair = _lpPair;\n        renewalDiscountBps = _renewalDiscountBps;\n        minRenewalPrice = _minRenewalPrice;\n        baseRenewalPrice = _baseRenewalPrice;\n        autoBuyback = _autoBuyback;\n        emit PricingParamsUpdated(_lpPair, _renewalDiscountBps, _minRenewalPrice, _baseRenewalPrice, _autoBuyback);\n    }\n\n    // ---------------- Mint & Blind-Box Draw ----------------\n\n    /// @notice Mint 1 card and automatically deploy it to the mining pool.\n    function mint() external payable {\n        _mintCards(msg.sender, 1, true);\n    }\n\n    /// @notice Mint `quantity` cards (1..20) and automatically deploy them to the mining pool.\n    function mint(uint256 quantity) external payable {\n        _mintCards(msg.sender, quantity, true);\n    }\n\n    /// @notice Mint `quantity` cards with explicit autoDeploy flag.\n    function mintCards(uint256 quantity, bool autoDeploy) external payable {\n        _mintCards(msg.sender, quantity, autoDeploy);\n    }\n\n    function _mintCards(address minter, uint256 quantity, bool autoDeploy) internal {\n        if (quantity == 0 || quantity > MAX_PER_TX) revert InvalidQuantity();\n        if (totalSupply + quantity > MAX_SUPPLY) revert MaxSupplyReached();\n        if (AGENT_ID.balanceOf(minter) == 0) revert NotAgentIdHolder();\n\n        bool useFree = canClaimFree(minter);\n        uint256 paidCount = useFree ? (quantity - 1) : quantity;\n        uint256 requiredValue = paidCount * MINT_PRICE;\n        if (msg.value != requiredValue) revert WrongPayment();\n\n        if (useFree) {\n            claimedFree[minter] = true;\n            unchecked {\n                ++freeMinted;\n            }\n        }\n\n        mintedBy[minter] += quantity;\n        uint256 baseId = totalSupply;\n        totalSupply = baseId + quantity;\n\n        for (uint256 i = 1; i <= quantity; ++i) {\n            _mintSingleCard(minter, baseId + i, !(useFree && i == 1), autoDeploy);\n        }\n\n        if (autoDeploy) {\n            totalStakedCards += quantity;\n        }\n\n        if (msg.value > 0) {\n            _distributeRevenue(msg.value);\n        }\n    }\n\n    function _mintSingleCard(address minter, uint256 tokenId, bool isPaidCard, bool autoDeploy) private {\n        uint40 nowTs = uint40(block.timestamp);\n        uint40 exp = nowTs + (isPaidCard ? PAID_DURATION : FREE_DURATION);\n        uint8 tier = _drawTier(minter, tokenId);\n        tierMintedCount[tier] += 1;\n        cards[tokenId] = CardInfo({\n            tier: tier,\n            isPaid: isPaidCard,\n            isStaked: autoDeploy,\n            mintedAt: nowTs,\n            expiresAt: exp,\n            lastSettledAt: nowTs\n        });\n        _mintToken(minter, tokenId);\n        emit CardMinted(minter, tokenId, tier, isPaidCard, exp, autoDeploy);\n        if (autoDeploy) {\n            emit CardDeployedToPool(minter, tokenId, tier);\n        }\n    }\n\n    /// @notice Renew or upgrade any card for +15 days of mining validity at the dynamic renewal price.\n    function renewCard(uint256 tokenId) external payable {\n        if (_owners[tokenId] == address(0)) revert NonexistentToken();\n        uint256 price = getRenewalPrice(tokenId);\n        if (msg.value < price) revert WrongPayment();\n\n        _settleCard(tokenId);\n        CardInfo storage c = cards[tokenId];\n        uint40 nowTs = uint40(block.timestamp);\n        uint40 baseTs = c.expiresAt > nowTs ? c.expiresAt : nowTs;\n        uint40 newExp = baseTs + PAID_DURATION;\n\n        c.isPaid = true;\n        c.expiresAt = newExp;\n        if (c.lastSettledAt < nowTs) {\n            c.lastSettledAt = nowTs;\n        }\n\n        _distributeRevenue(price);\n\n        uint256 excess = msg.value - price;\n        if (excess > 0) {\n            (bool okRefund, ) = msg.sender.call{value: excess}(\"\");\n            if (!okRefund) revert TransferFailed();\n        }\n\n        emit CardRenewed(msg.sender, tokenId, newExp, price);\n    }\n\n    function _drawTier(address minter, uint256 tokenId) private view returns (uint8) {\n        uint256 roll = uint256(\n            keccak256(\n                abi.encodePacked(\n                    block.prevrandao,\n                    block.timestamp,\n                    blockhash(block.number - 1),\n                    minter,\n                    tokenId,\n                    totalSupply\n                )\n            )\n        ) % 100;\n        if (roll < 5) return 4;  // 5% Gold Card (0.4 AGM/min)\n        if (roll < 15) return 3; // 10% Silver Card (0.3 AGM/min)\n        if (roll < 35) return 2; // 20% Bronze Card (0.2 AGM/min)\n        return 1;                // 65% Iron Card (0.1 AGM/min)\n    }\n\n    function _distributeRevenue(uint256 amount) private {\n        uint256 buybackShare = (amount * 20) / 100;\n        uint256 creatorShare = amount - buybackShare;\n        totalCreatorRevenueBNB += creatorShare;\n        totalBuybackReserveBNB += buybackShare;\n        emit RevenueSplit(msg.sender, creatorShare, buybackShare);\n\n        bool boughtBack = false;\n        if (autoBuyback && buybackShare > 0) {\n            (uint256 reserveAGM, uint256 reserveBNB) = getPoolReserves();\n            if (reserveAGM > 0 && reserveBNB > 0) {\n                boughtBack = _trySwapAndBurn(buybackShare, 0);\n            }\n        }\n\n        uint256 toCreator = boughtBack ? creatorShare : amount;\n        (bool ok, ) = CREATOR.call{value: toCreator}(\"\");\n        if (!ok) revert TransferFailed();\n    }\n\n    /// @notice Manual buyback & burn trigger for `$AGM` on PancakeSwap V2.\n    function executeBuyback(uint256 minAgmOut) external payable {\n        if (msg.value == 0) revert WrongPayment();\n        totalBuybackReserveBNB += msg.value;\n        if (!_trySwapAndBurn(msg.value, minAgmOut)) revert TransferFailed();\n    }\n\n    function _trySwapAndBurn(uint256 bnbAmount, uint256 minAgmOut) private returns (bool) {\n        address[] memory path = new address[](2);\n        path[0] = WBNB;\n        path[1] = address(agmToken);\n        uint256 beforeBal = agmToken.balanceOf(DEAD_ADDRESS);\n        try\n            IPancakeRouter02(PANCAKE_ROUTER).swapExactETHForTokensSupportingFeeOnTransferTokens{value: bnbAmount}(\n                minAgmOut,\n                path,\n                DEAD_ADDRESS,\n                block.timestamp\n            )\n        {\n            uint256 burned = agmToken.balanceOf(DEAD_ADDRESS) - beforeBal;\n            totalAgmBoughtBack += burned;\n            emit BuybackExecuted(bnbAmount, burned);\n            return true;\n        } catch {\n            return false;\n        }\n    }\n\n    // ---------------- Approval-Free Mining Pool ----------------\n\n    function deployToPool(uint256 tokenId) external {\n        if (_owners[tokenId] != msg.sender) revert NotCardOwner();\n        CardInfo storage c = cards[tokenId];\n        if (c.isStaked) revert CardAlreadyStaked();\n        if (block.timestamp >= c.expiresAt) revert CardExpired();\n\n        c.isStaked = true;\n        c.lastSettledAt = uint40(block.timestamp);\n        totalStakedCards += 1;\n        emit CardDeployedToPool(msg.sender, tokenId, c.tier);\n    }\n\n    function deployAllToPool() external {\n        uint256[] storage userTokens = _ownedTokens[msg.sender];\n        uint256 len = userTokens.length;\n        uint40 nowTs = uint40(block.timestamp);\n        uint256 newlyStaked = 0;\n\n        for (uint256 i = 0; i < len; ++i) {\n            uint256 tokenId = userTokens[i];\n            CardInfo storage c = cards[tokenId];\n            if (!c.isStaked && nowTs < c.expiresAt) {\n                c.isStaked = true;\n                c.lastSettledAt = nowTs;\n                ++newlyStaked;\n                emit CardDeployedToPool(msg.sender, tokenId, c.tier);\n            }\n        }\n        if (newlyStaked > 0) {\n            totalStakedCards += newlyStaked;\n        }\n    }\n\n    function withdrawFromPool(uint256 tokenId) external {\n        if (_owners[tokenId] != msg.sender) revert NotCardOwner();\n        CardInfo storage c = cards[tokenId];\n        if (!c.isStaked) revert CardNotStaked();\n\n        _settleCard(tokenId);\n        c.isStaked = false;\n        totalStakedCards -= 1;\n        emit CardWithdrawnFromPool(msg.sender, tokenId);\n    }\n\n    function pendingCardRewards(uint256 tokenId) public view returns (uint256) {\n        CardInfo memory c = cards[tokenId];\n        if (!c.isStaked) return 0;\n        uint256 endTs = block.timestamp < c.expiresAt ? block.timestamp : c.expiresAt;\n        if (endTs <= c.lastSettledAt) return 0;\n        uint256 elapsed = endTs - c.lastSettledAt;\n        return (elapsed * uint256(c.tier) * RATE_PER_WEIGHT_PER_MIN) / 60;\n    }\n\n    function pendingRewards(address user) public view returns (uint256 total) {\n        total = unclaimedRewards[user];\n        uint256[] storage userTokens = _ownedTokens[user];\n        uint256 len = userTokens.length;\n        for (uint256 i = 0; i < len; ++i) {\n            total += pendingCardRewards(userTokens[i]);\n        }\n    }\n\n    /// @notice Returns active mining rate in wei ($AGM) per minute for `user`.\n    function userMiningRatePerMin(address user) public view returns (uint256 ratePerMinWei) {\n        uint256[] storage userTokens = _ownedTokens[user];\n        uint256 len = userTokens.length;\n        uint256 nowTs = block.timestamp;\n        for (uint256 i = 0; i < len; ++i) {\n            CardInfo memory c = cards[userTokens[i]];\n            if (c.isStaked && nowTs < c.expiresAt) {\n                ratePerMinWei += uint256(c.tier) * RATE_PER_WEIGHT_PER_MIN;\n            }\n        }\n    }\n\n    function claimRewards() external payable {\n        if (msg.value != CLAIM_FEE) revert WrongPayment();\n\n        uint256[] storage userTokens = _ownedTokens[msg.sender];\n        uint256 len = userTokens.length;\n        for (uint256 i = 0; i < len; ++i) {\n            _settleCard(userTokens[i]);\n        }\n\n        uint256 reward = unclaimedRewards[msg.sender];\n        if (reward == 0) revert NothingToClaim();\n        unclaimedRewards[msg.sender] = 0;\n\n        totalClaimFeeBNB += msg.value;\n        totalCreatorRevenueBNB += msg.value;\n\n        (bool ok, ) = CREATOR.call{value: msg.value}(\"\");\n        if (!ok) revert TransferFailed();\n\n        uint256 minted = agmToken.mintReward(msg.sender, reward);\n        emit RewardsClaimed(msg.sender, minted, msg.value);\n    }\n\n    function _settleCard(uint256 tokenId) internal {\n        CardInfo storage c = cards[tokenId];\n        if (!c.isStaked) return;\n        uint40 endTs = uint40(block.timestamp < c.expiresAt ? block.timestamp : c.expiresAt);\n        if (endTs > c.lastSettledAt) {\n            uint256 elapsed = uint256(endTs - c.lastSettledAt);\n            uint256 reward = (elapsed * uint256(c.tier) * RATE_PER_WEIGHT_PER_MIN) / 60;\n            c.lastSettledAt = endTs;\n            address owner = _owners[tokenId];\n            if (owner != address(0) && reward > 0) {\n                unclaimedRewards[owner] += reward;\n            }\n        }\n    }\n\n    // ---------------- Dashboard Batch Views ----------------\n\n    function tokensOfOwner(address owner) external view returns (uint256[] memory) {\n        return _ownedTokens[owner];\n    }\n\n    function getUserCards(address user)\n        external\n        view\n        returns (\n            uint256[] memory tokenIds,\n            uint8[] memory tiers,\n            bool[] memory isPaidList,\n            bool[] memory isStakedList,\n            uint40[] memory expiresAtList,\n            uint256[] memory pendingList\n        )\n    {\n        uint256[] storage owned = _ownedTokens[user];\n        uint256 len = owned.length;\n        tokenIds = new uint256[](len);\n        tiers = new uint8[](len);\n        isPaidList = new bool[](len);\n        isStakedList = new bool[](len);\n        expiresAtList = new uint40[](len);\n        pendingList = new uint256[](len);\n\n        for (uint256 i = 0; i < len; ++i) {\n            uint256 tid = owned[i];\n            CardInfo memory c = cards[tid];\n            tokenIds[i] = tid;\n            tiers[i] = c.tier;\n            isPaidList[i] = c.isPaid;\n            isStakedList[i] = c.isStaked;\n            expiresAtList[i] = c.expiresAt;\n            pendingList[i] = pendingCardRewards(tid);\n        }\n    }\n\n    // ---------------- On-Chain Dynamic SVG Art ----------------\n\n    function _tierName(uint8 tier) private pure returns (string memory) {\n        if (tier == 4) return \"GOLD\";\n        if (tier == 3) return \"SILVER\";\n        if (tier == 2) return \"BRONZE\";\n        return \"IRON\";\n    }\n\n    function _tierRateText(uint8 tier) private pure returns (string memory) {\n        if (tier == 4) return \"0.4 $AGM/MIN (24/HR)\";\n        if (tier == 3) return \"0.3 $AGM/MIN (18/HR)\";\n        if (tier == 2) return \"0.2 $AGM/MIN (12/HR)\";\n        return \"0.1 $AGM/MIN (6/HR)\";\n    }\n\n    function _tierCnName(uint8 tier) private pure returns (string memory) {\n        if (tier == 4) return unicode\"金卡 · 5% 稀有\";\n        if (tier == 3) return unicode\"银卡 · 10% 稀有\";\n        if (tier == 2) return unicode\"铜卡 · 20% 稀有\";\n        return unicode\"铁卡 · 65% 基础\";\n    }\n\n    function _tierPalette(uint8 tier)\n        private\n        pure\n        returns (string memory bg1, string memory bg2, string memory accent, string memory badgeBg)\n    {\n        if (tier == 4) return (\"#2A1B02\", \"#0D0902\", \"#FFD700\", \"#5C4004\");\n        if (tier == 3) return (\"#1B2432\", \"#0A0E14\", \"#E2E8F0\", \"#334155\");\n        if (tier == 2) return (\"#291509\", \"#0E0703\", \"#F59E0B\", \"#572B0F\");\n        return (\"#161922\", \"#090B10\", \"#38BDF8\", \"#1E293B\");\n    }\n\n    function _svgTop(uint256 tokenId, uint8 tier) private pure returns (string memory) {\n        (string memory bg1, string memory bg2, string memory accent, string memory badgeBg) = _tierPalette(tier);\n        string memory h = string.concat(\n            '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 420 560\"><defs><linearGradient id=\"bg\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0%\" stop-color=\"',\n            bg1, '\"/><stop offset=\"100%\" stop-color=\"', bg2,\n            '\"/></linearGradient><linearGradient id=\"ac\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"0\"><stop offset=\"0%\" stop-color=\"',\n            accent, '\"/><stop offset=\"100%\" stop-color=\"#FFFFFF\"/></linearGradient></defs><rect width=\"420\" height=\"560\" rx=\"28\" fill=\"url(#bg)\"/><rect x=\"12\" y=\"12\" width=\"396\" height=\"536\" rx=\"22\" fill=\"none\" stroke=\"',\n            accent, '\" stroke-width=\"2\" stroke-opacity=\"0.65\"/>'\n        );\n        string memory b1 = string.concat(\n            '<rect x=\"30\" y=\"32\" width=\"150\" height=\"32\" rx=\"16\" fill=\"', badgeBg,\n            '\"/><text x=\"105\" y=\"53\" text-anchor=\"middle\" font-family=\"monospace\" font-weight=\"bold\" font-size=\"13\" fill=\"', accent,\n            '\">.ai AGENT MINER</text><text x=\"390\" y=\"54\" text-anchor=\"end\" font-family=\"monospace\" font-weight=\"bold\" font-size=\"16\" fill=\"#94A3B8\">#', _toString(tokenId), '</text>'\n        );\n        return string.concat(\n            h, b1,\n            '<circle cx=\"210\" cy=\"195\" r=\"78\" fill=\"', badgeBg, '\" stroke=\"', accent,\n            '\" stroke-width=\"3\"/><polygon points=\"210,132 230,174 275,180 242,212 250,256 210,234 170,256 178,212 145,180 190,174\" fill=\"url(#ac)\"/><text x=\"210\" y=\"318\" text-anchor=\"middle\" font-family=\"sans-serif\" font-weight=\"900\" font-size=\"34\" fill=\"', accent,\n            '\">', _tierName(tier), ' CARD</text><text x=\"210\" y=\"346\" text-anchor=\"middle\" font-family=\"sans-serif\" font-size=\"15\" fill=\"#CBD5E1\">', _tierCnName(tier), '</text>'\n        );\n    }\n\n    function _svgBottom(CardInfo memory c) private view returns (string memory) {\n        (, , string memory accent, string memory badgeBg) = _tierPalette(c.tier);\n        string memory statusText = (c.isStaked && block.timestamp < c.expiresAt)\n            ? \"MINING ACTIVE\"\n            : (block.timestamp >= c.expiresAt ? \"EXPIRED (RENEW)\" : \"IDLE IN WALLET\");\n        string memory validityText = c.isPaid ? \"15D PASS (RENEWABLE)\" : \"5D FREE PASS\";\n        return string.concat(\n            '<rect x=\"30\" y=\"374\" width=\"360\" height=\"74\" rx=\"14\" fill=\"#000000\" fill-opacity=\"0.45\" stroke=\"', accent,\n            '\" stroke-opacity=\"0.35\"/><text x=\"50\" y=\"404\" font-family=\"monospace\" font-size=\"13\" fill=\"#94A3B8\">HASHRATE</text><text x=\"370\" y=\"406\" text-anchor=\"end\" font-family=\"monospace\" font-weight=\"bold\" font-size=\"16\" fill=\"', accent,\n            '\">', _tierRateText(c.tier), '</text><text x=\"50\" y=\"432\" font-family=\"monospace\" font-size=\"13\" fill=\"#94A3B8\">VALIDITY</text><text x=\"370\" y=\"432\" text-anchor=\"end\" font-family=\"monospace\" font-size=\"13\" fill=\"#F8FAFC\">', validityText,\n            '</text><rect x=\"30\" y=\"468\" width=\"360\" height=\"50\" rx=\"12\" fill=\"', badgeBg,\n            '\"/><text x=\"210\" y=\"499\" text-anchor=\"middle\" font-family=\"monospace\" font-weight=\"bold\" font-size=\"15\" fill=\"#FFFFFF\">', statusText, '</text></svg>'\n        );\n    }\n\n    function _renderSvg(uint256 tokenId) private view returns (string memory) {\n        CardInfo memory c = cards[tokenId];\n        return string.concat(_svgTop(tokenId, c.tier), _svgBottom(c));\n    }\n\n    function tokenURI(uint256 tokenId) public view override returns (string memory) {\n        if (_owners[tokenId] == address(0)) revert NonexistentToken();\n        CardInfo memory c = cards[tokenId];\n        string memory svg = _renderSvg(tokenId);\n        string memory json = string.concat(\n            '{\"name\":\"Agent Gold Miner #', _toString(tokenId), ' (', _tierName(c.tier), ')\",',\n            '\"description\":\"Agent Gold Miner (.ai) on BNB Chain. 4-tier on-chain mining cards producing $AGM every minute with 20% automated token buyback & burn.\",',\n            '\"attributes\":[',\n            '{\"trait_type\":\"Tier\",\"value\":\"', _tierName(c.tier), '\"},',\n            '{\"trait_type\":\"Mining Rate\",\"value\":\"', _tierRateText(c.tier), '\"},',\n            '{\"trait_type\":\"Pass Type\",\"value\":\"', (c.isPaid ? \"15-Day Paid Pass\" : \"5-Day Free Pass\"), '\"},',\n            '{\"trait_type\":\"Pool Status\",\"value\":\"', (c.isStaked ? \"Deployed\" : \"Idle\"), '\"},',\n            '{\"display_type\":\"date\",\"trait_type\":\"Expires At\",\"value\":', _toString(c.expiresAt), '}',\n            '],\"image\":\"data:image/svg+xml;base64,', _base64(bytes(svg)), '\"}'\n        );\n        return string.concat(\"data:application/json;base64,\", _base64(bytes(json)));\n    }\n\n    // ---------------- ERC-721 Standard Implementation ----------------\n\n    function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {\n        return\n            interfaceId == type(IERC165).interfaceId ||\n            interfaceId == type(IERC721).interfaceId ||\n            interfaceId == type(IERC721Metadata).interfaceId;\n    }\n\n    function balanceOf(address owner) external view override returns (uint256) {\n        if (owner == address(0)) revert ZeroAddress();\n        return _balances[owner];\n    }\n\n    function ownerOf(uint256 tokenId) public view override returns (address) {\n        address owner = _owners[tokenId];\n        if (owner == address(0)) revert NonexistentToken();\n        return owner;\n    }\n\n    function approve(address to, uint256 tokenId) external override {\n        address owner = ownerOf(tokenId);\n        if (msg.sender != owner && !_operatorApprovals[owner][msg.sender]) revert NotAuthorized();\n        _tokenApprovals[tokenId] = to;\n        emit Approval(owner, to, tokenId);\n    }\n\n    function getApproved(uint256 tokenId) external view override returns (address) {\n        if (_owners[tokenId] == address(0)) revert NonexistentToken();\n        return _tokenApprovals[tokenId];\n    }\n\n    function setApprovalForAll(address operator, bool approved) external override {\n        if (operator == address(0)) revert ZeroAddress();\n        _operatorApprovals[msg.sender][operator] = approved;\n        emit ApprovalForAll(msg.sender, operator, approved);\n    }\n\n    function isApprovedForAll(address owner, address operator) external view override returns (bool) {\n        return _operatorApprovals[owner][operator];\n    }\n\n    function transferFrom(address from, address to, uint256 tokenId) public override {\n        if (to == address(0)) revert ZeroAddress();\n        address owner = ownerOf(tokenId);\n        if (owner != from) revert NotCardOwner();\n        if (\n            msg.sender != owner &&\n            !_operatorApprovals[owner][msg.sender] &&\n            _tokenApprovals[tokenId] != msg.sender\n        ) revert NotAuthorized();\n        if (cards[tokenId].isStaked) revert CardStakedInPool();\n\n        delete _tokenApprovals[tokenId];\n        _removeTokenFromOwnerEnumeration(from, tokenId);\n        _addTokenToOwnerEnumeration(to, tokenId);\n\n        unchecked {\n            _balances[from] -= 1;\n            _balances[to] += 1;\n        }\n        _owners[tokenId] = to;\n        emit Transfer(from, to, tokenId);\n    }\n\n    function safeTransferFrom(address from, address to, uint256 tokenId) external override {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public override {\n        transferFrom(from, to, tokenId);\n        if (to.code.length > 0) {\n            if (IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, data) != IERC721Receiver.onERC721Received.selector) {\n                revert TransferFailed();\n            }\n        }\n    }\n\n    function _mintToken(address to, uint256 tokenId) private {\n        _owners[tokenId] = to;\n        unchecked {\n            _balances[to] += 1;\n        }\n        _addTokenToOwnerEnumeration(to, tokenId);\n        emit Transfer(address(0), to, tokenId);\n    }\n\n    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n        _ownedTokensIndex[tokenId] = _ownedTokens[to].length;\n        _ownedTokens[to].push(tokenId);\n    }\n\n    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n        uint256 lastIndex = _ownedTokens[from].length - 1;\n        uint256 tokenIndex = _ownedTokensIndex[tokenId];\n        if (tokenIndex != lastIndex) {\n            uint256 lastTokenId = _ownedTokens[from][lastIndex];\n            _ownedTokens[from][tokenIndex] = lastTokenId;\n            _ownedTokensIndex[lastTokenId] = tokenIndex;\n        }\n        _ownedTokens[from].pop();\n        delete _ownedTokensIndex[tokenId];\n    }\n\n    // ---------------- String & Base64 Helpers ----------------\n\n    function _toString(uint256 value) private pure returns (string memory) {\n        if (value == 0) return \"0\";\n        uint256 temp = value;\n        uint256 digits;\n        while (temp != 0) {\n            digits++;\n            temp /= 10;\n        }\n        bytes memory buffer = new bytes(digits);\n        while (value != 0) {\n            digits -= 1;\n            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n            value /= 10;\n        }\n        return string(buffer);\n    }\n\n    string private constant _TABLE = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n    function _base64(bytes memory data) private pure returns (string memory) {\n        if (data.length == 0) return \"\";\n        string memory table = _TABLE;\n        string memory result = new string(4 * ((data.length + 2) / 3));\n        assembly {\n            let tablePtr := add(table, 1)\n            let resultPtr := add(result, 0x20)\n            let dataPtr := data\n            let endPtr := add(data, mload(data))\n            let afterPtr := add(endPtr, 0x20)\n            let afterCache := mload(afterPtr)\n            mstore(afterPtr, 0x00)\n            for {} lt(dataPtr, endPtr) {} {\n                dataPtr := add(dataPtr, 3)\n                let input := mload(dataPtr)\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))\n                resultPtr := add(resultPtr, 1)\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))\n                resultPtr := add(resultPtr, 1)\n                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))\n                resultPtr := add(resultPtr, 1)\n                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))\n                resultPtr := add(resultPtr, 1)\n            }\n            mstore(afterPtr, afterCache)\n            switch mod(mload(data), 3)\n            case 1 {\n                mstore8(sub(resultPtr, 1), 0x3d)\n                mstore8(sub(resultPtr, 2), 0x3d)\n            }\n            case 2 {\n                mstore8(sub(resultPtr, 1), 0x3d)\n            }\n        }\n        return result;\n    }\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"creator_","type":"address","internalType":"address payable"}],"stateMutability":"nonpayable"},{"name":"CardAlreadyStaked","type":"error","inputs":[]},{"name":"CardExpired","type":"error","inputs":[]},{"name":"CardNotStaked","type":"error","inputs":[]},{"name":"CardStakedInPool","type":"error","inputs":[]},{"name":"InvalidQuantity","type":"error","inputs":[]},{"name":"MaxSupplyReached","type":"error","inputs":[]},{"name":"NonexistentToken","type":"error","inputs":[]},{"name":"NotAgentIdHolder","type":"error","inputs":[]},{"name":"NotAuthorized","type":"error","inputs":[]},{"name":"NotCardOwner","type":"error","inputs":[]},{"name":"NothingToClaim","type":"error","inputs":[]},{"name":"OnlyCreator","type":"error","inputs":[]},{"name":"TransferFailed","type":"error","inputs":[]},{"name":"WrongPayment","type":"error","inputs":[]},{"name":"ZeroAddress","type":"error","inputs":[]},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"ApprovalForAll","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"BuybackExecuted","type":"event","inputs":[{"name":"bnbSpent","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"agmBurned","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"CardDeployedToPool","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"tier","type":"uint8","indexed":false,"internalType":"uint8"}],"anonymous":false},{"name":"CardMinted","type":"event","inputs":[{"name":"minter","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"tier","type":"uint8","indexed":false,"internalType":"uint8"},{"name":"isPaid","type":"bool","indexed":false,"internalType":"bool"},{"name":"expiresAt","type":"uint40","indexed":false,"internalType":"uint40"},{"name":"autoStaked","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"CardRenewed","type":"event","inputs":[{"name":"payer","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"newExpiresAt","type":"uint40","indexed":false,"internalType":"uint40"},{"name":"pricePaid","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"CardWithdrawnFromPool","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"PricingParamsUpdated","type":"event","inputs":[{"name":"lpPair","type":"address","indexed":false,"internalType":"address"},{"name":"renewalDiscountBps","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"minRenewalPrice","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"baseRenewalPrice","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"autoBuyback","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"RevenueSplit","type":"event","inputs":[{"name":"payer","type":"address","indexed":true,"internalType":"address"},{"name":"creatorShare","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"buybackShare","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"RewardsClaimed","type":"event","inputs":[{"name":"user","type":"address","indexed":true,"internalType":"address"},{"name":"amount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"feePaid","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Transfer","type":"event","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"AGENT_ID","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IAgentId"}],"stateMutability":"view"},{"name":"BNB_USD_FEED","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"CLAIM_FEE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"CREATOR","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address payable"}],"stateMutability":"view"},{"name":"DEAD_ADDRESS","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"FREE_DURATION","type":"function","inputs":[],"outputs":[{"name":"","type":"uint40","internalType":"uint40"}],"stateMutability":"view"},{"name":"FREE_QUOTA","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_PER_TX","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MINT_PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PAID_DURATION","type":"function","inputs":[],"outputs":[{"name":"","type":"uint40","internalType":"uint40"}],"stateMutability":"view"},{"name":"PANCAKE_FACTORY","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"PANCAKE_ROUTER","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"RATE_PER_WEIGHT_PER_MIN","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"WBNB","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"agmToken","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract AgentGoldMinerToken"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"autoBuyback","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"balanceOf","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"baseRenewalPrice","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"canClaimFree","type":"function","inputs":[{"name":"minter","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"cards","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"tier","type":"uint8","internalType":"uint8"},{"name":"isPaid","type":"bool","internalType":"bool"},{"name":"isStaked","type":"bool","internalType":"bool"},{"name":"mintedAt","type":"uint40","internalType":"uint40"},{"name":"expiresAt","type":"uint40","internalType":"uint40"},{"name":"lastSettledAt","type":"uint40","internalType":"uint40"}],"stateMutability":"view"},{"name":"claimRewards","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"name":"claimedFree","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"deployAllToPool","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"deployToPool","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"executeBuyback","type":"function","inputs":[{"name":"minAgmOut","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"freeMinted","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getApproved","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"getPoolReserves","type":"function","inputs":[],"outputs":[{"name":"reserveAGM","type":"uint256","internalType":"uint256"},{"name":"reserveBNB","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getRenewalPrice","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getRenewalPriceByTier","type":"function","inputs":[{"name":"tier","type":"uint8","internalType":"uint8"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getUserCards","type":"function","inputs":[{"name":"user","type":"address","internalType":"address"}],"outputs":[{"name":"tokenIds","type":"uint256[]","internalType":"uint256[]"},{"name":"tiers","type":"uint8[]","internalType":"uint8[]"},{"name":"isPaidList","type":"bool[]","internalType":"bool[]"},{"name":"isStakedList","type":"bool[]","internalType":"bool[]"},{"name":"expiresAtList","type":"uint40[]","internalType":"uint40[]"},{"name":"pendingList","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"name":"isAgent","type":"function","inputs":[{"name":"account","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isApprovedForAll","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"lpPair","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"minRenewalPrice","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"name":"mint","type":"function","inputs":[{"name":"quantity","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintCards","type":"function","inputs":[{"name":"quantity","type":"uint256","internalType":"uint256"},{"name":"autoDeploy","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"payable"},{"name":"mintedBy","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"pendingCardRewards","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"pendingRewards","type":"function","inputs":[{"name":"user","type":"address","internalType":"address"}],"outputs":[{"name":"total","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"priceFor","type":"function","inputs":[{"name":"minter","type":"address","internalType":"address"},{"name":"quantity","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"quote","type":"function","inputs":[{"name":"minter","type":"address","internalType":"address"},{"name":"quantity","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"renewCard","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"renewalDiscountBps","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"resolveLpPair","type":"function","inputs":[],"outputs":[{"name":"pair","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setApprovalForAll","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setPricingParams","type":"function","inputs":[{"name":"_lpPair","type":"address","internalType":"address"},{"name":"_renewalDiscountBps","type":"uint256","internalType":"uint256"},{"name":"_minRenewalPrice","type":"uint256","internalType":"uint256"},{"name":"_baseRenewalPrice","type":"uint256","internalType":"uint256"},{"name":"_autoBuyback","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supportsInterface","type":"function","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"pure"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tierMintedCount","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"tokenURI","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tokensOfOwner","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"name":"totalAgmBoughtBack","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalBuybackReserveBNB","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalClaimFeeBNB","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalCreatorRevenueBNB","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalLpReserveBNB","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalStakedCards","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"unclaimedRewards","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"userMiningRatePerMin","type":"function","inputs":[{"name":"user","type":"address","internalType":"address"}],"outputs":[{"name":"ratePerMinWei","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"withdrawFromPool","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"56897484","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-10-25T01:10:25Z","match":"exact_match","chainId":"56","address":"0x6dE46f5D65833E551b6d00c8A30665E65E241A2c"}