{"rewardSnapshot":null,"merkleRoot":null,"claims":null,"id":"328add1b-9584-461f-aa63-47549a03bde7","launchNumber":2148,"kind":"evm_contracts","status":"live","chainId":4663,"sourceRepoUrl":"https://github.com/identity-md-launches/launch-2148-dsa","sourceCommit":"e880bd5931c48ca32e7de751471a4506bd25e6e4","parkedReason":null,"artifactCount":1,"manifestHash":"2ec05740701b17eb821f5a30977efbeefc7b9acd8270981b98284ad677c416a7","attestationHash":"d218fc6c9de8b8b7869ef0664326793fd76a6adbe8a5f6beaa301da5e704ce18","attestation":{"treeHash":"4a2466f437d303cb892e0ffe5d12f5d5a894ccf7","verifierVersion":"0.1.0+745c1db4","verifierKey":"68249df1f422fa72f61ca7f0ddaf9b62043959c5c134498441d5e552a9921782","toolchain":{"solc":"0.8.26","forge":"forge Version: 1.8.3","viaIR":false,"optimizer":true,"evmVersion":"cancun","bytecodeHash":"none","optimizerRuns":200},"contracts":[{"name":"PixelFun","path":"src/PixelFun.sol","abiHash":"09f8b105371325b58910811cdccbffe043c5458e665a59629163ade864ac8221","opcodes":{"callcode":false,"delegatecall":false,"selfdestruct":false},"metadataHash":"0522a98fdd5cc611a2936263cb60a11fdbb60013881e80400358f731d658f3b0","creationCodeHash":"27367ccb0050e989098f7d67fc6b0be9348a395d28607ebb71b15db58c6e7308","deployedCodeHash":"ae80bd01d13916d83094a202313ce187538f7d104e0d4115b609964e05b37e08","creationCodeBytes":7196,"deployedCodeBytes":6921}],"manifest":{"kind":"evm_contracts","notes":"PixelFun is an ownerless 512x512 on-chain pixel canvas with a 32-color palette on Robinhood Chain. Constructor arguments: imd_ = 0x5F7Bb59365ce557C26dbcAa4EE9d39A4b95B7127 (the $IMD token named by the brief, a static address) and minPixels_ = 20 (MIN_PIXELS, the value the brief says the launch passes). EPOCH_START is the deployment block timestamp. The constructor makes no external call; PRICE = 5 * 10**(decimals-3) (0.005 IMD) is read from the token on first use and cached, reverting if decimals < 3. Users deposit IMD into a per-user vault (credited by balance difference, so fee-on-transfer tokens are handled), withdraw unspent balance at any time, and paint 1..100 pixels per call at PRICE each; the cost is burned immediately by transferring it to 0x000000000000000000000000000000000000dEaD, because the bridged IMD token's burn(uint256) could not be confirmed permissionless. Pixels are packed 32 per storage slot (0 = unpainted, 1..32 = color+1) and readable via getPixels/pixelAt. Each 3-day epoch keeps an on-chain board of the top 66 painters (entry requires >= MIN_PIXELS in that epoch, strict-greater displacement, ties favor earlier reach), readable via getBoard/isWhitelisted; finished boards are frozen. The contract has no owner, admin, pause, upgrade or privileged function, so no $owner argument is used.","contracts":[{"contract":"PixelFun","constructorArgs":["0x5F7Bb59365ce557C26dbcAa4EE9d39A4b95B7127","20"]}]},"manifestError":null},"attestationFailure":null,"deployFailure":null,"policyVersion":28,"economics":null,"poolFee":null,"requester":"0xc4a8ea10819d341d19d1dfbba7bb0e0f2295d952","admissionChecks":[{"name":"provenance","detail":"8 node(s) accepted at e880bd59","status":"passed"},{"name":"findings","detail":"8 accepted submission(s), no unresolved blocking findings","status":"passed"},{"name":"independent_review","detail":"1 independent review(s)","status":"passed"},{"name":"bytecode","detail":"1 contract(s) clean and reproducible","status":"passed"},{"name":"manifest","detail":"1 application contracts; no protocol token or pool","status":"passed"},{"name":"protected_invariants","detail":"invariants-9c691c05ee3c: Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 650.52µs (464.09µs CPU time)","status":"passed"},{"name":"economics","detail":"policy explicitly selects no on-chain contributor rewards","status":"passed"}],"assurances":[],"logo":null,"seeded":null,"createdAt":"2026-10-18T06:38:10.331Z","updatedAt":"2026-10-18T06:38:41.212Z","jobs":[{"id":"7080a75d-d9a3-48da-a85c-9cb4e20a6f67","objective":"# Brief for the IMD swarm: PixelFun — a fully on-chain, ownerless pixel canvas that burns IMD\n\nBuild, audit and deploy ONE smart contract, \"PixelFun\", on Robinhood Chain, deployed unchanged after audit. It must genuinely use $IMD (token on Robinhood Chain: 0x5F7Bb59365ce557C26dbcAa4EE9d39A4b95B7127): every pixel painted burns IMD. NO owner, NO admin, NO upgradeability, NO pause, NO privileged function of any kind. Do not add features beyond this brief.\n\n## What it is\nA shared 512x512 canvas (262,144 pixels) with a 32-color palette. Anyone paints pixels by spending a vault balance: 0.005 IMD per pixel, burned immediately. A 3-day round (\"epoch\") tracks the top 66 painters by pixels painted in that round; the top 66 of every finished round are the whitelist for a later NFT mint (the mint itself is OUT of scope). Everything needed to render the canvas and read the leaderboard must be readable from the contract alone, so a static website with only RPC access can show it.\n\n## Immutables / constants (constructor takes only the IMD address and MIN_PIXELS)\n- imd: the IMD token. PRICE = 5 * 10**(decimals-3) (0.005 token; require decimals >= 3, read decimals from the token).\n- WIDTH = 512, HEIGHT = 512, PALETTE_SIZE = 32, MAX_BATCH = 100, BOARD_SIZE = 66, EPOCH_LENGTH = 3 days.\n- EPOCH_START = block.timestamp at deployment. MIN_PIXELS = constructor argument (the owner of the launch will pass 20).\n- Burn: inspect the token first. If it has a permissionless burn(uint256), burn from the contract's own balance; otherwise send the tokens to 0x000000000000000000000000000000000000dEaD. Document which one and why (bridged tokens may restrict burn).\n\n## Vault\n- balanceOf(address) public: vault balance in IMD.\n- deposit(uint256 amount): SafeERC20 transferFrom, credit the amount actually received (balance difference), nonReentrant, emit Deposited(user, amount).\n- withdraw(uint256 amount): nonReentrant, checks-effects-interactions, returns only unspent balance, emit Withdrawn(user, amount). Always works.\n- Only msg.sender can spend their own vault balance. Nobody can move anyone else's funds.\n\n## Painting\n- paint(uint32[] ids, uint8[] colors): nonReentrant. Require equal lengths, 1..MAX_BATCH items, each id < WIDTH*HEIGHT (id = y*WIDTH + x), each color < PALETTE_SIZE. Duplicates in a batch are allowed (last wins, each is paid and counted).\n- cost = n * PRICE, deducted from the caller's vault balance and burned immediately.\n- Store pixel colors in contract storage, packed 32 pixels per 32-byte slot, 1 byte per pixel: 0 = never painted, 1..32 = colorIndex + 1.\n- Emit Painted(address indexed painter, uint64 indexed epoch, uint32[] ids, uint8[] colors, uint256 burned).\n- Counters: totalPixelsPainted (uint256), pixelsPaintedIn[epoch][painter] (uint32).\n\n## Rounds and leaderboard (all on-chain)\n- currentEpoch() = (block.timestamp - EPOCH_START) / EPOCH_LENGTH; epochStart(epoch), epochEnd(epoch) views.\n- For each epoch keep a board of at most BOARD_SIZE painters ranked by pixelsPaintedIn[epoch][painter]. A painter can enter the board only once they have >= MIN_PIXELS in that epoch. When the board is full, a newcomer displaces the lowest entry only if STRICTLY greater; ties are resolved in favor of whoever reached that count first (store the timestamp or block at which each entry last increased). Boards of finished epochs are frozen automatically because paint() only touches the current epoch.\n- Views: getBoard(epoch) returns (address[] painters, uint32[] counts) sorted by count descending, ties by earlier reach first, only filled entries; isWhitelisted(epoch, account) returns true if the account is on that epoch's board; epochEnded(epoch).\n- Keep the per-paint gas bounded (a 100-pixel batch must stay comfortably inside one transaction on the target chain). Choose an efficient board structure (for example packed entries with a cached minimum) and justify it.\n\n## Reads for the website\n- getPixels(uint256 startSlot, uint256 slotCount) returns bytes (slotCount*32 bytes, row-major pixel order); require a sane max slotCount; pixelAt(uint256 id) returns uint8.\n- PRICE, WIDTH, HEIGHT, PALETTE_SIZE, MAX_BATCH, BOARD_SIZE, MIN_PIXELS, EPOCH_LENGTH, EPOCH_START, imd, totalPixelsPainted as public getters.\n\n## Security and acceptance criteria\n- Tests must cover: deposit/withdraw accounting (including a fee-on-transfer token), paint cost and burned amount, bounds and palette checks, batch limits, insufficient balance, packed storage read/write correctness at slot boundaries, duplicate ids, epoch boundaries, board insert/displace/tie behavior, MIN_PIXELS gating, frozen boards after epoch end, reentrancy attempt, and the invariants: sum of vault balances <= token balance held, burned == PRICE * totalPixelsPainted.\n- If any requirement here cannot be met safely, say so and propose the smallest deviation. Do not silently drop it.\n- Verify the source on the explorer. Report the launch number, the final address, the audit report link and the final ABI so the website can integrate.\n- Requester / payout wallet for this launch: 0xc4a8ea10819d341d19d1dfbba7bb0e0f2295d952\n\nToken name: dsa\nToken symbol: fffa","state":"completed","attachedAt":"2026-10-18T06:38:10.331Z"}],"artifacts":[{"role":"other","name":"PixelFun","address":"0x30da521f63553ec3ea2dbb82c30581c00ccf9009","creationCodeHash":"27367ccb0050e989098f7d67fc6b0be9348a395d28607ebb71b15db58c6e7308","txHash":"0xd7c0e30bc98b22a71eff1aa35df2362f131a295cbc981c764c74fc0511b72523","blockNumber":91565987,"verifiedAt":"2026-10-18T06:39:01.411Z","verifyFailure":null}],"allocations":[]}