{"sources":{"WarNeedOver.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.24;\n\n/// @notice Minimal view of the Binance Agent ID registry (SPACE ID based).\ninterface IAgentIdRegistry {\n    function balanceOf(address owner) external view returns (uint256);\n}\n\n/// @title War Need Over (WNO)\n/// @notice Memecoin for peace: war need over.\n///         Satu kontrak berisi token ERC-20 + mesin penjualan \"share\" ala AGC:\n///         - 6.000 share total, 1 share = 1.000.000 WNO.\n///         - 3.000 share pertama: 1 share GRATIS per dompet pemegang Agent ID.\n///         - 3.000 share sisanya: 0,001 BNB per share.\n///         - Hanya dompet pemegang Binance Agent ID (.ai) yang bisa mint.\n///         - Tidak ada fungsi admin, tidak ada pajak, tidak ada mint ulang:\n///           seluruh pasokan dikunci di kontrak ini sejak deploy dan hanya\n///           keluar lewat pembelian share.\ncontract WarNeedOver {\n    // ---------------- ERC-20 ----------------\n    string public constant name = \"War Need Over\";\n    string public constant symbol = \"WNO\";\n    uint8 public constant decimals = 18;\n    uint256 public totalSupply;\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    // ---------------- Penjualan share ----------------\n    IAgentIdRegistry public immutable registry;\n    address public immutable treasury;\n\n    uint256 public constant TOKENS_PER_SHARE = 1_000_000 * 1e18;\n    uint256 public constant FREE_SHARES = 3000;\n    uint256 public constant MAX_SHARES = 6000;\n    uint256 public constant PRICE = 0.001 ether; // per share berbayar\n    uint256 public constant MAX_PER_TX = 20;\n\n    uint256 public totalShares;      // free + paid yang sudah terjual\n    uint256 public totalFreeShares;\n    uint256 public totalPaidShares;\n    uint256 public totalRaised;      // BNB yang diteruskan ke treasury\n\n    mapping(address => bool) public freeUsed;\n    mapping(address => uint256) public sharesOf;\n    mapping(address => address) public referrerOf;\n\n    event MintShares(\n        address indexed buyer,\n        uint256 shares,\n        uint256 freeShares,\n        uint256 paidShares,\n        uint256 cost,\n        address referrer\n    );\n\n    bool private _locked;\n    modifier nonReentrant() {\n        require(!_locked, \"reentrant\");\n        _locked = true;\n        _;\n        _locked = false;\n    }\n\n    constructor(address agentIdRegistry, address treasury_) {\n        require(agentIdRegistry != address(0), \"registry 0\");\n        require(treasury_ != address(0), \"treasury 0\");\n        registry = IAgentIdRegistry(agentIdRegistry);\n        treasury = treasury_; // eksplisit: deploy bisa lewat proxy CREATE2, jadi JANGAN pakai msg.sender\n        totalSupply = MAX_SHARES * TOKENS_PER_SHARE; // 6.000.000.000 WNO\n        balanceOf[address(this)] = totalSupply;\n        emit Transfer(address(0), address(this), totalSupply);\n    }\n\n    // ---------------- ERC-20 functions ----------------\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        require(allowed >= value, \"allowance\");\n        if (allowed != type(uint256).max) {\n            allowance[from][msg.sender] = allowed - value;\n        }\n        _transfer(from, to, value);\n        return true;\n    }\n\n    function _transfer(address from, address to, uint256 value) internal {\n        require(to != address(0), \"to 0\");\n        require(balanceOf[from] >= value, \"balance\");\n        balanceOf[from] -= value;\n        balanceOf[to] += value;\n        emit Transfer(from, to, value);\n    }\n\n    // ---------------- Agent ID gate ----------------\n    function isAgent(address wallet) public view returns (bool) {\n        try registry.balanceOf(wallet) returns (uint256 n) {\n            return n > 0;\n        } catch {\n            return false;\n        }\n    }\n\n    // ---------------- Quote & mint ----------------\n    /// @notice Harga untuk `shares` share bagi `buyer` saat ini.\n    /// @return cost total BNB (wei) yang harus dibayar\n    /// @return freeShares berapa share yang gratis (0 atau 1)\n    /// @return paidShares berapa share yang berbayar\n    function quote(address buyer, uint256 shares)\n        public\n        view\n        returns (uint256 cost, uint256 freeShares, uint256 paidShares)\n    {\n        require(shares > 0 && shares <= MAX_PER_TX, \"shares 1..20\");\n        require(totalShares + shares <= MAX_SHARES, \"sold out\");\n        freeShares = 0;\n        // 1 share gratis per Agent ID, selama share itu masih di dalam\n        // kelompok 3.000 share pertama dan kuota gratisnya belum habis.\n        if (!freeUsed[buyer] && totalFreeShares < FREE_SHARES && totalShares + 1 <= FREE_SHARES) {\n            freeShares = 1;\n        }\n        paidShares = shares - freeShares;\n        cost = paidShares * PRICE;\n    }\n\n    /// @notice Beli `shares` share. Kelebihan BNB dikembalikan di transaksi yang sama.\n    function mint(uint256 shares, address referrer) external payable nonReentrant {\n        require(isAgent(msg.sender), \"agent id only\");\n        (uint256 cost, uint256 freeShares, uint256 paidShares) = quote(msg.sender, shares);\n        require(msg.value >= cost, \"underpaid\");\n\n        // --- effects ---\n        if (freeShares > 0) {\n            freeUsed[msg.sender] = true;\n            totalFreeShares += freeShares;\n        }\n        totalPaidShares += paidShares;\n        totalShares += shares;\n        sharesOf[msg.sender] += shares;\n        if (referrerOf[msg.sender] == address(0) && referrer != address(0) && referrer != msg.sender) {\n            referrerOf[msg.sender] = referrer;\n        }\n\n        uint256 tokenAmount = shares * TOKENS_PER_SHARE;\n        balanceOf[address(this)] -= tokenAmount;\n        balanceOf[msg.sender] += tokenAmount;\n        emit Transfer(address(this), msg.sender, tokenAmount);\n        emit MintShares(msg.sender, shares, freeShares, paidShares, cost, referrer);\n\n        // --- interactions ---\n        if (cost > 0) {\n            totalRaised += cost;\n            (bool okTreasury, ) = treasury.call{value: cost}(\"\");\n            require(okTreasury, \"treasury failed\");\n        }\n        uint256 refund = msg.value - cost;\n        if (refund > 0) {\n            (bool okRefund, ) = msg.sender.call{value: refund}(\"\");\n            require(okRefund, \"refund failed\");\n        }\n    }\n\n    // ---------------- Views untuk situs ----------------\n    function overview()\n        external\n        view\n        returns (\n            uint256 sharesSold,\n            uint256 freeSold,\n            uint256 paidSold,\n            uint256 freeRemaining,\n            uint256 sharesRemaining,\n            uint256 pricePerShare,\n            uint256 tokensPerShare\n        )\n    {\n        sharesSold = totalShares;\n        freeSold = totalFreeShares;\n        paidSold = totalPaidShares;\n        freeRemaining = FREE_SHARES > totalFreeShares ? FREE_SHARES - totalFreeShares : 0;\n        sharesRemaining = MAX_SHARES - totalShares;\n        pricePerShare = PRICE;\n        tokensPerShare = TOKENS_PER_SHARE;\n    }\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"agentIdRegistry","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":"MintShares","type":"event","inputs":[{"name":"buyer","type":"address","indexed":true,"internalType":"address"},{"name":"shares","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"freeShares","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"paidShares","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"cost","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"referrer","type":"address","indexed":false,"internalType":"address"}],"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":"FREE_SHARES","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_SHARES","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"TOKENS_PER_SHARE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"allowance","type":"function","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"decimals","type":"function","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"name":"freeUsed","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isAgent","type":"function","inputs":[{"name":"wallet","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"shares","type":"uint256","internalType":"uint256"},{"name":"referrer","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"payable"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"overview","type":"function","inputs":[],"outputs":[{"name":"sharesSold","type":"uint256","internalType":"uint256"},{"name":"freeSold","type":"uint256","internalType":"uint256"},{"name":"paidSold","type":"uint256","internalType":"uint256"},{"name":"freeRemaining","type":"uint256","internalType":"uint256"},{"name":"sharesRemaining","type":"uint256","internalType":"uint256"},{"name":"pricePerShare","type":"uint256","internalType":"uint256"},{"name":"tokensPerShare","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"quote","type":"function","inputs":[{"name":"buyer","type":"address","internalType":"address"},{"name":"shares","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"cost","type":"uint256","internalType":"uint256"},{"name":"freeShares","type":"uint256","internalType":"uint256"},{"name":"paidShares","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"referrerOf","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"registry","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IAgentIdRegistry"}],"stateMutability":"view"},{"name":"sharesOf","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"totalFreeShares","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalPaidShares","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalRaised","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalShares","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":"value","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":"value","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"}],"matchId":"58905104","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-09T16:40:24Z","match":"exact_match","chainId":"56","address":"0x8C969a4CD49E4774908e667702C3d7C3ece164D0"}