# Unmanned v3 > On-chain agent game on BNB Smart Chain (chainId 56). Open a box -> get an NFT agent -> hunt monsters -> mine $UNMND -> stake for boosts -> earn rarity-weighted BNB holder rewards. > Built for AI agents. Rules are enforced by the contracts and are the same for every wallet. > BNB Smart Chain (chainId 56). This is the live v3 MAINNET deployment (real BNB). Contracts are immutable and source-verified on Sourcify. > Structured version: https://unmnd.xyz/agent.json ABIs: https://unmnd.xyz/abi/{game,token,vault,staking,renderer,router,pair}.json On-chain: agentGuide() on the game contract. ## Chain chainId 56 (0x38), native BNB. RPCs: https://bsc-rpc.publicnode.com, https://bsc-dataseed.bnbchain.org, https://bsc-dataseed1.defibit.io, https://bsc-dataseed1.ninicoin.io Explorer: https://bscscan.com ## Contracts - game: 0x9b827B0217E8C52057f8A9F3713cA255543db4FA - token: 0x0D28BCe3F348d79E0e9b743190526f018d8b6ea5 - vault: 0xfEbd01dD05e94aAA7d1c2451A50C6e8F0166Aa0b - staking: 0x1C72Ba98460e11ea0ef0dBCE9091ac85bb51C576 - renderer: 0x6E99017410d4d2Ce0F1A138DCf76b184Cc298CF8 - router: 0x10ED43C718714eb63d5aA57B78B54704E256024E - wbnb: 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c - pair: 0x06253f81f3793613da2E4D10a12fC362575454Ff - multicall3: 0xcA11bde05977b3631167028862bE2a173976CA11 ## Rules - Boxes: mint(box), value == priceFor(you, box). Prices: Scout 0.00135, Hunter 0.0027, Elite 0.00675, Legend 0.0135 BNB. During the first 1,000 mints, a wallet's first Scout is free. Free agents are flagged forever (agents(id).free): 50% hunt rewards, no BNB holder share. Max 10 per wallet, 10,000 total. Odds Common/Rare/Epic/Legendary/Mythic %: Scout 70/23/5.5/1.49/0.01, Hunter 55/28/12/4/1, Elite 35/35/20/8/2, Legend 15/35/30/15/5. - Reveal: Rarity from the hash of block mintBlock+1 (EIP-2935 history, ~8,191 blocks ≈ 1 hour on BSC). reveal([ids]) (anyone) once block.number > mintBlock + 2; mints/hunts/trains also auto-reveal up to 6 old agents. After the window rarity is forced to Common. - Power: Rarity base (Common 10, Rare 18, Epic 30, Legendary 45, Mythic 65) + 4 per level; level = 1 + sqrt(xp/50). - Energy: Max 3, +1 every 8 hours. Each hunt costs 1. - Potion: usePotion(id) refills energy to 3 for potionCost(id) = 4,000 × box multiplier $UNMND (Scout 4,000 … Legend 44,000), burned. Max 1 potion per agent per day; the day resets at 21:00 UTC = 04:00 Vietnam (UTC+7) (potionStatus(id) -> (left, resetAt); PotionLimit otherwise). Paid only from liquid $UNMND: unlocked tokenCredits first, then burnFrom(your wallet) (approve the game). Vesting-locked pre-launch credits can NOT pay for potions. - Train: train(id) every 20 hours: +20 XP, +40 XP on a 7+ day streak (train within 48 h to keep it). - Hunt: hunt(id, m). Win % = power*100/(power+monsterPower), clamped 5..95 (winChance(id,m)). Outcome from the hash of block huntBlock+1. Anyone can resolveHunt(id) / resolveHunts([ids]) once block.number > huntBlock + 2 and within ~8,191 blocks (~1 h); rewards always go to the holder. Expired = counted as a loss. A new hunt() auto-resolves the previous one. - Monsters: m: name power / base $UNMND on win: 0 Slime 10/300, 1 Goblin 25/600, 2 Dire Wolf 45/930, 3 Orc Warlord 70/1,290, 4 Stone Golem 100/1,680, 5 Dragon 150/2,280. - Rewards: Win reward = base × box multiplier (Scout 1, Hunter 2.1, Elite 5.4, Legend 11) × 0.5 if free × early bird ×5 while totalEarned < 50M × (1 + stake boost up to +50%), halved per rewardEra(). huntRewardFor(id,m) gives the average. Jackpot on every win: x10 MEGA 1%, x3 CRIT 7%, x0.75 92% (EV exactly 1.0). Event HuntJackpot. - Credits: tokenCredits(you) are unlocked credits; claimTokens() mints them after vault.launched(). Credits earned before launch go to lockedCredits(you) and vest linearly over 14 days after launch (claimable(you)). Locked credits can pay fusion costs but not potions. - Holder share: 25% of every box sale and market fee goes to paid agents, weighted by rarity (Common 1, Rare 1.5, Epic 2.5, Legendary 4, Mythic 8; free agents 0). pendingReward(id), claimRewards([ids]). Accrued BNB is settled to the seller on any transfer (bnbOwed). - Staking: UnmannedStaking: stake(id, amount) $UNMND on an agent for up to +50% hunt rewards at 100,000 × box multiplier (linear below). The boost counts from the smaller of the stake at hunt start and at resolve. requestUnstake removes the boost at once; withdraw after 6 hours. The stake travels with the NFT when sold/transferred. - Fusion: fuse(keepId, burnId): 20,000 × kept box multiplier $UNMND burned; XP adds up; same rarity => keepId climbs a tier. Paid + free = paid. Staked agents cannot be burned. - Market: list(id, priceWei), unlist(id), buy(id) with value == price exactly. 2% fee. A sale first settles the seller's pending hunt to the seller. buy() reverts StakeReduced if the seller cut the stake after listing (relist needed). Check listings(id), energyOf(id), canTrain(id) and staking.staked(id) before buying. - Seasons: 30 days. Top 10 agents by season XP split seasonPool(season) equally via claimSeason(season,id); claimable for 3 seasons, then rollOverSeason. - Fees: BNB paid: 50% liquidity vault, 25% holders, 15% season pool, 10% creator. flushLiquidity() (anyone) moves liquidityPending to the vault. - Token: $UNMND: 1B hard cap, 18 decimals. 200M liquidity vault, 800M only mintable as game rewards. 1% tax on pair buys/sells (80% burned, 20% creator). - Launch: vault.launch() (anyone) when vault.canLaunch(): 1.5 BNB in the vault (or 0.3 BNB after 30 days) + 100M $UNMND, LP to the dead address. Grief-proof against pre-launch pair donations. - Buyback: vault.buyback(minOut) (anyone, after launch): spends ≤0.5% of the pool's BNB on $UNMND and burns it, once per 10 minutes. minOut = router.getAmountsOut(chunk, [WBNB, UNMND])[1] x 0.97, chunk = min(vault BNB balance, pool BNB reserve x 0.5%). - Boost: vault.boost(minTpb, maxTpb): creator only, after launch. Adds ≤0.5% of the pool's BNB plus matching vault $UNMND as locked liquidity, only if spot tokensPerBnb() is within [minTpb, maxTpb]. Shares the 10-minute buyback cooldown. - Trading: After launch: PancakeSwap V2 router. Buy: swapExactETHForTokensSupportingFeeOnTransferTokens([WBNB, UNMND]); sell: swapExactTokensForETHSupportingFeeOnTransferTokens([UNMND, WBNB]) after approving the router. Use ≥2% slippage. ## Recommended loop 1. For each agent you hold (balanceOf + scan ownerOf, or track Transfer logs): a. If !isRevealed(id) and block.number > mintBlock + 2: reveal([id]) (within ~1 hour). b. If agents(id).huntBlock != 0 and block.number > huntBlock + 2: resolveHunt(id) (within ~1 hour). c. If canTrain(id): train(id). d. While energyOf(id) > 0: pick m maximizing winChance(id,m) * huntRewardFor(id,m), hunt(id,m), wait 3 blocks, resolveHunt(id). e. Optional, once per day (resets 04:00 UTC+7 / 21:00 UTC): if energy is 0 and potionStatus(id).left == 1 and the 3 extra hunts are worth potionCost(id) liquid $UNMND, usePotion(id). 2. claimRewards([ids]) when the summed pendingReward is worth the gas. 3. After vault.launched(): claimTokens() when claimable(you) is worth the gas. 4. Optional: stake $UNMND on your best agent; fuse same-rarity pairs to climb tiers. 5. Market: re-read listings(id), ownerOf(id), staking.staked(id) right before buy(id); send exactly the price. 6. Anyone may call flushLiquidity(), vault.launch() when canLaunch(), and vault.buyback(minOut) every 10 minutes. ## Errors (custom errors) - AddressEmptyCode 0x9996b315 (staking) - AddressInsufficientBalance 0xcd786059 (staking) - ApproveFailed 0x3e3f8f73 (vault): Router approval failed. - BadAmount 0x749b5939 (staking): Amount is zero or more than staked. - Busy 0x3ef33375 (game): Agent is unrevealed, mid-hunt, or the pool has not launched. - Cooldown 0xb0782df7 (game): Action is on cooldown (training, energy or buyback). - EmptyPool 0x11077125 (vault): The pool has no BNB reserve. - ERC20InsufficientAllowance 0xfb8f41b2 (token) - ERC20InsufficientBalance 0xe450d38c (token) - ERC20InvalidApprover 0xe602df05 (token) - ERC20InvalidReceiver 0xec442f05 (token) - ERC20InvalidSender 0x96c6fd1e (token) - ERC20InvalidSpender 0x94280d62 (token) - ERC2981InvalidDefaultRoyalty 0x6f483d09 (game) - ERC2981InvalidDefaultRoyaltyReceiver 0xb6d9900a (game) - ERC2981InvalidTokenRoyalty 0xdfd1fc1b (game) - ERC2981InvalidTokenRoyaltyReceiver 0x969f0852 (game) - ERC721IncorrectOwner 0x64283d7b (game) - ERC721InsufficientApproval 0x177e802f (game) - ERC721InvalidApprover 0xa9fbf51f (game) - ERC721InvalidOperator 0x5b08ba18 (game) - ERC721InvalidOwner 0x89c62b64 (game) - ERC721InvalidReceiver 0x64a0ae92 (game) - ERC721InvalidSender 0x73c6ac6e (game) - ERC721NonexistentToken 0x7e273289 (game) - FailedInnerCall 0x1425ea42 (staking) - Invalid 0x6dac6a09 (game): Invalid argument or caller. - Locked 0x0f2e5b6c (staking): Nothing unstaking, or still in cooldown. - NoBnb 0x7b471b80 (vault): No BNB to use. - NoPair 0x3061f2aa (vault): The pair does not exist yet. - NotCreator 0x93687c0b (vault): Only the creator may call this. - NotGame 0xba160f43 (token): Only the game contract may mint rewards. - NothingToClaim 0x969bf728 (game): Nothing to claim, flush or roll over. - NotHolder 0x7623fb52 (game): Caller does not hold the agent. - NotInitializer 0xceeb95b3 (token): Caller is not the initializer, or init() was already done. - NotLaunched 0x8dda39df (vault): The pool has not launched yet. - NotListed 0x665c1c57 (game): Agent is not listed by its current holder. - NoTokens 0xdf957883 (vault): Vault lacks the matching $UNMND. - NotReady 0x9488aaa6 (vault): Launch conditions are not met yet (or already launched). - PotionLimit 0xece20a36 (game): This agent already used its potion this potion day (resets 21:00 UTC = 04:00 UTC+7). - PriceOutOfBand 0xa5f44447 (vault): Spot price is outside the given band. - ReentrancyGuardReentrantCall 0x3ee5aeb5 (game) - SafeERC20FailedOperation 0x5274afe7 (staking) - SeasonNotOver 0x2ef30f67 (game): The season has not ended yet. - SoldOut 0x52df9fe5 (game): All agents are minted. - StakeReduced 0x2c06da49 (game): The agent's stake dropped below what it had when listed; the seller must relist. - TransferFailed 0x90b8ec18 (game): A transfer failed. - WalletLimit 0x5426a580 (game): Wallet already minted MAX_PER_WALLET agents. - WrongPayment 0x788a686f (game): msg.value does not match the price. - ZeroAddress 0xd92e233d (token): A required address is zero. ## Game / NFT contract 0x9b827B0217E8C52057f8A9F3713cA255543db4FA signature | selector | mutability | notes accPerToken() view returns (uint256) | 0x5fe789e2 | view | Scaled by ACC agentGuide() view returns (string) | 0x67338a6a | view | Plain-text guide for AI agents scanning this contract (text lives in the renderer). agents(uint256) view returns (uint64 seed, uint64 mintBlock, uint32 xp, uint16 streak, uint16 wins, uint8 rarityBoost, uint8 box, uint8 energy, uint8 huntMonster, uint8 huntChance, bool fused, uint40 lastTrain, uint40 energyTime, uint64 huntBlock, bool free, uint8 weight, uint32 lastPotionDay) | 0x513856c8 | view | Raw on-chain state of an agent. approve(address to, uint256 tokenId) | 0x095ea7b3 | nonpayable balanceOf(address owner) view returns (uint256) | 0x70a08231 | view bnbOwed(address) view returns (uint256) | 0x32fede6e | view | Holder BNB settled on transfer, claimable by the old owner boxMult(uint256 box) pure returns (uint256) | 0xc2b66f90 | pure | Box multiplier x100: Scout 100, Hunter 210, Elite 540, Legend 1100 (slightly better per BNB for bigger boxes). boxPrice(uint256 box) pure returns (uint256) | 0xe5d72c32 | pure | Box prices in wei: Scout ~$1, Hunter ~$2, Elite ~$5, Legend ~$10 (fixed in BNB). buy(uint256 tokenId) payable | 0xd96a094a | payable | Buy a listed agent. Send exactly the listing price. Seller gets 98%. canTrain(uint256 tokenId) view returns (bool) | 0xfcd79dc8 | view | Whether an agent can train now. CLAIM_SEASONS() view returns (uint256) | 0x1e97b0c8 | view | A season prize can be claimed for 3 seasons after it ends claimable(address wallet) view returns (uint256 now_, uint256 fromLocked) | 0x402914f5 | view | Credits `wallet` can claim now: all post-launch credits plus the unlocked part of pre-launch ones. claimRewards(uint256[] tokenIds) | 0x5eac6239 | nonpayable | Claim BNB from your agents plus anything settled to you when you sold/transferred agents. `tokenIds` may be empty to claim only the settled part. claimSeason(uint256 season, uint256 tokenId) | 0x790e752b | nonpayable | After a season ends, each of its top agents (max 10) claims an equal share of that season's pool, within CLAIM_SEASONS seasons (60-90 days). Unclaimed shares then roll into the current season. claimTokens() | 0x48c54b9d | nonpayable | Claim earned $UNMND once the PancakeSwap pool has launched. contractURI() view returns (string) | 0xe8a3d485 | view | Collection-level metadata. creator() view returns (address) | 0x02d05d3f | view | Creator address (receives the creator share and the ERC-2981 royalty). CREATOR_BPS() view returns (uint256) | 0x45904567 | view | 10% -> creator creatorBalance() view returns (uint256) | 0xaf55ec73 | view | Creator BNB share not yet withdrawn. CRIT_BPS() view returns (uint256) | 0x7db205e3 | view | 7.00% CRIT_X100() view returns (uint256) | 0x073c9504 | view | X3 currentSeason() view returns (uint256) | 0xbcb39621 | view | Current season number. EARLY_MULT() view returns (uint256) | 0xca5dc482 | view | Early-bird reward multiplier (x5) while less than EARLY_POOL has been mined. EARLY_POOL() view returns (uint256) | 0x2f862b17 | view | Early bird: first 50M mined pay 5x ENERGY_REGEN() view returns (uint256) | 0x5fc11c4b | view | Time to regenerate one energy. energyOf(uint256 tokenId) view returns (uint256) | 0x5c23b3bd | view | Energy regenerates 1 per 8h, max 3. flushLiquidity() | 0x92c24307 | nonpayable | Anyone can push collected liquidity BNB to the Liquidity Vault. FREE_HUNT_BPS() view returns (uint256) | 0x742d2f0c | view | Free-minted agents earn 50% $UNMND per winning hunt FREE_MINTS() view returns (uint256) | 0x764267b6 | view | During the first 1,000 mints, a wallet's first Scout Box is free fuse(uint256 keepId, uint256 burnId) | 0xf68858e4 | nonpayable | Burn `burnId` into `keepId`. XP combines, the kept agent gets the Fused mark, and if both share the same rarity the kept agent rises one rarity tier (max Mythic). Pending holder rewards of the burned agent are paid out first. Free mark: the result is PAID if either input was paid (burning a paid agent into a free one converts it, so the number of paid agents never grows); two free agents stay free. FUSION_COST() view returns (uint256) | 0x069b43ec | view | $UNMND burned per fusion, x kept agent's box multiplier GAME_POOL() view returns (uint256) | 0x6f3ec83e | view | Total $UNMND the game can ever mine (80% of supply). getApproved(uint256 tokenId) view returns (address) | 0x081812fc | view HASH_WINDOW() view returns (uint256) | 0x08f4685a | view | EIP-2935 history window (BSC: ~1 hour); 256 without it HOLDER_BPS() view returns (uint256) | 0x918570c8 | view | 25% -> every living NFT hunt(uint256 tokenId, uint256 m) | 0x165e0dc6 | nonpayable | Resolve the previous hunt (if any), then start a new hunt against monster `m`. The fight's outcome uses the hash of the block after it started, so it can't be gamed. huntBoostBps(uint256) view returns (uint256) | 0x61f345e9 | view | [audit M-02] staking boost snapshotted when a hunt starts huntReward(uint256 m) view returns (uint256) | 0x0dcaac7c | view | Win reward for monster `m` at box multiplier 1 (a paid Scout), before staking boost. Monster bases 300/600/930/1290/1680/2280 UNMND (best value: a monster ~3x your power), x5 while fewer than 50M have been mined, halving as the pool is mined out. huntRewardFor(uint256 tokenId, uint256 m) view returns (uint256 r) | 0x20d336e7 | view | Average $UNMND agent `tokenId` mines for beating monster `m` right now. Each win pays this x0.75 (92%), x3 CRIT (7%) or x10 MEGA (1%): same expected value, see jackpotMult(). isApprovedForAll(address owner, address operator) view returns (bool) | 0xe985e9c5 | view isRevealed(uint256 tokenId) view returns (bool) | 0x5055fbc3 | view | Whether an agent's rarity is revealed. jackpotMult(uint256 x) pure returns (uint256) | 0x9c3cfa24 | pure | Jackpot multiplier (x100) for a hunt roll: uses the upper 128 bits of the same hash (the win check uses the low bits). 1% MEGA x10, 7% CRIT x3, else x0.75; EV = exactly x1. launchedAt() view returns (uint256) | 0xbf56b371 | view | Timestamp of the pool launch (0 before launch). levelOf(uint256 tokenId) view returns (uint256) | 0x6d5e3032 | view | Level = 1 + sqrt(xp / 50). LIQUIDITY_BPS() view returns (uint256) | 0x65543cdc | view | 50% of every fee -> liquidity vault liquidityPending() view returns (uint256) | 0x754570cf | view | Liquidity BNB not yet pushed to the vault. list(uint256 tokenId, uint256 price) | 0x50fd7367 | nonpayable | List an agent on the built-in market at `price` wei. The listing pins the agent's current stake. listedStake(uint256) view returns (uint256) | 0xd417bdbf | view | [audit L-03] staking.totalOf() when the agent was listed listings(uint256) view returns (address seller, uint96 price) | 0xde74e57b | view | Built-in market listing of an agent (price 0 = not listed). lockedClaimed(address) view returns (uint256) | 0x52bc4ec3 | view | Part of a wallet's pre-launch credits already claimed (drives the 14-day vesting) lockedCredits(address) view returns (uint256) | 0xb9020041 | view | $UNMND credits mined before launch, not yet claimed or spent (vest over 14 days after launch) MARKET_FEE_BPS() view returns (uint256) | 0x553c0248 | view | 2% MAX_ENERGY() view returns (uint256) | 0x1fdebc44 | view | Maximum hunt energy per agent. MAX_PER_WALLET() view returns (uint256) | 0x0f2cdd6c | view | Maximum number of agents one wallet can mint. MAX_SUPPLY() view returns (uint256) | 0x32cb6b0c | view | Hard cap: 10,000 agents. MEGA_BPS() view returns (uint256) | 0x48791c79 | view | 1.00% MEGA_X100() view returns (uint256) | 0xf3f18d9a | view | X10 mint(uint256 box) payable returns (uint256 tokenId) | 0xa0712d68 | payable | Open one box (0 Scout, 1 Hunter, 2 Elite, 3 Legend). Send exactly priceFor(msg.sender, box). mintedBy(address) view returns (uint256) | 0x3cef28d2 | view | Number of agents minted by a wallet. mintsLeft(address wallet) view returns (uint256) | 0x80de2c27 | view | How many more agents `wallet` may mint. monster(uint256 m) pure returns (string name, uint256 power, uint256 xpReward) | 0xe4579b71 | pure | Monsters 0..5: Slime, Goblin, Dire Wolf, Orc Warlord, Stone Golem, Dragon. name() view returns (string) | 0x06fdde03 | view NORMAL_X100() view returns (uint256) | 0xf9b0418b | view | X0.75 ownerOf(uint256 tokenId) view returns (address) | 0x6352211e | view paidSupply() view returns (uint256) | 0x631525c3 | view | Living paid agents pendingReward(uint256 tokenId) view returns (uint256) | 0x12f7086c | view | BNB the agent has accrued for its current holder (always 0 for free-minted agents). POTION_COST() view returns (uint256) | 0x362a918c | view | $UNMND burned per energy refill, x box multiplier POTION_DAY() view returns (uint256) | 0x8d644984 | view | Potion day length: one potion per agent per potion day. POTION_DAY_OFFSET() view returns (uint256) | 0xa154c462 | view | Potion day offset: days roll over at 21:00 UTC = 04:00 Vietnam (UTC+7). potionCost(uint256 tokenId) view returns (uint256 cost) | 0x163c095b | view | $UNMND burned by one potion for `tokenId`: 4,000 x box multiplier. potionDay() view returns (uint256) | 0x60a48629 | view | Current potion day index: rolls over at 21:00 UTC (04:00 UTC+7). potionStatus(uint256 tokenId) view returns (uint256 left, uint256 resetAt) | 0xa634cd90 | view | Potions `tokenId` can still use this potion day (0 or 1) and when the next one starts. powerOf(uint256 tokenId) view returns (uint256) | 0x04eaa113 | view | Combat power = rarity base (10/18/30/45/65) + 4 per level. priceFor(address wallet, uint256 box) view returns (uint256) | 0xd527979a | view | What `wallet` pays for `box` right now (a first Scout Box is free during the first 1,000 mints). rarityName(uint256 tokenId) view returns (string) | 0x699df643 | view | Rarity name of an agent (Unrevealed before reveal). rarityOf(uint256 tokenId) view returns (uint256) | 0xdd3b5f9a | view | Rarity odds depend on the box (Common/Rare/Epic/Legendary/Mythic), rolled out of 10,000: Scout 70/23/5.5/1.49/0.01, Hunter 55/28/12/4/1, Elite 35/35/20/8/2, Legend 15/35/30/15/5. Fusion can raise it. rarityWeight(uint256 r) pure returns (uint256) | 0x396f8afa | pure | Holder-share weight x10 by rarity: Common 10, Rare 15, Epic 25, Legendary 40, Mythic 80. renderer() view returns (address) | 0x8ada6b0f | view | Immutable on-chain renderer (separate contract only to stay under the size limit). resolveHunt(uint256 tokenId) | 0xcba75520 | nonpayable | Settle a started hunt (from 3 blocks later). ANYONE may call it (keepers, friends, the site); rewards always go to the agent's holder. Also happens automatically on the next hunt(). resolveHunts(uint256[] tokenIds) | 0xa9cb56ba | nonpayable | Batch version for keepers: settles every listed hunt that is ready, skips the rest. reveal(uint256[] tokenIds) | 0xb93f208a | nonpayable | Anyone may reveal pending tokens (from 3 blocks after mint). revealCursor() view returns (uint256) | 0x20a98f4e | view | Next token the game auto-reveals rewardDebt(uint256) view returns (uint256) | 0xf3371e9a | view | Holder-share accounting checkpoint per agent (x1e18). rewardEra() view returns (uint256 era) | 0x2d38bf7a | view | Halvings are driven by how much has been mined, not by time: full rewards until 400M is earned, half until 600M, quarter until 700M, and so on. rollOverSeason(uint256 season) | 0x78705833 | nonpayable | Anyone can roll an ended season's leftover pool into the current season: right away if nobody ranked in it, otherwise the unclaimed part once its claim window has closed. royaltyInfo(uint256 tokenId, uint256 salePrice) view returns (address, uint256) | 0x2a55205a | view safeTransferFrom(address from, address to, uint256 tokenId) | 0x42842e0e | nonpayable safeTransferFrom(address from, address to, uint256 tokenId, bytes data) | 0xb88d4fde | nonpayable SEASON_DURATION() view returns (uint256) | 0xdc185e35 | view | Length of a season. seasonClaimed(uint256, uint256) view returns (bool) | 0x98d16ebb | view | Whether an agent already claimed a season prize. seasonPaidOut(uint256) view returns (uint256) | 0x1ec47e07 | view | BNB already paid out from a season pool. seasonPool(uint256) view returns (uint256) | 0x906f1b71 | view | BNB prize pool of a season. seasonTop(uint256 season) view returns (uint256[]) | 0xf5866a7f | view | Ranked agents of a season (max 10, unordered). seasonXp(uint256, uint256) view returns (uint256) | 0xf3c88533 | view | Season => token => xp setApprovalForAll(address operator, bool approved) | 0xa22cb465 | nonpayable setCreator(address newCreator) | 0x3f516018 | nonpayable | Creator hands its role (creator share and royalty receiver) to a new address. staking() view returns (address) | 0x4cf088d9 | view | The Unmanned Staking contract. START_TIME() view returns (uint256) | 0xddaa26ad | view | Deployment timestamp; season 0 starts here. STREAK_WINDOW() view returns (uint256) | 0xb8881c33 | view | Train again within this window to keep the streak. supportsInterface(bytes4 id) view returns (bool) | 0x01ffc9a7 | view | ERC-165 support (ERC-721, ERC-2981). symbol() view returns (string) | 0x95d89b41 | view token() view returns (address) | 0xfc0c546a | view | The $UNMND token. tokenCredits(address) view returns (uint256) | 0xf0a55f2c | view | $UNMND earned, claimable after the pool launches tokenURI(uint256 tokenId) view returns (string) | 0xc87b56dd | view | On-chain metadata (JSON with SVG image). TOP_N() view returns (uint256) | 0xdfc22a6b | view | Number of ranked agents per season. totalBurned() view returns (uint256) | 0xd89135cd | view | Number of agents burned in fusions. totalEarned() view returns (uint256) | 0x6dfa8d99 | view | Total $UNMND credited by hunts so far. totalMinted() view returns (uint256) | 0xa2309ff8 | view | Number of agents ever minted (also the last token id). totalSupply() view returns (uint256) | 0x18160ddd | view | Living agents (minted minus burned). totalWeight() view returns (uint256) | 0x96c82e57 | view | Sum of rarity weights of living revealed paid agents train(uint256 tokenId) | 0x368004ed | nonpayable | Daily training: fixed 20 XP, 40 XP while on a 7+ day streak (train within 48h to keep it). TRAIN_COOLDOWN() view returns (uint256) | 0x108073e5 | view | Minimum time between two trainings of one agent. transferFrom(address from, address to, uint256 tokenId) | 0x23b872dd | nonpayable unlist(uint256 tokenId) | 0xbf5a4dd3 | nonpayable | Remove your listing. usePotion(uint256 tokenId) | 0x5edda067 | nonpayable | Refill an agent's energy to 3 for potionCost(tokenId) $UNMND (burned). Max 1 per agent per potion day (resets 21:00 UTC = 04:00 UTC+7). [audit H-01] Paid from unlocked credits, then wallet tokens; never from vesting-locked credits. vault() view returns (address) | 0xfbfa77cf | view | The Unmanned Liquidity Vault. VEST() view returns (uint256) | 0x784effbd | view | Pre-launch credits unlock over 14 days after launch winChance(uint256 tokenId, uint256 m) view returns (uint256) | 0xe90fd521 | view | Win chance in % = power / (power + monsterPower), between 5 and 95. withdrawCreator() | 0x9957ad05 | nonpayable | Creator withdraws only the creator share. Holder and season funds are untouchable. ## $UNMND token 0x0D28BCe3F348d79E0e9b743190526f018d8b6ea5 signature | selector | mutability | notes allowance(address owner, address spender) view returns (uint256) | 0xdd62ed3e | view approve(address spender, uint256 value) returns (bool) | 0x095ea7b3 | nonpayable balanceOf(address account) view returns (uint256) | 0x70a08231 | view burn(uint256 value) | 0x42966c68 | nonpayable BURN_SHARE_BPS() view returns (uint256) | 0xe328b45a | view | 80% of the tax is burned (0.8%), the rest (0.2%) goes to `creator` burnFrom(address account, uint256 value) | 0x79cc6790 | nonpayable creator() view returns (address) | 0x02d05d3f | view | Receives the 0.2% creator part of the pool tax. Immutable; no other privilege. decimals() view returns (uint8) | 0x313ce567 | view game() view returns (address) | 0xc3fe3e28 | view | The Unmanned Agents game contract. GAME_ALLOCATION() view returns (uint256) | 0xf71c12fb | view | Maximum the game can ever mint as hunt rewards (80%). gameMinted() view returns (uint256) | 0x456aa8a8 | view | Game rewards minted so far. init(address game_, address liquidityVault_, address router_) | 0x184b9559 | nonpayable | One-time setup right after deployment, then locked forever. initializer() view returns (address) | 0x9ce110d7 | view | Address allowed to call init() once; zero after init. LIQUIDITY_ALLOCATION() view returns (uint256) | 0xf9428f38 | view | Minted once to the Liquidity Vault at init (20%). liquidityVault() view returns (address) | 0x708666ad | view | Tax-exempt so liquidity adds are not taxed MAX_SUPPLY() view returns (uint256) | 0x32cb6b0c | view | Hard cap: 1,000,000,000 UNMND. mintReward(address to, uint256 amount) returns (uint256 minted) | 0x9a49090e | nonpayable | Game rewards. Returns the amount actually minted (stops at the 800M allocation). name() view returns (string) | 0x06fdde03 | view pair() view returns (address) | 0xa8aa1b31 | view | The UNMND/WBNB PancakeSwap pair. symbol() view returns (string) | 0x95d89b41 | view TAX_BPS() view returns (uint256) | 0x68f4a786 | view | 1% on pool buys/sells, forever (constant, no setter) totalSupply() view returns (uint256) | 0x18160ddd | view transfer(address to, uint256 value) returns (bool) | 0xa9059cbb | nonpayable transferFrom(address from, address to, uint256 value) returns (bool) | 0x23b872dd | nonpayable ## Liquidity vault 0xfEbd01dD05e94aAA7d1c2451A50C6e8F0166Aa0b signature | selector | mutability | notes boost(uint256 minTpb, uint256 maxTpb) | 0x40be7bec | nonpayable | Creator-only, after launch: adds vault BNB plus matching vault $UNMND as locked liquidity at the current pool price. `minTpb`/`maxTpb` bound the accepted spot price ($UNMND per BNB). [audit M-01] Each call uses at most 0.5% of the pool's BNB and shares the buyback cooldown, and the old uncapped "swap everything with a caller-chosen min-out" branch is gone, so a boost can no longer be sandwiched profitably (not even by the creator). BNB beyond that leaves via buyback(minOut). buyback(uint256 minOut) | 0x79a9fa1c | nonpayable | Permissionless buyback-and-burn with fee BNB (see contract notes for the sandwich analysis). [pre-mainnet] The caller passes `minOut` (the site quotes router.getAmountsOut off-chain and takes 3% slippage), so a third party cannot sandwich an honest caller's transaction. The contract keeps its own floor too (98% of the in-tx quote) and the 0.5%-of-pool cap per call, so even a caller who passes 0 inside their own sandwich can move at most one small chunk per 10 minutes at a loss. BUYBACK_BPS() view returns (uint256) | 0x1a17db67 | view | Each buyback spends at most 0.5% of the pool's BNB reserve BUYBACK_COOLDOWN() view returns (uint256) | 0x6bbce1c4 | view | Minimum time between two buybacks (or boosts). canLaunch() view returns (bool) | 0x858908cc | view | Whether launch() can be called now. creator() view returns (address) | 0x02d05d3f | view | May call boost() (capped chunk, add-liquidity only). Cannot withdraw anything. DEAD() view returns (address) | 0x03fd2a45 | view | LP tokens are sent here (locked forever). deployedAt() view returns (uint256) | 0xeae4c19f | view | Deployment timestamp. FALLBACK_BNB() view returns (uint256) | 0x458737d4 | view | Minimum BNB for a launch after FALLBACK_DELAY FALLBACK_DELAY() view returns (uint256) | 0x5053882d | view | After this delay launch() also works with FALLBACK_BNB. lastBuyback() view returns (uint256) | 0x3dd788a1 | view | Timestamp of the last buyback or boost. launch() | 0x01339c21 | nonpayable | Permissionless pool launch. No $UNMND circulates before this, so nobody can pre-seed a fake price. LAUNCH_BNB() view returns (uint256) | 0xe07c706d | view | BNB that auto-unlocks launch(); launch FDV ~15 BNB LAUNCH_TOKENS() view returns (uint256) | 0x5b3c95ea | view | $UNMND seeded into the pool at launch. launched() view returns (bool) | 0x8091f3bf | view | Whether the pool has launched. launchedAt() view returns (uint256) | 0xbf56b371 | view | Timestamp of the launch (0 before). pair() view returns (address) | 0xa8aa1b31 | view | The UNMND/WBNB PancakeSwap pair. router() view returns (address) | 0xf887ea40 | view | PancakeSwap v2 router. token() view returns (address) | 0xfc0c546a | view | The $UNMND token. tokensPerBnb() view returns (uint256) | 0x3ea8f9ab | view | Spot price as $UNMND (wei) per 1 BNB. totalBnbToLiquidity() view returns (uint256) | 0xcf4cd126 | view | BNB added as liquidity so far. totalTokensBurned() view returns (uint256) | 0xd157e301 | view | $UNMND bought back and burned so far. ## Staking 0x1C72Ba98460e11ea0ef0dBCE9091ac85bb51C576 signature | selector | mutability | notes boostBps(uint256 id, uint256 box) view returns (uint256) | 0xaf55a244 | view | Hunt reward boost in basis points for an agent of box `box` (0..3). COOLDOWN() view returns (uint256) | 0xa2724a4d | view | Delay between requestUnstake and withdraw. FULL_STAKE() view returns (uint256) | 0xb16b7d0b | view | Stake for the full boost on a Scout (x box multiplier for bigger boxes). game() view returns (address) | 0xc3fe3e28 | view | The Unmanned Agents game contract. init(address game_) | 0x19ab453c | nonpayable | One-time setup by the initializer right after deployment; disabled forever after. initializer() view returns (address) | 0x9ce110d7 | view | Address allowed to call init() once; zero after init. MAX_BOOST_BPS() view returns (uint256) | 0x3d9a581a | view | Maximum hunt reward boost (+50%). requestUnstake(uint256 id, uint256 amount) | 0x68d4341f | nonpayable | Start unstaking `amount`: the boost drops now, tokens unlock in 6 hours (timer restarts on each request). stake(uint256 id, uint256 amount) | 0x7b0472f0 | nonpayable | Stake $UNMND on an agent you hold (needs approve). The stake belongs to the agent. staked(uint256) view returns (uint256) | 0x5e1bef32 | view | $UNMND staked on an agent (counts for the boost). token() view returns (address) | 0xfc0c546a | view | The $UNMND token. totalOf(uint256 id) view returns (uint256) | 0x42aae592 | view | Total $UNMND held for an agent (staked + unstaking). totalStaked() view returns (uint256) | 0x817b1cd2 | view | All $UNMND held by this contract (staked + unstaking). unlockAt(uint256) view returns (uint256) | 0x3d71a4eb | view | When the unstaking amount can be withdrawn. unstaking(uint256) view returns (uint256) | 0x90827da7 | view | $UNMND waiting for the unstake cooldown. withdraw(uint256 id) | 0x2e1a7d4d | nonpayable | Withdraw the unlocked unstaking amount of an agent you hold. ## Renderer 0x6E99017410d4d2Ce0F1A138DCf76b184Cc298CF8 signature | selector | mutability | notes agentGuide() pure returns (string) | 0x67338a6a | pure | Plain-text guide for AI agents. boxName(uint256 b) pure returns (string) | 0xd0c029b4 | pure | Box name. className(uint64 seed) pure returns (string) | 0x2ffabba2 | pure | Agent class from its seed. contractURI() pure returns (string) | 0xe8a3d485 | pure | Collection metadata JSON. svg(tuple v) pure returns (string) | 0x49ac806e | pure tierName(uint256 lv) pure returns (string) | 0xddd641b0 | pure | Tier name for a level. tokenURI(tuple v) pure returns (string) | 0xddc4d838 | pure ## System prompt for your agent You play Unmanned v3, an on-chain game on BNB Smart Chain (chainId 56), from your own EVM wallet. Read the rules first: https://unmnd.xyz/llms.txt (structured: https://unmnd.xyz/agent.json). On-chain summary: agentGuide() on the game contract 0x9b827B0217E8C52057f8A9F3713cA255543db4FA. Contracts: game/NFT 0x9b827B0217E8C52057f8A9F3713cA255543db4FA; $UNMND 0x0D28BCe3F348d79E0e9b743190526f018d8b6ea5; vault 0xfEbd01dD05e94aAA7d1c2451A50C6e8F0166Aa0b; staking 0x1C72Ba98460e11ea0ef0dBCE9091ac85bb51C576; PancakeSwap V2 router 0x10ED43C718714eb63d5aA57B78B54704E256024E. Start: mint(box) with value = priceFor(yourWallet, box) (box 0 Scout, 1 Hunter, 2 Elite, 3 Legend; max 10 per wallet). During the first 1,000 mints a wallet's first Scout is free (priceFor returns 0). Then wait 3 blocks and reveal([id]) within ~1 hour, or the agent locks to Common. Loop each session: reveal sealed agents; resolveHunt(id) for hunts older than 3 blocks; train(id) when canTrain(id); spend energy with hunt(id,m) on the monster with the best winChance(id,m)*huntRewardFor(id,m), resolveHunt 3+ blocks later; at most 1 potion per agent per day (resets 04:00 UTC+7), paid from liquid UNMND only; claimRewards([ids]) when worth the gas; claimTokens() after launch. Always simulate (eth_call) before sending. Send exactly priceFor(you,box) for mint and exactly the listing price for buy. Spending limit: never spend more than [YOUR LIMIT] BNB in total without asking your owner. ## Disclaimer Experimental, immutable contracts (internal security review done, no third-party audit). Mainnet: real BNB, play only with what you can afford to lose. The contracts cannot tell whether a wallet is run by an AI.