{"workflow":{"id":"bbfc18fc-1431-4767-a891-3e6fb7ae5b3b","objective":"Release Pixel Wall (ERC-20 symbol PIXL) on Sepolia as an evm_project: the fixed-supply launch token plus one application contract. Token: Pixel Wall (PIXL), total supply 1,000,000,000 PIXL with 18 decimals, minted once to the deployer. Application contract: PixelCanvas. Currency: PIXL is the app's working currency. PixelCanvas takes the PIXL address as its only constructor argument (constructorArgs [\"$token\"]), stores it immutable, exposes it as token(), and holds no PIXL at deploy; players get PIXL by swapping Sepolia ETH in the launch pool the factory seeds. Every payment in is approve + SafeERC20.safeTransferFrom (permit not required). PixelCanvas has no payable function and no receive/fallback, so it never holds ETH. Payouts are pull-based (the recipient calls to collect; nothing is pushed to third parties), follow checks-effects-interactions and are nonReentrant. Burns are transfers to 0x000000000000000000000000000000000000dEaD. No owner, admin, pause or upgrade path. A 32x32 shared canvas paid in PIXL. Pixels: index = y * 32 + x with x, y in 0..31; any other index reverts. A colour is a uint24 0xRRGGBB; the canvas starts all 0x000000. Colours are stored packed and canvas() returns all 1,024 colours in one call as bytes of length 3,072 (3 bytes per pixel, index order). Price: every pixel has its own price, starting at 10 PIXL (10 * 10^18 base units). paint(index, colour) charges the pixel's current price; afterwards that pixel's price becomes floor(old * 11 / 10), capped at 1,000,000 PIXL. paintBatch(indices, colours) paints up to 64 pixels with one safeTransferFrom of the summed cost; mismatched lengths, an empty batch or more than 64 entries revert; a repeated index in one batch is processed in order, each at its then-current price. Split: the first paint of a pixel burns 100% of the price; a repaint credits floor(price / 2) to the previous painter's withdrawable balance and burns the rest in the same call. Repainting your own pixel is allowed (you are credited half, the rest burns). withdraw() pays the caller's whole withdrawable balance and reverts on zero. Views: canvas(), priceOf(index), painterOf(index), withdrawable(address), token(). Events: Painted(index, colour, painter, price), Withdrawn(account, amount). Tests (Foundry) must cover: price growth and the 1,000,000 PIXL cap; the first-paint vs repaint split with odd prices; batch limits and a repeated index; out-of-range index reverts; withdraw of zero reverts and cannot pay twice; and the invariant that PIXL held by PixelCanvas always equals the sum of withdrawable balances (the rest was burned at paint time). The independent adversarial review must attack: rounding in the 50/50 split and the 10% step, the price-cap boundary, batch cost arithmetic (a batch must never cost less than the same paints one by one), and reentrancy or griefing through withdraw. Deploy through the project factory, then publish a one-page website to draw the live canvas from canvas() and Painted events, pick a colour, queue up to 64 pixels and show the total cost before painting. The page reads the PIXL address from PixelCanvas.token(), shows the connected wallet's PIXL balance, allowance and withdrawable balance, has an Approve step before every paying action and a Withdraw button, and says that PIXL comes from swapping Sepolia ETH in the launch pool (no in-page swap). Lists come from contract views and events only (no backend, no indexer). Keep it to one small page; the static export has index.html in dist/.","status":"completed","brief":"# Approved workflow\n\nRelease Pixel Wall (ERC-20 symbol PIXL) on Sepolia as an evm_project: the fixed-supply launch token plus one application contract. Token: Pixel Wall (PIXL), total supply 1,000,000,000 PIXL with 18 decimals, minted once to the deployer. Application contract: PixelCanvas. Currency: PIXL is the app's working currency. PixelCanvas takes the PIXL address as its only constructor argument (constructorArgs [\"$token\"]), stores it immutable, exposes it as token(), and holds no PIXL at deploy; players get PIXL by swapping Sepolia ETH in the launch pool the factory seeds. Every payment in is approve + SafeERC20.safeTransferFrom (permit not required). PixelCanvas has no payable function and no receive/fallback, so it never holds ETH. Payouts are pull-based (the recipient calls to collect; nothing is pushed to third parties), follow checks-effects-interactions and are nonReentrant. Burns are transfers to 0x000000000000000000000000000000000000dEaD. No owner, admin, pause or upgrade path. A 32x32 shared canvas paid in PIXL. Pixels: index = y * 32 + x with x, y in 0..31; any other index reverts. A colour is a uint24 0xRRGGBB; the canvas starts all 0x000000. Colours are stored packed and canvas() returns all 1,024 colours in one call as bytes of length 3,072 (3 bytes per pixel, index order). Price: every pixel has its own price, starting at 10 PIXL (10 * 10^18 base units). paint(index, colour) charges the pixel's current price; afterwards that pixel's price becomes floor(old * 11 / 10), capped at 1,000,000 PIXL. paintBatch(indices, colours) paints up to 64 pixels with one safeTransferFrom of the summed cost; mismatched lengths, an empty batch or more than 64 entries revert; a repeated index in one batch is processed in order, each at its then-current price. Split: the first paint of a pixel burns 100% of the price; a repaint credits floor(price / 2) to the previous painter's withdrawable balance and burns the rest in the same call. Repainting your own pixel is allowed (you are credited half, the rest burns). withdraw() pays the caller's whole withdrawable balance and reverts on zero. Views: canvas(), priceOf(index), painterOf(index), withdrawable(address), token(). Events: Painted(index, colour, painter, price), Withdrawn(account, amount). Tests (Foundry) must cover: price growth and the 1,000,000 PIXL cap; the first-paint vs repaint split with odd prices; batch limits and a repeated index; out-of-range index reverts; withdraw of zero reverts and cannot pay twice; and the invariant that PIXL held by PixelCanvas always equals the sum of withdrawable balances (the rest was burned at paint time). The independent adversarial review must attack: rounding in the 50/50 split and the 10% step, the price-cap boundary, batch cost arithmetic (a batch must never cost less than the same paints one by one), and reentrancy or griefing through withdraw. Deploy through the project factory, then publish a one-page website to draw the live canvas from canvas() and Painted events, pick a colour, queue up to 64 pixels and show the total cost before painting. The page reads the PIXL address from PixelCanvas.token(), shows the connected wallet's PIXL balance, allowance and withdrawable balance, has an Approve step before every paying action and a Withdraw button, and says that PIXL comes from swapping Sepolia ETH in the launch pool (no in-page swap). Lists come from contract views and events only (no backend, no indexer). Keep it to one small page; the static export has index.html in dist/.\n\nSepolia (11155111) only. GitHub publication and IPFS hosting are approved. Launch token: a separate fixed-supply ERC-20, 18 decimals, no constructor arguments, exactly 1,000,000,000 minted to msg.sender, no mint or admin functions. The factory sends that supply to LP and rewards, so no application contract may need a launch-token balance at deploy. Application contracts are fully configured in nonpayable constructors using only address, uint, bool or bytes32 arguments (no strings, arrays, proxies, delegatecall or selfdestruct); anything else is set at runtime. No owner unless the request names one, and then it is $owner. No external oracles, VRF or keepers: randomness is commit-reveal or a future blockhash read within 256 blocks with a refund path. foundry.toml sets bytecode_hash = \"none\". The website is a static export with index.html in dist/. Site label lab-pixel-canvas.\n\nBuild PIXL and PixelCanvas (PixelCanvas takes constructorArgs [\"$token\"] and charges PIXL) with Foundry tests and an independent adversarial review, deploy them through the project factory, then build the one-page website against the live deployment.\n","briefDigest":"47dac2b44433622cde458322075beadb80939f82099b5347b2488a3ca0ff866a"},"planning":null,"id":"48fdb771-69d6-4f52-9dd9-e066a8ef5cf2","state":"completed","template":"shape:chain","objective":"WORKFLOW CONTRACT STAGE CONTEXT: the stage produces implemented and tested contracts, ABI documentation and an independently reviewed launch.json. Each assignment contributes only within its own role and write scope. Source-producing assignments own implementation, tests and ABI exports at docs/abi/<Contract>.json where their scope permits. The generated manifest assignment writes only launch.json. Review assignments inspect accepted source and manifest and return findings without editing files; they do not implement contracts or generate ABI files. Use the supplied canonical manifest guidance: policy and signed artifact linkage belong to services, while concrete source, constructor, policy or authorization conflicts remain review findings. Services publish source, attest, admit and deploy after this stage, then start the frontend. Read .imd/reads/workflow.md for the complete approved requirements and apply them to your assigned contribution; later service outcomes are not prerequisites of this assignment.","blockedReason":null,"createdAt":"2026-09-27T05:08:17.792Z","updatedAt":"2026-09-27T05:29:19.579Z","paidBy":"0x8a3b860f6dbfbbbb07f21905ed8cb0234538bdc8","via":"api.imd.fun","parentJobId":null,"project":{"id":"48fdb771-69d6-4f52-9dd9-e066a8ef5cf2","head":"959b62c5-9e80-4b76-b612-bf255a24d7ad","running":null,"versions":[{"jobId":"48fdb771-69d6-4f52-9dd9-e066a8ef5cf2","workflowId":"bbfc18fc-1431-4767-a891-3e6fb7ae5b3b","objective":"Release Pixel Wall (ERC-20 symbol PIXL) on Sepolia as an evm_project: the fixed-supply launch token plus one application contract. Token: Pixel Wall (PIXL), total supply 1,000,000,000 PIXL with 18 decimals, minted once to the deployer. Application contract: PixelCanvas. Currency: PIXL is the app's working currency. PixelCanvas takes the PIXL address as its only constructor argument (constructorArgs [\"$token\"]), stores it immutable, exposes it as token(), and holds no PIXL at deploy; players get PIXL by swapping Sepolia ETH in the launch pool the factory seeds. Every payment in is approve + SafeERC20.safeTransferFrom (permit not required). PixelCanvas has no payable function and no receive/fallback, so it never holds ETH. Payouts are pull-based (the recipient calls to collect; nothing is pushed to third parties), follow checks-effects-interactions and are nonReentrant. Burns are transfers to 0x000000000000000000000000000000000000dEaD. No owner, admin, pause or upgrade path. A 32x32 shared canvas paid in PIXL. Pixels: index = y * 32 + x with x, y in 0..31; any other index reverts. A colour is a uint24 0xRRGGBB; the canvas starts all 0x000000. Colours are stored packed and canvas() returns all 1,024 colours in one call as bytes of length 3,072 (3 bytes per pixel, index order). Price: every pixel has its own price, starting at 10 PIXL (10 * 10^18 base units). paint(index, colour) charges the pixel's current price; afterwards that pixel's price becomes floor(old * 11 / 10), capped at 1,000,000 PIXL. paintBatch(indices, colours) paints up to 64 pixels with one safeTransferFrom of the summed cost; mismatched lengths, an empty batch or more than 64 entries revert; a repeated index in one batch is processed in order, each at its then-current price. Split: the first paint of a pixel burns 100% of the price; a repaint credits floor(price / 2) to the previous painter's withdrawable balance and burns the rest in the same call. Repainting your own pixel is allowed (you are credited half, the rest burns). withdraw() pays the caller's whole withdrawable balance and reverts on zero. Views: canvas(), priceOf(index), painterOf(index), withdrawable(address), token(). Events: Painted(index, colour, painter, price), Withdrawn(account, amount). Tests (Foundry) must cover: price growth and the 1,000,000 PIXL cap; the first-paint vs repaint split with odd prices; batch limits and a repeated index; out-of-range index reverts; withdraw of zero reverts and cannot pay twice; and the invariant that PIXL held by PixelCanvas always equals the sum of withdrawable balances (the rest was burned at paint time). The independent adversarial review must attack: rounding in the 50/50 split and the 10% step, the price-cap boundary, batch cost arithmetic (a batch must never cost less than the same paints one by one), and reentrancy or griefing through withdraw. Deploy through the project factory, then publish a one-page website to draw the live canvas from canvas() and Painted events, pick a colour, queue up to 64 pixels and show the total cost before painting. The page reads the PIXL address from PixelCanvas.token(), shows the connected wallet's PIXL balance, allowance and withdrawable balance, has an Approve step before every paying action and a Withdraw button, and says that PIXL comes from swapping Sepolia ETH in the launch pool (no in-page swap). Lists come from contract views and events only (no backend, no indexer). Keep it to one small page; the static export has index.html in dist/.","baseCommit":"0243d7da4a4337ae8b16bcdf15bb4ead736fd68f","state":"completed","createdAt":"2026-09-27T05:08:17.792Z"}]},"deliver":true,"host":false,"site":null,"launch":{"requested":true,"kind":"evm_project","id":"0ac37315-248f-49a3-b0ae-6087acd07c31","status":"live","chainId":11155111},"oracleRequestId":null,"delivery":{"repoUrl":"https://github.com/identity-md-launches/launch-230-pixelcanvas","pullRequestUrl":null,"commit":"47402819880637849506a175967fa00aa1ba91a6","deliveredAt":"2026-09-27T05:29:30.173Z","media":null},"media":null,"nodes":[{"key":"adversarial_review","role":"review","state":"accepted","attempt":1,"revisions":0,"judgeRevisions":0,"dependsOn":["build_contract_project","manifest"],"allowedPaths":[],"failureReason":null,"dispatchNote":null,"dispatchNoteAt":null,"updatedAt":"2026-09-27T05:29:19.579Z","verdict":null,"seat":{"tokenId":"211","agentId":"51060"},"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-09-27T05:22:07.017Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+ff982c0f","verifiedTreeHash":"555feb9c1ff38abd72d5e8c96bac478ec75b2fb7","at":"2026-09-27T05:22:07.020Z","failedChecks":[]},"seat":{"tokenId":"494","agentId":"50904"},"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-09-27T05:25:02.888Z","verdict":{"status":"accepted","profile":"foundry","evaluation":"checks","rejectionCode":null,"detail":"all checks passed","verifierVersion":"0.1.0+ff982c0f","verifiedTreeHash":"b7591b825c3e54973186088534569a76f45ab268","at":"2026-09-27T05:25:02.891Z","failedChecks":[]},"seat":{"tokenId":"494","agentId":"50904"},"live":null}],"reviews":[{"status":"sent","chainId":1,"txHash":"0x40f43d4b46136797d4ae64701a92fa7a8be91b4a9dc65ae8ba83f17f65b28ab2","blockNumber":26115275,"sentAt":"2026-10-04T00:03:13.836Z","entries":[]},{"status":"sent","chainId":1,"txHash":"0x6b5e60dc5375e517173015494a08d3b8fa7e1d2cd7df53e22e2e91a20266b346","blockNumber":26114062,"sentAt":"2026-10-03T20:00:15.534Z","entries":[{"nodeKey":"adversarial_review","agentId":"51060","value":1,"role":"review:submission"},{"nodeKey":"build_contract_project","agentId":"50904","value":1,"role":"verification:checks"},{"nodeKey":"manifest","agentId":"50904","value":1,"role":"verification:checks"}]}]}