{"sources":{"Collection.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\ninterface IERC721Receiver {\n    function onERC721Received(address, address, uint256, bytes calldata) external returns (bytes4);\n}\n\n/// Minimal ERC-721 drop: the first `freeSupply` tokens are free, the rest cost `price`.\ncontract Collection {\n    string public name;\n    string public symbol;\n    string public baseURI;\n    address public owner;\n\n    uint256 public immutable maxSupply;\n    uint256 public immutable freeSupply;\n    uint256 public immutable price;\n    uint256 public immutable maxPerWallet;\n    uint256 public totalSupply;\n    bool public paused;\n\n    mapping(uint256 => address) public ownerOf;\n    mapping(address => uint256) public balanceOf;\n    mapping(address => uint256) public minted;\n    mapping(uint256 => address) public getApproved;\n    mapping(address => mapping(address => bool)) public isApprovedForAll;\n\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 approved);\n\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"not owner\");\n        _;\n    }\n\n    constructor(\n        string memory name_,\n        string memory symbol_,\n        string memory baseURI_,\n        uint256 maxSupply_,\n        uint256 freeSupply_,\n        uint256 price_,\n        uint256 maxPerWallet_,\n        address owner_\n    ) {\n        require(freeSupply_ <= maxSupply_, \"free > max\");\n        name = name_;\n        symbol = symbol_;\n        baseURI = baseURI_;\n        maxSupply = maxSupply_;\n        freeSupply = freeSupply_;\n        price = price_;\n        maxPerWallet = maxPerWallet_;\n        owner = owner_;\n    }\n\n    /// Cost of minting `qty` more tokens right now (free ones first).\n    function cost(uint256 qty) public view returns (uint256) {\n        uint256 freeLeft = totalSupply < freeSupply ? freeSupply - totalSupply : 0;\n        return qty > freeLeft ? (qty - freeLeft) * price : 0;\n    }\n\n    function mint(uint256 qty) external payable {\n        require(!paused, \"paused\");\n        require(qty > 0 && totalSupply + qty <= maxSupply, \"sold out\");\n        require(minted[msg.sender] + qty <= maxPerWallet, \"wallet limit\");\n        require(msg.value == cost(qty), \"wrong value\");\n        minted[msg.sender] += qty;\n        for (uint256 i; i < qty; ++i) {\n            uint256 id = ++totalSupply;\n            ownerOf[id] = msg.sender;\n            emit Transfer(address(0), msg.sender, id);\n        }\n        balanceOf[msg.sender] += qty;\n    }\n\n    function tokenURI(uint256 id) external view returns (string memory) {\n        require(ownerOf[id] != address(0), \"no token\");\n        bytes memory b = bytes(baseURI);\n        if (b.length > 0 && b[b.length - 1] == \"/\") return string.concat(baseURI, _str(id), \".json\");\n        return baseURI;\n    }\n\n    function approve(address spender, uint256 id) external {\n        address o = ownerOf[id];\n        require(msg.sender == o || isApprovedForAll[o][msg.sender], \"not allowed\");\n        getApproved[id] = spender;\n        emit Approval(o, spender, id);\n    }\n\n    function setApprovalForAll(address operator, bool approved) external {\n        isApprovedForAll[msg.sender][operator] = approved;\n        emit ApprovalForAll(msg.sender, operator, approved);\n    }\n\n    function transferFrom(address from, address to, uint256 id) public {\n        require(from == ownerOf[id], \"wrong from\");\n        require(to != address(0), \"zero to\");\n        require(msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id], \"not allowed\");\n        unchecked {\n            balanceOf[from]--;\n            balanceOf[to]++;\n        }\n        ownerOf[id] = to;\n        delete getApproved[id];\n        emit Transfer(from, to, id);\n    }\n\n    function safeTransferFrom(address from, address to, uint256 id) external {\n        safeTransferFrom(from, to, id, \"\");\n    }\n\n    function safeTransferFrom(address from, address to, uint256 id, bytes memory data) public {\n        transferFrom(from, to, id);\n        require(\n            to.code.length == 0 ||\n                IERC721Receiver(to).onERC721Received(msg.sender, from, id, data) == IERC721Receiver.onERC721Received.selector,\n            \"unsafe recipient\"\n        );\n    }\n\n    function supportsInterface(bytes4 id) external pure returns (bool) {\n        return id == 0x01ffc9a7 || id == 0x80ac58cd || id == 0x5b5e139f; // ERC165, ERC721, ERC721Metadata\n    }\n\n    function setBaseURI(string calldata uri) external onlyOwner {\n        baseURI = uri;\n    }\n\n    function setPaused(bool p) external onlyOwner {\n        paused = p;\n    }\n\n    function transferOwnership(address o) external onlyOwner {\n        owner = o;\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 _str(uint256 v) private pure returns (string memory) {\n        if (v == 0) return \"0\";\n        uint256 len;\n        for (uint256 t = v; t != 0; t /= 10) ++len;\n        bytes memory s = new bytes(len);\n        while (v != 0) {\n            s[--len] = bytes1(uint8(48 + (v % 10)));\n            v /= 10;\n        }\n        return string(s);\n    }\n}\n"}},"abi":[{"type":"constructor","inputs":[{"name":"name_","type":"string","internalType":"string"},{"name":"symbol_","type":"string","internalType":"string"},{"name":"baseURI_","type":"string","internalType":"string"},{"name":"maxSupply_","type":"uint256","internalType":"uint256"},{"name":"freeSupply_","type":"uint256","internalType":"uint256"},{"name":"price_","type":"uint256","internalType":"uint256"},{"name":"maxPerWallet_","type":"uint256","internalType":"uint256"},{"name":"owner_","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":"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":"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":"id","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"name":"approve","type":"function","inputs":[{"name":"spender","type":"address","internalType":"address"},{"name":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"balanceOf","type":"function","inputs":[{"name":"","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":"cost","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"freeSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"getApproved","type":"function","inputs":[{"name":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"isApprovedForAll","type":"function","inputs":[{"name":"","type":"address","internalType":"address"},{"name":"","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"maxPerWallet","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"maxSupply","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"name":"mint","type":"function","inputs":[{"name":"qty","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"payable"},{"name":"minted","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":"","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"name":"paused","type":"function","inputs":[],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"name":"price","type":"function","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"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":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"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":"uri","type":"string","internalType":"string"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"setPaused","type":"function","inputs":[{"name":"p","type":"bool","internalType":"bool"}],"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":"id","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":"id","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"transferOwnership","type":"function","inputs":[{"name":"o","type":"address","internalType":"address"}],"outputs":[],"stateMutability":"nonpayable"},{"name":"withdraw","type":"function","inputs":[],"outputs":[],"stateMutability":"nonpayable"}],"matchId":"57836946","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-10-31T15:06:47Z","match":"exact_match","chainId":"56","address":"0xA914594df425bea8c1CC1CEbb9be37e0bBFa6B05"}