{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"1336f7b0-b673-420e-9479-a25a6a184cab","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"0233461c5713df6078080a6d601e15a04039dbc548bd7ff6d2b665dd88722510","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"7ea96cfc8122ed820d0b584cdc72f21cce9bf563059266b853632129fa805e89","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"17d4d47588a0eb3ef16dfd677c7c9cc40f2340f3d7763dc2be0ab88cac16ace3","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"d22046654595b7505e1604e3b3ba12a19ada2c360daa1eedb0c24f45e427c20c","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"240030220f33c98177fdd9b96397c241e360fe7d34b7ad0ba8953b1a59d351ff","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"4a7e3d39e3de7b8c22589f94fff565629560de521007b6a217350e9cd4353e9b","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"c6866d67bf1a744111bda916c34fdc8b4343d83c1d524ed7512c09e2da361ac8","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"834218b6af8531fc33d1aa91f60d9053e0f2035d7af5e3b6bd4dcef0c77f1845","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","state":"accepted"}],"objective":"You are tasked with launching the first token ever created through Adam’s new ERC20T infrastructure on Ethereum mainnet, and building a complete professional website/app for it.\n\nGoal: Deploy a new ERC20T token named \"erc20t\" paired with $IMD, immediately launch its Uniswap v4 pool using the ERC20TFactory, and deliver a polished retro-punk style website/app that presents every important detail cleanly and professionally.\n\nKey contracts:\n- Factory: 0x801411c6acec4fa80c75c5d3c0eae13c84f8a173\n- Hook: 0xed9a04fa6693e754661a22502524df9b1857e544\n- IMD (quoteToken): 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7\n- Uniswap v4 PositionManager: 0xbd216513d74c8cf14cf4747e6aaa6420ff64ee9e\n- Permit2: 0x000000000022D473030F116dDEE9F6B43aC78BA3\n\nToken parameters:\n- Name: erc20t\n- Symbol: ERC20T\n- Total supply: 1_000_000_000 * 1e18 (1 billion)\n- Creator allocation: 5% (500 bps) — send the rest into the LP\n- Owner: the wallet that is paying for this job (or a designated deployer wallet)\n- Hook: the address above\n- Quote token: IMD\n- Resting tax: 100 bps (1%)\n- Launch tax: 9900 bps (99%), decaying 100 bps every 60 seconds\n- Fee recipient: owner wallet\n- Fee decay recipient: owner wallet (or protocol if required)\n\nAction — Token launch:\n1. Confirm no tokens have been created on the factory yet.\n2. Call createAndLaunchAtPrice (preferred) or createAndLaunch on the factory.\n3. Use a reasonable starting price that creates a healthy initial market cap (equivalent to a few thousand USD in IMD).\n4. Ensure single-sided liquidity is permanently locked.\n5. Return the new token address, transaction hash, and confirmation it is the first (or among the first).","parentJobId":null,"planHash":"40683daf2e17e11ad4fd3f8ce5a0e7e2ddf769a569a7166d2846e749ca438e12","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"1336f7b0-b673-420e-9479-a25a6a184cab","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2034-you-are-tasked-launching"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52615","feedbackHash":"c9377224e7593a4207f37413ec68ddb4de5c5109948055fa604f722f3c582769","nodeKey":"audit_economics","submissionHash":"0233461c5713df6078080a6d601e15a04039dbc548bd7ff6d2b665dd88722510","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52599","feedbackHash":"edfbd8a387e7b28b9c9eb92326e5184be55ed335994408d5506423b008c38048","nodeKey":"audit_flow","submissionHash":"7ea96cfc8122ed820d0b584cdc72f21cce9bf563059266b853632129fa805e89","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51482","feedbackHash":"6fc680fd841f704910800b26029c6245844810711e25cd6cbf2905c7d37cb941","nodeKey":"audit_judge","submissionHash":"c2e64b201a1a071fb1a62dbacd9034362b1aabf31109d06e93c7e2e15dbcc9d9","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50989","feedbackHash":"51335c6fc5f6401fe3d722982aacf17ed60fee45712cfcff21fd6b0941de8416","nodeKey":"audit_judge","submissionHash":"17d4d47588a0eb3ef16dfd677c7c9cc40f2340f3d7763dc2be0ab88cac16ace3","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52609","feedbackHash":"cae0abf9708bff161827e0ec575cb490fc28dda6ff14c1e6606ec836c4214aa2","nodeKey":"audit_math","submissionHash":"d22046654595b7505e1604e3b3ba12a19ada2c360daa1eedb0c24f45e427c20c","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52257","feedbackHash":"5ba73e909713b41bd2a3875e17c69f6148e43cae77a50addac5207ac93648848","nodeKey":"audit_permissions","submissionHash":"240030220f33c98177fdd9b96397c241e360fe7d34b7ad0ba8953b1a59d351ff","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52258","feedbackHash":"a16eb66a07329f0e7195723ff7fc54d8229cb5c70df99832b48d2e4c763694a1","nodeKey":"build_contract_project","submissionHash":"4a7e3d39e3de7b8c22589f94fff565629560de521007b6a217350e9cd4353e9b","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51522","feedbackHash":"686541cbd67fb71c973e26451bd44ab63834f9bfa178a22b0f7bb7b4209f90d7","nodeKey":"build_contract_project","submissionHash":"fc4347b09b41bd64d5c43085c726000595772753587a5030411ca524a496b085","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52611","feedbackHash":"68cd59706ae4c30dd71cbee34a8a4c81f2720054ff5f75aed9035d369bf4c55c","nodeKey":"manifest","submissionHash":"c6866d67bf1a744111bda916c34fdc8b4343d83c1d524ed7512c09e2da361ac8","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"50954","feedbackHash":"a83c133061c1f8b2b20b6a3f04f4aefc2e6a008b6c698d9511b4d990669b3172","nodeKey":"manifest","submissionHash":"733e99ee97ca965cff5cceede8c4f96185a5c504a6fd3da468ac579f4207699e","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52590","feedbackHash":"db3b01a78b9c42095383cc7c69e89bb0d5422ad8281a7e8b4926c83f95253fed","nodeKey":"write_foundry_tests","submissionHash":"d3f6cf125d05358b5513fa8f0c0341c9cc8cd33e2a6489ef19d6e56cf5adc2d4","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52612","feedbackHash":"d1478252f0ce66e3b5434b511ba6801e488f125d4990b263f4504bea839bebe6","nodeKey":"write_foundry_tests","submissionHash":"834218b6af8531fc33d1aa91f60d9053e0f2035d7af5e3b6bd4dcef0c77f1845","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"68c43e8cd2c5934608d542156ba34e21bfe13c8fd71edc5d167006173b589af7","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"b8fd8054ea57c5d8","findings":[{"citation":"resolved","description":"tokenConfig() sets both feeRecipient and feeDecayRecipient to `owner` (as the brief requests). The existing hook takes the launch tax (99% decaying 1 point/min for 98 min), converts it to ETH through the IMD/ETH 1% pool and pays (tax - 15bps share) to feeDecayRecipient. Seam periphery x first-principles: the launch tax is the only anti-sniping mechanism of this launch (single-sided pool, no IMD backing), but for the one wallet that also holds the 5% liquid creator allocation and the token's admin role, almost the whole tax comes back. So during the 98-minute window, when every other buyer is priced out (an outsider pays 100x spot at t=0 and 2x at t=49min), the owner can buy pool supply near the opening price. They can also sell the 50M creator tokens into early buyers' IMD and get the 99% sell tax refunded the same way. Their loss is only the conversion pool fee/slippage plus the 15/9900 protocol share. Neither README.md (line 54 'Both token fee streams initially go to the owner'), site/index.html ('Early trading carries a very high tax') nor docs.html tells buyers that the high early tax does not apply in effect to the creator. The ERC20TLaunch code is correct for the requested parameters. The defect is an undisclosed economic asymmetry that breaks the guarantee buyers would read into a 99% launch tax. Per the review rules this is reported as a trust/economic finding, not a request to change the requested recipients.","line":104,"path":"src/ERC20TLaunch.sol","reproduction":"Fixture state (MainnetState, block 26208519). 1) OWNER=0x3d6a..6193 calls app.launch(540540540540, block.timestamp+300, false). 2) Same block, tax=9900: a router whose PoolManager take() pays OWNER swaps exact-input 10e18 IMD -> ERC20T on t.poolKey() (zeroForOne = IMD<token). Observed: OWNER receives 181,214.015e18 ERC20T and 0.022499598919220122 ETH from the hook. Swapping that ETH back through the hook's own route externalBasePool(IMD) (ETH/IMD fee 10000, ts 60, hook 0xc6C9..2840) returns 9.690263065434519041 IMD. Owner's net cost: 10 - 9.69 = 0.31 IMD for tokens a non-recipient pays 10 IMD for: an outsider doing the identical 10 IMD buy right after receives 181,145.547e18 ERC20T and gets nothing back (OWNER receives another 0.0224990 ETH from that outsider's tax). Expected for a launch tax meant to deter early accumulation: the creator/admin wallet faces the same ~99% cost as everyone else, or the asymmetry is clearly disclosed. Actual: ~3.1% of notional for the owner vs 99% for others, undisclosed. Mitigation that keeps the brief: document it prominently in README/site/docs (owner effectively exempt from launch/decay tax), or with requester approval route feeDecayRecipient to a non-owner sink/protocol (the brief allows 'or protocol if required').","severity":"low","snippet":"            feeRecipient: owner,\n            launchTaxBps: LAUNCH_TAX_BPS,\n            taxDecayIntervalSeconds: TAX_DECAY_INTERVAL_SECONDS,\n            feeDecayRecipient: owner","title":"Launch-tax anti-snipe does not bind the owner: 99% buy/sell tax is paid back to the owner as ETH, so the owner can accumulate or dump at ~1-3% effective cost during the decay window"}],"hash":"0233461c5713df6078080a6d601e15a04039dbc548bd7ff6d2b665dd88722510","nodeId":"f2bfe4d7-8ca3-49b4-a5b3-73a4f7d1481d","outcome":"completed","summary":"I found one economic issue, rated low. The launch contract itself behaves as specified. The project's 42 Foundry tests pass, and the working tree is unchanged: I deleted my scratch tests, and `.imd-findings.json` (one finding, seven coverage rows) doesn't appear in `git status`.\n\n**The finding: the 99% launch tax doesn't really apply to the owner.** `tokenConfig()` (`src/ERC20TLaunch.sol:104`) makes the owner both fee recipients, as the brief asks. The hook converts the collected tax to ETH and pays it to that recipient. So the one wallet that also holds the 5% liquid creator allocation and the token's admin role gets almost all of the tax back. I measured it on the recorded mainnet state:\n- **Owner:** in the launch block, a 10 IMD buy returned 181,214 ERC20T plus 0.0225 ETH. That ETH swaps back to 9.69 IMD, so the net cost was about 0.31 IMD.\n- **Outsider:** the identical buy right after returned 181,146 ERC20T and nothing back.\n\nSo for the whole 98-minute window that prices everyone else out, the owner can buy near the opening price, or sell the 50M creator tokens, for about 1–3% instead of 99%. The README, site and docs never say this. Since the brief asks for owner-paid fees, I've reported it as a disclosure and trust gap, not a demand to change who gets paid. The fixes it suggests are a prominent disclosure, or (with the requester's approval) sending decay fees to the protocol, which the brief already allows.\n\n**Checks that held:**\n- **Pre-initializing the pool:** no outsider can set up the v4 pool at the token's predictable address before launch to grief or misprice it. The hook rejects it at low, middle and high starting prices.\n- **Dodging the tax:** exact-output buys and sells are rejected by the hook, during the launch window and after.\n- **Freezing trading:** a fee recipient that rejects ETH doesn't stop trades, and the payout still lands. The owner address is a plain wallet (EOA) on mainnet.\n- **Supply:** owner 50M plus pool plus at most 1e12 wei of rounding dust always equals 1 billion. This holds across the full price range and both token orderings.\n- **Locked liquidity:** the position NFT is owned by the burn address, has liquidity, and nobody else is approved to move it.\n- **Tax schedule:** decay starts in the launch block, 99% falling 1 point per minute to 1%.\n\n**Static-analysis leads:** the reentrancy warnings are dealt with by the contract setting a \"launching\" status before it calls the factory, plus the existing callback test. The hash-collision warning is a fixed-length address calculation with nothing an attacker controls. The ignored return value is unused on purpose. None of them is a defect.\n\n**Not covered:**\n- I didn't check IMD's live price, so the roughly $3,000 starting valuation rests on the README's $5.55 figure.\n- I didn't test what happens to trading if the IMD/ETH route the hook uses to convert fees fails or runs dry.\n- Tax-avoiding trades through other, untaxed pools are a general issue for any taxed token, so I left them out.","treeHash":null,"usage":{"cachedInputTokens":1365014,"inputTokens":36,"model":"claude-opus-5-5","outputTokens":27500,"runtime":"claude","turns":20,"wallClockMs":438114}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e36579e0223ff908","findings":[{"citation":"resolved","description":"Second-round settlement of the earlier low finding ce5497a8. The author disputed the location of the guard and I accept the dispute: src/ was deliberately left unchanged because site/abi/ERC20TLaunch.json must equal the built runtime, and I confirmed this round that the artifact's deployedBytecode is byte-identical to a fresh forge build (20002 hex chars, equal). The mitigation is real: checkPriceBand in site/core.mjs (CONFIG.minPriceX18 = 1e10, maxPriceX18 = 1e14 in site/config.mjs) runs before simulation (site/app.mjs line 262) and again before sending (line 309), with a live warning under the price field (line 88); test/web/core.test.mjs 'price band stops a slipped decimal point before the wallet' passes (14/14). README 'Price assumptions', site/docs.html 'Price band' and docs/SECURITY_REVIEW.md state that the application bound is not a valuation check and that a price outside the band is reachable only by calling launch directly. This entry records the residual as an accepted, documented trust assumption on the owner; it is not a request for a code change in this revision.","line":122,"path":"src/ERC20TLaunch.sol","reproduction":"forge test --match-test test_priceLowerBoundOneWeiLaunches passes: owner calls launch(1, block.timestamp, false) and it succeeds (status Launched, LP to 0xdead), so the on-chain bound is unchanged. Web: node --test test/web/core.test.mjs shows checkPriceBand(1n) and checkPriceBand(540540n) throw 'outside the 10 to 100000 IMD band' while checkPriceBand(540540540540n) returns the price. Expected after this revision: on-chain unchanged (documented), website refuses the slip. Actual: matches.","severity":"info","snippet":"        if (priceX18 == 0 || priceX18 > MAX_PRICE_X18) revert InvalidPrice();","title":"Settled, no action required: on-chain priceX18 bound still spans 1..1e18; the shipped website path now refuses prices outside 1e10..1e14 and the gap is documented"},{"citation":"resolved","description":"Second-round settlement of the earlier low finding 0d1c9919 (duplicate of audit_permissions 15a4f371). The author's dispute holds: an application constructed with HOOK, IMD, POSITION_MANAGER, PERMIT2, POOL_MANAGER, IMPLEMENTATION or IMD_ETH_HOOK as owner_ holds no assets and can never launch (launch requires msg.sender == owner), so the only cost is a wasted deployment, and it is reachable only through a mis-resolved $owner in launch.json, which names the fixed designated wallet. site/app.mjs line 132 throws 'The application has a different owner.' when owner() != CONFIG.owner, README 'After launch' (line 137) and docs/SECURITY_REVIEW.md 'Authority and deployment' describe the exact guard, the inert outcome and the operator's owner() check. src/ was left unchanged for the same artifact-binding reason as the price band; the artifact matches the build. Recorded as a documented residual, not a defect requiring revision.","line":77,"path":"src/ERC20TLaunch.sol","reproduction":"new ERC20TLaunch(0xed9A04Fa6693e754661A22502524DF9b1857e544) deploys and owner() == HOOK (expected InvalidOwner under a symmetric guard; actual success, unchanged this round). Any EOA calling launch(540540540540, block.timestamp, false) on it reverts Unauthorized. The website's loadApplication rejects such a deployment before any transaction. No funds or token can be affected.","severity":"info","snippet":"        if (owner_ == address(0) || owner_ == address(this) || owner_ == FACTORY) revert InvalidOwner();","title":"Settled, no action required: constructor accepts pinned infrastructure addresses other than FACTORY as owner; the result is an inert deployment the website refuses, and this is now documented"}],"hash":"17d4d47588a0eb3ef16dfd677c7c9cc40f2340f3d7763dc2be0ab88cac16ace3","nodeId":"8c4a8f86-48dd-4ff5-882a-9c50fbf77f52","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written. No tracked files were changed.\n\n**Outcome: every finding from the previous round is settled. Nothing blocks the launch.**\n\nWhat I verified this round, running the checks the author's worker could not:\n\n- **Medium, undisclosed transfer restriction (fixed).** The author's correction is right. A wallet's own `transfer` in its own transaction succeeds on the captured implementation. My earlier repro saw reverts because the buyer was a contract and the EOA case pranked `msg.sender` without `tx.origin`. The four new tests pass against the fixture, and the policy is now disclosed in the README, site FAQ, review dialog, technical notes and security review.\n- **Low, owner pays almost none of the launch tax (fixed).** Disclosed with the measured figures in the README, site economics card, FAQ, review dialog and docs. Recipients stay as the brief requires.\n- **Low, price bound and low, owner guard (disputed, accepted).** Both still reproduce on-chain, but the author's reasoning holds. The site now refuses prices outside an FDV of 10 to 100,000 IMD before simulating and before sending, the site refuses an application whose owner differs from the designated wallet, and both residuals are documented. I confirmed the site's runtime artifact is byte-identical to a fresh build, so leaving src untouched was the correct call. Recorded as info, no action needed.\n\nCheck results this round:\n\n| Check | Result |\n| --- | --- |\n| forge build | ok |\n| forge test | 85 passed, 0 failed |\n| forge fmt --check | clean |\n| node --test test/web | 14 passed |\n\nOne stale note, not a defect: docs/VALIDATION.md expects 46 Foundry tests, but the suite now has 85 because other contributors added edge and invariant suites.\n\nCoverage: the single entry point `ERC20TLaunch.launch(uint256,uint256,bool)` holds, with four extra rows recording the settled findings and the artifact and check results.","treeHash":null,"usage":{"cachedInputTokens":759556,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":11427,"runtime":"claude","turns":24,"wallClockMs":383345}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"22c9b760d0a15149","findings":[{"citation":"resolved","description":"The constructor intends to refuse infrastructure contracts as the launch owner (test_constructorRejectsInfrastructureAsOwner), but the guard names only FACTORY. The contract pins seven other infrastructure addresses (HOOK, IMD, POSITION_MANAGER, PERMIT2, POOL_MANAGER, IMPLEMENTATION, IMD_ETH_HOOK) and accepts any of them as owner_. Because launch() requires msg.sender == owner and none of those contracts can originate that call, an application deployed with such an owner is permanently unlaunchable, and tokenConfig() would also name that contract as token owner, feeRecipient and feeDecayRecipient. The guard is asymmetric: the same class of value is rejected on one branch and accepted on seven others. Only reachable through a misresolved $owner in the manifest, so impact is wasted deployment plus a dead application rather than loss of funds. Minimal fix that preserves the design: extend the check to all pinned constants (and optionally require owner_.code.length == 0 or document that a contract owner must be able to call launch).","line":77,"path":"src/ERC20TLaunch.sol","reproduction":"forge test on test/scratch/OwnerGuard.t.sol: `new ERC20TLaunch(0x801411c6aCeC4Fa80c75c5d3C0eAe13C84f8a173)` reverts InvalidOwner (expected), but `new ERC20TLaunch(0xed9A04Fa6693e754661A22502524DF9b1857e544)` (HOOK) succeeds; the same holds for IMD 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7, POSITION_MANAGER, PERMIT2, POOL_MANAGER, IMPLEMENTATION and IMD_ETH_HOOK. Expected: InvalidOwner for every pinned infrastructure address. Actual: deployment succeeds, owner() == HOOK, and launch() can never be called by that owner.","severity":"low","snippet":"        if (owner_ == address(0) || owner_ == address(this) || owner_ == FACTORY) revert InvalidOwner();","title":"Constructor owner guard rejects only the factory; every other pinned infrastructure address is accepted as owner and bricks the launch"},{"citation":"resolved","description":"Verified against the captured mainnet token implementation (Solady Ownable slot 0xffff...74873927 holds the designated owner after launch). transferOwnership(address) on the token is single-step and takes effect immediately; there is no pending-owner acceptance. The README discloses that ownership can change under the token's own access controls but not that the handover is one-step. This is not a defect in ERC20TLaunch and the requested design keeps the owner role; it is recorded as the privileged-power risk the audit guide asks to document separately: actor = token owner (0x3d6a89C8751a45DD577a4C1F3b34E71C58236193), precondition = one mistaken transferOwnership call, consequence = permanent loss of tax/recipient control. All other token entry points (initialize, launch, accountTransferDelta, setTaxBps, setFeeRecipient, setFeeDecayRecipient, completeOwnershipHandover) reject outsiders after launch, and initialize() on the implementation itself reverts.","line":107,"path":"README.md","reproduction":"After a launch on the captured mainnet state (test/scratch/FeePush.t.sol test_ownerRoutes): vm.prank(OWNER); token.transferOwnership(address(1)) succeeds and token.owner() == address(1) immediately. Expected per two-step pattern: pending until accepted. Actual: effective at once. Outsider calls in test/scratch/ReInit.t.sol all revert (Unauthorized 0x82b42900 / AlreadyInitialized 0x0dc149f0).","severity":"info","snippet":"There are no missing requester-owned services, oracle IDs or contract settings, and no app setters to initialize after deployment. Price, deadline and first-only acceptance are explicit owner inputs at launch. The **existing token** retains administrative powers: resting-tax edits are blocked during decay, then restricted to the implementation’s **30–500 bps** range; fee recipients, distributor permissions and ownership can change under its own access controls. Both initial fee recipients belong to the owner, while the hook’s protocol recipient belongs to the existing protocol. The creator’s 5% allocation is immediately available and not vested. Single-sided liquidity locking does not guarantee a price or prevent selling the creator allocation.","title":"Trust assumption: the created token's ownership transfer is single-step with no acceptance; owner powers are irrecoverable on a wrong address"}],"hash":"240030220f33c98177fdd9b96397c241e360fe7d34b7ad0ba8953b1a59d351ff","nodeId":"71e04d43-b217-439b-8d4d-476409cf30f4","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds the result.\n\n**Outcome.** The permission model of `ERC20TLaunch` holds. The single entry point `launch` is owner-only, chain-pinned, sets its status guard before the one external write call, and re-verifies every token, allocation, pool and lock postcondition after the factory returns. I found one low defect and recorded one trust assumption.\n\n**Findings written**\n- **Low, constructor guard asymmetry.** The constructor at `src/ERC20TLaunch.sol:77` rejects only the factory as owner. The hook, IMD, PositionManager, Permit2, PoolManager, implementation and conversion hook are all accepted, which would produce an application whose `launch` can never be called. Reproduced with a scratch test: deploying with the hook address succeeds while the factory address reverts.\n- **Info, trust assumption.** The created token's ownership transfer is single-step and immediate, which the README does not say. Verified on the captured mainnet bytecode.\n\n**What I verified as holding, with evidence**\n- A storage-write scan across all nine dependencies after a real launch shows no role, allowance, ETH or token balance left with the launch contract. The token's owner and fee slots hold the designated wallet, and the Permit2 allowance is consumed and expired.\n- Every privileged token entry point rejects an outsider after launch, including re-initialization of the clone and of the implementation.\n- Swaps still succeed when the fee recipient or the hook's protocol recipient is a reverting contract, so there is no push-payment denial of service.\n- The website's launch path checks runtime bytecode with the owner immutable, compares the on-chain owner to the configured owner before simulating and before sending, and forces chain id 1.\n- All six static-analysis leads were traced and none is a defect.\n\n**Not reached.** Hook internals beyond black-box swap tests, the web history-scanning code, and the tick range of the locked position, which the contract does not check.\n\nScratch tests were removed. The tree contains only the findings file as new content.","treeHash":null,"usage":{"cachedInputTokens":1372905,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":31489,"runtime":"claude","turns":36,"wallClockMs":508016}},{"artifacts":[],"attempt":1,"bundleHash":"a65a51ae7f65973ac34aa029afe08a674521c60ed97cdb2348ae47e06605c619","device":"76f57db4177175be","findings":[],"hash":"4a7e3d39e3de7b8c22589f94fff565629560de521007b6a217350e9cd4353e9b","nodeId":"a67fadd1-195f-422f-9f0a-c7d1c799f903","outcome":"completed","summary":"The revision is complete. The shell sandbox on this worker refused to start any process for the entire run, so I could not execute `forge build`, `forge test` or the JavaScript tests here; I state that plainly in the validation record and in each response.\n\n**What I found**\n\n- **Transfer restriction (medium): confirmed and fixed by disclosure plus tests.** The implementation the factory clones has verified source on Blockscout and Sourcify. Its transfer hook reverts with `InvalidTransfer()` unless the transfer is a mint or burn, settles a swap through the PoolManager, involves the owner, involves an approved distributor contract, or is a direct wallet call where the sender is also the transaction origin and neither side has code. One correction to the report: a wallet sending to another wallet in its own transaction does work. The proof saw a revert because the buyer was a contract and the pranked wallet had a different transaction origin. New tokens also trust the hook owner's shared distributor registry by default, which was undisclosed.\n- **Price band (low): disputed in placement, mitigated.** The website now refuses any price outside an FDV of 10 to 100,000 IMD before simulating and again before sending, with a live warning under the price field. The contract was left unchanged because the site verifies deployments against the reviewed runtime artifact, which only a build can regenerate.\n- **Owner pays almost no launch tax (low): fixed by disclosure** in the README, the site FAQ, the economics card, the review dialog, the technical notes and the security review. Recipients follow the brief and were not changed.\n- **Constructor owner guard (low): disputed.** A mis-resolved owner yields an inert application that nothing can launch or lose. The site already refuses an application whose owner differs from the designated wallet. The guard and the operator check are now documented.\n\n**Files changed**\n\n- `test/ERC20TLaunch.t.sol` and new `test/helpers/HolderProbe.sol`: four tests running the captured implementation for direct wallet transfers, `transferFrom`, contract holders, relayed calls, distributor approval and revocation, and the shared-registry switch, plus a selector-binding test.\n- `README.md`, `docs/SECURITY_REVIEW.md`, `docs/VALIDATION.md`, `site/index.html`, `site/docs.html`: transfer policy, owner tax, price band, owner guard and after-launch steps.\n- `site/config.mjs`, `site/core.mjs`, `site/app.mjs`, `test/web/core.test.mjs`: the price band and its test.\n- `.imd-responses.json`: one answer per finding.\n\n**What remains unverified.** No `src/` file changed, so the accepted runtime, artifact and protected checks are unaffected. The new tests are written against the verified source and the file's existing passing patterns, but they were not compiled or run on this machine. Expected on the verifier: 46 Foundry tests and 14 JavaScript tests passing.","treeHash":"af72a5ee125a089180eefd20aee296cb9bb8915c","usage":{"cachedInputTokens":3342594,"inputTokens":834,"model":"claude-fable-5-1","outputTokens":61750,"runtime":"claude","turns":108,"wallClockMs":805536}},{"artifacts":[],"attempt":1,"bundleHash":"24530674bdffadd966c2a736244c5476bebf9be89250685f0da6844e475f08c5","device":"cc309a7afc70b0b1","findings":[],"hash":"733e99ee97ca965cff5cceede8c4f96185a5c504a6fd3da468ac579f4207699e","nodeId":"e4aa719a-09ec-4d9f-aa3e-f7429a964bd9","outcome":"completed","summary":"Created [launch.json](/home/imd/.identitymd/work/1336f7b0-b673-420e-9479-a25a6a184cab/e4aa719a-09ec-4d9f-aa3e-f7429a964bd9/launch.json) for `ERC20TLaunch` with `$owner`.\n\nManifest structure and compiled constructor ABI match. `forge build` succeeded; all 42 tests passed with the required fuzz seed. Only `launch.json` is included in the change.","treeHash":"b2a6c465a9ee053fe0d9ae897d8cdcdd9c4cdf75","usage":{"cachedInputTokens":409344,"inputTokens":30958,"model":"gpt-6-astra","outputTokens":4353,"runtime":"codex","turns":4,"wallClockMs":139171}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"a315ee4cb81c640c","findings":[],"hash":"7ea96cfc8122ed820d0b584cdc72f21cce9bf563059266b853632129fa805e89","nodeId":"fb38009e-7cd9-4438-a2d8-cd762761c0cb","outcome":"completed","summary":"Review complete. The findings file is written at the repository root with an empty findings list and ten coverage rows, and the scratch tests are removed so the tree is unchanged.\n\n**Outcome: no substantiated defect in the assigned area.** The single entry point, `ERC20TLaunch.launch`, holds under the Execution Trace, Periphery and First Principles checks. Everything I claim was run against the captured mainnet runtimes of the factory, token implementation, hook, PoolManager and PositionManager, with all 42 Foundry tests and 13 JavaScript tests passing.\n\nWhat I traced and confirmed:\n- **Guards and ordering.** Owner, chain 1, Ready status, price bound, deadline bound and dependency codehash plus configuration checks all run before the status flips to Launching. The factory call is the only state-changing external call. A reentrant call from an owner callback fails the Ready check, so the slither and aderyn reentrancy lines are not exploitable.\n- **Postconditions before writes.** Token config, the exact 50M owner balance, 950M in the PoolManager plus bounded dust, exactly one new position NFT owned by the dead address with nonzero liquidity, and a pool key equal to the sorted token/IMD pair with fee 0, spacing 60 and the expected hook. Any failure reverts the factory creation too.\n- **Boundaries.** I launched at 1 wei, the 1e18 maximum and the suggested price with the token as currency0 and as currency1. All succeed, the opening tick matches the request, and the position range runs from the opening tick to the maximum tick rounded to spacing, so liquidity is single-sided.\n- **Residuals and custody.** The real factory resets the token's Permit2 allowance to zero after the mint. The application holds no ETH or tokens, has no receive or fallback, and records no privilege for itself. The factory only puts the application address in event topics.\n- **Site periphery.** Price parsing, valuation, tax schedule, receipt parsing, ordinal derivation, full-range history scan with reorg check, and the two-step simulate-then-send flow with an explicit chain id all behave as documented.\n\nWhat I could not reach: the internals of the source-unverified external infrastructure beyond what the captured bytecode shows through ABI probes, emitted logs and the existing swap and fee tests. One non-finding is recorded as a note for the judge: a launch with the first-only flag off would still revert if the nonce-2 slot were empty while the factory nonce had advanced, but that state is unreachable on mainnet because that slot already holds code.","treeHash":null,"usage":{"cachedInputTokens":838212,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":24831,"runtime":"claude","turns":34,"wallClockMs":430294}},{"artifacts":[],"attempt":1,"bundleHash":"d6650a553e35b336e2b89af513567dd6f4086bc0e98e120ff9701f370927f13b","device":"fbdcf3c80b280e3b","findings":[],"hash":"834218b6af8531fc33d1aa91f60d9053e0f2035d7af5e3b6bd4dcef0c77f1845","nodeId":"0628c374-06cc-4d9d-8868-7eb61afadf58","outcome":"completed","summary":"I've made a small revision to my own test files; nothing else changed. `forge build` succeeds and `forge test`, run with the verifier's fuzz seed, passes all 85 tests with none skipped.\n\n**Why I revised:** this round came with no findings to address. But since my last round, the implementer documented in `docs/SECURITY_REVIEW.md` how the launched token's transfer rule works. A wallet can send its own tokens to another wallet when it makes the call itself (`msg.sender == from == tx.origin`). A relayed call, a transfer to a contract, or a contract holder sending to anyone but the owner, pool or an approved distributor reverts with `InvalidTransfer`. My invariant tests only ever moved tokens out of contract holders, so they never tested the allowed path. Two of my comments also still pointed to an earlier findings report and described the rule as broader than it is.\n\n**What changed:**\n- **`test/helpers/LaunchInvariantHandler.sol`:** the random-sequence tests now include ordinary wallets as well as contracts.\n  - The owner can hand part of the 5% creator allocation to a wallet.\n  - Wallets then transfer in three ways: directly to another wallet (must succeed), relayed through another caller (must revert), and to a contract (must revert).\n  - Counters record any transfer whose result breaks that rule, including a contract holder successfully sending to someone other than the owner.\n  - I removed the outdated reference to the findings report.\n- **`test/ERC20TLaunchInvariant.t.sol`:** two new checks that run after every random sequence.\n  - **Wallet balances are conserved:** what wallets hold always equals what the owner gave them, so wallet-to-wallet transfers are never taxed and never lose or create tokens.\n  - **The transfer rule matches the documentation**, both during the 99% launch tax and after it has decayed.\n  - The existing check on the owner's balance now subtracts what the owner gave away.\n  - Wallets are counted when checking that the total supply is all accounted for.\n  - The scripted test that proves every random action actually runs now also does each kind of wallet transfer, before and after the decay.\n- **`test/ERC20TLaunchEdges.t.sol`:** I corrected one test's comment so it describes the documented rule (the buyer in that test is a contract) instead of calling it an undisclosed defect. The test's assertions are unchanged.\n\nIn the verifier-seeded run, the 11 checks held over 48 random sequences of 32 calls each, all 9 action types ran, and none reverted unexpectedly.\n\n**No findings to report.** The transfer restriction I reported earlier is now documented as part of the factory's existing token design, and the tests confirm it behaves as documented. Because the owner receives both fee streams, as the brief requires, the owner's own trades during the launch decay are taxed far less than everyone else's. The implementer has already disclosed this. So I have not written a `.imd-findings.json`.","treeHash":"e5a5208a8f47a1346c0b0b5cdab54ec77ec0691a","usage":{"cachedInputTokens":481599,"inputTokens":20,"model":"claude-opus-5-5","outputTokens":9619,"runtime":"claude","turns":11,"wallClockMs":241032}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"dedd4428da8fa41e","findings":[{"citation":"resolved","description":"The token this adapter launches, through the implementation it pins, reverts with custom error 0x2f352531 when a non-owner holder transfers to an ordinary address (buyer->EOA, transferFrom, EOA->EOA), both during and after the tax decay. Only pool swaps and transfers to or from the owner go through. Nothing in the adapter, the README or the site states that bought tokens cannot be moved between wallets. Merged from write_foundry_tests (medium) and the related undisclosed owner-power note (info).","line":132,"path":"src/ERC20TLaunch.sol","reproduction":"I ran .imd/reads/proofs/Proof_7bce4ee3d676.t.sol against the fixture (test/fixtures/MainnetState.sol). owner calls launch(540540540540, block.timestamp, false). A swap harness buys with 2 IMD. Warp +98 min, then the buyer calls token.transfer(0xCAFE, bought/2). Expected: the call returns true. Actual: it reverts with 0x2f352531 (test FAIL '/5%1').","severity":"medium","snippet":"        created = IERC20TFactory(FACTORY).createAndLaunchAtPrice(tokenConfig(), CREATOR_BPS, priceX18);","title":"Launched token (fixed implementation 0x2df7..0eEe) rejects ordinary holder-to-holder transfers; launch config and docs do not address it"},{"citation":"resolved","description":"The brief asks for an opening FDV of a few thousand USD (SUGGESTED_PRICE_X18 = 540_540_540_540). The only check is 0 < price <= 1e18, so a unit slip (for example 540540 or 1) passes. The status becomes Launched and the LP is burned to 0xdead, so a mis-priced launch cannot be retried. Only the owner can trigger this.","line":122,"path":"src/ERC20TLaunch.sol","reproduction":"owner calls launch(1, block.timestamp, false). Line 122 passes because 1 is neither 0 nor above 1e18, and _checkToken/_checkPosition check no price. Expected: InvalidPrice for an FDV of 1e-9 IMD. Actual: the launch succeeds (audit_math reports pool tick -414480, and a 1e10-wei IMD buy after decay receives ~858.9M tokens).","severity":"low","snippet":"        if (priceX18 == 0 || priceX18 > MAX_PRICE_X18) revert InvalidPrice();","title":"priceX18 bound accepts 18 orders of magnitude; an irreversible one-shot launch at priceX18=1 sells ~90% of supply for dust"},{"citation":"resolved","description":"The brief requests these recipients, so the code matches the brief. The defect is that buyers are not told the owner pays almost none of the anti-snipe tax. Fix: disclose this in the README and site, or route feeDecayRecipient to the protocol if the requester approves (the brief allows that).","line":107,"path":"src/ERC20TLaunch.sol","reproduction":"From audit_economics, at fixture block 26208519: launch(540540540540,...), then the owner buys with 10 IMD at tax 9900. The owner receives ~181,214 tokens plus 0.0225 ETH of tax, which swaps back to 9.69 IMD, for a net cost of 0.31 IMD. An outsider making the same buy pays 10 IMD with no rebate. Traced in code: lines 104 and 107 name owner, and _checkToken lines 190-191 require exactly this.","severity":"low","snippet":"            feeDecayRecipient: owner","title":"Launch tax does not deter the owner: feeRecipient and feeDecayRecipient are the owner, so the owner trades through the 99% window at ~3% cost, and this is undisclosed"},{"citation":"resolved","description":"With owner_ = HOOK (or IMD, POSITION_MANAGER, PERMIT2, POOL_MANAGER, IMPLEMENTATION, IMD_ETH_HOOK), deployment succeeds. launch() requires msg.sender == owner, which those contracts can never send, so the launcher is dead. Reachable only through a mis-resolved $owner.","line":77,"path":"src/ERC20TLaunch.sol","reproduction":"new ERC20TLaunch(0xed9A04Fa6693e754661A22502524DF9b1857e544): expected InvalidOwner, actual success with owner()==HOOK. launch(...) from any EOA then reverts Unauthorized.","severity":"low","snippet":"        if (owner_ == address(0) || owner_ == address(this) || owner_ == FACTORY) revert InvalidOwner();","title":"Constructor owner guard rejects only FACTORY; the other pinned infrastructure contracts are accepted as owner, leaving a launcher that can never launch"}],"hash":"c2e64b201a1a071fb1a62dbacd9034362b1aabf31109d06e93c7e2e15dbcc9d9","nodeId":"8c4a8f86-48dd-4ff5-882a-9c50fbf77f52","outcome":"completed","summary":"I've written four findings to `.imd-findings.json`: one medium and three low. No critical or high findings survived, and no project files were changed.\n\n1. **Medium – bought tokens can't be sent to another wallet** (`src/ERC20TLaunch.sol:132`). I ran the tester's proof against the offline mainnet fixture and it failed as described. A buyer's transfer to another wallet reverts with error `0x2f352531`, and the README and site never mention this. I merged the related note about undisclosed owner powers into this finding. The behaviour comes from the existing ERC20T token code that the launch contract uses, not from the launch contract itself.\n2. **Low – the price check is far too loose** (`:122`). Any price from 1 up to 1e18 is accepted, and the launch can only happen once. A unit slip such as `launch(1, …)` passes the check and opens the pool at a near-zero price. Nothing afterwards checks the price, and the locked liquidity can't be recovered.\n3. **Low – the owner effectively doesn't pay the 99% launch tax, and buyers aren't told** (`:104/107`). The brief asked for both fee recipients to be the owner, so the code matches the request. The problem is disclosure: the economics specialist measured the owner's net cost on a 10 IMD buy at about 0.31 IMD, against the full 10 IMD for anyone else. I only traced that this follows from the recipient settings; I didn't rerun the trade myself.\n4. **Low – the owner check only rejects the factory** (`:77`). Setting the owner to the hook or another pinned contract deploys fine, but no one can ever call `launch()` after that. This can only happen if `$owner` resolves to the wrong address.\n\n- **The one entry point** (`launch(uint256,uint256,bool)`): marked `finding`, citing finding 2. It is owner-only and can't be re-entered, because `status` is set before the factory call. The checks after the launch are thorough.\n- **Dropped:**\n  - The test-fixture size limit is a gap in the test setup, not a code defect.\n  - The token's one-step ownership transfer is a property of the existing token code, not this contract.\n  - The scanners' reentrancy and `abi.encodePacked` hash-collision warnings don't hold up. Re-entry is blocked by `status`, and the hash input has a fixed length.\n\nNone of the findings carries a proof file, since one is only required for critical or high.","treeHash":null,"usage":{"cachedInputTokens":234817,"inputTokens":10,"model":"claude-opus-5-5","outputTokens":3509,"runtime":"claude","turns":6,"wallClockMs":101786}},{"artifacts":[],"attempt":1,"bundleHash":"11d58af5c13fa428fc31acaeaf0afc4eaa911a428da8a623af710580dab5bbcd","device":"2a4ad9be53991100","findings":[],"hash":"c6866d67bf1a744111bda916c34fdc8b4343d83c1d524ed7512c09e2da361ac8","nodeId":"e4aa719a-09ec-4d9f-aa3e-f7429a964bd9","outcome":"completed","summary":"I left `launch.json` as it was. No review findings came with this round, and the existing manifest already matches the accepted source, so I didn't change any files.\n\n**What the manifest says:**\n- **Shape:** it has exactly `kind: \"evm_contracts\"`, `contracts` and `notes`, with nothing extra.\n- **Contract:** it names one contract, `ERC20TLaunch`, with `constructorArgs: [\"$owner\"]`. That matches the source: the only constructor parameter is `constructor(address owner_)`, and the owner is the paying wallet.\n- **Fixed values:** the factory, hook, IMD, PositionManager and Permit2 addresses are built into the contract, along with the supply, 5% creator share and tax schedule. None of them are constructor arguments, so they don't belong in the manifest.\n- **Notes:** about 1,000 characters, under the 4,000 limit.\n\n**One point to be aware of:** the brief asks to confirm this is the first token on the factory, and it isn't. The accepted evidence shows the factory's first token slot was already taken, so the manifest makes no first-token claim. Deploying this manifest also doesn't launch the token. The owner does that later with a separate transaction, so there is no token address or transaction hash yet.\n\n**Checks:**\n- `forge build` succeeds.\n- `forge test` with the verifier's fuzz seed: all 46 tests pass.\n- A scratch test in `test/scratch/` deployed `ERC20TLaunch` with the owner address 0x3d6a89…36193 on chain id 1, the way the protected check does. The deployment worked, the owner was set correctly, the runtime code is under the 24,576-byte limit, and it contains none of the forbidden opcodes (DELEGATECALL, CALLCODE, SELFDESTRUCT).\n- A Python script confirmed the manifest's keys, types and argument count.","treeHash":"bea000227e7c7a492404feda42187a7f5a17ac6d","usage":{"cachedInputTokens":402620,"inputTokens":26,"model":"claude-opus-5-5","outputTokens":3989,"runtime":"claude","turns":13,"wallClockMs":88696}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"8e25456c4ae69acf","findings":[{"citation":"resolved","description":"Boundary x precision. The brief requires 'a reasonable starting price that creates a healthy initial market cap (equivalent to a few thousand USD in IMD)'. The contract's own suggested price is SUGGESTED_PRICE_X18 = 540_540_540_540 (FDV 540.54 IMD, about $3,000). The only on-chain validation is 0 < priceX18 <= MAX_PRICE_X18 = 1e18, i.e. FDV from 1e-9 IMD to 1e9 IMD (about $5.5e-9 to $5.5e9). That is 18 orders of magnitude, and the approved target is never enforced. The launch is one-shot (status becomes Launched) and the 950M-token single-sided position is burned to 0xdead, so a mis-scaled price cannot be corrected or retried. A plausible unit slip passes validation: priceX18 is IMD-per-token scaled by 1e18, and passing 540540 (forgetting the 1e6 factor), or 1, is accepted silently. The pool then opens at a near-zero price, and the hook's tax goes only to the owner during the first 98 minutes. The input is owner-only, so this is a missing guard on a trusted actor's irreversible parameter, not a permission bypass. Minimal fix that keeps the design: bound priceX18 to a band around SUGGESTED_PRICE_X18 (e.g. 1/10x to 10x, or MIN/MAX FDV constants derived from the brief), keeping the owner's explicit choice inside that band. The site's priceFromInput (site/core.mjs:18) mirrors the same 0 < p <= 1e18 bound and should use the same band.","line":122,"path":"src/ERC20TLaunch.sol","reproduction":"Mainnet fork at block 26208629 (forge test --fork-url https://ethereum-rpc.publicnode.com): deploy ERC20TLaunch(0x3d6a89C8751a45DD577a4C1F3b34E71C58236193); prank owner; launch(1, block.timestamp, false). Expected: InvalidPrice, since FDV = 1 * 1e9 / 1e18 = 1e-9 IMD, nowhere near 'a few thousand USD'. Actual: it succeeds. The pool initializes at tick -414480 (opening price 1.0006e-18 IMD per token), status = Launched, and the LP NFT is owned by 0xdead. Then warp +98 minutes (tax reaches its 100 bps resting rate) and do an exact-input buy of 1e10 wei IMD (0.00000001 IMD) through PoolManager.unlock/swap: the buyer receives 858,859,094,992,976,787,467,986,777 token-wei = 858.86M ERC20T, 90.4% of total supply and 90.4% of the locked LP inventory. Same check offline on the captured fixture (test/fixtures/MainnetState.sol): launch(1, ...) succeeds in both currency sort orders with dust 3.1e8 wei, so every postcondition in _checkToken/_checkPosition passes and nothing catches the mis-pricing.","severity":"low","snippet":"        if (priceX18 == 0 || priceX18 > MAX_PRICE_X18) revert InvalidPrice();","title":"Price bounds span 18 orders of magnitude and do not encode the brief's 'few thousand USD' opening market cap; a 1-wei price irreversibly sells ~90% of supply for 1e-8 IMD"},{"citation":"resolved","description":"Test-coverage gap on the numerical boundary of the hook's tax/fee-conversion path. The fixture loads only the storage slots in the access list of the captured simulations. Larger swaps reach IMD/ETH pool ticks and other state that was not captured, which read as zero. Inside the IMD/ETH conversion hook 0xc6C965Bd164c483e87d0B550671798e9A3602840 afterSwap this yields SafeCastOverflow(). Live mainnet does not revert. The suite's only trade tests use 1 IMD (test_actualBuyAndSellAgainstMainnetPoolAndHook), so the tax math at launch-sized buys, the protocol-share split and fee conversion are not exercised offline at the scale the owner will see. A future reviewer could also misread this artifact as an on-chain defect. This is not a defect in src/. Recorded so that conclusions about large trades come from a fork, not from the fixture.","line":5,"path":"test/fixtures/MainnetState.sol","reproduction":"Offline (fixture): loadMainnetState(); launch(540540540540, block.timestamp, false); exact-input buy of 10,000e18 IMD via PoolManager.unlock -> swap(zeroForOne = IMD is currency0? false here, amountSpecified = -10000e18). Actual: reverts with WrappedError(hook 0xed9a..e544, afterSwap selector 0xb47b2fb1, inner WrappedError(0xc6C965..2840, 0xb47b2fb1, SafeCastOverflow() 0x93dafdf1)). A 100e18 IMD buy in the same setup succeeds (1,546,621 ERC20T net at 99% tax). Mainnet fork at block 26208629, same launch: exact-input buys of 1e15 through 1e24 wei IMD (0.001 to 1,000,000 IMD) all succeed at launch tax, at +30 minutes and at resting tax. Expected from the fixture: the same result as the fork, or an explicit documented size limit for which offline trade results are valid.","severity":"info","snippet":"// Mainnet runtime bytecode and access-list state, NOT replacement implementations.","title":"Offline fixture cannot execute realistic trade sizes: a 10,000 IMD buy reverts SafeCastOverflow in the fixture but succeeds on mainnet, so the trade/tax tests only cover <=100 IMD"}],"hash":"d22046654595b7505e1604e3b3ba12a19ada2c360daa1eedb0c24f45e427c20c","nodeId":"d50385f6-f47b-42b1-8f6c-41c8645e93f8","outcome":"completed","summary":"I found one low-severity defect in the launch math and one informational test gap; the rest of the math holds. Both are written to `.imd-findings.json`, along with a coverage row for the only entry point, `ERC20TLaunch.launch(uint256,uint256,bool)`. The working tree is unchanged: the 42 existing tests still pass and I deleted my scratch tests.\n\n**Findings**\n1. **Low — the price check doesn't enforce the \"few thousand USD\" market cap** (`src/ERC20TLaunch.sol:122`). The only check is `0 < priceX18 <= 1e18`, which allows a starting value anywhere from 1e-9 IMD to 1e9 IMD. On a mainnet fork at block 26,208,629, `launch(1, now, false)` succeeds and passes every after-launch check. After the 98-minute tax decay, a buyer spending 0.00000001 IMD gets 858.86M ERC20T, about 90% of supply. The launch can only happen once and the pool position is burned, so a wrong price can't be undone. Only the owner can call `launch`, so this is a missing safety check on an owner input, not a permission bypass. Suggested fix: limit the price to a band around the suggested `540_540_540_540`, and apply the same band in the website (`site/core.mjs:18`).\n2. **Info — the offline test data can't simulate large trades** (`test/fixtures/MainnetState.sol`). With the captured mainnet data, a 10,000 IMD buy fails with `SafeCastOverflow` in the IMD/ETH fee-conversion hook. On a live fork, buys from 0.001 up to 1,000,000 IMD all succeed. So the failure comes from incomplete test data, not the chain. Offline tests only cover trades of about 100 IMD or less.\n\n**What holds** (checked by running it):\n- **Price range:** launch works across the whole accepted range (from 1 up to 1e18, both token orderings). The supply always adds up exactly, and leftover rounding dust peaks around 5e8 wei, far below the 1e12 cap.\n- **Opening price:** it always rounds to a 60-tick step in the creator's favour, and is exact at 1e18.\n- **Tax:** it follows 99% minus 1% per 60 seconds, bottoming out at 1%. Even a 1-wei buy pays the right rate (18,474 token-wei received at 99%, 1,828,901 at 1%).\n- **Deadline:** the 0 to 1,800-second window is enforced and can't underflow.\n- **First-token check:** the first-token address calculation is correct.\n- **Pool hijack:** an outsider trying to set up the pool for the next token address first is blocked by the hook.\n- **Website math:** price parsing, the market cap (FDV) figure and the tax schedule display are correct.\n\n**Not reached:** I didn't do a full economic or access-control review of the external factory, token and hook. I only probed them at the boundaries above.\n\n**Not findings:**\n- The hook rejects exact-output swaps. That's a design choice, not a math defect.\n- Large sells stop at the price floor because single-sided liquidity can only absorb what buyers have put in. That's normal behaviour.\n- The scanner leads on reentrancy, the ignored return value and `abi.encodePacked` didn't hold up in the math: the `encodePacked` input is fixed, and there's a launch-state guard.\n\nNone of the findings is critical or high, so neither includes a Foundry proof file.","treeHash":null,"usage":{"cachedInputTokens":1580204,"inputTokens":42,"model":"claude-opus-5-5","outputTokens":27508,"runtime":"claude","turns":24,"wallClockMs":514625}},{"artifacts":[],"attempt":1,"bundleHash":"a05a4766cb5906d9b88c65fa04fc799a14bb6f3890590fe9152417dfa3b36fa7","device":"99e4819277ea59fc","findings":[{"description":"The token created through the captured factory/implementation (0x2df7DCf4D19a7924e00AE96629CC1d1261670eEe) reverts with custom error 0x2f352531 whenever a holder other than the owner transfers to another ordinary address: buyer -> EOA, EOA -> EOA, transferFrom by an approved spender, and a transfer to itself all revert, before and after the 98-minute tax decay. Only pool swaps and transfers to or from the token owner succeed (owner -> EOA ok, buyer -> owner ok). The integration (README.md, docs/SECURITY_REVIEW.md, site) presents erc20t as an ordinary ERC-20 with a tax and lists owner powers, but never states that bought tokens cannot be sent to another wallet. Whether this is an intended anti-OTC design of Adam’s ERC20T or a misconfiguration (the token launches with pairingEnabled=false and useGlobalDistributors=true, and no address is a distributor) cannot be decided from the unverified bytecode; either way the behaviour must be disclosed and tested as intended, or the launch configuration changed, before the token is presented to the public. The adapter cannot work around this: it is a property of the external implementation chosen at launch.","line":132,"path":"src/ERC20TLaunch.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {ERC20TLaunch} from \"src/ERC20TLaunch.sol\";\nimport {IERC20T} from \"src/interfaces/IERC20T.sol\";\nimport {MainnetState} from \"test/fixtures/MainnetState.sol\";\nimport {SwapHarness, ITestToken} from \"test/helpers/SwapHarness.sol\";\n\n/// @notice Fails on the captured token implementation: a buyer cannot transfer bought ERC20T to\n///         another ordinary address (custom error 0x2f352531). Passes once holder-to-holder\n///         transfers are allowed, or once the integration documents and tests the restriction as intended.\ncontract TransferRestrictionProof is MainnetState {\n    address internal constant OWNER = 0x3d6a89C8751a45DD577a4C1F3b34E71C58236193;\n\n    function test_buyerCanTransferBoughtTokensToAnotherWallet() public {\n        loadMainnetState();\n        ERC20TLaunch app = new ERC20TLaunch(OWNER);\n        vm.prank(OWNER);\n        address token = app.launch(540_540_540_540, block.timestamp, false);\n        SwapHarness buyer = new SwapHarness(app.POOL_MANAGER());\n        deal(app.IMD(), address(buyer), 2 ether);\n        uint256 bought = buyer.trade(IERC20T(token).poolKey(), app.IMD() < token, 2 ether, 1);\n        assertGt(bought, 0);\n        vm.warp(block.timestamp + 98 minutes); // past the launch tax decay\n        vm.prank(address(buyer));\n        assertTrue(ITestToken(token).transfer(address(0xCAFE), bought / 2));\n        assertEq(ITestToken(token).balanceOf(address(0xCAFE)), bought / 2);\n    }\n}","reproduction":"forge test --match-path test/scratch/TransferRestrictionProof.t.sol. Load test/fixtures/MainnetState.sol, deploy ERC20TLaunch(owner), owner calls launch(540540540540, block.timestamp, false); a SwapHarness buys with 2 IMD and receives >0 ERC20T; warp +98 minutes; prank the buyer and call token.transfer(0xCAFE, bought/2). Expected: returns true and 0xCAFE holds bought/2. Actual: revert with custom error 0x2f352531 (also for 1 wei, at launch, via transferFrom, and EOA->EOA). test/ERC20TLaunchEdges.t.sol::test_observedHolderToHolderTransfersAreRejectedByTheTokenImplementation pins the observed behaviour so a change is noticed; it does not assert it is desired.","severity":"medium","title":"Launched ERC20T rejects holder-to-holder transfers; undisclosed by the README and site"},{"description":"The captured token implementation exposes owner-only setters not listed in the README’s disclosure of retained powers: setPairingEnabled(bool), setExternalLiquidityEnabled(bool), setDistributors(address[],bool), setUseGlobalDistributors(bool), and Solady-style renounceOwnership / ownership handover. In the offline fixture the owner successfully toggled pairingEnabled and renounced ownership (owner() became address(0)), after which the resting tax and fee recipients can never be changed again. These are powers of the existing infrastructure, not of the adapter; the website should present them alongside the 30-500 bps tax range it already discloses.","line":1,"path":"README.md","reproduction":"After launch in the fixture: vm.prank(owner); token.call(abi.encodeWithSignature(\"setPairingEnabled(bool)\", false)) succeeds; token.call(abi.encodeWithSignature(\"renounceOwnership()\")) succeeds and IERC20T(token).owner() == address(0). Selectors were recovered from the runtime dispatch table (0x27c3251e, 0x1759a64c, 0xb12d85ca, 0xc82d2bbf, 0x715018a6) and resolved against the public signature database.","severity":"info","title":"Token owner powers beyond those disclosed: setPairingEnabled, setExternalLiquidityEnabled, setDistributors, renounceOwnership"}],"hash":"d3f6cf125d05358b5513fa8f0c0341c9cc8cd33e2a6489ef19d6e56cf5adc2d4","nodeId":"0628c374-06cc-4d9d-8868-7eb61afadf58","outcome":"completed","summary":"The findings file is in place at the repository root (the harness excludes it from git on purpose), and the full delivered suite passes with the verifier's seed. Work is complete.\n\n## Summary\n\n**Delivered.** Three new files under `test/`, all passing with `forge build` and `forge test` under the verifier's fuzz seed:\n\n| Suite | Tests | Result |\n| --- | --- | --- |\n| Existing suites (unchanged) | 42 | pass |\n| `test/ERC20TLaunchEdges.t.sol` | 37 | pass |\n| `test/ERC20TLaunchInvariant.t.sol` + handler | 2 (9 invariants, 48 runs × 32 depth) | pass |\n\n**Invariant suite.** `test/helpers/LaunchInvariantHandler.sol` drives the adapter and the real captured factory, hook and Uniswap runtimes with random launches from owner and non-owner callers, bounded buys, sells, transfers, burns, time warps and owner tax edits across three actors. Invariants check that launch happens at most once and only for the owner with valid inputs, status never rests in Launching, the adapter never holds ETH, IMD or tokens, total supply equals one billion minus voluntary burns, every token is held by a tracked address, the owner's 5% stays exact, IMD is conserved, the position stays owned by the burn address with unchanged liquidity, and the tax follows the decay schedule then the owner setting. A scripted liveness test proves each handler path actually fires, so the invariants are not vacuous.\n\n**Edge unit tests.** Pinned price bounds of 1 wei and 1e18, the exact 30-minute deadline boundary, zero and max deadline, any other chain, the exact `Launched` event, every postcondition the adapter rejects (position id drift, position for another pool, token reporting a wrong owner, launched flag, tax, symbol, decimals, supply, dust, fee recipient), three more dependency-route mismatches, the owner's inability to move or approve the locked NFT, burnable supply, a stranger's lookalike token, and launch gas.\n\n**Findings reported in `.imd-findings.json`:**\n- **Medium, with a failing proof test.** The token created through the captured implementation rejects every holder-to-holder transfer with custom error 0x2f352531, before and after tax decay, including `transferFrom` and EOA-to-EOA. Only pool swaps and transfers to or from the owner succeed. Neither the README, the security review nor the site discloses that bought tokens cannot be sent to another wallet. I pinned the observed behaviour in one clearly labelled unit test so a change is noticed, without asserting it is desired.\n- **Info.** Undisclosed owner powers on the token: `setPairingEnabled`, `setExternalLiquidityEnabled`, distributor setters, and `renounceOwnership`, which succeeded in the fixture and permanently freezes tax and recipient settings.\n\n**Still owed.** Fork runs against live mainnet state remain untested here, since neither this machine's verifier nor the task has network access. The fixture is a captured block, so a live preflight before signing is still the operator's responsibility.","treeHash":"f1ae11e2cf2f3568d885b69eda926a5263e69d6e","usage":{"cachedInputTokens":1965373,"inputTokens":578,"model":"claude-fable-5-1","outputTokens":52580,"runtime":"claude","turns":45,"wallClockMs":1093528}},{"artifacts":[],"attempt":1,"bundleHash":"1900a4b4d1eabe0f331f8763e941c0bb6b0e9f617a8bcd7819d552910cb534c8","device":"fd7c32744e171d7d","findings":[],"hash":"fc4347b09b41bd64d5c43085c726000595772753587a5030411ca524a496b085","nodeId":"a67fadd1-195f-422f-9f0a-c7d1c799f903","outcome":"completed","summary":"Implemented the launch contract, polished retro-punk website, offline dependencies, and [deployment documentation](/home/imd1161/.identitymd/work/1336f7b0-b673-420e-9479-a25a6a184cab/a67fadd1-195f-422f-9f0a-c7d1c799f903/README.md).\n\nPassed: `forge build`, 42 Foundry tests, formatting, 13 JavaScript tests, and browser checks.\n\nThe factory already has five tokens, so “first-ever” is unavailable. No mainnet transaction was broadcast; the owner’s confirmed launch will supply the actual token address and transaction hash.","treeHash":"a7c53d37c63451edfaf4d4ce3888ae8168bfef11","usage":{"cachedInputTokens":13726336,"inputTokens":339878,"model":"gpt-6-astra","outputTokens":127625,"runtime":"codex","turns":15,"wallClockMs":3265456}}],"verification":[{"checks":[{"durationMs":23401,"exitCode":0,"name":"build","output":"Compiling 29 files with Solc 0.8.26\nSolc 0.8.26 finished in 23.33s\nCompiler run successful!\n","passed":true},{"durationMs":176,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_constructorOnEmptyChainHasExplicitOwner() (gas: 40384)\n[PASS] test_constructorRejectsInfrastructureAsOwner() (gas: 3776)\n[PASS] test_constructorRejectsZeroOwner() (gas: 3798)\n[PASS] test_runtimeBoundedAndHasNoEscapeOpcodes() (gas: 5162817)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 16.65ms (17.21ms CPU time)\n\nRan 42 tests for test/ERC20TLaunch.t.sol:ERC20TLaunchTest\n[PASS] testFuzz_invalidPrices(uint256) (runs: 512, μ: 33701, ~: 33702)\n[PASS] testFuzz_nonOwnerCannotLaunch(address) (runs: 512, μ: 31323, ~: 31323)\n[PASS] testFuzz_pricesConserveSupply(uint256) (runs: 512, μ: 1169072, ~: 1176410)\nLogs:\n  Bound result 16880\n\n[PASS] testFuzz_reverseOrderPricesConserveSupply(uint256) (runs: 512, μ: 1150961, ~: 1158064)\nLogs:\n  Bound result 18894\n\n[PASS] testFuzz_taxDecayNeverUnderflows(uint32) (runs: 512, μ: 1126884, ~: 1126765)\n[PASS] test_actualBuyAndSellAgainstMainnetPoolAndHook() (gas: 2944495)\n[PASS] test_bothCurrencySortOrdersLaunch() (gas: 1116084)\n[PASS] test_cannotSendEtherToLaunch() (gas: 38144)\n[PASS] test_changedFeeConversionPoolRejected() (gas: 95857)\n[PASS] test_deadlineBoundaryAccepted() (gas: 1120647)\n[PASS] test_directWalletTransfersSucceedDuringAndAfterDecay() (gas: 1392887)\n[PASS] test_disabledFeeConversionRouteRejected() (gas: 83809)\n[PASS] test_distantDeadline() (gas: 33231)\n[PASS] test_emptyPositionRollsBackCreation() (gas: 1053416)\n[PASS] test_expiredDeadline() (gas: 33128)\n[PASS] test_factoryFailureRollsBackAndCanRetry() (gas: 1237215)\n[PASS] test_factoryMatchesRequestedConfig() (gas: 1205270)\n[PASS] test_factoryReturningAnEOAFailsAtomically() (gas: 114660)\n[PASS] test_failsClosedIfAnyDependencyChanges() (gas: 610436)\n[PASS] test_firstLaunchOnAnUnusedFactoryState() (gas: 1158629)\n[PASS] test_firstProbeAloneCannotMislabelLaterNonce() (gas: 1011312)\n[PASS] test_holderTransfersThroughSpendersOrContractsRevertWithInvalidTransfer() (gas: 1997786)\n[PASS] test_initialPriceWithinOneTickSpacingOfRequestedQuotePrice() (gas: 1314548)\n[PASS] test_missingCreatorAllocationRollsBackCreation() (gas: 1031003)\n[PASS] test_onlyOwnerMayLaunch() (gas: 37211)\n[PASS] test_ownerCallbackCannotReenterLaunch() (gas: 445335)\n[PASS] test_ownerCanApproveAndRevokeDistributorContracts() (gas: 1947236)\n[PASS] test_realMainnetLaunchAndLock() (gas: 1530504)\n[PASS] test_rejectsSecondLaunch() (gas: 1164723)\n[PASS] test_reverseCurrencyOrderInitialPrice() (gas: 1293631)\n[PASS] test_selectorMatchesObservedMainnetCalldata() (gas: 3255)\n[PASS] test_strictFirstRejectsExistingTokenWithoutSideEffects() (gas: 116780)\n[PASS] test_taxDecayExactBoundaries() (gas: 1239665)\n[PASS] test_tradeSlippageFailureLeavesFundsUnchanged() (gas: 2385654)\n[PASS] test_transferPolicySelectorsMatchTheVerifiedImplementation() (gas: 4938)\n[PASS] test_unconfiguredProtocolRecipientRejected() (gas: 63278)\n[PASS] test_underlyingOwnerPowersRemainAndAreDocumented() (gas: 1383059)\n[PASS] test_unlockedPositionRollsBackCreation() (gas: 1067055)\n[PASS] test_wrongChain() (gas: 31205)\n[PASS] test_wrongIMDDecimalsRejected() (gas: 62390)\n[PASS] test_wrongImplementationReferenceRejected() (gas: 61716)\n[PASS] test_zeroPrice() (gas: 32948)\nSuite result: ok. 42 passed; 0 failed; 0 skipped; finished in 92.23ms (373.66ms CPU time)\n\nRan 2 test suites in 93.00ms (108.87ms CPU time): 46 tests passed, 0 failed, 0 skipped (46 total tests)\n","passed":true},{"durationMs":55,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ERC20TLaunch.launch(uint256,uint256,bool)\"],\"files\":{\".gitignore\":5,\"Makefile\":17,\"README.md\":154,\"THIRD_PARTY.md\":14,\"docs/EVIDENCE.md\":69,\"docs/SECURITY_REVIEW.md\":59,\"docs/VALIDATION.md\":37,\"docs/preflight-observation.json\":113,\"foundry.toml\":17,\"package.json\":9,\"remappings.txt\":1,\"site/abi/ERC20TLaunch.json\":705,\"site/app.mjs\":349,\"site/config.mjs\":36,\"site/core.mjs\":123,\"site/deployment.json\":6,\"site/docs.html\":16,\"site/favicon.svg\":1,\"site/fonts/Anton-OFL.txt\":93,\"site/fonts/Anton-Regular.ttf\":1369,\"site/fonts/SpaceGrotesk-OFL.txt\":93,\"site/fonts/SpaceGrotesk.ttf\":1091,\"site/index.html\":77,\"site/style.css\":11,\"site/vendor/ethers.LICENSE.md\":21,\"site/vendor/ethers.min.js\":1,\"src/ERC20TLaunch.sol\":210,\"src/interfaces/IERC20T.sol\":48,\"src/interfaces/IERC20TFactory.sol\":30,\"test/Deployment.t.sol\":45,\"test/ERC20TLaunch.t.sol\":664,\"test/browser/check.mjs\":200,\"test/fixtures/MainnetState.sol\":220,\"test/fixtures/provenance.json\":108,\"test/helpers/HolderProbe.sol\":19,\"test/helpers/LaunchAndTradeProbe.sol\":23,\"test/helpers/ReentryProbe.sol\":37,\"test/helpers/SwapHarness.sol\":73,\"test/web/core.test.mjs\":151,\"tools/capture-fixture.mjs\":109,\"tools/export-artifacts.mjs\":7,\"tools/preflight.mjs\":65},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"4a7e3d39e3de7b8c22589f94fff565629560de521007b6a217350e9cd4353e9b","verifiedTreeHash":"af72a5ee125a089180eefd20aee296cb9bb8915c","verifierVersion":"0.1.0+d952fceb"},{"checks":[{"durationMs":26122,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 26.04s\nCompiler run successful!\n","passed":true},{"durationMs":180,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_constructorOnEmptyChainHasExplicitOwner() (gas: 40384)\n[PASS] test_constructorRejectsInfrastructureAsOwner() (gas: 3776)\n[PASS] test_constructorRejectsZeroOwner() (gas: 3798)\n[PASS] test_runtimeBoundedAndHasNoEscapeOpcodes() (gas: 5162817)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 102.65ms (10.80ms CPU time)\n\nRan 38 tests for test/ERC20TLaunch.t.sol:ERC20TLaunchTest\n[PASS] testFuzz_invalidPrices(uint256) (runs: 512, μ: 33698, ~: 33701)\n[PASS] testFuzz_nonOwnerCannotLaunch(address) (runs: 512, μ: 31389, ~: 31389)\n[PASS] testFuzz_pricesConserveSupply(uint256) (runs: 512, μ: 1168771, ~: 1176395)\nLogs:\n  Bound result 409589113597597865\n\n[PASS] testFuzz_reverseOrderPricesConserveSupply(uint256) (runs: 512, μ: 1150670, ~: 1158057)\nLogs:\n  Bound result 16483\n\n[PASS] testFuzz_taxDecayNeverUnderflows(uint32) (runs: 512, μ: 1126842, ~: 1126721)\n[PASS] test_actualBuyAndSellAgainstMainnetPoolAndHook() (gas: 2944398)\n[PASS] test_bothCurrencySortOrdersLaunch() (gas: 1116128)\n[PASS] test_cannotSendEtherToLaunch() (gas: 38080)\n[PASS] test_changedFeeConversionPoolRejected() (gas: 95901)\n[PASS] test_deadlineBoundaryAccepted() (gas: 1120624)\n[PASS] test_disabledFeeConversionRouteRejected() (gas: 83809)\n[PASS] test_distantDeadline() (gas: 33275)\n[PASS] test_emptyPositionRollsBackCreation() (gas: 1053438)\n[PASS] test_expiredDeadline() (gas: 33105)\n[PASS] test_factoryFailureRollsBackAndCanRetry() (gas: 1237215)\n[PASS] test_factoryMatchesRequestedConfig() (gas: 1205270)\n[PASS] test_factoryReturningAnEOAFailsAtomically() (gas: 114572)\n[PASS] test_failsClosedIfAnyDependencyChanges() (gas: 610436)\n[PASS] test_firstLaunchOnAnUnusedFactoryState() (gas: 1158629)\n[PASS] test_firstProbeAloneCannotMislabelLaterNonce() (gas: 1011312)\n[PASS] test_initialPriceWithinOneTickSpacingOfRequestedQuotePrice() (gas: 1314548)\n[PASS] test_missingCreatorAllocationRollsBackCreation() (gas: 1031025)\n[PASS] test_onlyOwnerMayLaunch() (gas: 37233)\n[PASS] test_ownerCallbackCannotReenterLaunch() (gas: 445335)\n[PASS] test_realMainnetLaunchAndLock() (gas: 1530503)\n[PASS] test_rejectsSecondLaunch() (gas: 1164745)\n[PASS] test_reverseCurrencyOrderInitialPrice() (gas: 1293631)\n[PASS] test_selectorMatchesObservedMainnetCalldata() (gas: 3255)\n[PASS] test_strictFirstRejectsExistingTokenWithoutSideEffects() (gas: 116780)\n[PASS] test_taxDecayExactBoundaries() (gas: 1239620)\n[PASS] test_tradeSlippageFailureLeavesFundsUnchanged() (gas: 2385511)\n[PASS] test_unconfiguredProtocolRecipientRejected() (gas: 63255)\n[PASS] test_underlyingOwnerPowersRemainAndAreDocumented() (gas: 1383059)\n[PASS] test_unlockedPositionRollsBackCreation() (gas: 1067055)\n[PASS] test_wrongChain() (gas: 31249)\n[PASS] test_wrongIMDDecimalsRejected() (gas: 62390)\n[PASS] test_wrongImplementationReferenceRejected() (gas: 61715)\n[PASS] test_zeroPrice() (gas: 32970)\nSuite result: ok. 38 passed; 0 failed; 0 skipped; finished in 102.56ms (332.62ms CPU time)\n\nRan 2 test suites in 103.56ms (205.21ms CPU time): 42 tests passed, 0 failed, 0 skipped (42 total tests)\n","passed":true},{"durationMs":54,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ERC20TLaunch.launch(uint256,uint256,bool)\"],\"files\":{\".gitignore\":5,\"Makefile\":17,\"README.md\":123,\"THIRD_PARTY.md\":14,\"docs/EVIDENCE.md\":69,\"docs/SECURITY_REVIEW.md\":49,\"docs/VALIDATION.md\":29,\"docs/preflight-observation.json\":113,\"foundry.toml\":17,\"launch.json\":10,\"package.json\":9,\"remappings.txt\":1,\"site/abi/ERC20TLaunch.json\":705,\"site/app.mjs\":344,\"site/config.mjs\":33,\"site/core.mjs\":114,\"site/deployment.json\":6,\"site/docs.html\":13,\"site/favicon.svg\":1,\"site/fonts/Anton-OFL.txt\":93,\"site/fonts/Anton-Regular.ttf\":1369,\"site/fonts/SpaceGrotesk-OFL.txt\":93,\"site/fonts/SpaceGrotesk.ttf\":1091,\"site/index.html\":77,\"site/style.css\":11,\"site/vendor/ethers.LICENSE.md\":21,\"site/vendor/ethers.min.js\":1,\"src/ERC20TLaunch.sol\":210,\"src/interfaces/IERC20T.sol\":48,\"src/interfaces/IERC20TFactory.sol\":30,\"test/Deployment.t.sol\":45,\"test/ERC20TLaunch.t.sol\":536,\"test/browser/check.mjs\":200,\"test/fixtures/MainnetState.sol\":220,\"test/fixtures/provenance.json\":108,\"test/helpers/LaunchAndTradeProbe.sol\":23,\"test/helpers/ReentryProbe.sol\":37,\"test/helpers/SwapHarness.sol\":73,\"test/web/core.test.mjs\":138,\"tools/capture-fixture.mjs\":109,\"tools/export-artifacts.mjs\":7,\"tools/preflight.mjs\":65},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"733e99ee97ca965cff5cceede8c4f96185a5c504a6fd3da468ac579f4207699e","verifiedTreeHash":"b2a6c465a9ee053fe0d9ae897d8cdcdd9c4cdf75","verifierVersion":"0.1.0+d952fceb"},{"checks":[{"durationMs":73957,"exitCode":0,"name":"build","output":"Compiling 32 files with Solc 0.8.26\nSolc 0.8.26 finished in 73.87s\nCompiler run successful!\n","passed":true},{"durationMs":696,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_constructorOnEmptyChainHasExplicitOwner() (gas: 40384)\n[PASS] test_constructorRejectsInfrastructureAsOwner() (gas: 3776)\n[PASS] test_constructorRejectsZeroOwner() (gas: 3798)\n[PASS] test_runtimeBoundedAndHasNoEscapeOpcodes() (gas: 5162817)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 103.39ms (11.98ms CPU time)\n\nRan 42 tests for test/ERC20TLaunch.t.sol:ERC20TLaunchTest\n[PASS] testFuzz_invalidPrices(uint256) (runs: 512, μ: 33701, ~: 33702)\n[PASS] testFuzz_nonOwnerCannotLaunch(address) (runs: 512, μ: 31323, ~: 31323)\n[PASS] testFuzz_pricesConserveSupply(uint256) (runs: 512, μ: 1169036, ~: 1176373)\nLogs:\n  Bound result 16880\n\n[PASS] testFuzz_reverseOrderPricesConserveSupply(uint256) (runs: 512, μ: 1150923, ~: 1158052)\nLogs:\n  Bound result 18894\n\n[PASS] testFuzz_taxDecayNeverUnderflows(uint32) (runs: 512, μ: 1126880, ~: 1126765)\n[PASS] test_actualBuyAndSellAgainstMainnetPoolAndHook() (gas: 2944495)\n[PASS] test_bothCurrencySortOrdersLaunch() (gas: 1116084)\n[PASS] test_cannotSendEtherToLaunch() (gas: 38144)\n[PASS] test_changedFeeConversionPoolRejected() (gas: 95857)\n[PASS] test_deadlineBoundaryAccepted() (gas: 1120647)\n[PASS] test_directWalletTransfersSucceedDuringAndAfterDecay() (gas: 1392887)\n[PASS] test_disabledFeeConversionRouteRejected() (gas: 83809)\n[PASS] test_distantDeadline() (gas: 33231)\n[PASS] test_emptyPositionRollsBackCreation() (gas: 1053416)\n[PASS] test_expiredDeadline() (gas: 33128)\n[PASS] test_factoryFailureRollsBackAndCanRetry() (gas: 1237215)\n[PASS] test_factoryMatchesRequestedConfig() (gas: 1205270)\n[PASS] test_factoryReturningAnEOAFailsAtomically() (gas: 114660)\n[PASS] test_failsClosedIfAnyDependencyChanges() (gas: 610436)\n[PASS] test_firstLaunchOnAnUnusedFactoryState() (gas: 1158629)\n[PASS] test_firstProbeAloneCannotMislabelLaterNonce() (gas: 1011312)\n[PASS] test_holderTransfersThroughSpendersOrContractsRevertWithInvalidTransfer() (gas: 1997786)\n[PASS] test_initialPriceWithinOneTickSpacingOfRequestedQuotePrice() (gas: 1314548)\n[PASS] test_missingCreatorAllocationRollsBackCreation() (gas: 1031003)\n[PASS] test_onlyOwnerMayLaunch() (gas: 37211)\n[PASS] test_ownerCallbackCannotReenterLaunch() (gas: 445335)\n[PASS] test_ownerCanApproveAndRevokeDistributorContracts() (gas: 1947236)\n[PASS] test_realMainnetLaunchAndLock() (gas: 1530504)\n[PASS] test_rejectsSecondLaunch() (gas: 1164723)\n[PASS] test_reverseCurrencyOrderInitialPrice() (gas: 1293631)\n[PASS] test_selectorMatchesObservedMainnetCalldata() (gas: 3255)\n[PASS] test_strictFirstRejectsExistingTokenWithoutSideEffects() (gas: 116780)\n[PASS] test_taxDecayExactBoundaries() (gas: 1239665)\n[PASS] test_tradeSlippageFailureLeavesFundsUnchanged() (gas: 2385654)\n[PASS] test_transferPolicySelectorsMatchTheVerifiedImplementation() (gas: 4938)\n[PASS] test_unconfiguredProtocolRecipientRejected() (gas: 63278)\n[PASS] test_underlyingOwnerPowersRemainAndAreDocumented() (gas: 1383059)\n[PASS] test_unlockedPositionRollsBackCreation() (gas: 1067055)\n[PASS] test_wrongChain() (gas: 31205)\n[PASS] test_wrongIMDDecimalsRejected() (gas: 62390)\n[PASS] test_wrongImplementationReferenceRejected() (gas: 61716)\n[PASS] test_zeroPrice() (gas: 32948)\nSuite result: ok. 42 passed; 0 failed; 0 skipped; finished in 103.39ms (495.19ms CPU time)\n\nRan 37 tests for test/ERC20TLaunchEdges.t.sol:ERC20TLaunchEdgesTest\n[PASS] testFuzz_anyOtherChainRejected(uint256) (runs: 512, μ: 41790, ~: 41998)\nLogs:\n  Bound result 16483643509165785101\n\n[PASS] testFuzz_deadlineInsideWindowAccepted(uint256) (runs: 512, μ: 1124784, ~: 1124872)\nLogs:\n  Bound result 884\n\n[PASS] testFuzz_deadlineOutsideWindowRejected(uint256,bool) (runs: 512, μ: 37206, ~: 37172)\nLogs:\n  Bound result 100000000000000000000\n\n[PASS] test_constructorRejectsItsOwnAddressAsOwner() (gas: 4787)\n[PASS] test_conversionRouteHookOrSpacingChangeRejected() (gas: 232414)\n[PASS] test_creatorAllocationIsLiquidAndSellable() (gas: 3780601)\n[PASS] test_deadlineAtExactlyThirtyMinutesAccepted() (gas: 1120823)\n[PASS] test_deadlineOneSecondPastThirtyMinutesRejected() (gas: 33317)\n[PASS] test_dependencyCheckIsFreeOfSideEffectsAndPublic() (gas: 55446)\n[PASS] test_launchGasFitsComfortablyInABlock() (gas: 1115328)\n[PASS] test_launchReturnsTheRecordedToken() (gas: 1121316)\n[PASS] test_launchedEventCarriesTheExactReceipt() (gas: 1177355)\n[PASS] test_lookalikeTokenFromAStrangerDoesNotTouchTheAdapter() (gas: 2086429)\n[PASS] test_maxDeadlineRejected() (gas: 33555)\n[PASS] test_notRequiringFirstStillRecordsFirstWhenSlotIsEmpty() (gas: 1136368)\n[PASS] test_observedHolderToHolderTransfersAreRejectedByTheTokenImplementation() (gas: 2606027)\n[PASS] test_ownerCannotMoveOrApproveTheLockedPosition() (gas: 1196672)\n[PASS] test_positionForAnotherPoolRollsBack() (gas: 1072360)\n[PASS] test_positionIdDriftRollsBack() (gas: 1067485)\n[PASS] test_priceJustAboveUpperBoundRejected() (gas: 33071)\n[PASS] test_priceLowerBoundOneWeiLaunches() (gas: 1240299)\n[PASS] test_priceMaxUintRejectedBeforeAnyExternalCall() (gas: 44450)\n[PASS] test_priceUpperBoundOneIMDLaunches() (gas: 1206671)\n[PASS] test_protocolFeeShareChangeRejected() (gas: 66118)\n[PASS] test_quoteTokenNoLongerAnExternalBaseRejected() (gas: 83831)\n[PASS] test_supplyIsBurnableByAnyHolder() (gas: 1213101)\n[PASS] test_tokenConfigIsExactlyTheBrief() (gas: 49857)\n[PASS] test_tokenReportingAnotherFeeRecipientRollsBack() (gas: 1077890)\n[PASS] test_tokenReportingAnotherOwnerRollsBack() (gas: 1050431)\n[PASS] test_tokenReportingAnotherRestingTaxRollsBack() (gas: 1070782)\n[PASS] test_tokenReportingExcessDustRollsBack() (gas: 1078119)\n[PASS] test_tokenReportingInflatedSupplyRollsBack() (gas: 1057366)\n[PASS] test_tokenReportingNotLaunchedRollsBack() (gas: 1048809)\n[PASS] test_tokenReportingSixDecimalsRollsBack() (gas: 1053046)\n[PASS] test_tokenReportingWrongLaunchTaxRollsBack() (gas: 1073263)\n[PASS] test_tokenReportingWrongSymbolRollsBack() (gas: 1056328)\n[PASS] test_zeroDeadlineRejected() (gas: 33001)\nSuite result: ok. 37 passed; 0 failed; 0 skipped; finished in 103.43ms (325.66ms CPU time)\n\nRan 2 tests for test/ERC20TLaunchInvariant.t.sol:ERC20TLaunchInvariantTest\n[PASS]\nERC20TLaunchInvariantTest invariants:\n[PASS] invariant_adapterNeverHoldsValue\n[PASS] invariant_initialPositionStaysLockedWithItsLiquidity\n[PASS] invariant_launchHappensAtMostOnceAndOnlyForTheOwnerWithValidInputs\n[PASS] invariant_ownerAllocationIsExactlyFivePercent\n[PASS] invariant_quoteTokenIsConserved\n[PASS] invariant_statusNeverRestsInLaunching\n[PASS] invariant_supplyIsFixedMinusVoluntaryBurns\n[PASS] invariant_taxFollowsTheDecayScheduleThenTheOwnerSetting\n[PASS] invariant_tradersNeverHoldMoreThanThePoolReleased\n[PASS] invariant_transferPolicyMatchesTheDisclosure\n[PASS] invariant_walletTransfersAreUntaxedAndConserveTheGiftedAmount\n ERC20TLaunchInvariantTest invariants (runs: 48, calls: 1536, reverts: 0)\n\n╭------------------------+----------------+-------+---------+----------╮\n| Contract               | Selector       | Calls | Reverts | Discards |\n+======================================================================+\n| LaunchInvariantHandler | burn           | 172   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | buy            | 148   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | launch         | 187   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | ownerGift      | 173   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | ownerSetTax    | 163   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | sell           | 160   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | transferTokens | 188   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | walletTransfer | 177   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | warp           | 168   | 0       | 0        |\n╰------------------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 501\n  Bound result 257\n  Bound result 649\n  Bound result 242\n  Bound result 208\n  Bound result 603\n  Bound result 550\n  Bound result 260\n  Bound result 1607\n  Bound result 2854\n\n[PASS] test_handlerSequenceExercisesEveryPath() (gas: 5391531)\nLogs:\n  Bound result 540540540540\n  Bound result 100\n  Bound result 540540540540\n  Bound result 100\n  Bound result 540540540540\n  Bound result 100\n  Bound result 540540540540\n  Bound result 100\n  Bound result 3000000000000000000\n  Bound result 2000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000000\n  Bound result 400000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 50\n  Bound result 5880\n  Bound result 50\n  Bound result 100000000000000000000\n  Bound result 1000000000000000000\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 597.76ms (594.64ms CPU time)\n\nRan 4 test suites in 600.69ms (907.97ms CPU time): 85 tests passed, 0 failed, 0 skipped (85 total tests)\n","passed":true},{"durationMs":61,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ERC20TLaunch.launch(uint256,uint256,bool)\"],\"files\":{\".gitignore\":5,\"Makefile\":17,\"README.md\":154,\"THIRD_PARTY.md\":14,\"docs/EVIDENCE.md\":69,\"docs/SECURITY_REVIEW.md\":59,\"docs/VALIDATION.md\":37,\"docs/preflight-observation.json\":113,\"foundry.toml\":17,\"package.json\":9,\"remappings.txt\":1,\"site/abi/ERC20TLaunch.json\":705,\"site/app.mjs\":349,\"site/config.mjs\":36,\"site/core.mjs\":123,\"site/deployment.json\":6,\"site/docs.html\":16,\"site/favicon.svg\":1,\"site/fonts/Anton-OFL.txt\":93,\"site/fonts/Anton-Regular.ttf\":1369,\"site/fonts/SpaceGrotesk-OFL.txt\":93,\"site/fonts/SpaceGrotesk.ttf\":1091,\"site/index.html\":77,\"site/style.css\":11,\"site/vendor/ethers.LICENSE.md\":21,\"site/vendor/ethers.min.js\":1,\"src/ERC20TLaunch.sol\":210,\"src/interfaces/IERC20T.sol\":48,\"src/interfaces/IERC20TFactory.sol\":30,\"test/Deployment.t.sol\":45,\"test/ERC20TLaunch.t.sol\":664,\"test/ERC20TLaunchEdges.t.sol\":456,\"test/ERC20TLaunchInvariant.t.sol\":258,\"test/browser/check.mjs\":200,\"test/fixtures/MainnetState.sol\":220,\"test/fixtures/provenance.json\":108,\"test/helpers/HolderProbe.sol\":19,\"test/helpers/LaunchAndTradeProbe.sol\":23,\"test/helpers/LaunchInvariantHandler.sol\":246,\"test/helpers/ReentryProbe.sol\":37,\"test/helpers/SwapHarness.sol\":73,\"test/web/core.test.mjs\":151,\"tools/capture-fixture.mjs\":109,\"tools/export-artifacts.mjs\":7,\"tools/preflight.mjs\":65},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"834218b6af8531fc33d1aa91f60d9053e0f2035d7af5e3b6bd4dcef0c77f1845","verifiedTreeHash":"e5a5208a8f47a1346c0b0b5cdab54ec77ec0691a","verifierVersion":"0.1.0+d952fceb"},{"checks":[{"durationMs":23876,"exitCode":0,"name":"build","output":"Compiling 29 files with Solc 0.8.26\nSolc 0.8.26 finished in 23.80s\nCompiler run successful!\n","passed":true},{"durationMs":175,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_constructorOnEmptyChainHasExplicitOwner() (gas: 40384)\n[PASS] test_constructorRejectsInfrastructureAsOwner() (gas: 3776)\n[PASS] test_constructorRejectsZeroOwner() (gas: 3798)\n[PASS] test_runtimeBoundedAndHasNoEscapeOpcodes() (gas: 5162817)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 89.13ms (14.21ms CPU time)\n\nRan 42 tests for test/ERC20TLaunch.t.sol:ERC20TLaunchTest\n[PASS] testFuzz_invalidPrices(uint256) (runs: 512, μ: 33701, ~: 33702)\n[PASS] testFuzz_nonOwnerCannotLaunch(address) (runs: 512, μ: 31323, ~: 31323)\n[PASS] testFuzz_pricesConserveSupply(uint256) (runs: 512, μ: 1169072, ~: 1176410)\nLogs:\n  Bound result 137261506246584121\n\n[PASS] testFuzz_reverseOrderPricesConserveSupply(uint256) (runs: 512, μ: 1150961, ~: 1158064)\nLogs:\n  Bound result 16880\n\n[PASS] testFuzz_taxDecayNeverUnderflows(uint32) (runs: 512, μ: 1126884, ~: 1126765)\n[PASS] test_actualBuyAndSellAgainstMainnetPoolAndHook() (gas: 2944495)\n[PASS] test_bothCurrencySortOrdersLaunch() (gas: 1116084)\n[PASS] test_cannotSendEtherToLaunch() (gas: 38144)\n[PASS] test_changedFeeConversionPoolRejected() (gas: 95857)\n[PASS] test_deadlineBoundaryAccepted() (gas: 1120647)\n[PASS] test_directWalletTransfersSucceedDuringAndAfterDecay() (gas: 1392887)\n[PASS] test_disabledFeeConversionRouteRejected() (gas: 83809)\n[PASS] test_distantDeadline() (gas: 33231)\n[PASS] test_emptyPositionRollsBackCreation() (gas: 1053416)\n[PASS] test_expiredDeadline() (gas: 33128)\n[PASS] test_factoryFailureRollsBackAndCanRetry() (gas: 1237215)\n[PASS] test_factoryMatchesRequestedConfig() (gas: 1205270)\n[PASS] test_factoryReturningAnEOAFailsAtomically() (gas: 114660)\n[PASS] test_failsClosedIfAnyDependencyChanges() (gas: 610436)\n[PASS] test_firstLaunchOnAnUnusedFactoryState() (gas: 1158629)\n[PASS] test_firstProbeAloneCannotMislabelLaterNonce() (gas: 1011312)\n[PASS] test_holderTransfersThroughSpendersOrContractsRevertWithInvalidTransfer() (gas: 1997786)\n[PASS] test_initialPriceWithinOneTickSpacingOfRequestedQuotePrice() (gas: 1314548)\n[PASS] test_missingCreatorAllocationRollsBackCreation() (gas: 1031003)\n[PASS] test_onlyOwnerMayLaunch() (gas: 37211)\n[PASS] test_ownerCallbackCannotReenterLaunch() (gas: 445335)\n[PASS] test_ownerCanApproveAndRevokeDistributorContracts() (gas: 1947236)\n[PASS] test_realMainnetLaunchAndLock() (gas: 1530504)\n[PASS] test_rejectsSecondLaunch() (gas: 1164723)\n[PASS] test_reverseCurrencyOrderInitialPrice() (gas: 1293631)\n[PASS] test_selectorMatchesObservedMainnetCalldata() (gas: 3255)\n[PASS] test_strictFirstRejectsExistingTokenWithoutSideEffects() (gas: 116780)\n[PASS] test_taxDecayExactBoundaries() (gas: 1239665)\n[PASS] test_tradeSlippageFailureLeavesFundsUnchanged() (gas: 2385654)\n[PASS] test_transferPolicySelectorsMatchTheVerifiedImplementation() (gas: 4938)\n[PASS] test_unconfiguredProtocolRecipientRejected() (gas: 63278)\n[PASS] test_underlyingOwnerPowersRemainAndAreDocumented() (gas: 1383059)\n[PASS] test_unlockedPositionRollsBackCreation() (gas: 1067055)\n[PASS] test_wrongChain() (gas: 31205)\n[PASS] test_wrongIMDDecimalsRejected() (gas: 62390)\n[PASS] test_wrongImplementationReferenceRejected() (gas: 61716)\n[PASS] test_zeroPrice() (gas: 32948)\nSuite result: ok. 42 passed; 0 failed; 0 skipped; finished in 93.38ms (390.02ms CPU time)\n\nRan 2 test suites in 94.16ms (182.52ms CPU time): 46 tests passed, 0 failed, 0 skipped (46 total tests)\n","passed":true},{"durationMs":54,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ERC20TLaunch.launch(uint256,uint256,bool)\"],\"files\":{\".gitignore\":5,\"Makefile\":17,\"README.md\":154,\"THIRD_PARTY.md\":14,\"docs/EVIDENCE.md\":69,\"docs/SECURITY_REVIEW.md\":59,\"docs/VALIDATION.md\":37,\"docs/preflight-observation.json\":113,\"foundry.toml\":17,\"launch.json\":10,\"package.json\":9,\"remappings.txt\":1,\"site/abi/ERC20TLaunch.json\":705,\"site/app.mjs\":349,\"site/config.mjs\":36,\"site/core.mjs\":123,\"site/deployment.json\":6,\"site/docs.html\":16,\"site/favicon.svg\":1,\"site/fonts/Anton-OFL.txt\":93,\"site/fonts/Anton-Regular.ttf\":1369,\"site/fonts/SpaceGrotesk-OFL.txt\":93,\"site/fonts/SpaceGrotesk.ttf\":1091,\"site/index.html\":77,\"site/style.css\":11,\"site/vendor/ethers.LICENSE.md\":21,\"site/vendor/ethers.min.js\":1,\"src/ERC20TLaunch.sol\":210,\"src/interfaces/IERC20T.sol\":48,\"src/interfaces/IERC20TFactory.sol\":30,\"test/Deployment.t.sol\":45,\"test/ERC20TLaunch.t.sol\":664,\"test/browser/check.mjs\":200,\"test/fixtures/MainnetState.sol\":220,\"test/fixtures/provenance.json\":108,\"test/helpers/HolderProbe.sol\":19,\"test/helpers/LaunchAndTradeProbe.sol\":23,\"test/helpers/ReentryProbe.sol\":37,\"test/helpers/SwapHarness.sol\":73,\"test/web/core.test.mjs\":151,\"tools/capture-fixture.mjs\":109,\"tools/export-artifacts.mjs\":7,\"tools/preflight.mjs\":65},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c6866d67bf1a744111bda916c34fdc8b4343d83c1d524ed7512c09e2da361ac8","verifiedTreeHash":"bea000227e7c7a492404feda42187a7f5a17ac6d","verifierVersion":"0.1.0+d952fceb"},{"checks":[{"durationMs":73328,"exitCode":0,"name":"build","output":"Compiling 31 files with Solc 0.8.26\nSolc 0.8.26 finished in 73.25s\nCompiler run successful!\n","passed":true},{"durationMs":547,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_constructorOnEmptyChainHasExplicitOwner() (gas: 40384)\n[PASS] test_constructorRejectsInfrastructureAsOwner() (gas: 3776)\n[PASS] test_constructorRejectsZeroOwner() (gas: 3798)\n[PASS] test_runtimeBoundedAndHasNoEscapeOpcodes() (gas: 5162817)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 100.18ms (15.29ms CPU time)\n\nRan 38 tests for test/ERC20TLaunch.t.sol:ERC20TLaunchTest\n[PASS] testFuzz_invalidPrices(uint256) (runs: 512, μ: 33695, ~: 33695)\n[PASS] testFuzz_nonOwnerCannotLaunch(address) (runs: 512, μ: 31389, ~: 31389)\n[PASS] testFuzz_pricesConserveSupply(uint256) (runs: 512, μ: 1168593, ~: 1176384)\nLogs:\n  Bound result 18894\n\n[PASS] testFuzz_reverseOrderPricesConserveSupply(uint256) (runs: 512, μ: 1150491, ~: 1158049)\nLogs:\n  Bound result 1000000000000000000\n\n[PASS] testFuzz_taxDecayNeverUnderflows(uint32) (runs: 512, μ: 1126845, ~: 1126721)\n[PASS] test_actualBuyAndSellAgainstMainnetPoolAndHook() (gas: 2944398)\n[PASS] test_bothCurrencySortOrdersLaunch() (gas: 1116128)\n[PASS] test_cannotSendEtherToLaunch() (gas: 38080)\n[PASS] test_changedFeeConversionPoolRejected() (gas: 95901)\n[PASS] test_deadlineBoundaryAccepted() (gas: 1120624)\n[PASS] test_disabledFeeConversionRouteRejected() (gas: 83809)\n[PASS] test_distantDeadline() (gas: 33275)\n[PASS] test_emptyPositionRollsBackCreation() (gas: 1053438)\n[PASS] test_expiredDeadline() (gas: 33105)\n[PASS] test_factoryFailureRollsBackAndCanRetry() (gas: 1237215)\n[PASS] test_factoryMatchesRequestedConfig() (gas: 1205270)\n[PASS] test_factoryReturningAnEOAFailsAtomically() (gas: 114572)\n[PASS] test_failsClosedIfAnyDependencyChanges() (gas: 610436)\n[PASS] test_firstLaunchOnAnUnusedFactoryState() (gas: 1158629)\n[PASS] test_firstProbeAloneCannotMislabelLaterNonce() (gas: 1011312)\n[PASS] test_initialPriceWithinOneTickSpacingOfRequestedQuotePrice() (gas: 1314548)\n[PASS] test_missingCreatorAllocationRollsBackCreation() (gas: 1031025)\n[PASS] test_onlyOwnerMayLaunch() (gas: 37233)\n[PASS] test_ownerCallbackCannotReenterLaunch() (gas: 445335)\n[PASS] test_realMainnetLaunchAndLock() (gas: 1530503)\n[PASS] test_rejectsSecondLaunch() (gas: 1164745)\n[PASS] test_reverseCurrencyOrderInitialPrice() (gas: 1293631)\n[PASS] test_selectorMatchesObservedMainnetCalldata() (gas: 3255)\n[PASS] test_strictFirstRejectsExistingTokenWithoutSideEffects() (gas: 116780)\n[PASS] test_taxDecayExactBoundaries() (gas: 1239620)\n[PASS] test_tradeSlippageFailureLeavesFundsUnchanged() (gas: 2385511)\n[PASS] test_unconfiguredProtocolRecipientRejected() (gas: 63255)\n[PASS] test_underlyingOwnerPowersRemainAndAreDocumented() (gas: 1383059)\n[PASS] test_unlockedPositionRollsBackCreation() (gas: 1067055)\n[PASS] test_wrongChain() (gas: 31249)\n[PASS] test_wrongIMDDecimalsRejected() (gas: 62390)\n[PASS] test_wrongImplementationReferenceRejected() (gas: 61715)\n[PASS] test_zeroPrice() (gas: 32970)\nSuite result: ok. 38 passed; 0 failed; 0 skipped; finished in 101.74ms (407.91ms CPU time)\n\nRan 37 tests for test/ERC20TLaunchEdges.t.sol:ERC20TLaunchEdgesTest\n[PASS] testFuzz_anyOtherChainRejected(uint256) (runs: 512, μ: 41791, ~: 41998)\nLogs:\n  Bound result 18446744073709551615\n\n[PASS] testFuzz_deadlineInsideWindowAccepted(uint256) (runs: 512, μ: 1124783, ~: 1124872)\nLogs:\n  Bound result 646\n\n[PASS] testFuzz_deadlineOutsideWindowRejected(uint256,bool) (runs: 512, μ: 37208, ~: 37254)\nLogs:\n  Bound result 1641067361\n\n[PASS] test_constructorRejectsItsOwnAddressAsOwner() (gas: 4787)\n[PASS] test_conversionRouteHookOrSpacingChangeRejected() (gas: 232414)\n[PASS] test_creatorAllocationIsLiquidAndSellable() (gas: 3780601)\n[PASS] test_deadlineAtExactlyThirtyMinutesAccepted() (gas: 1120823)\n[PASS] test_deadlineOneSecondPastThirtyMinutesRejected() (gas: 33317)\n[PASS] test_dependencyCheckIsFreeOfSideEffectsAndPublic() (gas: 55446)\n[PASS] test_launchGasFitsComfortablyInABlock() (gas: 1115328)\n[PASS] test_launchReturnsTheRecordedToken() (gas: 1121316)\n[PASS] test_launchedEventCarriesTheExactReceipt() (gas: 1177355)\n[PASS] test_lookalikeTokenFromAStrangerDoesNotTouchTheAdapter() (gas: 2086429)\n[PASS] test_maxDeadlineRejected() (gas: 33555)\n[PASS] test_notRequiringFirstStillRecordsFirstWhenSlotIsEmpty() (gas: 1136368)\n[PASS] test_observedHolderToHolderTransfersAreRejectedByTheTokenImplementation() (gas: 2606027)\n[PASS] test_ownerCannotMoveOrApproveTheLockedPosition() (gas: 1196672)\n[PASS] test_positionForAnotherPoolRollsBack() (gas: 1072360)\n[PASS] test_positionIdDriftRollsBack() (gas: 1067485)\n[PASS] test_priceJustAboveUpperBoundRejected() (gas: 33071)\n[PASS] test_priceLowerBoundOneWeiLaunches() (gas: 1240299)\n[PASS] test_priceMaxUintRejectedBeforeAnyExternalCall() (gas: 44450)\n[PASS] test_priceUpperBoundOneIMDLaunches() (gas: 1206671)\n[PASS] test_protocolFeeShareChangeRejected() (gas: 66118)\n[PASS] test_quoteTokenNoLongerAnExternalBaseRejected() (gas: 83831)\n[PASS] test_supplyIsBurnableByAnyHolder() (gas: 1213101)\n[PASS] test_tokenConfigIsExactlyTheBrief() (gas: 49857)\n[PASS] test_tokenReportingAnotherFeeRecipientRollsBack() (gas: 1077890)\n[PASS] test_tokenReportingAnotherOwnerRollsBack() (gas: 1050431)\n[PASS] test_tokenReportingAnotherRestingTaxRollsBack() (gas: 1070782)\n[PASS] test_tokenReportingExcessDustRollsBack() (gas: 1078119)\n[PASS] test_tokenReportingInflatedSupplyRollsBack() (gas: 1057366)\n[PASS] test_tokenReportingNotLaunchedRollsBack() (gas: 1048809)\n[PASS] test_tokenReportingSixDecimalsRollsBack() (gas: 1053046)\n[PASS] test_tokenReportingWrongLaunchTaxRollsBack() (gas: 1073263)\n[PASS] test_tokenReportingWrongSymbolRollsBack() (gas: 1056328)\n[PASS] test_zeroDeadlineRejected() (gas: 33001)\nSuite result: ok. 37 passed; 0 failed; 0 skipped; finished in 101.81ms (278.62ms CPU time)\n\nRan 2 tests for test/ERC20TLaunchInvariant.t.sol:ERC20TLaunchInvariantTest\n[PASS]\nERC20TLaunchInvariantTest invariants:\n[PASS] invariant_adapterNeverHoldsValue\n[PASS] invariant_initialPositionStaysLockedWithItsLiquidity\n[PASS] invariant_launchHappensAtMostOnceAndOnlyForTheOwnerWithValidInputs\n[PASS] invariant_ownerAllocationIsExactlyFivePercent\n[PASS] invariant_quoteTokenIsConserved\n[PASS] invariant_statusNeverRestsInLaunching\n[PASS] invariant_supplyIsFixedMinusVoluntaryBurns\n[PASS] invariant_taxFollowsTheDecayScheduleThenTheOwnerSetting\n[PASS] invariant_tradersNeverHoldMoreThanThePoolReleased\n ERC20TLaunchInvariantTest invariants (runs: 48, calls: 1536, reverts: 0)\n\n╭------------------------+----------------+-------+---------+----------╮\n| Contract               | Selector       | Calls | Reverts | Discards |\n+======================================================================+\n| LaunchInvariantHandler | burn           | 227   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | buy            | 195   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | launch         | 231   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | ownerSetTax    | 217   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | sell           | 221   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | transferTokens | 216   | 0       | 0        |\n|------------------------+----------------+-------+---------+----------|\n| LaunchInvariantHandler | warp           | 229   | 0       | 0        |\n╰------------------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 5239\n  Bound result 6597\n  Bound result 1828\n  Bound result 242\n  Bound result 467933\n  Bound result 2195\n  Bound result 4254\n  Bound result 27\n  Bound result 1667\n  Bound result 2729\n  Bound result 5411\n  Bound result 4046\n  Bound result 244\n  Bound result 740\n  Bound result 0\n  Bound result 762\n  Bound result 1999999999999999998\n  Bound result 893\n  Bound result 6013\n  Bound result 144\n  Bound result 2264\n  Bound result 1709364798849435191\n  Bound result 1144\n\n[PASS] test_handlerSequenceExercisesEveryPath() (gas: 4413164)\nLogs:\n  Bound result 540540540540\n  Bound result 100\n  Bound result 540540540540\n  Bound result 100\n  Bound result 540540540540\n  Bound result 100\n  Bound result 540540540540\n  Bound result 100\n  Bound result 3000000000000000000\n  Bound result 2000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 50\n  Bound result 5880\n  Bound result 50\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 454.99ms (455.10ms CPU time)\n\nRan 4 test suites in 458.54ms (758.73ms CPU time): 81 tests passed, 0 failed, 0 skipped (81 total tests)\n","passed":true},{"durationMs":54,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ERC20TLaunch.launch(uint256,uint256,bool)\"],\"files\":{\".gitignore\":5,\"Makefile\":17,\"README.md\":123,\"THIRD_PARTY.md\":14,\"docs/EVIDENCE.md\":69,\"docs/SECURITY_REVIEW.md\":49,\"docs/VALIDATION.md\":29,\"docs/preflight-observation.json\":113,\"foundry.toml\":17,\"package.json\":9,\"remappings.txt\":1,\"site/abi/ERC20TLaunch.json\":705,\"site/app.mjs\":344,\"site/config.mjs\":33,\"site/core.mjs\":114,\"site/deployment.json\":6,\"site/docs.html\":13,\"site/favicon.svg\":1,\"site/fonts/Anton-OFL.txt\":93,\"site/fonts/Anton-Regular.ttf\":1369,\"site/fonts/SpaceGrotesk-OFL.txt\":93,\"site/fonts/SpaceGrotesk.ttf\":1091,\"site/index.html\":77,\"site/style.css\":11,\"site/vendor/ethers.LICENSE.md\":21,\"site/vendor/ethers.min.js\":1,\"src/ERC20TLaunch.sol\":210,\"src/interfaces/IERC20T.sol\":48,\"src/interfaces/IERC20TFactory.sol\":30,\"test/Deployment.t.sol\":45,\"test/ERC20TLaunch.t.sol\":536,\"test/ERC20TLaunchEdges.t.sol\":456,\"test/ERC20TLaunchInvariant.t.sol\":217,\"test/browser/check.mjs\":200,\"test/fixtures/MainnetState.sol\":220,\"test/fixtures/provenance.json\":108,\"test/helpers/LaunchAndTradeProbe.sol\":23,\"test/helpers/LaunchInvariantHandler.sol\":173,\"test/helpers/ReentryProbe.sol\":37,\"test/helpers/SwapHarness.sol\":73,\"test/web/core.test.mjs\":138,\"tools/capture-fixture.mjs\":109,\"tools/export-artifacts.mjs\":7,\"tools/preflight.mjs\":65},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"d3f6cf125d05358b5513fa8f0c0341c9cc8cd33e2a6489ef19d6e56cf5adc2d4","verifiedTreeHash":"f1ae11e2cf2f3568d885b69eda926a5263e69d6e","verifierVersion":"0.1.0+d952fceb"},{"checks":[{"durationMs":26414,"exitCode":0,"name":"build","output":"Compiling 28 files with Solc 0.8.26\nSolc 0.8.26 finished in 26.33s\nCompiler run successful!\n","passed":true},{"durationMs":191,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] test_constructorOnEmptyChainHasExplicitOwner() (gas: 40384)\n[PASS] test_constructorRejectsInfrastructureAsOwner() (gas: 3776)\n[PASS] test_constructorRejectsZeroOwner() (gas: 3798)\n[PASS] test_runtimeBoundedAndHasNoEscapeOpcodes() (gas: 5162817)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 98.37ms (18.04ms CPU time)\n\nRan 38 tests for test/ERC20TLaunch.t.sol:ERC20TLaunchTest\n[PASS] testFuzz_invalidPrices(uint256) (runs: 512, μ: 33698, ~: 33701)\n[PASS] testFuzz_nonOwnerCannotLaunch(address) (runs: 512, μ: 31389, ~: 31389)\n[PASS] testFuzz_pricesConserveSupply(uint256) (runs: 512, μ: 1168771, ~: 1176395)\nLogs:\n  Bound result 18289\n\n[PASS] testFuzz_reverseOrderPricesConserveSupply(uint256) (runs: 512, μ: 1150670, ~: 1158057)\nLogs:\n  Bound result 4987\n\n[PASS] testFuzz_taxDecayNeverUnderflows(uint32) (runs: 512, μ: 1126842, ~: 1126721)\n[PASS] test_actualBuyAndSellAgainstMainnetPoolAndHook() (gas: 2944398)\n[PASS] test_bothCurrencySortOrdersLaunch() (gas: 1116128)\n[PASS] test_cannotSendEtherToLaunch() (gas: 38080)\n[PASS] test_changedFeeConversionPoolRejected() (gas: 95901)\n[PASS] test_deadlineBoundaryAccepted() (gas: 1120624)\n[PASS] test_disabledFeeConversionRouteRejected() (gas: 83809)\n[PASS] test_distantDeadline() (gas: 33275)\n[PASS] test_emptyPositionRollsBackCreation() (gas: 1053438)\n[PASS] test_expiredDeadline() (gas: 33105)\n[PASS] test_factoryFailureRollsBackAndCanRetry() (gas: 1237215)\n[PASS] test_factoryMatchesRequestedConfig() (gas: 1205270)\n[PASS] test_factoryReturningAnEOAFailsAtomically() (gas: 114572)\n[PASS] test_failsClosedIfAnyDependencyChanges() (gas: 610436)\n[PASS] test_firstLaunchOnAnUnusedFactoryState() (gas: 1158629)\n[PASS] test_firstProbeAloneCannotMislabelLaterNonce() (gas: 1011312)\n[PASS] test_initialPriceWithinOneTickSpacingOfRequestedQuotePrice() (gas: 1314548)\n[PASS] test_missingCreatorAllocationRollsBackCreation() (gas: 1031025)\n[PASS] test_onlyOwnerMayLaunch() (gas: 37233)\n[PASS] test_ownerCallbackCannotReenterLaunch() (gas: 445335)\n[PASS] test_realMainnetLaunchAndLock() (gas: 1530503)\n[PASS] test_rejectsSecondLaunch() (gas: 1164745)\n[PASS] test_reverseCurrencyOrderInitialPrice() (gas: 1293631)\n[PASS] test_selectorMatchesObservedMainnetCalldata() (gas: 3255)\n[PASS] test_strictFirstRejectsExistingTokenWithoutSideEffects() (gas: 116780)\n[PASS] test_taxDecayExactBoundaries() (gas: 1239620)\n[PASS] test_tradeSlippageFailureLeavesFundsUnchanged() (gas: 2385511)\n[PASS] test_unconfiguredProtocolRecipientRejected() (gas: 63255)\n[PASS] test_underlyingOwnerPowersRemainAndAreDocumented() (gas: 1383059)\n[PASS] test_unlockedPositionRollsBackCreation() (gas: 1067055)\n[PASS] test_wrongChain() (gas: 31249)\n[PASS] test_wrongIMDDecimalsRejected() (gas: 62390)\n[PASS] test_wrongImplementationReferenceRejected() (gas: 61715)\n[PASS] test_zeroPrice() (gas: 32970)\nSuite result: ok. 38 passed; 0 failed; 0 skipped; finished in 99.80ms (467.15ms CPU time)\n\nRan 2 test suites in 101.51ms (198.17ms CPU time): 42 tests passed, 0 failed, 0 skipped (42 total tests)\n","passed":true},{"durationMs":51,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ERC20TLaunch.launch(uint256,uint256,bool)\"],\"files\":{\".gitignore\":5,\"Makefile\":17,\"README.md\":123,\"THIRD_PARTY.md\":14,\"docs/EVIDENCE.md\":69,\"docs/SECURITY_REVIEW.md\":49,\"docs/VALIDATION.md\":29,\"docs/preflight-observation.json\":113,\"foundry.toml\":17,\"package.json\":9,\"remappings.txt\":1,\"site/abi/ERC20TLaunch.json\":705,\"site/app.mjs\":344,\"site/config.mjs\":33,\"site/core.mjs\":114,\"site/deployment.json\":6,\"site/docs.html\":13,\"site/favicon.svg\":1,\"site/fonts/Anton-OFL.txt\":93,\"site/fonts/Anton-Regular.ttf\":1369,\"site/fonts/SpaceGrotesk-OFL.txt\":93,\"site/fonts/SpaceGrotesk.ttf\":1091,\"site/index.html\":77,\"site/style.css\":11,\"site/vendor/ethers.LICENSE.md\":21,\"site/vendor/ethers.min.js\":1,\"src/ERC20TLaunch.sol\":210,\"src/interfaces/IERC20T.sol\":48,\"src/interfaces/IERC20TFactory.sol\":30,\"test/Deployment.t.sol\":45,\"test/ERC20TLaunch.t.sol\":536,\"test/browser/check.mjs\":200,\"test/fixtures/MainnetState.sol\":220,\"test/fixtures/provenance.json\":108,\"test/helpers/LaunchAndTradeProbe.sol\":23,\"test/helpers/ReentryProbe.sol\":37,\"test/helpers/SwapHarness.sol\":73,\"test/web/core.test.mjs\":138,\"tools/capture-fixture.mjs\":109,\"tools/export-artifacts.mjs\":7,\"tools/preflight.mjs\":65},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":590,"exitCode":0,"name":"slither","output":"[medium/medium] reentrancy-no-eth at src/ERC20TLaunch.sol:115: Reentrancy in ERC20TLaunch.launch(uint256,uint256,bool) (src/ERC20TLaunch.sol#115-146):\n[medium/medium] unused-return at src/ERC20TLaunch.sol:195: ERC20TLaunch._checkPosition(address,uint256) (src/ERC20TLaunch.sol#195-209) ignores return value by (positionKey,None) = pm.getPoolAndPositionInfo(id) (src/ERC20TLaunch.sol#202)\n[low/medium] reentrancy-benign at src/ERC20TLaunch.sol:115: Reentrancy in ERC20TLaunch.launch(uint256,uint256,bool) (src/ERC20TLaunch.sol#115-146):\n[low/medium] reentrancy-events at src/ERC20TLaunch.sol:115: Reentrancy in ERC20TLaunch.launch(uint256,uint256,bool) (src/ERC20TLaunch.sol#115-146):\n[low/medium] timestamp at src/ERC20TLaunch.sol:176: ERC20TLaunch._checkToken(address) (src/ERC20TLaunch.sol#176-193) uses timestamp for comparisons\n[low/medium] timestamp at src/ERC20TLaunch.sol:115: ERC20TLaunch.launch(uint256,uint256,bool) (src/ERC20TLaunch.sol#115-146) uses timestamp for comparisons","passed":true},{"durationMs":263,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/ERC20TLaunch.sol:84: `abi.encodePacked()` Hash Collision\n[high] reentrancy-state-change at src/ERC20TLaunch.sol:131: Reentrancy: State change after external call (2 places)\n[low] large-numeric-literal at src/ERC20TLaunch.sol:24: Large Numeric Literal (3 places)\n[low] literal-instead-of-constant at src/ERC20TLaunch.sol:159: Literal Instead of Constant (4 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"fc4347b09b41bd64d5c43085c726000595772753587a5030411ca524a496b085","verifiedTreeHash":"a7c53d37c63451edfaf4d4ce3888ae8168bfef11","verifierVersion":"0.1.0+d952fceb"}]}