{"sources":{"contracts/PixelLaptopNFTv3 (1).sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ninterface IERC20 {\n    function transfer(address to, uint256 value) external returns (bool);\n    function balanceOf(address account) external view returns (uint256);\n}\n\ninterface IAgentID {\n    function balanceOf(address account) external view returns (uint256);\n}\n\n/// @title PixelLaptopNFT — AGENT ID ONLY — NFT FREE, pay 0.001 BNB for $PIXEL tokens\n/// @notice 3,333 max supply, max 10 per wallet.\n/// @notice The NFT itself is FREE (no mint fee). Each mint costs 0.001 BNB\n///         which pays for 50,000 $PIXEL tokens sent to the minter.\n/// @notice All PIXEL comes FROM this contract's fixed reserve (500M total).\n///         No new tokens are ever minted — the reserve only goes down.\n/// @notice Owner must fund this contract with 500M PIXEL after deployment.\ncontract PixelLaptopNFT {\n    string public name = \"Pixel Laptop\";\n    string public symbol = \"PLAPTOP\";\n\n    uint256 public constant MAX_SUPPLY = 3333;\n    uint256 public constant FREE_SUPPLY = 1800;\n    uint256 public constant MAX_PER_WALLET = 10;\n    uint256 public constant MAX_FREE_PER_WALLET = 1;\n    mapping(address => uint256) public freeMintedPerWallet;\n    uint256 public constant TOKEN_PRICE = 0.001 ether; // 0.001 BNB per 50k PIXEL (NFT itself is free)\n    uint256 public constant TOKENS_PER_MINT = 75_000 * 10 ** 18;\n    uint256 public constant TOKENS_PER_FREE_MINT = 25_000 * 10 ** 18; // 50k PIXEL per mint\n\n    IERC20 public voltToken;\n    IAgentID public constant AGENT_ID = IAgentID(0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F);\n    address public treasury;\n    address public owner;\n\n    uint256 public totalSupply;\n    string public baseURI;\n\n    mapping(uint256 => address) private _owners;\n    mapping(address => uint256) private _balances;\n    mapping(address => uint256) public mintedPerWallet;\n    mapping(uint256 => address) private _tokenApprovals;\n    mapping(address => mapping(address => bool)) private _operatorApprovals;\n\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    modifier onlyOwner() {\n        require(msg.sender == owner, \"not owner\");\n        _;\n    }\n\n    constructor(address voltToken_, address treasury_) {\n        owner = msg.sender;\n        voltToken = IERC20(voltToken_);\n        treasury = treasury_;\n    }\n\n    // ---------- ERC721Metadata ----------\n\n    function tokenURI(uint256 tokenId) public view returns (string memory) {\n        require(_owners[tokenId] != address(0), \"nonexistent token\");\n        return string(abi.encodePacked(baseURI, _toString(tokenId), \".json\"));\n    }\n\n    function setBaseURI(string calldata newBaseURI) external onlyOwner {\n        baseURI = newBaseURI;\n    }\n\n    // ---------- ERC721 core ----------\n\n    function balanceOf(address account) public view returns (uint256) {\n        require(account != address(0), \"zero address\");\n        return _balances[account];\n    }\n\n    function ownerOf(uint256 tokenId) public view returns (address) {\n        address o = _owners[tokenId];\n        require(o != address(0), \"nonexistent token\");\n        return o;\n    }\n\n    function approve(address to, uint256 tokenId) public {\n        address o = ownerOf(tokenId);\n        require(msg.sender == o || _operatorApprovals[o][msg.sender], \"not authorized\");\n        _tokenApprovals[tokenId] = to;\n        emit Approval(o, to, tokenId);\n    }\n\n    function getApproved(uint256 tokenId) public view returns (address) {\n        require(_owners[tokenId] != address(0), \"nonexistent token\");\n        return _tokenApprovals[tokenId];\n    }\n\n    function setApprovalForAll(address operator, bool approved) public {\n        _operatorApprovals[msg.sender][operator] = approved;\n        emit ApprovalForAll(msg.sender, operator, approved);\n    }\n\n    function isApprovedForAll(address o, address operator) public view returns (bool) {\n        return _operatorApprovals[o][operator];\n    }\n\n    function transferFrom(address from, address to, uint256 tokenId) public {\n        address o = ownerOf(tokenId);\n        require(o == from, \"not owner\");\n        require(\n            msg.sender == o ||\n            _tokenApprovals[tokenId] == msg.sender ||\n            _operatorApprovals[o][msg.sender],\n            \"not authorized\"\n        );\n        require(to != address(0), \"zero address\");\n        _tokenApprovals[tokenId] = address(0);\n        _balances[from] -= 1;\n        _balances[to] += 1;\n        _owners[tokenId] = to;\n        emit Transfer(from, to, tokenId);\n    }\n\n    // ---------- Mint ----------\n\n    /// @notice Mint qty FREE NFTs. Each mint costs 0.001 BNB which pays for\n    ///         50,000 PIXEL tokens (sent to minter). BNB goes to treasury.\n    /// @notice The NFT itself has no mint fee — the 0.001 BNB is the token price.\n    function mint(uint256 qty) external payable {\n        require(AGENT_ID.balanceOf(msg.sender) > 0, \"agent ID required\");\n        require(qty >= 1 && qty <= MAX_PER_WALLET, \"bad qty\");\n        require(totalSupply + qty <= MAX_SUPPLY, \"sold out\");\n        // Free: 1 per wallet (first 1800 supply). Paid: max 10 per wallet.\n        uint256 freeLeft = FREE_SUPPLY > totalSupply ? FREE_SUPPLY - totalSupply : 0;\n        uint256 walletFreeLeft = MAX_FREE_PER_WALLET > freeMintedPerWallet[msg.sender] \n            ? MAX_FREE_PER_WALLET - freeMintedPerWallet[msg.sender] : 0;\n        uint256 freeQty = qty < freeLeft ? qty : freeLeft;\n        freeQty = freeQty < walletFreeLeft ? freeQty : walletFreeLeft;\n        uint256 paidQty = qty - freeQty;\n        uint256 cost = paidQty * TOKEN_PRICE;\n        require(msg.value >= cost, \"insufficient BNB\");\n        require(mintedPerWallet[msg.sender] + paidQty <= MAX_PER_WALLET, \"paid wallet cap\");\n\n        uint256 voltNeeded = freeQty * TOKENS_PER_FREE_MINT + paidQty * TOKENS_PER_MINT;\n        require(voltToken.balanceOf(address(this)) >= voltNeeded, \"volt reserve empty\");\n\n        // send BNB (token payment) to treasury\n        (bool sent, ) = treasury.call{value: cost}(\"\");\n        require(sent, \"treasury payment failed\");\n        // refund excess BNB\n        if (msg.value > cost) {\n            (bool ok, ) = msg.sender.call{value: msg.value - cost}(\"\");\n            require(ok, \"refund failed\");\n        }\n\n        for (uint256 i = 0; i < qty; i++) {\n            uint256 tokenId = totalSupply + 1;\n            totalSupply = tokenId;\n            _owners[tokenId] = msg.sender;\n            _balances[msg.sender] += 1;\n            emit Transfer(address(0), msg.sender, tokenId);\n            uint256 payout = i < freeQty ? TOKENS_PER_FREE_MINT : TOKENS_PER_MINT;\n            require(voltToken.transfer(msg.sender, payout), \"volt payout failed\");\n        }\n        mintedPerWallet[msg.sender] += paidQty;\n        freeMintedPerWallet[msg.sender] += freeQty;\n    }\n\n    /// @notice View remaining PIXEL reserve in this contract.\n    function voltReserve() external view returns (uint256) {\n        return voltToken.balanceOf(address(this));\n    }\n\n    // ---------- Owner ----------\n\n    /// @notice Withdraw leftover PIXEL (e.g. unminted reserve) to treasury.\n    function withdrawVolt() external onlyOwner {\n        uint256 bal = voltToken.balanceOf(address(this));\n        require(bal > 0, \"empty\");\n        require(voltToken.transfer(treasury, bal), \"withdraw failed\");\n    }\n\n    function withdraw() external onlyOwner {\n        (bool ok, ) = owner.call{value: address(this).balance}(\"\");\n        require(ok, \"withdraw failed\");\n    }\n\n    function setTreasury(address newTreasury) external onlyOwner {\n        require(newTreasury != address(0), \"zero address\");\n        treasury = newTreasury;\n    }\n\n    function transferOwnership(address newOwner) external onlyOwner {\n        require(newOwner != address(0), \"zero address\");\n        owner = newOwner;\n    }\n\n    // ---------- utils ----------\n\n    function _toString(uint256 v) internal pure returns (string memory) {\n        if (v == 0) return \"0\";\n        uint256 len;\n        uint256 x = v;\n        while (x != 0) { len++; x /= 10; }\n        bytes memory b = new bytes(len);\n        while (v != 0) { len--; b[len] = bytes1(uint8(48 + v % 10)); v /= 10; }\n        return string(b);\n    }\n\n    function supportsInterface(bytes4 id) public pure returns (bool) {\n        return\n            id == 0x01ffc9a7 || // ERC165\n            id == 0x80ac58cd || // ERC721\n            id == 0x5b5e139f;   // ERC721Metadata\n    }\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"voltToken_","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":"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":"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":"FREE_SUPPLY","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"MAX_FREE_PER_WALLET","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":"TOKENS_PER_FREE_MINT","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"TOKENS_PER_MINT","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"TOKEN_PRICE","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"approve","type":"function","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"account","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":"freeMintedPerWallet","type":"function","inputs":[{"name":"","type":"address","internalType":"address"}],"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":"isApprovedForAll","type":"function","inputs":[{"name":"o","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"mintedPerWallet","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":"owner","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"ownerOf","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"setApprovalForAll","type":"function","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setBaseURI","type":"function","inputs":[{"name":"newBaseURI","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setTreasury","type":"function","inputs":[{"name":"newTreasury","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"supportsInterface","type":"function","inputs":[{"name":"id","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":"tokenURI","type":"function","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"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":"transferOwnership","type":"function","inputs":[{"name":"newOwner","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"treasury","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"voltReserve","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"voltToken","type":"function","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IERC20"}],"stateMutability":"view"},{"name":"withdraw","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdrawVolt","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"58404512","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-11-04T19:57:16Z","match":"exact_match","chainId":"56","address":"0x273fc2C7705B23eb129E35aC8Da26348E6Fc4980"}