{"sources":{"King.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\n/// @title 王座争霸 (King of the Hill, KING) — ERC-20 on BSC whose only\n/// emission is the rewards of an on-chain throne game.\n/// One contract = ERC-20 + game. No admin functions, no owner.\n///\n/// THE GAME\n/// - Anyone holding an Agent ID may seize() the throne by paying the\n///   current price (starts at BASE_PRICE = 0.0005 BNB). The standing\n///   king cannot seize their own throne, and a seize is only possible\n///   while the reign is live (block.timestamp < deadline); with no king\n///   seated a fresh reign is always open.\n/// - Every seize resets the deadline to now + 1 hour and raises the\n///   price by PRICE_STEP = 0.00005 BNB. The price paid splits in the\n///   same transaction: 60% to the outgoing king (or to the pot when\n///   there is no king yet), 25% to the pot, 15% to the treasury.\n/// - The new king is minted SEIZE_REWARD = 100,000 KING.\n/// - Once the deadline passes with the king still seated, anyone may\n///   settle(): the winner takes 85% of the pot, the treasury 15%, the\n///   winner is minted WINNER_BONUS = 1,000,000 KING, and a fresh reign\n///   starts at the base price.\n/// - KING is minted ONLY as these game rewards, hard-capped at\n///   MAX_SUPPLY = 1,000,000,000 KING. If the cap is reached, rewards\n///   silently shrink to the remaining room and then stop; the BNB game\n///   itself continues unchanged. Plain ERC-20 transfers carry no tax\n///   (there is no official pair and no trading mechanic in scope).\ninterface IAgentRegistry {\n    function balanceOf(address account) external view returns (uint256);\n}\n\ncontract King {\n    string public constant name = unicode\"王座争霸\";\n    string public constant symbol = \"KING\";\n    uint8 public constant decimals = 18;\n\n    uint256 public constant MAX_SUPPLY = 1_000_000_000 * 10 ** 18;\n    uint256 public constant BASE_PRICE = 0.0005 ether;\n    uint256 public constant PRICE_STEP = 0.00005 ether;\n    uint256 public constant REIGN_DURATION = 3600; // 1 hour\n    uint256 public constant SEIZE_REWARD = 100_000 * 10 ** 18;\n    uint256 public constant WINNER_BONUS = 1_000_000 * 10 ** 18;\n\n    address public immutable registry;\n    address public immutable treasury;\n\n    // ---- game state ----\n    address public currentKing;\n    uint256 public currentPrice;\n    uint256 public deadline;\n    uint256 public pot;\n    uint256 public reign; // starts at 1\n    uint256 public totalSeizes;\n    uint256 public kingSince;\n    uint256 public seizesThisReign;\n    uint256 public treasuryPaidTotal; // BNB, in wei (seize cuts + settle cuts)\n    uint256 public winnersPaidTotal;  // BNB, in wei (settle payouts to winners)\n\n    // ---- ERC-20 state ----\n    uint256 public totalMinted;\n    mapping(address => uint256) private _balances;\n    mapping(address => mapping(address => uint256)) private _allowances;\n\n    bool private _lock;\n    modifier lock() {\n        require(!_lock, \"reentrant\");\n        _lock = true;\n        _;\n        _lock = false;\n    }\n\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n    event Seized(address indexed king, uint256 reign, uint256 priceWei, uint256 deadline);\n    event Settled(address indexed winner, uint256 reign, uint256 potWei, uint256 winnerWei);\n\n    constructor(address registry_, address treasury_) {\n        require(registry_ != address(0) && treasury_ != address(0), \"zero addr\");\n        registry = registry_;\n        treasury = treasury_;\n        currentPrice = BASE_PRICE;\n        reign = 1;\n    }\n\n    receive() external payable {\n        if (_lock) return; // mid-game flows settle through seize()/settle() accounting\n        (bool ok, ) = treasury.call{value: msg.value}(\"\");\n        require(ok, \"forward failed\");\n    }\n\n    // ================= views =================\n    function totalSupply() external view returns (uint256) {\n        return totalMinted;\n    }\n\n    function balanceOf(address w) public view returns (uint256) {\n        return _balances[w];\n    }\n\n    /// Seconds left in the current reign; 0 when no king is seated or\n    /// the deadline has passed.\n    function timeLeft() external view returns (uint256) {\n        if (currentKing == address(0) || block.timestamp >= deadline) return 0;\n        return deadline - block.timestamp;\n    }\n\n    /// Fixed 10-word layout for the site and the daily snapshot:\n    /// (reign, priceWei, deadline, potWei, totalSeizes, totalMinted,\n    ///  kingSince, seizesThisReign, treasuryPaidTotal, winnersPaidTotal)\n    function status() external view returns (\n        uint256 reign_, uint256 priceWei_, uint256 deadline_,\n        uint256 potWei_, uint256 totalSeizes_, uint256 totalMinted_,\n        uint256 kingSince_, uint256 seizesThisReign_,\n        uint256 treasuryPaidTotal_, uint256 winnersPaidTotal_\n    ) {\n        return (reign, currentPrice, deadline, pot, totalSeizes,\n                totalMinted, kingSince, seizesThisReign,\n                treasuryPaidTotal, winnersPaidTotal);\n    }\n\n    // ================= game =================\n    function seize() external payable lock {\n        require(IAgentRegistry(registry).balanceOf(msg.sender) > 0, \"no agent id\");\n        require(msg.sender != currentKing, \"already king\");\n        if (currentKing != address(0)) {\n            require(block.timestamp < deadline, \"reign over\");\n        }\n        uint256 price = currentPrice;\n        require(msg.value >= price, \"underpaid\");\n        uint256 refund = msg.value - price;\n\n        address outgoing = currentKing;\n        uint256 toKing = (price * 60) / 100;\n        uint256 toPot = (price * 25) / 100;\n        uint256 toTreasury = price - toKing - toPot; // exactly 15% on the ladder\n\n        // ---- state first ----\n        if (outgoing == address(0)) {\n            pot += toKing; // no king to pay: the 60% share feeds the pot\n        }\n        pot += toPot;\n        treasuryPaidTotal += toTreasury;\n        currentKing = msg.sender;\n        kingSince = block.timestamp;\n        currentPrice = price + PRICE_STEP;\n        deadline = block.timestamp + REIGN_DURATION;\n        totalSeizes++;\n        seizesThisReign++;\n        _mintReward(msg.sender, SEIZE_REWARD);\n        emit Seized(msg.sender, reign, price, deadline);\n\n        // ---- money out ----\n        if (outgoing != address(0)) {\n            (bool okK, ) = outgoing.call{value: toKing}(\"\");\n            require(okK, \"king pay failed\");\n        }\n        (bool okT, ) = treasury.call{value: toTreasury}(\"\");\n        require(okT, \"treasury failed\");\n        if (refund > 0) {\n            (bool okR, ) = msg.sender.call{value: refund}(\"\");\n            require(okR, \"refund failed\");\n        }\n    }\n\n    function settle() external lock {\n        require(currentKing != address(0), \"no king\");\n        require(block.timestamp >= deadline, \"reign ongoing\");\n        address winner = currentKing;\n        uint256 p = pot;\n        uint256 toWinner = (p * 85) / 100;\n        uint256 toTreasury = p - toWinner; // exactly 15% on ladder amounts\n        uint256 settledReign = reign;\n\n        // ---- reset first: a fresh reign opens at the base price ----\n        winnersPaidTotal += toWinner;\n        treasuryPaidTotal += toTreasury;\n        currentKing = address(0);\n        currentPrice = BASE_PRICE;\n        pot = 0;\n        reign++;\n        deadline = 0;\n        kingSince = 0;\n        seizesThisReign = 0;\n        _mintReward(winner, WINNER_BONUS);\n        emit Settled(winner, settledReign, p, toWinner);\n\n        // ---- money out ----\n        if (toWinner > 0) {\n            (bool okW, ) = winner.call{value: toWinner}(\"\");\n            require(okW, \"winner pay failed\");\n        }\n        if (toTreasury > 0) {\n            (bool okT, ) = treasury.call{value: toTreasury}(\"\");\n            require(okT, \"treasury failed\");\n        }\n    }\n\n    /// Mints a game reward, silently shrinking to the remaining room\n    /// under the hard cap and to zero once the cap is reached.\n    function _mintReward(address to, uint256 amount) internal {\n        if (totalMinted >= MAX_SUPPLY) return;\n        uint256 room = MAX_SUPPLY - totalMinted;\n        uint256 m = amount < room ? amount : room;\n        if (m == 0) return;\n        totalMinted += m;\n        _balances[to] += m;\n        emit Transfer(address(0), to, m);\n    }\n\n    // ================= ERC-20 =================\n    function allowance(address owner, address spender) external view returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    function approve(address spender, uint256 amount) external returns (bool) {\n        _allowances[msg.sender][spender] = amount;\n        emit Approval(msg.sender, spender, amount);\n        return true;\n    }\n\n    function transfer(address to, uint256 amount) external returns (bool) {\n        _transfer(msg.sender, to, amount);\n        return true;\n    }\n\n    function transferFrom(address from, address to, uint256 amount) external returns (bool) {\n        uint256 allowed = _allowances[from][msg.sender];\n        require(allowed >= amount, \"allowance\");\n        if (allowed != type(uint256).max) {\n            _allowances[from][msg.sender] = allowed - amount;\n        }\n        _transfer(from, to, amount);\n        return true;\n    }\n\n    function _transfer(address from, address to, uint256 amount) internal {\n        require(to != address(0), \"zero to\");\n        require(_balances[from] >= amount, \"balance\");\n        _balances[from] -= amount;\n        _balances[to] += amount;\n        emit Transfer(from, to, amount);\n    }\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"registry_","type":"address","internalType":"address"},{"name":"treasury_","type":"address","internalType":"address"}],"stateMutability":"nonpayable"},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"spender","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Seized","type":"event","inputs":[{"name":"king","type":"address","indexed":true,"internalType":"address"},{"name":"reign","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"priceWei","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"deadline","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Settled","type":"event","inputs":[{"name":"winner","type":"address","indexed":true,"internalType":"address"},{"name":"reign","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"potWei","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"winnerWei","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":"value","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"BASE_PRICE","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":"PRICE_STEP","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"REIGN_DURATION","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"SEIZE_REWARD","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"WINNER_BONUS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"allowance","type":"function","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"spender","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"w","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"currentKing","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"currentPrice","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"deadline","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"decimals","type":"function","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"name":"kingSince","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"pot","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"registry","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"reign","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"seize","type":"function","inputs":[],"outputs":[],"stateMutability":"payable"},{"name":"seizesThisReign","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"settle","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"status","type":"function","inputs":[],"outputs":[{"name":"reign_","type":"uint256","internalType":"uint256"},{"name":"priceWei_","type":"uint256","internalType":"uint256"},{"name":"deadline_","type":"uint256","internalType":"uint256"},{"name":"potWei_","type":"uint256","internalType":"uint256"},{"name":"totalSeizes_","type":"uint256","internalType":"uint256"},{"name":"totalMinted_","type":"uint256","internalType":"uint256"},{"name":"kingSince_","type":"uint256","internalType":"uint256"},{"name":"seizesThisReign_","type":"uint256","internalType":"uint256"},{"name":"treasuryPaidTotal_","type":"uint256","internalType":"uint256"},{"name":"winnersPaidTotal_","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"timeLeft","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalMinted","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalSeizes","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":"transfer","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"transferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"amount","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"treasury","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"treasuryPaidTotal","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"winnersPaidTotal","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"receive","stateMutability":"payable"}],"matchId":"59109392","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-11T16:21:40Z","match":"exact_match","chainId":"56","address":"0xDF204022dC298D04B18215C1Ea58437f7CF040c3"}