{"sources":{"Botlings.sol":{"content":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.28;\n\n/// @notice Public interface of BNB Botlings (the contract dispatches these selectors in assembly to stay tiny).\ninterface IBNBBotlings {\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    function mint(uint256 qty) external payable; // msg.value must equal qty * price(); max 20 per wallet\n    function mint() external payable; // qty 1\n    function price() external pure returns (uint256); // 100000000000000 wei = 0.0001 BNB\n    function mintPrice() external pure returns (uint256);\n    function quote(address minter, uint256 qty) external pure returns (uint256);\n    function mintOpen() external pure returns (bool);\n    function MAX_SUPPLY() external pure returns (uint256); // 10000\n    function maxPerWallet() external pure returns (uint256); // 20\n    function totalSupply() external view returns (uint256);\n    function creator() external pure returns (address);\n    function owner() external pure returns (address);\n    function withdraw() external;\n    function name() external pure returns (string memory);\n    function symbol() external pure returns (string memory);\n    function tokenURI(uint256 id) external view returns (string memory);\n    function contractURI() external pure returns (string memory);\n    function balanceOf(address owner) external view returns (uint256);\n    function ownerOf(uint256 id) external view returns (address);\n    function getApproved(uint256 id) external view returns (address);\n    function isApprovedForAll(address owner, address operator) external view returns (bool);\n    function approve(address to, uint256 id) external payable;\n    function setApprovalForAll(address operator, bool approved) external;\n    function transferFrom(address from, address to, uint256 id) external payable;\n    function safeTransferFrom(address from, address to, uint256 id) external payable;\n    function safeTransferFrom(address from, address to, uint256 id, bytes calldata data) external payable;\n    function supportsInterface(bytes4 id) external pure returns (bool);\n    function royaltyInfo(uint256 id, uint256 salePrice) external pure returns (address, uint256);\n}\n\n/// @title BNB Botlings - 10,000 cute pixel robots, art generated 100% on-chain (SVG), with rarity tiers.\n/// @notice Mint: mint(uint256 qty) payable, msg.value == qty * 0.0001 BNB, max 20 per wallet, open at deploy.\n///         Every mint forwards the payment to the creator. ERC-2981 royalty: 10% to the creator.\n/// @dev Gas-minimal hand-rolled ERC721 dispatched in assembly (see IBNBBotlings for the ABI).\n///      No constructor and no msg.sender ownership: creator is a constant, so deploying through the\n///      CREATE2 deployer 0x4e59b44847b379578588920ca78fbf26c0b4956c is safe.\n///      Storage: slot 0 totalSupply | slot id (1..10000) owner | slot (1<<160)|addr balance (low128) + minted (high128)\n///      | slot (1<<200)+id approved | slot keccak(owner, operator) operator approval.\ncontract BNBBotlings {\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    fallback() external payable {\n        assembly {\n                function arg(o) -> a { a := shr(96, shl(96, calldataload(o))) }\n                function own(id) -> o {\n                    if lt(sub(id, 1), 10000) { o := sload(id) }\n                    if iszero(o) { revert(0, 0) }\n                }\n                function opk(o, op) -> k {\n                    mstore(0, o)\n                    mstore(0x20, op)\n                    k := keccak256(0, 0x40)\n                }\n                function pay() {\n                    if selfbalance() {\n                        if iszero(call(gas(), 0x3D8335c954B05B6Da74CE8cbfd63611f86522590, selfbalance(), 0, 0, 0, 0)) { revert(0, 0) }\n                    }\n                }\n                // number of free tokens in a mint of q by wallet a: min(q, 500 - freeMinted, 2 - freeUsed[a])\n                function fr(a, q) -> f {\n                    f := q\n                    let fm := shr(128, sload(0))\n                    let x := 0\n                    if lt(fm, 500) { x := sub(500, fm) }\n                    if lt(x, f) { f := x }\n                    let fu := shr(192, sload(or(a, shl(160, 1))))\n                    x := 0\n                    if lt(fu, 2) { x := sub(2, fu) }\n                    if lt(x, f) { f := x }\n                }\n                function mintq(q) {\n                    let s0 := sload(0)\n                    let s := and(s0, 0xffffffffffffffffffffffffffffffff)\n                    let bk := or(caller(), shl(160, 1))\n                    let b := sload(bk)\n                    let e := add(s, q)\n                    let f := fr(caller(), q)\n                    if or(\n                        or(iszero(q), gt(q, 20)),\n                        or(sub(callvalue(), mul(sub(q, f), 100000000000000)), or(gt(e, 10000), gt(add(and(shr(128, b), 0xffffffffffffffff), q), 20)))\n                    ) { revert(0, 0) }\n                    sstore(bk, add(b, add(add(q, shl(128, q)), shl(192, f))))\n                    sstore(0, add(s0, add(q, shl(128, f))))\n                    for {} lt(s, e) {} {\n                        s := add(s, 1)\n                        sstore(s, caller())\n                        log4(0, 0, 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0, caller(), s)\n                    }\n                    pay()\n                }\n                function xfer(f, t, id) {\n                    let ak := add(id, shl(200, 1))\n                    if or(\n                        or(iszero(t), iszero(f)),\n                        or(\n                            or(gt(sub(id, 1), 9999), sub(sload(id), f)),\n                            iszero(or(or(eq(caller(), f), sload(opk(f, caller()))), eq(caller(), sload(ak))))\n                        )\n                    ) { revert(0, 0) }\n                    let fk := or(f, shl(160, 1))\n                    sstore(fk, sub(sload(fk), 1))\n                    let tk := or(t, shl(160, 1))\n                    sstore(tk, add(sload(tk), 1))\n                    sstore(id, t)\n                    sstore(ak, 0)\n                    log4(0, 0, 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, f, t, id)\n                }\n                function safe(f, t, id, d, n) {\n                    xfer(f, t, id)\n                    if extcodesize(t) {\n                        let m := mload(0x40)\n                        mstore(m, 0x150b7a02)\n                        mstore(add(m, 0x20), caller())\n                        mstore(add(m, 0x40), f)\n                        mstore(add(m, 0x60), id)\n                        mstore(add(m, 0x80), 0x80)\n                        mstore(add(m, 0xa0), n)\n                        calldatacopy(add(m, 0xc0), d, n)\n                        mstore(0, 0)\n                        if iszero(and(call(gas(), t, 0, add(m, 0x1c), add(0xa4, n), 0, 0x20), eq(mload(0), shl(224, 0x150b7a02)))) {\n                            revert(0, 0)\n                        }\n                    }\n                }\n                function str(s, n) {\n                    mstore(0, 0x20)\n                    mstore(0x20, n)\n                    mstore(0x40, s)\n                    return(0, 0x60)\n                }\n                let r := 0\n                let m := 0\n                switch shr(224, calldataload(0))\n                case 0x06fdde03 { str(\"BNB Botlings\", 12) }\n                case 0x95d89b41 { str(\"BOTL\", 4) }\n                case 0x8da5cb5b { r := 0x3D8335c954B05B6Da74CE8cbfd63611f86522590 }\n                case 0x02d05d3f { r := 0x3D8335c954B05B6Da74CE8cbfd63611f86522590 }\n                case 0x6817c76c { r := mul(gt(shr(128, sload(0)), 499), 100000000000000) }\n                case 0xa035b1fe { r := mul(gt(shr(128, sload(0)), 499), 100000000000000) }\n                case 0x8f79306e {\n                    let q := calldataload(0x24)\n                    if gt(q, 10000) { revert(0, 0) }\n                    r := mul(sub(q, fr(arg(4), q)), 100000000000000)\n                }\n                case 0x24a6ab0c { r := 500 }\n                case 0xd10a1a2b { r := shr(128, sload(0)) }\n                case 0x24bbd049 { r := 1 }\n                case 0x32cb6b0c { r := 10000 }\n                case 0x453c2310 { r := 20 }\n                case 0x18160ddd { r := and(sload(0), 0xffffffffffffffffffffffffffffffff) }\n                case 0x6352211e { r := own(calldataload(4)) }\n                case 0x70a08231 {\n                    let a := arg(4)\n                    if iszero(a) { revert(0, 0) }\n                    r := and(sload(or(a, shl(160, 1))), 0xffffffffffffffffffffffffffffffff)\n                }\n                case 0x081812fc {\n                    let id := calldataload(4)\n                    pop(own(id))\n                    r := sload(add(id, shl(200, 1)))\n                }\n                case 0xe985e9c5 { r := sload(opk(arg(4), arg(0x24))) }\n                case 0x01ffc9a7 {\n                    let i := shr(224, calldataload(4))\n                    r := or(or(eq(i, 0x01ffc9a7), eq(i, 0x80ac58cd)), or(eq(i, 0x5b5e139f), eq(i, 0x2a55205a)))\n                }\n                case 0x2a55205a {\n                    mstore(0, 0x3D8335c954B05B6Da74CE8cbfd63611f86522590)\n                    mstore(0x20, div(calldataload(0x24), 10))\n                    return(0, 0x40)\n                }\n                case 0x1249c58b { mintq(1) }\n                case 0xa0712d68 { mintq(calldataload(4)) }\n                case 0x3ccfd60b { pay() }\n                case 0x095ea7b3 {\n                    let id := calldataload(0x24)\n                    let o := own(id)\n                    if iszero(or(eq(caller(), o), sload(opk(o, caller())))) { revert(0, 0) }\n                    let t := arg(4)\n                    sstore(add(id, shl(200, 1)), t)\n                    log4(0, 0, 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925, o, t, id)\n                }\n                case 0xa22cb465 {\n                    let op := arg(4)\n                    let ok := iszero(iszero(calldataload(0x24)))\n                    sstore(opk(caller(), op), ok)\n                    mstore(0, ok)\n                    log3(0, 0x20, 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31, caller(), op)\n                }\n                case 0x23b872dd { xfer(arg(4), arg(0x24), calldataload(0x44)) }\n                case 0x42842e0e { safe(arg(4), arg(0x24), calldataload(0x44), 0, 0) }\n                case 0xb88d4fde {\n                    let d := add(4, calldataload(0x64))\n                    safe(arg(4), arg(0x24), calldataload(0x44), add(d, 0x20), calldataload(d))\n                }\n                case 0xc87b56dd { m := 1 }\n                case 0xe8a3d485 { m := 1 }\n                default { revert(0, 0) }\n                if iszero(m) {\n                    mstore(0, r)\n                    return(0, 0x20)\n                }\n        }\n        // ---- tokenURI(uint256) / contractURI(): fully on-chain JSON + SVG ----\n        // Data blob: [trait table] 0x1f [SVG template] 0x1f [token JSON template] 0x1f [contract JSON template] 0x1f\n        // Table entry = [placeholder][selector][option|option|...]~ ; selector = seed shift (0 => 8 colours, else 4 options), 'T' = rarity tier.\n        // Template bytes 0x01..0x12 are placeholders filled from p[]: 1 id, 2 bg hue, 3 body hue, 4 eye hue, 5 antenna stem,\n        // 6 eyes, 7 antenna glow, 8 accessory, 9-11 trait names, 12 SVG base64, 13 colour, 14 rarity, 15 sparkles, 16 frame, 17 crown, 18 trait count.\n        bytes memory D = \"\\x03\\x000|25|48|95|150|185|215|275~\\x0d\\x00Red|Orange|Gold|Lime|Mint|Cyan|Blue|Purple~\\x09\\x08Pixel|Visor|Wink|Sleepy~\\x06\\x08M5 5h2v2H5zM9 5h2v2H9z|M5 6h6v1H5z|M5 5h2v2H5zM9 6h2v1H9z|M5 6h2v1H5zM9 6h2v1H9z~\\x0a\\x10Ball|Twin|Crest|Horns~\\x05\\x10M7 2h2v1H7z|M4 1h1v2H4zM11 1h1v2h-1z||~\\x07\\x10M6 0h4v2H6z|M4 0h1v1H4zM11 0h1v1h-1z|M6 2h4v1H6zM7 1h2v1H7z|M3 1h2v2H3zM11 1h2v2h-2z~\\x0b\\x18None|Bowtie|Gold Badge|Blush~\\x12\\x184|5|5|5~\\x17\\x18none|#e23|#fb1|#f8a~\\x08\\x180 0|5 10h1v3H5zM10 10h1v3h-1zM6 11h4v1H6z|7 13h2v2H7z|4 7h1v1H4zM11 7h1v1h-1z~\\x0eTCommon|Rare|Epic|Legendary~\\x0fTnone|#fff|#7ff|#fd4~\\x10Tnone|none|#c6f|#fb1~\\x11Tnone|none|none|#fb1~\\x18Tnone|none|none|#e23~\\x13Z<path fill='~\\x14Z\\\"},{\\\"trait_type\\\":\\\"~\\x15Z\\\",\\\"value\\\":\\\"~\\x16Z' d='M~\\x1f\"\n            \"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' shape-rendering='crispEdges'><rect width='16' height='16' fill='hsl(\\x02,70%,88%)'/>\\x13hsl(\\x03,45%,38%)\\x162 6h12v3H2zM6 11h4v1H6zM2 12h12v3H2z\\x05'/>\\x13hsl(\\x03,75%,62%)\\x163 3h10v8H3zM4 12h8v4H4z'/>\\x13#213\\x164 4h8v6H4z'/>\\x13hsl(\\x04,100%,65%)\\x167 8h2v1H7z\\x06\\x07'/>\\x13\\x17\\x16\\x08'/>\\x13\\x0f\\x161 1h1v1H1zM14 1h1v1h-1zM1 10h1v1H1zM14 10h1v1h-1z'/><rect x='.5' y='.5' width='15' height='15' fill='none' stroke='\\x10'/>\\x13\\x11\\x164 1h8v2H4zM4 0h1v1H4zM7 0h2v1H7zM11 0h1v1h-1z'/>\\x13\\x18\\x167 1h2v1H7z'/></svg>\\x1f\"\n            '{\"name\":\"BNB Botling #\\x01\",\"description\":\"Cute pixel robot, art 100% on-chain on BNB Chain.\",\"image\":\"data:image/svg+xml;base64,\\x0c\",\"attributes\":[{\"trait_type\":\"Rarity\\x15\\x0e\\x14Color\\x15\\x0d\\x14Eyes\\x15\\x09\\x14Antenna\\x15\\x0a\\x14Accessory\\x15\\x0b\\x14Fully On-Chain\\x15Yes\\x14Trait Count\",\"value\":\\x12}]}\\x1f'\n            '{\"name\":\"BNB Botlings\",\"description\":\"10,000 cute pixel robots, art generated 100% on-chain (SVG) on BNB Chain: no IPFS, no servers, forever. Hard-capped 10,000 supply. Rarity: Common, Rare, Epic, Legendary (2%, gold crown). First 500 mints free (max 2/wallet), then 0.0001 BNB. 10% royalty (ERC-2981). Mint: mint(uint256 qty) payable with value = quote(you,qty).\",\"image\":\"data:image/svg+xml;base64,\\x0c\",\"seller_fee_basis_points\":1000,\"fee_recipient\":\"0x3D8335c954B05B6Da74CE8cbfd63611f86522590\"}\\x1f';\n        assembly {\n            function str(v) -> r {\n                r := add(mload(0x40), 0x80)\n                mstore(0x40, add(r, 0x20))\n                mstore(r, 0)\n                let e := r\n                for {} 1 {} {\n                    r := sub(r, 1)\n                    mstore8(r, add(48, mod(v, 10)))\n                    v := div(v, 10)\n                    if iszero(v) { break }\n                }\n                let n := sub(e, r)\n                r := sub(r, 0x20)\n                mstore(r, n)\n            }\n            function cut(r, o) {\n                mstore(r, sub(o, add(r, 0x20)))\n                mstore(0x40, and(add(o, 63), not(31)))\n            }\n            function ch(q) -> c { c := byte(0, mload(q)) }\n            function skip(q, c) -> n {\n                for {} iszero(eq(ch(q), c)) {} { q := add(q, 1) }\n                n := add(q, 1)\n            }\n            // copy template at q until 0x1f, substituting placeholders from P\n            function fill(q, P) -> r, n {\n                r := mload(0x40)\n                let o := add(r, 0x20)\n                for {} 1 {} {\n                    let c := ch(q)\n                    q := add(q, 1)\n                    if eq(c, 0x1f) { break }\n                    switch lt(c, 0x20)\n                    case 0 {\n                        mstore8(o, c)\n                        o := add(o, 1)\n                    }\n                    default {\n                        let x := mload(add(P, shl(5, c)))\n                        let l := mload(x)\n                        mcopy(o, add(x, 0x20), l)\n                        o := add(o, l)\n                    }\n                }\n                cut(r, o)\n                n := q\n            }\n            function b64(d) -> r {\n                let len := mload(d)\n                r := mload(0x40)\n                mstore(0, \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef\")\n                mstore(0x20, \"ghijklmnopqrstuvwxyz0123456789+/\")\n                let o := add(r, 0x20)\n                for { let p := d let e := add(d, len) } lt(p, e) {} {\n                    p := add(p, 3)\n                    let x := mload(p)\n                    mstore8(o, byte(0, mload(and(shr(18, x), 63))))\n                    mstore8(add(o, 1), byte(0, mload(and(shr(12, x), 63))))\n                    mstore8(add(o, 2), byte(0, mload(and(shr(6, x), 63))))\n                    mstore8(add(o, 3), byte(0, mload(and(x, 63))))\n                    o := add(o, 4)\n                }\n                switch mod(len, 3)\n                case 1 { mstore(sub(o, 2), shl(240, 0x3d3d)) }\n                case 2 { mstore8(sub(o, 1), 0x3d) }\n                cut(r, o)\n            }\n            let P := mload(0x40)\n            mstore(0x40, add(P, 0x320))\n            let tok := eq(shr(224, calldataload(0)), 0xc87b56dd)\n            let s := 7\n            if tok {\n                s := calldataload(4)\n                if iszero(and(lt(sub(s, 1), 10000), gt(sload(s), 0))) { revert(0, 0) }\n                mstore(add(P, 0x20), str(s))\n            }\n            mstore(0, s)\n            s := keccak256(0, 0x20)\n            let v := mod(shr(56, s), 100)\n            let t := add(add(gt(v, 69), gt(v, 89)), gt(v, 97)) // Common 70% | Rare 20% | Epic 8% | Legendary 2%\n            let bg := mod(shr(32, s), 360)\n            let eye := mod(shr(48, s), 360)\n            if eq(t, 3) {\n                bg := 48\n                eye := 45\n            }\n            mstore(add(P, 0x40), str(bg))\n            mstore(add(P, 0x80), str(eye))\n            // trait table\n            let q := add(D, 0x20)\n            for {} iszero(eq(ch(q), 0x1f)) {} {\n                let b := ch(add(q, 1))\n                let i := and(shr(b, s), add(3, shl(2, iszero(b))))\n                if eq(b, 0x54) { i := t }\n                if eq(b, 0x5a) { i := 0 }\n                let k := ch(q)\n                q := add(q, 2)\n                for {} i {} {\n                    if eq(ch(q), 0x7c) { i := sub(i, 1) }\n                    q := add(q, 1)\n                }\n                let r := mload(0x40)\n                let o := add(r, 0x20)\n                for {} mul(sub(ch(q), 0x7c), sub(ch(q), 0x7e)) {} {\n                    mstore8(o, ch(q))\n                    o := add(o, 1)\n                    q := add(q, 1)\n                }\n                cut(r, o)\n                mstore(add(P, shl(5, k)), r)\n                q := skip(q, 0x7e)\n            }\n            let svg, q2 := fill(add(q, 1), P)\n            mstore(add(P, 0x180), b64(svg))\n            if iszero(tok) { q2 := skip(q2, 0x1f) }\n            let j, q3 := fill(q2, P)\n            pop(q3)\n            j := b64(j)\n            let m := mload(0x40)\n            let n := mload(j)\n            mstore(m, 0x20)\n            mstore(add(m, 0x20), add(n, 29))\n            mstore(add(m, 0x40), \"data:application/json;base64,\")\n            mcopy(add(m, 0x5d), add(j, 0x20), n)\n            mstore(add(add(m, 0x5d), n), 0)\n            return(m, and(add(n, 0x7c), not(31)))\n        }\n    }\n}\n"}},"abi":[{"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},{"type":"fallback","stateMutability":"payable"}],"matchId":"57251002","creationMatch":"match","runtimeMatch":"match","verifiedAt":"2026-10-27T13:57:43Z","match":"match","chainId":"56","address":"0x31D833810dCa153732A000CD3932Fe16ED1D2635"}