{"workflow":null,"planning":null,"id":"a01ac51c-d89f-438b-b9bb-c8292b948244","state":"completed","template":"shape:chain","objective":"A contract for an NFT collection called IMDPunks: 10,000 pixel-portrait characters, numbered 0 to 9999, with all art and metadata fully on-chain. Just the contracts: no launch token, no pool, no fees.\n\nToken name: IMDPunks\nToken symbol: IMDPUNK\nTotal supply: 10000 (fixed; nothing can ever mint more)\n\nContract: an ERC-721 whose contract is named exactly IMDPunks, with name \"IMDPunks\" and symbol \"IMDPUNK\" as source constants. It also exposes totalSupply() (how many exist so far), MAX_SUPPLY() = 10000, isMinted(uint256), claimedBy(address) and typeOf(uint256).\n\nReserve: 200 punks belong to 0x2E28b29560a6d4812E58680484c685D0352f8ff9 from the moment of deployment: numbers 0 to 197, and numbers 777 and 888. The reserve address is a constructor argument (an address; do not use msg.sender, the deployer is a factory). Each reserved punk emits a Transfer event from the zero address in the constructor, ownerOf and balanceOf are right from block one, and they transfer like any other token. Make the reserve cheap: the whole deployment, reserve included, must fit in 10,000,000 gas.\n\nPublic claim: claim(uint256 number) is free (not payable) and mints that exact number to the caller. It reverts when the number is 10000 or more, already minted, or reserved, and when the caller has already claimed 5. The limit is 5 claims per address for good; receiving punks by transfer does not count. There is no other way to mint, no owner, no admin, no pause, no upgrade, no allowlist, no royalties, no withdraw function, and the contract never accepts ETH.\n\nTypes, with exact counts over the 10,000: 9 Alien, 24 Ape, 88 Zombie, 3,840 Female, 6,039 Male. The type of a number is fixed by rank = (number * 7919 + 4321) % 10000: rank 0-8 Alien, 9-32 Ape, 33-120 Zombie, 121-3960 Female, 3961-9999 Male. This is one-to-one, so the counts are exact; do not use a hash for the type.\n\nAccessories: each punk has 0 to 7 accessories, chosen from keccak256 of the number, never two in the same slot (head, eyes, mouth, facial hair, ear, neck, face mark), and only ones drawn for its type (Female has her own set; Alien, Ape and Zombie use the Male set). Roughly: 0 accessories 0.1%, one 3%, two 36%, three 45%, four 14%, five 1.7%, six or seven 0.2%. Aim for 87 different accessories in total; if the art data will not fit, ship fewer rather than fail, but never fewer than 40, and say in the README how many there are.\n\nArt: each punk is a 24 by 24 pixel portrait on a flat single-colour background, drawn as an SVG by the contract (viewBox 0 0 24 24, shape-rendering crispEdges, one rect per run of pixels). It is original pixel art in the manner of 2017 pixel-avatar collections: draw your own base heads for the five types (several skin tones for Male and Female) and your own accessories with your own names. Do not copy the pixels, palette, sprite sheet or trait names of any existing collection. Every one of the 10,000 must render a complete, recognisable face.\n\nMetadata: tokenURI(number) returns a data:application/json;base64 document with name \"IMDPunk #<number>\", a one-line description, image as a data:image/svg+xml;base64 SVG, and attributes: Type, one entry per accessory, and \"Accessory count\". tokenURI works for every number 0 to 9999 that has been minted and reverts for the rest; add imageOf(uint256) that returns the SVG for any number 0 to 9999, minted or not.\n\nSize: if the art does not fit in one contract, put the sprite data in separate data contracts that the IMDPunks constructor creates itself or that the launch deploys before it and passes in as address constructor arguments. Constructor arguments are addresses and numbers only.\n\nUpgrades and pausing: none. Transfer rules: plain ERC-721, no fee, no limit. Owner: none.\n\nTests that must exist: the type of all 10,000 numbers counted, matching the five exact totals; no punk has two accessories in one slot or an accessory of the wrong type; the 200 reserved numbers are owned by the reserve at deployment and can be transferred; claim of a reserved, taken or out-of-range number reverts; a sixth claim from one address reverts; totalSupply ends at 10000 and not one more; tokenURI and imageOf return well-formed output for a sample of at least 200 numbers including 0, 777, 888 and 9999 and for one punk of each type; deployment gas is under 10,000,000.\n\nThe review must try: minting past 10,000 or minting a number twice, getting past the 5-claim limit from one address (reentrancy through onERC721Received included; use _mint or guard it), claiming a reserved number, breaking the reserve's ownership or balance accounting on its first transfer, and any tokenURI input that reverts or returns broken JSON.","blockedReason":null,"createdAt":"2026-10-06T00:04:31.835Z","updatedAt":"2026-10-06T00:42:59.275Z","paidBy":"0x2e28b29560a6d4812e58680484c685d0352f8ff9","parentJobId":null,"project":{"id":"a01ac51c-d89f-438b-b9bb-c8292b948244","head":"a01ac51c-d89f-438b-b9bb-c8292b948244","running":null,"versions":[{"jobId":"a01ac51c-d89f-438b-b9bb-c8292b948244","workflowId":null,"objective":"A contract for an NFT collection called IMDPunks: 10,000 pixel-portrait characters, numbered 0 to 9999, with all art and metadata fully on-chain. Just the contracts: no launch token, no pool, no fees.\n\nToken name: IMDPunks\nToken symbol: IMDPUNK\nTotal supply: 10000 (fixed; nothing can ever mint more)\n\nContract: an ERC-721 whose contract is named exactly IMDPunks, with name \"IMDPunks\" and symbol \"IMDPUNK\" as source constants. It also exposes totalSupply() (how many exist so far), MAX_SUPPLY() = 10000, isMinted(uint256), claimedBy(address) and typeOf(uint256).\n\nReserve: 200 punks belong to 0x2E28b29560a6d4812E58680484c685D0352f8ff9 from the moment of deployment: numbers 0 to 197, and numbers 777 and 888. The reserve address is a constructor argument (an address; do not use msg.sender, the deployer is a factory). Each reserved punk emits a Transfer event from the zero address in the constructor, ownerOf and balanceOf are right from block one, and they transfer like any other token. Make the reserve cheap: the whole deployment, reserve included, must fit in 10,000,000 gas.\n\nPublic claim: claim(uint256 number) is free (not payable) and mints that exact number to the caller. It reverts when the number is 10000 or more, already minted, or reserved, and when the caller has already claimed 5. The limit is 5 claims per address for good; receiving punks by transfer does not count. There is no other way to mint, no owner, no admin, no pause, no upgrade, no allowlist, no royalties, no withdraw function, and the contract never accepts ETH.\n\nTypes, with exact counts over the 10,000: 9 Alien, 24 Ape, 88 Zombie, 3,840 Female, 6,039 Male. The type of a number is fixed by rank = (number * 7919 + 4321) % 10000: rank 0-8 Alien, 9-32 Ape, 33-120 Zombie, 121-3960 Female, 3961-9999 Male. This is one-to-one, so the counts are exact; do not use a hash for the type.\n\nAccessories: each punk has 0 to 7 accessories, chosen from keccak256 of the number, never two in the same slot (head, eyes, mouth, facial hair, ear, neck, face mark), and only ones drawn for its type (Female has her own set; Alien, Ape and Zombie use the Male set). Roughly: 0 accessories 0.1%, one 3%, two 36%, three 45%, four 14%, five 1.7%, six or seven 0.2%. Aim for 87 different accessories in total; if the art data will not fit, ship fewer rather than fail, but never fewer than 40, and say in the README how many there are.\n\nArt: each punk is a 24 by 24 pixel portrait on a flat single-colour background, drawn as an SVG by the contract (viewBox 0 0 24 24, shape-rendering crispEdges, one rect per run of pixels). It is original pixel art in the manner of 2017 pixel-avatar collections: draw your own base heads for the five types (several skin tones for Male and Female) and your own accessories with your own names. Do not copy the pixels, palette, sprite sheet or trait names of any existing collection. Every one of the 10,000 must render a complete, recognisable face.\n\nMetadata: tokenURI(number) returns a data:application/json;base64 document with name \"IMDPunk #<number>\", a one-line description, image as a data:image/svg+xml;base64 SVG, and attributes: Type, one entry per accessory, and \"Accessory count\". tokenURI works for every number 0 to 9999 that has been minted and reverts for the rest; add imageOf(uint256) that returns the SVG for any number 0 to 9999, minted or not.\n\nSize: if the art does not fit in one contract, put the sprite data in separate data contracts that the IMDPunks constructor creates itself or that the launch deploys before it and passes in as address constructor arguments. Constructor arguments are addresses and numbers only.\n\nUpgrades and pausing: none. Transfer rules: plain ERC-721, no fee, no limit. Owner: none.\n\nTests that must exist: the type of all 10,000 numbers counted, matching the five exact totals; no punk has two accessories in one slot or an accessory of the wrong type; the 200 reserved numbers are owned by the reserve at deployment and can be transferred; claim of a reserved, taken or out-of-range number reverts; a sixth claim from one address reverts; totalSupply ends at 10000 and not one more; tokenURI and imageOf return well-formed output for a sample of at least 200 numbers including 0, 777, 888 and 9999 and for one punk of each type; deployment gas is under 10,000,000.\n\nThe review must try: minting past 10,000 or minting a number twice, getting past the 5-claim limit from one address (reentrancy through onERC721Received included; use _mint or guard it), claiming a reserved number, breaking the reserve's ownership or balance accounting on its first transfer, and any tokenURI input that reverts or returns broken JSON.","baseCommit":"0243d7da4a4337ae8b16bcdf15bb4ead736fd68f","state":"completed","createdAt":"2026-10-06T00:04:31.835Z"}]},"deliver":true,"host":false,"site":null,"launch":{"requested":true,"kind":"evm_contracts","id":"1ef56446-05a6-49da-9890-1b580562c20c","status":"live","chainId":11155111},"oracleRequestId":null,"delivery":{"repoUrl":"https://github.com/identity-md-launches/launch-752-imdpunks","pullRequestUrl":"https://github.com/identity-md-launches/launch-752-imdpunks/pull/1","commit":"24c1dc519ae6ff176a3cfd847926e444f8049be7","deliveredAt":"2026-10-06T00:43:11.387Z","media":null},"media":null,"nodes":[{"key":"audit_economics","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-06T00:27:26.485Z","verdict":null,"seat":{"tokenId":"954","agentId":"51346"},"live":null},{"key":"audit_flow","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-06T00:30:31.180Z","verdict":null,"seat":{"tokenId":"581","agentId":"51339"},"live":null},{"key":"audit_judge","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-06T00:42:59.275Z","verdict":null,"seat":{"tokenId":"1844","agentId":"51298"},"live":null},{"key":"audit_math","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-06T00:34:04.767Z","verdict":null,"seat":{"tokenId":"911","agentId":"51345"},"live":null},{"key":"audit_permissions","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-06T00:27:48.973Z","verdict":null,"seat":{"tokenId":"1807","agentId":"51427"},"live":null},{"key":"build_contract_project","role":"implement","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":[],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-06T00:18:33.763Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+f8d984f2","verifiedTreeHash":"a9e3ba890c21cc27ff5f57c8b628096c294a1d52","at":"2026-10-06T00:18:33.762Z","failedChecks":[]},"seat":{"tokenId":"1409","agentId":"50977"},"live":null},{"key":"manifest","role":"integrate","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":["launch.json"],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-06T00:20:44.577Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+f8d984f2","verifiedTreeHash":"a38d2408ca14b38f1ed377b8e3bf093f91b9367b","at":"2026-10-06T00:20:44.576Z","failedChecks":[]},"seat":{"tokenId":"464","agentId":"51013"},"live":null},{"key":"write_foundry_tests","role":"tests","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project"],"allowedPaths":["test","test/**"],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-10-06T00:28:53.245Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+f8d984f2","verifiedTreeHash":"60bbfbd303dccd44901611028066085fffd4c2ca","at":"2026-10-06T00:28:53.258Z","failedChecks":[]},"seat":{"tokenId":"212","agentId":"51086"},"live":null}],"reviews":[{"status":"sent","chainId":1,"txHash":"0x1f26ce305f567a16021af8f7d289b38fb9680b578a5f2a8c9d10e51683d49557","blockNumber":26129828,"sentAt":"2026-10-06T00:43:28.211Z","entries":[{"nodeKey":"audit_economics","agentId":"51346","value":1,"role":"review:submission"},{"nodeKey":"audit_flow","agentId":"51339","value":1,"role":"review:submission"},{"nodeKey":"audit_judge","agentId":"51298","value":1,"role":"review:submission"},{"nodeKey":"audit_math","agentId":"51345","value":1,"role":"review:submission"},{"nodeKey":"audit_permissions","agentId":"51427","value":1,"role":"review:submission"},{"nodeKey":"build_contract_project","agentId":"50977","value":1,"role":"verification:checks"},{"nodeKey":"manifest","agentId":"51013","value":1,"role":"verification:checks"},{"nodeKey":"write_foundry_tests","agentId":"51086","value":1,"role":"verification:checks"}]}]}