{"sources":{"contracts/BanksNFT.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\n/**\n * BANKS — 3,333 pixel vaults on BNB Smart Chain.\n * Free: 2 per Agentic wallet. Paid: $1 (0.0017 BNB) each, up to 3 more. Cap 5/wallet.\n * All mint revenue -> TREASURY immediately.\n * Built-in market: seller lists, buyer pays price, 2% fee -> TREASURY, 98% -> seller.\n * Seller pays gas to list, buyer pays gas + price. No premine.\n */\n\ninterface IERC721Like { function balanceOf(address owner) external view returns (uint256); }\n\ncontract BANKS {\n    // ---------------- config ----------------\n    string  public name   = \"BANKS\";\n    string  public symbol = \"BANKS\";\n    uint256 public constant MAX_SUPPLY      = 3333;\n    uint256 public constant FREE_PER_WALLET = 2;\n    uint256 public constant MAX_PER_WALLET  = 5;\n    uint256 public constant MAX_PAID        = 3;\n    uint256 public constant FEE_BPS         = 200;   // 2% market fee\n    uint256 public constant BPS_DENOM       = 10_000;\n\n    address public constant TREASURY = 0x68AdD3EdcBe82cE1FB5d01AbC44383e4Ee3F54a2;\n    address public rewards;   // 50% of the market fee -> staking reward pool / buyback\n\n    uint256 public price = 0.0017 ether;             // ~$1, owner-updatable\n    address public owner;\n    address public registry = 0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F;\n    string  public baseURI;\n\n    uint256 public totalMinted;\n    mapping(address => uint256) public freeMinted;\n    mapping(address => uint256) public paidMinted;\n    mapping(uint256 => address) private _owner;\n    mapping(address => uint256) private _balance;\n    mapping(uint256 => address) private _approved;\n    mapping(address => mapping(address => bool)) private _operator;\n\n    struct Listing { address seller; uint256 price; }\n    mapping(uint256 => Listing) public listings;\n    uint256 public totalVolume;\n\n    // ---------------- events ----------------\n    event Transfer(address indexed from, address indexed to, uint256 indexed id);\n    event Approval(address indexed owner, address indexed spender, uint256 indexed id);\n    event ApprovalForAll(address indexed owner, address indexed operator, bool ok);\n    event Minted(address indexed to, uint256 indexed id, bool free);\n    event Listed(uint256 indexed id, address indexed seller, uint256 price);\n    event Sold(uint256 indexed id, address indexed seller, address indexed buyer, uint256 price, uint256 fee);\n\n    modifier onlyOwner() { require(msg.sender == owner, \"not owner\"); _; }\n\n    constructor(string memory _base) {\n        owner = msg.sender;\n        baseURI = _base;\n        rewards = TREASURY;   // owner should point this at the staking contract after deploy\n    }\n\n    // ---------------- eligibility ----------------\n    function isAgentic(address who) public view returns (bool) {\n        try IERC721Like(registry).balanceOf(who) returns (uint256 b) { return b > 0; }\n        catch { return false; }\n    }\n    function freeLeft(address who) public view returns (uint256) {\n        if (!isAgentic(who)) return 0;\n        uint256 u = freeMinted[who];\n        return u >= FREE_PER_WALLET ? 0 : FREE_PER_WALLET - u;\n    }\n    function paidLeft(address who) public view returns (uint256) {\n        uint256 used = freeMinted[who] + paidMinted[who];\n        if (used >= MAX_PER_WALLET) return 0;\n        uint256 room = MAX_PER_WALLET - used;\n        return room > MAX_PAID ? MAX_PAID : room;\n    }\n    function remaining() public view returns (uint256) { return MAX_SUPPLY - totalMinted; }\n\n    // ---------------- mint ----------------\n    /// Mints min(freeLeft,2) free tokens to an Agentic wallet.\n    function mintFree() external {\n        require(isAgentic(msg.sender), \"not agentic\");\n        uint256 n = freeLeft(msg.sender);\n        require(n > 0, \"no free left\");\n        require(totalMinted + n <= MAX_SUPPLY, \"sold out\");\n        for (uint256 i = 0; i < n; i++) _mint(msg.sender, true);\n        freeMinted[msg.sender] += n;\n    }\n\n    /// Mints `qty` paid tokens; all value forwarded to TREASURY now.\n    function mintPaid(uint256 qty) external payable {\n        require(qty > 0 && qty <= MAX_PAID, \"bad qty\");\n        require(paidLeft(msg.sender) >= qty, \"cap reached\");\n        require(msg.value == price * qty, \"wrong value\");\n        require(totalMinted + qty <= MAX_SUPPLY, \"sold out\");\n        for (uint256 i = 0; i < qty; i++) _mint(msg.sender, false);\n        paidMinted[msg.sender] += qty;\n        (bool ok, ) = TREASURY.call{value: msg.value}(\"\");\n        require(ok, \"treasury xfer failed\");\n    }\n\n    function _mint(address to, bool free) internal {\n        totalMinted += 1;\n        uint256 id = totalMinted;\n        _owner[id] = to;\n        _balance[to] += 1;\n        emit Transfer(address(0), to, id);\n        emit Minted(to, id, free);\n    }\n\n    // ---------------- market ----------------\n    /// List your token. Seller pays gas only.\n    function list(uint256 id, uint256 p) external {\n        require(_owner[id] == msg.sender, \"not owner\");\n        require(p > 0, \"price 0\");\n        listings[id] = Listing(msg.sender, p);\n        emit Listed(id, msg.sender, p);\n    }\n\n    function cancel(uint256 id) external {\n        require(listings[id].seller == msg.sender, \"not seller\");\n        delete listings[id];\n    }\n\n    /// Buy a listed token. 2% -> treasury, 98% -> seller. Buyer pays gas + price.\n    function buy(uint256 id) external payable {\n        Listing memory l = listings[id];\n        require(l.seller != address(0), \"not listed\");\n        require(_owner[id] == l.seller, \"seller no longer owns\");\n        require(msg.value == l.price, \"wrong price\");\n        delete listings[id];\n\n        uint256 fee = (l.price * FEE_BPS) / BPS_DENOM;\n        uint256 toTreasury = fee / 2;\n        uint256 toRewards  = fee - toTreasury;\n        uint256 toSeller = l.price - fee;\n        totalVolume += l.price;\n\n        _transfer(l.seller, msg.sender, id);\n        if (toTreasury > 0) { (bool a, ) = TREASURY.call{value: toTreasury}(\"\"); require(a, \"fee xfer\"); }\n        if (toRewards > 0)  { (bool c, ) = rewards.call{value: toRewards}(\"\");  require(c, \"reward xfer\"); }\n        (bool b, ) = l.seller.call{value: toSeller}(\"\");\n        require(b, \"seller xfer\");\n        emit Sold(id, l.seller, msg.sender, l.price, fee);\n    }\n\n    // ---------------- ERC721 ----------------\n    function balanceOf(address a) public view returns (uint256) { return _balance[a]; }\n    function ownerOf(uint256 id) public view returns (address) {\n        address o = _owner[id]; require(o != address(0), \"nonexistent\"); return o;\n    }\n    function approve(address to, uint256 id) external {\n        address o = ownerOf(id);\n        require(msg.sender == o || _operator[o][msg.sender], \"not authorized\");\n        _approved[id] = to; emit Approval(o, to, id);\n    }\n    function getApproved(uint256 id) external view returns (address) { return _approved[id]; }\n    function setApprovalForAll(address op, bool ok) external {\n        _operator[msg.sender][op] = ok; emit ApprovalForAll(msg.sender, op, ok);\n    }\n    function isApprovedForAll(address o, address op) external view returns (bool) { return _operator[o][op]; }\n\n    function _transfer(address from, address to, uint256 id) internal {\n        require(_owner[id] == from, \"wrong from\");\n        require(to != address(0), \"zero addr\");\n        _approved[id] = address(0);\n        _balance[from] -= 1; _balance[to] += 1; _owner[id] = to;\n        emit Transfer(from, to, id);\n    }\n\n    function transferFrom(address from, address to, uint256 id) public {\n        address o = ownerOf(id);\n        require(o == from, \"wrong from\");\n        require(msg.sender == o || _operator[o][msg.sender] || _approved[id] == msg.sender, \"not authorized\");\n        delete listings[id];\n        _transfer(from, to, id);\n    }\n    function safeTransferFrom(address from, address to, uint256 id) external { transferFrom(from, to, id); }\n    function safeTransferFrom(address from, address to, uint256 id, bytes calldata) external { transferFrom(from, to, id); }\n\n    /// All token ids held by `who` (max 3333, view-only).\n    function tokensOfOwner(address who) external view returns (uint256[] memory) {\n        uint256 n = _balance[who];\n        uint256[] memory out = new uint256[](n);\n        uint256 k;\n        for (uint256 i = 1; i <= totalMinted && k < n; i++) {\n            if (_owner[i] == who) { out[k] = i; k++; }\n        }\n        return out;\n    }\n\n    // ---------------- metadata ----------------\n    function tokenURI(uint256 id) external view returns (string memory) {\n        require(_owner[id] != address(0), \"nonexistent\");\n        return string(abi.encodePacked(baseURI, _toString(id), \".json\"));\n    }\n\n    // ---------------- royalty (ERC2981) ----------------\n    function royaltyInfo(uint256, uint256 salePrice) external pure returns (address, uint256) {\n        return (TREASURY, salePrice * 5 / 100);\n    }\n\n    // ---------------- owner ----------------\n    function setPrice(uint256 p) external onlyOwner { price = p; }\n    function setBaseURI(string calldata b) external onlyOwner { baseURI = b; }\n    function setRegistry(address r) external onlyOwner { registry = r; }\n    function setRewards(address r) external onlyOwner { rewards = r; }\n    function withdraw() external onlyOwner { // only stray funds; mint goes direct to treasury\n        (bool ok, ) = TREASURY.call{value: address(this).balance}(\"\"); require(ok, \"xfer failed\");\n    }\n\n    function _toString(uint256 v) internal pure returns (string memory) {\n        if (v == 0) return \"0\";\n        uint256 t = v; uint256 d;\n        while (t != 0) { d++; t /= 10; }\n        bytes memory b = new bytes(d);\n        while (v != 0) { d -= 1; b[d] = bytes1(uint8(48 + v % 10)); v /= 10; }\n        return string(b);\n    }\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"_base","type":"string","internalType":"string"}],"stateMutability":"nonpayable"},{"name":"Approval","type":"event","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"spender","type":"address","indexed":true,"internalType":"address"},{"name":"id","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":"ok","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"Listed","type":"event","inputs":[{"name":"id","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"seller","type":"address","indexed":true,"internalType":"address"},{"name":"price","type":"uint256","indexed":false,"internalType":"uint256"}],"anonymous":false},{"name":"Minted","type":"event","inputs":[{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"id","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"free","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"name":"Sold","type":"event","inputs":[{"name":"id","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"seller","type":"address","indexed":true,"internalType":"address"},{"name":"buyer","type":"address","indexed":true,"internalType":"address"},{"name":"price","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"fee","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":"id","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"BPS_DENOM","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"FEE_BPS","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"FREE_PER_WALLET","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_PAID","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_PER_WALLET","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":"TREASURY","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"a","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"baseURI","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"buy","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"cancel","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"freeLeft","type":"function","inputs":[{"name":"who","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeMinted","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getApproved","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"isAgentic","type":"function","inputs":[{"name":"who","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"isApprovedForAll","type":"function","inputs":[{"name":"o","type":"address","internalType":"address"},{"name":"op","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"list","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"},{"name":"p","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"listings","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"seller","type":"address","internalType":"address"},{"name":"price","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"mintFree","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"mintPaid","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"name","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"paidLeft","type":"function","inputs":[{"name":"who","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"paidMinted","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"price","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":"remaining","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"rewards","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"royaltyInfo","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"},{"name":"salePrice","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"pure"},{"name":"safeTransferFrom","type":"function","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"id","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":"id","type":"uint256","internalType":"uint256"},{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setApprovalForAll","type":"function","inputs":[{"name":"op","type":"address","internalType":"address"},{"name":"ok","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setBaseURI","type":"function","inputs":[{"name":"b","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setPrice","type":"function","inputs":[{"name":"p","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setRegistry","type":"function","inputs":[{"name":"r","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setRewards","type":"function","inputs":[{"name":"r","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"symbol","type":"function","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tokenURI","type":"function","inputs":[{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"name":"tokensOfOwner","type":"function","inputs":[{"name":"who","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256[]","internalType":"uint256[]"}],"stateMutability":"view"},{"name":"totalMinted","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"totalVolume","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":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdraw","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"57496553","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-10-29T06:53:26Z","match":"exact_match","chainId":"56","address":"0xaCe6E160FFA40C0d27F92e9349EEdbb1fA2BE0B5"}