{"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":"3a20ab27-93cc-4752-90d5-c606a3f3a9d1","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"d00b2f3986e76f812b3b6262b29a2d99733c1318843e9dafa6cd1fb4214c1d39","dependsOn":["token_logo","build_website","build_contract_project","write_foundry_tests","manifest"],"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":"5203d7243afda9b56d1b1223343985648f6fe2d0dd30e15386c171f592a61781","dependsOn":["token_logo","build_website","build_contract_project","write_foundry_tests","manifest"],"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":"454b4f5ea5037c210f7cce77a7083a31f8792e51192d086a34cf061b82629541","dependsOn":["token_logo","build_website","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":"b1723952aa787eb855834430c3bdd37ad8486bea3ab16e3bc99f282ba00f0642","dependsOn":["token_logo","build_website","build_contract_project","write_foundry_tests","manifest"],"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":"2927aa28ee83cec17f828c3071a1b3c99bb97bd1cfc1699b9093c58f48a0c074","dependsOn":["token_logo","build_website","build_contract_project","write_foundry_tests","manifest"],"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":"3b5bf290e60e9a4473bf51ef4efea2af466dd81bc6b7574db560b8670e479abf","dependsOn":["build_website"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"d13fcd90215ff428b75f6f349f153e97477d2f9ff8bfb406f7b5320ffb6a8a2e","dependsOn":["token_logo"],"execution":{"mustProduce":["dist/index.html"],"network":true,"optionalTools":["browser"],"profile":"foundry","requires":["network"],"skillHash":"fd6f55db4fafb257d4f31f207e5f234e3b9181141e56bdd273f6c130e64c2d8e","skillId":"build-website","tools":[]},"key":"build_website","kind":"code","role":"implement","skillHash":"fd6f55db4fafb257d4f31f207e5f234e3b9181141e56bdd273f6c130e64c2d8e","skillId":"build-website","state":"accepted"},{"acceptedSubmissionHash":"e5f1eee56b77c1875206610ff1ce8ea6a1f91ee51844ac5dfe25b5b2fe1c31bd","dependsOn":["token_logo","build_website","build_contract_project","write_foundry_tests"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"c12182ae163adcd0047d5abbb8ceb423a84ae20fb75cd66240937c437a101841","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":["tool:image"],"skillHash":"9fa92c5200aa48ce2c9551714aaa720e895a50b88afa3346815752b923cb8378","skillId":"token-logo","tools":["image"]},"key":"token_logo","kind":"code","role":"implement","skillHash":"9fa92c5200aa48ce2c9551714aaa720e895a50b88afa3346815752b923cb8378","skillId":"token-logo","state":"accepted"},{"acceptedSubmissionHash":"e2706d7158a40b426a90c006eafb2aa8b6d7ffeee653dfbcf9b94ea78705d5bc","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"[SIMD-LAUNCH]\nA custom token: Super Fren Pet Test (SFPT).\nToken name: Super Fren Pet Test\nToken symbol: SFPT\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.\nMinting after launch: none, the supply is fixed forever.\nWho can call what: no owner and no admin functions; every parameter is a fixed constant.\n\nWhat it does:\n1. The token SFPT has a fixed supply of 1,000,000,000 units with 18 decimals minted once at deployment.\n2. Exactly 10% of the total supply is allocated to the swarm off-contract; the remaining 90% seeds the Uniswap v4 pool.\n3. The pool fee is fixed at 1.25% with tickSpacing 60 and initialPrice per launchpad requirements.\n4. A creator tax of 2% is applied on every transfer FROM the Uniswap v4 PoolManager at address 0x000000000004444c5dc75cB358380D2e3dE08A90, representing buys.\n5. The 2% tax amount is automatically sent to the immutable treasury wallet 0x900bCC8d58B67fF741c32D0Cd9a28aA1555c8068.\n6. Buyers receive their purchase amount minus the 2% tax.\n7. Transfers TO the PoolManager (including sells or initial pool seed deposits) are exempt from any tax.\n8. Wallet-to-wallet transfers outside the pool are not taxed.\n9. No functionality exists to modify the tax rate or treasury wallet; all parameters are immutable constants.\n10. The token contract has no owner or administrative functions in compliance with SIMD policy.\n\nWho can call what:\n- Anyone can transfer tokens subject to the fixed fees described.\n- No owner or admin functions exist; all parameters and fees are fixed and immutable.\n\nTests:\n1. Verify total supply of 1,000,000,000 tokens minted at deployment.\n2. Confirm 10% of total supply is externally assigned to the swarm distribution, no contract mint or send for that portion.\n3. Test transfer FROM PoolManager deducts exactly 2% and sends it to the fixed wallet.\n4. Test transfer TO PoolManager does not apply tax and settles correctly.\n5. Validate wallet-to-wallet transfers occur tax-free.\n6. Confirm no owner or admin function exists and all constants remain immutable.\n7. Integrate with Uniswap v4 pool at fixed fee 1.25%, tickSpacing 60, and verify no trading anomalies occur.\n8.\n\nMechanics specification (authoritative: where anything above differs, follow these exactly):\nM1. Creator tax (same idea as live launches #1000, #747 and #843): 2% of every buy (transfers FROM the Uniswap v4 PoolManager 0x000000000004444c5dc75cB358380D2e3dE08A90) is sent to the fixed wallet 0x900bCC8d58B67fF741c32D0Cd9a28aA1555c8068, an immutable constant; the buyer receives the amount minus the tax. Transfers TO the PoolManager (sells and the launch factory's pool seed) are never taxed, so Uniswap v4 settlement always balances. Plain wallet-to-wallet transfers pay no tax. No owner can change the rate or the wallet.\n\nBuild requirements (mandatory):\n- Context: an ordinary, legitimate token launch on Ethereum. The coin's name, story and theme are branding only; nothing here is real-world harm or offensive security work.\n- A complete Foundry project at the repository root: foundry.toml with solc 0.8.26, evm_version cancun, optimizer on and bytecode_hash = \"none\", so the build is reproducible and verifiable: deployed contracts live in src/ and every import resolves to a committed file.\n- Token contract: SFPTToken. No selfdestruct and no delegatecall anywhere. No proxies, no owner, no upgradeability.\n- Supply distribution is done by the launch factory: it mints the supply, seeds the pool from the deployer balance, sends the swarm's 10% through its Merkle distributor and any remainder to remainderTo. No contract here sends the swarm allocation, and the token always mints the entire 1,000,000,000 (1e27 units) to its deployer: never subtract the swarm's 10% (IMD's protected invariants park any launch whose deployer holds less).\n- Chain: Ethereum mainnet (set by the order, not a launch.json field). Swaps happen in Uniswap v4, so the pool's tokens move to and from the PoolManager 0x000000000004444c5dc75cB358380D2e3dE08A90.\n- launch.json top-level keys, exactly: kind (\"custom_token\"), token {contract, name, symbol, decimals, constructorArgs, totalSupply}, contracts ([] if none), pool, economics, notes (one string). No chainId or other keys.\n- launch.json pool: pairedCurrency 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7, fee 12500, tickSpacing 60, initialPrice \"125270724187523965593206900\" (paired-currency minor units per SFPT minor unit with SFPT as currency0, provenance only; the deployer derives the real opening price from the economics using the deployed currency order). launch.json also carries the economics block below.\n- launch.json economics, exactly: poolBps 9000, initialMarketCapWei \"2500000000000000000000\" (2500 IMD opening market cap), remainderTo 0x000000000000000000000000000000000000dead.","parentJobId":null,"planHash":"06087da2a9ae85b510693b2fd1476b047b2f0537550d41e92b5b33c6fac1c3e1","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"3a20ab27-93cc-4752-90d5-c606a3f3a9d1","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1273-super-fren-pet-test"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51315","feedbackHash":"975fea2914eda7d8eb2fe3b32f7728cd8df2a1a444fdc0e582f73ee8974256cc","nodeKey":"audit_economics","submissionHash":"d00b2f3986e76f812b3b6262b29a2d99733c1318843e9dafa6cd1fb4214c1d39","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52136","feedbackHash":"8fcb5d2371997cb21218a3d74fced1f96b192e9a733224b1955e6fbc5f515cfe","nodeKey":"audit_flow","submissionHash":"5203d7243afda9b56d1b1223343985648f6fe2d0dd30e15386c171f592a61781","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52482","feedbackHash":"3bf13e217c82bf72f6f0ca16e469984bae27f77056cae291eccf04966a9d2f05","nodeKey":"audit_judge","submissionHash":"454b4f5ea5037c210f7cce77a7083a31f8792e51192d086a34cf061b82629541","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52131","feedbackHash":"c69672e4eee6b47540f59b9db395769d9d6b2e1af09e4fd7ba8753f3b46f566e","nodeKey":"audit_math","submissionHash":"b1723952aa787eb855834430c3bdd37ad8486bea3ab16e3bc99f282ba00f0642","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52255","feedbackHash":"cca2a3fc3fd0320cb6867243aa5d52e2e4b82915ee5517cb0ee6c3ffb13abc01","nodeKey":"audit_permissions","submissionHash":"2927aa28ee83cec17f828c3071a1b3c99bb97bd1cfc1699b9093c58f48a0c074","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51422","feedbackHash":"e7fd9eae32b31c16a6304b0e5f85063e8c501bc2966ecee05e39aa68ada8c1a2","nodeKey":"build_contract_project","submissionHash":"3b5bf290e60e9a4473bf51ef4efea2af466dd81bc6b7574db560b8670e479abf","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51292","feedbackHash":"de98aab00a46e6bdd3d9988486816d30cc511c5e695dcb9e2b1430d1f13fdef2","nodeKey":"build_website","submissionHash":"d13fcd90215ff428b75f6f349f153e97477d2f9ff8bfb406f7b5320ffb6a8a2e","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52375","feedbackHash":"2abd78da1450b1a563fa916535c6d300bc0156084c2e9f8ff8c576ca7cffc3c6","nodeKey":"manifest","submissionHash":"e5f1eee56b77c1875206610ff1ce8ea6a1f91ee51844ac5dfe25b5b2fe1c31bd","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51244","feedbackHash":"6c1eee37ca7fec96f627f58b9a46afe6582cbdcf9d06801448159035d22cc447","nodeKey":"token_logo","submissionHash":"c12182ae163adcd0047d5abbb8ceb423a84ae20fb75cd66240937c437a101841","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52198","feedbackHash":"1f4c4da8e94c64ec58f4a686a14aa66df35a626e72aff33598713182aee5ab5e","nodeKey":"write_foundry_tests","submissionHash":"e2706d7158a40b426a90c006eafb2aa8b6d7ffeee653dfbcf9b94ea78705d5bc","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"055a358fda30da393797c269b724ab6052971dea1f251e6c8d5e7e6e68aa4944","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e06554fd2816f9d7","findings":[{"citation":"resolved","description":"Area: Trust Gap (economics x asymmetry) and Asymmetry (branch pair: PoolManager take path vs PoolManager mint-claims path). The tax is keyed on the ERC20 `from` address, so it only fires when the PoolManager calls SFPTToken.transfer (PoolManager.take). Uniswap v4 also lets a swapper settle a positive delta with PoolManager.mint(to, currency.toId(), amount), which credits an ERC-6909 claim balance inside the PoolManager and moves no ERC20 at all; a later sell can be paid with PoolManager.burn of those claims, again with no ERC20 movement; and claims are freely transferable between accounts with PoolManager.transfer. None of these three steps reaches SFPTToken._update, so the treasury constant at line 13 receives nothing for a buy, a hand-off to another account, or a buy-and-sell roundtrip done entirely in claims. The brief says 'Buyers receive their purchase amount minus the 2% tax' and 'a creator tax of 2% is applied on every buy'; a claims buyer receives 100% of the purchase. The 2% is only collected when SFPT finally leaves the PoolManager as an ERC20, so it behaves as a one-time exit tax rather than a per-buy tax, and active traders (the volume the tax is meant to capture) can avoid it entirely by staying in claims. Who loses: the treasury, 2% of every claims-settled buy. Who gains: any unprivileged swapper using a claims-aware router (the Universal Router and PositionManager both expose ERC-6909 settlement). Note on fixability: a token alone cannot see a claims-settled swap; only a pool hook can, and the launch pool is created by the factory with its own initialization-guard hook, so this is a design limitation of the source-based tax requested in M1 rather than an implementation slip. The accurate remedy within this project's scope is to document in launch.json notes and the site that the tax applies to ERC20 withdrawals from the PoolManager and not to claims-settled swaps, or for the requester to decide whether a hook-based launch is wanted. The mechanics spec M1 defines a buy as 'transfers FROM the PoolManager', so by that letter the code is conformant; reported at low so the requester knows the economic gap exists.","line":22,"path":"src/SFPTToken.sol","reproduction":"State: real vendored v4 PoolManager built at 0x000000000004444c5dc75cB358380D2e3dE08A90, a plain ERC20 fixture etched at the paired currency 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7, SFPTToken deployed, pool (fee 12500, tickSpacing 60) initialised at the brief's price and single-sided seeded with 9e26 SFPT; alice holds 100e18 PAIR and has called PoolManager.setOperator(router, true). Call sequence, all inside one router unlock each: (1) alice swaps exact-input 1e18 PAIR for SFPT; the router settles the PAIR debt with sync/transferFrom/settle and settles the SFPT credit with PoolManager.mint(alice, SFPT.toId(), gross) instead of take. Observed with the brief's price: gross = 392519043447843667743750 SFPT credited as PoolManager.balanceOf(alice, id); SFPTToken.balanceOf(alice) = 0; SFPTToken.balanceOf(TREASURY) = 0. Expected by the brief: treasury +7850380868956873354875 (gross/50) and alice +98%. (2) alice calls PoolManager.transfer(carol, id, gross): carol now holds the whole purchase as claims, treasury still 0; carol hands them back the same way. (3) alice swaps exact-input gross SFPT for PAIR; the router pays the SFPT debt with PoolManager.burn(alice, id, gross) and takes the PAIR. Observed: treasury still 0 after a full buy-and-sell roundtrip; alice paid only the 1.25% LP fee (24838433757150157 PAIR net cost). Control: the same buy settled with PoolManager.take(SFPT, alice, gross) credits treasury exactly gross/50 = 7850380868956873354875 and alice gross - gross/50. Reproduced in a scratch Foundry test (ClaimsRouter implementing IUnlockCallback with mint/burn settlement) against this tree; both the bypass and the control passed as described.","severity":"low","snippet":"        if (from == POOL_MANAGER && to != POOL_MANAGER) {","title":"Buys settled as Uniswap v4 ERC-6909 claims pay no creator tax: the 2% is an exit tax, not a buy tax"}],"hash":"2927aa28ee83cec17f828c3071a1b3c99bb97bd1cfc1699b9093c58f48a0c074","nodeId":"e883a8a3-e7b3-4138-8f86-4fff9a8d852e","outcome":"completed","summary":"The review is complete. The findings file is in place at the repository root, the scratch test is removed, and no tracked file was changed.\n\n**Outcome: one low finding, no permission defects.** The token has no owner, roles, initializer, proxy, receive or fallback. Its whole state-changing surface is the three OpenZeppelin v5 entry points, and every parameter is a compile-time constant. The 2% tax is keyed on the ERC20 source address, so every launch flow the factory performs moves exactly what it says, buyers via the normal `take` path pay exactly floor(amount/50) to the treasury, and partial tax debits roll back atomically. The existing 36 tests pass, including the real-PoolManager seed, buy and sell in both currency orders, and the launch manifest is schema-valid and consistent with the code.\n\n**The finding** is a trust-gap item at the economics and asymmetry seam. Uniswap v4 lets a swapper settle a positive delta as ERC-6909 claims inside the PoolManager instead of an ERC20 `take`, and later pay a sell by burning those claims. Neither step calls the token, so the treasury receives nothing. I reproduced it against the vendored PoolManager at the mandated address with the brief's price and seed.\n\n| Path for a 1 IMD buy | SFPT to treasury |\n| --- | --- |\n| Settled with `take` | 7850380868956873354875 |\n| Settled as ERC-6909 claims, then transferred to another account, then sold from claims | 0 |\n\nI rated it low rather than medium because the mechanics spec defines a buy as a transfer from the PoolManager, so the code conforms to the letter, and a token alone cannot observe a claims-settled swap. The actionable remedy inside this project is documentation. A hook-based launch would be a requester-level design decision.\n\n**Coverage.** All three listed entry points hold. I also recorded rows for the no-privileged-role invariant, the launch-flow conservation invariant, the tax-reaches-treasury invariant (marked finding), and the manifest. Not reached: a live Ethereum fork against the production factory, its initialization-guard hook and the Universal Router, which this offline environment cannot run.","treeHash":null,"usage":{"cachedInputTokens":967812,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":21687,"runtime":"claude","turns":24,"wallClockMs":284311}},{"artifacts":[],"attempt":1,"bundleHash":"ae5824152f6e71c1e7667bc3c7947b24e48638774fc3bf7206699a2ba7e6a9de","device":"1d2eacca0a6e8449","findings":[],"hash":"3b5bf290e60e9a4473bf51ef4efea2af466dd81bc6b7574db560b8670e479abf","nodeId":"6cc5bfab-b342-4efb-b0a9-d631c9e7c660","outcome":"completed","summary":"Completed using the existing compliant token and exact launch manifest. Added two regression tests and clarified deployment responsibilities. Protected configuration and dependencies remain unchanged.\n\nValidation passed:\n- `forge build`\n- `forge test` — 25 tests passed\n- `forge fmt --check`\n\nLocal Uniswap v4 integration passed. Live mainnet and launch-factory hook validation were not run.","treeHash":"1043dfdcc9fca98b62a8a2fd327dc92d9ea031b3","usage":{"cachedInputTokens":743296,"inputTokens":98610,"model":"gpt-6-astra","outputTokens":6558,"runtime":"codex","turns":5,"wallClockMs":145162}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e8e860c7f2306473","findings":[{"citation":"resolved","description":"The token can only observe ERC-20 transfers, and the override taxes exactly the shape from == POOL_MANAGER && to != POOL_MANAGER (i.e. PoolManager.take). Uniswap v4 flash accounting also lets a swapper settle a positive SFPT delta with PoolManager.mint(to, currency.toId(), amount) (lib/v4-core/src/PoolManager.sol:321), which credits ERC-6909 claims inside the manager and moves no ERC-20, and pay a later sell with PoolManager.burn (line 331). Claims are transferable inside the manager (ERC6909.transfer/transferFrom), and multi-hop routes with SFPT as the intermediate currency never leave the manager either. None of these reaches SFPTToken._update, so the treasury receives nothing for such buys; the 2% is only charged once, when SFPT is finally withdrawn as an ERC-20. Mechanics spec M1 is authoritative and literally defines a buy as a transfer FROM the PoolManager, and the code implements that definition exactly; the same source-based design is used by live launches #1000, #747 and #843. The gap is between that mechanism and the headline the site uses ('transparent 2% buy tax', site/index.html lines 13, 46 and 109). launch.json notes and site/docs/index.html line 26 already describe the mechanism precisely ('transfers from PoolManager ... to any other address'; 'It checks whether SFPT leaves the ... PoolManager'). All three specialists reported this same root cause; it reproduces, so it is kept, merged into one, and calibrated to low: no holder loses funds, settlement always balances, the spec-defined rule holds, and the only effect is that treasury revenue is lower than the marketing phrase implies for traders who use claims-aware routers. There is no in-token fix that keeps sells and the factory seed untaxed (the token cannot see claim mints), and the launch pool hook is the factory initialization guard, so the remedy within this repository is documentation: add one sentence to launch.json notes and the site FAQ stating that trades settled as ERC-6909 claims or routed entirely inside the PoolManager are not taxed until SFPT is withdrawn as an ERC-20. Changing the mechanism (a swap hook) would be a change to M1 and is outside this brief.","line":22,"path":"src/SFPTToken.sol","reproduction":"State: vendored v4 PoolManager built in place at 0x000000000004444c5dc75cB358380D2e3dE08A90, plain ERC-20 fixture etched at the paired currency 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7, SFPTToken deployed, pool (fee 12500, tickSpacing 60, initialPrice 125270724187523965593206900 or its reciprocal for the other currency order) single-sided seeded with 9e26 SFPT, treasury balance 0; alice holds 100e18 PAIR and has called PoolManager.setOperator(router, true). Step 1 (buy as claims): alice -> router.swap(exact-in 1e18 PAIR -> SFPT); inside unlockCallback the router calls manager.swap, pays PAIR via sync/transferFrom/settle and settles the positive SFPT delta with manager.mint(alice, SFPT.toId(), gross) instead of manager.take. Observed: gross = 392519043447843667743750; manager.balanceOf(alice, id) == gross; token.balanceOf(MANAGER) unchanged; token.balanceOf(TREASURY) == 0. Expected by the brief headline (2% of every buy): treasury == gross/50 == 7850380868956873354875 and alice 98%. Step 2: alice -> manager.transfer(bob, id, gross): claims move, treasury still 0. Step 3 (sell by burning claims): bob -> router.swap(exact-in gross SFPT -> PAIR) paying the SFPT debt with manager.burn(bob, id, gross). Observed: bob receives 975161566242849843 PAIR, claims consumed, treasury still 0 after a full buy-hold-sell round trip. Control in the same harness: the identical 1e18 buy settled with manager.take(SFPT, alice, gross) credits treasury exactly 7850380868956873354875 and alice 384668662578886794388875. Reproduced during review in test/scratch/ClaimsBypass.t.sol (a ClaimsRouter implementing IUnlockCallback with mint/burn settlement): test_claimsBuyTransferSellPaysNoTax and test_takeBuyPaysTax both pass as described. No proof file is attached: the test demonstrates the gap on the current code and no token-side change that keeps M1 can make a fail-then-pass proof pass.","severity":"low","snippet":"        if (from == POOL_MANAGER && to != POOL_MANAGER) {","title":"Creator tax is keyed on ERC-20 transfers out of the PoolManager, so buys settled as Uniswap v4 ERC-6909 claims (mint/burn) or routed entirely inside the manager pay no tax (merged: audit_economics, au"}],"hash":"454b4f5ea5037c210f7cce77a7083a31f8792e51192d086a34cf061b82629541","nodeId":"31d53a8a-ffbf-4d0a-9f42-fedf44ce584d","outcome":"completed","summary":"The review is complete. The findings file is at `.imd-findings.json` and no other file in the tree was changed.\n\n**Outcome.** The token holds. All three specialists reported the same root cause, which I reproduced and merged into one low-severity finding. I found nothing else in my own pass.\n\n**The one finding (low).** The 2% tax fires only on ERC-20 transfers out of the PoolManager, at `src/SFPTToken.sol:22`. Uniswap v4 lets a buyer settle swap output as ERC-6909 claims through `PoolManager.mint` and pay a later sell by burning them, so SFPT never leaves the manager as an ERC-20 and the treasury receives nothing. My scratch harness showed this with the real vendored PoolManager.\n\n| Settlement of a 1e18 PAIR buy | Gross SFPT | Treasury receives |\n|---|---|---|\n| `take` (ERC-20 out) | 392519043447843667743750 | 7850380868956873354875 |\n| `mint` (claims), then transfer and burn-sell | 392519043447843667743750 | 0 |\n\nI calibrated it to low rather than the specialists' medium because mechanics spec M1 is authoritative and literally defines a buy as a transfer from the PoolManager, which the code implements exactly. No holder loses funds and settlement always balances. The gap is between that mechanism and the site's \"2% buy tax\" headline. No token-side change can close it while keeping sells and the seed untaxed, so the remedy is one documenting sentence in the manifest notes and the site FAQ. I attached no proof file, since a fail-then-pass test cannot exist for a limitation the token cannot fix.\n\n**What I verified myself.**\n- Build and all 36 committed tests pass offline with solc 0.8.26, cancun and no bytecode hash.\n- No gitlinks under lib/, so the verifier's networkless build will find every dependency.\n- The constructor mints exactly 1e27 to msg.sender, there are no admin, mint, burn or upgrade entry points, and the runtime has no delegatecall or selfdestruct.\n- Every launch flow the protected test exercises (seed, swarm share, claims, remainder, sells) moves the full amount, and a take-settled buy pays exactly floor(amount/50) to the treasury.\n- launch.json has exactly the six required keys, lowercase addresses, 886-character notes, and an initialPrice that matches the derived square-root price from the economics.\n\n**Coverage record.** All three ABI entry points are answered, plus six invariant rows. The approve row holds. The transfer and transferFrom rows cite finding 1, since both route through the taxed `_update` path whose scope the finding describes.","treeHash":null,"usage":{"cachedInputTokens":1224925,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":21659,"runtime":"claude","turns":22,"wallClockMs":301970}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"00920b27421b9a80","findings":[{"citation":"resolved","description":"The brief's guarantee is that 2% of every buy reaches the treasury and the buyer receives the amount minus tax; the site docs state the same ('Buying SFPT from the PoolManager incurs a 2% token tax'). The implementation keys the tax on `from == POOL_MANAGER` inside ERC20._update, i.e. on an ERC-20 transfer leaving the PoolManager. Uniswap v4 flash accounting lets a swapper settle a positive SFPT delta without any ERC-20 transfer: PoolManager.mint(to, currencyId, amount) credits ERC-6909 claim tokens instead of calling SFPT.transfer (PoolManager.sol `mint`, `_accountDelta` then `_mint`). Those claims are transferable wallet-to-wallet inside the manager (ERC6909.transfer/transferFrom) and can later pay a sell via PoolManager.burn, again with no SFPT transfer. The same applies to any multi-hop route whose intermediate currency is SFPT (e.g. arbitrage between the launch pool and any other SFPT pool in the manager): the token never sees a transfer and the treasury gets nothing. Any unprivileged trader with a small unlock-callback contract (or any router that offers claim-based settlement) therefore trades SFPT in and out of the pool tax-free; the only moment the 2% is ever charged is when SFPT is withdrawn from the manager as an ERC-20 balance. Treasury revenue from such traders is zero, and claim-holding wallets can buy and sell SFPT exposure without ever paying the creator tax. Note on scope: mechanics spec M1 defines the tax literally as 'transfers FROM the PoolManager', and the code implements that definition exactly; the defect is the gap between that mechanism and the stated 'every buy' guarantee, which is also what the published site promises. There is no token-side fix that keeps sells and seed deposits untaxed (the token cannot observe claim mints or in-manager routing), so this needs a product decision: either (a) accept and document the limitation precisely in launch.json notes and the site/docs ('tax applies when SFPT leaves the PoolManager as an ERC-20 transfer; trades settled as ERC-6909 claims or routed entirely inside the manager are not taxed'), or (b) change the mechanics, which is outside this brief. The existing test suite (test/UniswapV4.t.sol, V4Router) only ever settles with `take`, so this path is untested.","line":22,"path":"src/SFPTToken.sol","reproduction":"State: SFPTToken deployed, launch pool (SFPT/PAIR, fee 12500, tickSpacing 60, initialPrice 125270724187523965593206900) seeded single-sided with 9e26 SFPT; alice holds 1 PAIR and has called PoolManager.setOperator(router, true).\n1. alice -> router.swap(buy 1 PAIR exact-in, claims=true): inside unlockCallback the router calls manager.swap (SFPT delta +gross, e.g. gross = 3.9e23), pays PAIR via sync/transferFrom/settle, and settles the SFPT delta with manager.mint(alice, SFPT.toId(), gross) instead of manager.take.\n   Expected per brief: TREASURY SFPT balance == gross/50 (> 0), buyer receives gross - gross/50.\n   Actual: no SFPT.transfer is executed, SFPTToken._update never runs, TREASURY balance == 0, manager SFPT balance unchanged, alice holds `gross` ERC-6909 claims.\n2. alice -> manager.transfer(bob, SFPT.toId(), gross): claims move to bob, no tax (not even the wallet-to-wallet path runs).\n3. bob -> router.swap(sell gross exact-in, claims=true): router calls manager.burn(bob, SFPT.toId(), gross) to pay the negative SFPT delta and manager.take(PAIR, bob, out). bob receives PAIR > 0.\n   Actual: TREASURY still 0 after a full buy->hold->sell round trip. Contrast: the same buy settled with manager.take pays exactly gross/50 to TREASURY.\nRunnable Foundry test (passes on the current code, proving the bypass; placed at test/scratch/ClaimsBypass.t.sol during review):\n\n// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {SFPTToken} from \"src/SFPTToken.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {IUnlockCallback} from \"v4-core/src/interfaces/callback/IUnlockCallback.sol\";\nimport {IHooks} from \"v4-core/src/interfaces/IHooks.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {BalanceDelta} from \"v4-core/src/types/BalanceDelta.sol\";\nimport {ModifyLiquidityParams, SwapParams} from \"v4-core/src/types/PoolOperation.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {FullMath} from \"v4-core/src/libraries/FullMath.sol\";\n\ncontract PairFixture is ERC20 {\n    constructor() ERC20(\"Test paired currency\", \"PAIR\") {}\n    function mint(address to, uint256 value) external { _mint(to, value); }\n}\n\n/// @dev Router that settles SFPT output as ERC-6909 claims (mint) instead of `take`,\n/// and pays SFPT input by burning claims instead of transferring tokens.\ncontract ClaimsRouter is IUnlockCallback {\n    IPoolManager public immutable manager;\n    struct Op { PoolKey key; address payer; bool liquidity; ModifyLiquidityParams modify; SwapParams swap; bool claims; }\n\n    constructor(IPoolManager m) { manager = m; }\n\n    function modifyLiquidity(PoolKey memory key, int24 lower, int24 upper, int256 liq) external returns (BalanceDelta) {\n        Op memory op;\n        op.key = key; op.payer = msg.sender; op.liquidity = true;\n        op.modify = ModifyLiquidityParams(lower, upper, liq, bytes32(0));\n        return abi.decode(manager.unlock(abi.encode(op)), (BalanceDelta));\n    }\n\n    function swap(PoolKey memory key, bool zeroForOne, int256 amount, bool claims) external returns (BalanceDelta) {\n        Op memory op;\n        op.key = key; op.payer = msg.sender; op.claims = claims;\n        op.swap = SwapParams(zeroForOne, amount, zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1);\n        return abi.decode(manager.unlock(abi.encode(op)), (BalanceDelta));\n    }\n\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        require(msg.sender == address(manager));\n        Op memory op = abi.decode(data, (Op));\n        BalanceDelta delta;\n        if (op.liquidity) (delta,) = manager.modifyLiquidity(op.key, op.modify, \"\");\n        else delta = ma","severity":"medium","snippet":"        if (from == POOL_MANAGER && to != POOL_MANAGER) {\n            // Exactly floor(value * 2 / 100), without a potentially overflowing multiplication.\n            uint256 tax = value / (BPS_DENOMINATOR / BUY_TAX_BPS);\n            if (tax != 0) super._update(from, TREASURY, tax);\n            super._update(from, to, value - tax);\n        } else {\n            super._update(from, to, value);\n        }\n    }","title":"Creator tax is bound to ERC-20 transfers out of the PoolManager, so buys settled as Uniswap v4 ERC-6909 claims (or routed pool-to-pool inside the manager) pay no tax at all"}],"hash":"5203d7243afda9b56d1b1223343985648f6fe2d0dd30e15386c171f592a61781","nodeId":"1828289d-f978-45e8-b0de-e24a8618aad2","outcome":"completed","summary":"The review is complete. `.imd-findings.json` holds one substantiated finding and a seven-row coverage record, and no repository file was changed.\n\n**What I audited.** The token is a 31-line OpenZeppelin v5 ERC-20 override whose only logic is the tax branch in `_update`. I traced all three entry points through the base contract and the real vendored Uniswap v4 PoolManager, ran the existing 36-test suite (all pass, including the invariant campaign), checked the launch manifest against the schema and economics, and confirmed the doc copies under `dist/` and `site/` are byte-identical to the source.\n\n**Finding (medium).** The 2% creator tax fires only on an ERC-20 transfer whose sender is the PoolManager. Uniswap v4 flash accounting lets a buyer settle the SFPT they bought as ERC-6909 claim tokens via `PoolManager.mint` instead of `take`, hand those claims to anyone inside the manager, and later sell by burning them. No SFPT transfer ever happens, so `_update` never runs and the treasury receives nothing for a full buy, hold, sell cycle. Multi-hop routes with SFPT as the intermediate currency behave the same way. I reproduced this with a scratch Foundry test against the real PoolManager at its mainnet address; the claims-settled round trip pays zero tax while the identical buy via `take` pays exactly gross/50. The code matches the literal wording of mechanics spec M1, but not the \"every buy pays 2%\" guarantee the brief and the published site state. There is no token-side fix that keeps sells and seeds untaxed, so I framed it as a product decision: document the limitation precisely, or change the mechanics outside this brief. I did not attach it as a `proof` test because no token change can make it pass.\n\n**What holds.** Approve, transfer and transferFrom behave as intended on every path I traced: tax rounds down and never exceeds value, the tax leg and net leg revert atomically on a short balance, zero-address recipients are rejected before the override runs, PoolManager self-transfers and transfers to the treasury conserve value, allowance is spent on gross, and transfers into the PoolManager arrive whole so v4 sync and settle balance in both currency orders. Supply is minted once to the deployer with no mint, burn, owner, delegatecall or selfdestruct path. The manifest keys, supply, addresses, pool parameters and economics are exact, and the initial price matches the 2500 IMD opening cap.\n\n**Not reached.** A live Ethereum fork against the production factory, hook and router remains owed, as the repository's own test README already notes.","treeHash":null,"usage":{"cachedInputTokens":939603,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":24557,"runtime":"claude","turns":23,"wallClockMs":368171}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"de319b702da6aa2e","findings":[],"hash":"b1723952aa787eb855834430c3bdd37ad8486bea3ab16e3bc99f282ba00f0642","nodeId":"49569e63-b84e-4037-8f23-d2413bef7c20","outcome":"completed","summary":"I found no defects in the math, boundary or numerical-gap areas of `src/SFPTToken.sol`. `.imd-findings.json` has an empty findings list and a coverage row for each entry point.\n\n**Tests:** `forge test` passes all 36 tests, including the invariant suite and the Uniswap v4 tests against a real PoolManager in both currency orders. I couldn't run the protected launch test (`Token.protected.t.sol`) here: it needs the deployer's environment variables and launch support contracts that aren't in this repo. I read how it buys and sells instead.\n\n**What I checked:**\n- **Tax formula:** the tax is `value / (10_000 / 200)`, which is exactly `value / 50` with nothing lost to rounding. It can't overflow because there's no multiplication, and `value - tax` can't underflow. Tax plus what the buyer gets always equals the amount sent, so supply never changes. At the maximum possible amount the call reverts for insufficient balance, not overflow.\n- **Rounding down:** a buy under 50 wei pays no tax, and the tax always rounds down. This is intended, tested by `test_RoundingAtSmallestTaxBoundary`, and stated in the manifest notes. The most anyone can save is under 1 wei per transfer, and each transfer costs far more in gas. I didn't report it.\n- **Exempt paths:** sells, the pool seed, PoolManager-to-itself transfers, wallet-to-wallet, treasury and zero-amount transfers all move the full amount untaxed. The pool's balance accounting therefore always balances. The protected test sells back the trader's actual balance, so the 2% buy tax doesn't break its sell step.\n- **Allowances:** `transferFrom` spends the full amount from the allowance. A failed buy reverts completely, leaving no tax or allowance change behind.\n- **Opening price:** `pool.initialPrice` matches the price implied by the economics (2,500 IMD market cap over 1e27 units) exactly, and it is within the pool's valid range.\n- **Static analysis:** the Aderyn \"large numeric literal\" warning is about style, not correctness. Slither reported nothing.\n\n**What I didn't cover:** none of the three guides was skipped. Their checks for share prices, interest, casts, bit packing, oracles and payable functions don't apply, because the contract has none of those: it is only the token and its tax logic.","treeHash":null,"usage":{"cachedInputTokens":558650,"inputTokens":22,"model":"claude-opus-5-5","outputTokens":7503,"runtime":"claude","turns":11,"wallClockMs":130471}},{"artifacts":[],"attempt":1,"bundleHash":"8fa84eadae3dfecfbe7155c98ef494b39a245c39ba15c899437d6814aba1d8a7","device":"73d25b5e0857cef5","findings":[],"hash":"c12182ae163adcd0047d5abbb8ceb423a84ae20fb75cd66240937c437a101841","nodeId":"f227f499-85d1-4df3-8d2b-1a0811e4c5ee","outcome":"completed","summary":"Delivered five 1024×1024 PNG options in `logos/` and the selected icon at `artifacts/logo.png`.\n\nBuilt-in image generation drew all five drafts; all were retained. Option 2 reads best at 32 pixels. The alternatives’ lettering, rim, or finer details made them less suitable for the launch icon; `logos/README.md` records the review.\n\nAlso completed the SFPT token, manifest, and offline Foundry project. `forge build` and all **23 tests pass**, including Uniswap v4 integration. Live-chain fork validation was not run.","treeHash":"0e1cd07201143434282db4bfd1c6aab9826281ec","usage":{"cachedInputTokens":985344,"inputTokens":90057,"model":"gpt-6-astra","outputTokens":23635,"runtime":"codex","turns":7,"wallClockMs":613887}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e3a598aae0640402","findings":[{"citation":"resolved","description":"Spec M1 promises that 2% of every buy (SFPT leaving the Uniswap v4 PoolManager) goes to the treasury. The token can only observe ERC-20 transfers, and it taxes exactly one shape of them: from == POOL_MANAGER. Uniswap v4's PoolManager offers two standard ways to receive swap output: `take` (ERC-20 transfer out, taxed) and `mint` (credit ERC-6909 claim tokens inside the PoolManager, no ERC-20 transfer). Likewise swap input can be paid by `settle` (ERC-20 transfer in) or by `burn` of claims. A trader who buys SFPT into claims and later sells by burning those claims performs a full economic buy and sell against the pool without SFPT ever leaving the PoolManager as an ERC-20 transfer, so the override at line 22 never fires and the treasury receives 0 instead of 2% of the buy. Claim tokens are also freely transferable inside the PoolManager (ERC6909.transfer/transferFrom), so an untaxed secondary market in claim-wrapped SFPT is possible; tax is only paid once, if ever, when someone finally `take`s. These are ordinary PoolManager entry points that the v4 periphery exposes as router actions (MINT_6909/BURN_6909), so any unprivileged trader with a custom action sequence can use them. Who loses: the treasury, 2% of every buy routed this way; who gains: the trader, who saves the full 2% on round trips and can pass the discount to others via claim transfers. Flow-gap seam: periphery x first-principles. The execution trace is correct, the PoolManager is correct, but the stated guarantee does not hold. Fix tradeoff (scope decision for the requester): the token alone cannot see PoolManager-internal accounting, and the launch factory controls the pool's hook, so there is no in-token fix that preserves the current design. Options are (a) accept and document the limitation explicitly in README, site docs and launch.json notes (today none of them mention claim tokens, and the site advertises a 'transparent 2% buy tax'), or (b) move the tax into a swap hook, which would require a factory/hook change outside this repository. None of the existing tests exercise mint/burn settlement; test/UniswapV4.t.sol only uses take/settle.","line":22,"path":"src/SFPTToken.sol","reproduction":"State: SFPTToken deployed, pool initialized at fee 12500 / tickSpacing 60 with 9e26 SFPT seeded single-sided (as the launch does), PoolManager at 0x000000000004444c5dc75cB358380D2e3dE08A90, treasury balance 0. Trader alice holds 1e18 of the paired currency and has called PoolManager.setOperator(router, true). Call 1 (buy): router.unlock -> PoolManager.swap(key, zeroForOne = pair->SFPT, amountSpecified = -1e18) -> settle the paired-currency debt with sync/transferFrom/settle -> PoolManager.mint(alice, SFPT.toId(), gross) instead of take. Observed: alice's ERC-6909 balance for SFPT == gross (~3.925e23 at the opening price), PoolManager's ERC-20 SFPT balance unchanged, treasury balance unchanged (0). Call 2 (sell): router.unlock -> PoolManager.swap(key, SFPT->pair, amountSpecified = -gross) -> PoolManager.burn(alice, SFPT.toId(), gross) to pay the SFPT debt -> take paired currency to alice. Observed: alice receives paired currency, claims consumed, treasury balance still 0. Expected per spec M1: treasury balance == gross / 50 (~7.85e21) after the buy. Actual: 0. Control in the same test: the identical buy settled with PoolManager.take pays exactly gross / 50 to the treasury and gross - gross / 50 to alice. Run: forge test --match-path test/scratch/ClaimBypass.t.sol ; test_BuyAndSellThroughClaimsPayNoCreatorTax fails with '0 != 7850380868956873354875'.","severity":"medium","snippet":"        if (from == POOL_MANAGER && to != POOL_MANAGER) {\n            // Exactly floor(value * 2 / 100), without a potentially overflowing multiplication.\n            uint256 tax = value / (BPS_DENOMINATOR / BUY_TAX_BPS);\n            if (tax != 0) super._update(from, TREASURY, tax);\n            super._update(from, to, value - tax);","title":"Creator tax is bypassed by settling Uniswap v4 swaps as ERC-6909 claim tokens: buys and sells via mint/burn never move ERC-20 SFPT out of the PoolManager"}],"hash":"d00b2f3986e76f812b3b6262b29a2d99733c1318843e9dafa6cd1fb4214c1d39","nodeId":"fa900a57-1fad-44e3-b3f2-4ce5aefd1cc9","outcome":"completed","summary":"The findings file is in place and the harness deliberately excludes it from git, so the working tree is otherwise untouched. The review is complete.\n\n**Outcome:** one medium finding, no critical or high. The token's arithmetic, conservation, launch flows and manifest all hold.\n\n**Finding 1 (medium): the 2% creator tax can be avoided through Uniswap v4 claim tokens.** The tax lives in the ERC-20 transfer path and fires only when SFPT leaves the PoolManager as an ERC-20 transfer. Uniswap v4 lets a trader receive swap output as ERC-6909 claim tokens inside the PoolManager and pay later swap input by burning them. A buy into claims followed by a sell by burning claims is a full economic round trip that never triggers the override at `src/SFPTToken.sol:22`. I reproduced this against the real vendored PoolManager with the pool seeded as the launch would seed it. The same 1 PAIR buy paid the treasury about 7,850 SFPT via `take` and 0 via `mint`. Claim tokens are also transferable inside the PoolManager, so an untaxed secondary market is possible. The description states plainly that the token alone cannot fix this and the factory controls the hook, so the requester's choice is to document the limitation or move the tax into a swap hook outside this repository. The failing Foundry test is embedded as the proof.\n\n**What holds in the economics area:**\n- Supply conservation and PoolManager balance consistency under the tax split, including failed-transfer atomicity.\n- All launch flows arrive whole, since only transfers originating at the PoolManager are taxed.\n- Seed, buy and sell settle with zero outstanding deltas in both currency orderings.\n- Rounding is floor division by 50 with no overflow; the untaxed sub-50-wei window is dust and not farmable.\n- launch.json has exactly the six required keys, the economics copied verbatim, and an initialPrice that equals the derived sqrtPriceX96 to the digit.\n\n**Documented but not defects:** LP withdrawals, LP fee collection and protocol fee collection from the PoolManager are taxed 2%, consistent with the spec's literal definition of a buy and stated in the README.\n\n**Coverage:** all three entry points have rows, two pointing at the finding and approve marked holds, plus eight invariant rows. Static analysis leads were only a large-literal style note, which I left out.","treeHash":null,"usage":{"cachedInputTokens":1205437,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":25783,"runtime":"claude","turns":37,"wallClockMs":436237}},{"artifacts":[],"attempt":1,"bundleHash":"4fecd242d24c2017418cb66047950b485a4f71cd5c3ac8d0b9f274e8be10374d","device":"ca2eb76d92edd79d","findings":[],"hash":"d13fcd90215ff428b75f6f349f153e97477d2f9ff8bfb406f7b5320ffb6a8a2e","nodeId":"a812b7e8-12fc-4930-b2c6-41ff7b3624ab","outcome":"completed","summary":"Implemented the site in `site/` and production export in `dist/`, including the 3D den, live-data handling, calculator, guide, sharing, docs, and 404.\n\nPassed export, typecheck, browser/accessibility checks, and all 23 Foundry tests. Protected files remain unchanged; submission files fit under 8 MiB.\n\nDesign, validation, and publishing instructions are documented. Live deployment data remains pending.","treeHash":"4f96015f6e537ba90bd26573277ecc3fdf1cea6f","usage":{"cachedInputTokens":4533888,"inputTokens":152478,"model":"gpt-6-astra","outputTokens":64915,"runtime":"codex","turns":9,"wallClockMs":1412692}},{"artifacts":[],"attempt":1,"bundleHash":"bcc7ed213e22078455e011bf81dede9923c4eb5da5304027878f9633e5fd05b8","device":"45733b6bb4e97b16","findings":[],"hash":"e2706d7158a40b426a90c006eafb2aa8b6d7ffeee653dfbcf9b94ea78705d5bc","nodeId":"ee0c0819-d301-43d3-ab73-fc1626d6f18c","outcome":"completed","summary":"Implemented only under `test/`: expanded failure-path tests, stateful balance/allowance invariants, and real local Uniswap v4 swap, fee-collection, and rollback checks.\n\n`forge build` and `forge test` pass: 36 tests, default 256 fuzz runs, and 2,048 invariant calls.\n\nLive mainnet fork testing remains unperformed.","treeHash":"0d60d066af4959e9547f327580f44051f29456d9","usage":{"cachedInputTokens":918144,"inputTokens":81635,"model":"gpt-6-astra","outputTokens":17160,"runtime":"codex","turns":5,"wallClockMs":368028}},{"artifacts":[],"attempt":1,"bundleHash":"2c9efa280ae0711086618f8ff1afc4f3bf802b93ba203448c5e5ebfd8143cac1","device":"0b9c1289a6def0a1","findings":[],"hash":"e5f1eee56b77c1875206610ff1ce8ea6a1f91ee51844ac5dfe25b5b2fe1c31bd","nodeId":"198a919c-cc6e-4e80-b26c-332598c69a3b","outcome":"completed","summary":"Updated [launch.json](/root/.identitymd/work/3a20ab27-93cc-4752-90d5-c606a3f3a9d1/198a919c-cc6e-4e80-b26c-332598c69a3b/launch.json) to accurately describe the accepted token, preserving the required pool and economics values.\n\nManifest and constructor ABI checks passed. `forge build` succeeded; `forge test` passed all 36 tests.\n\nOnly `launch.json` changed outside disposable test scratch files.","treeHash":"cbe36360b389921615a7699a7bb20d21d2ac5b3c","usage":{"cachedInputTokens":225920,"inputTokens":48396,"model":"gpt-6-astra","outputTokens":2716,"runtime":"codex","turns":3,"wallClockMs":72041}}],"verification":[{"checks":[{"durationMs":1583,"exitCode":0,"name":"build","output":"Compiling 75 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.47s\nCompiler run successful!\n","passed":true},{"durationMs":191,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 19 tests for test/SFPTToken.t.sol:SFPTTokenTest\n[PASS] testFuzz_BuyConservesSupplyAndTaxRoundsDown(uint256) (runs: 1000, μ: 167835, ~: 170910)\n[PASS] testFuzz_BuyWalletTransferSellRoundtrip(uint256) (runs: 1000, μ: 291127, ~: 294709)\n[PASS] test_BuySplitsGrossDebitIntoTwoTransferEvents() (gas: 159749)\n[PASS] test_BuySucceedsWhenTreasuryRejectsCalls() (gas: 291194)\n[PASS] test_BuyWithTreasuryAsRecipientConservesFullAmount() (gas: 121049)\n[PASS] test_DeployerHasNoAdministrativeEntryPoints() (gas: 540627)\n[PASS] test_InsufficientGrossBalanceRollsBackTaxAndAllowance() (gas: 202128)\n[PASS] test_ManagerAsSpenderDoesNotTaxWalletTransfer() (gas: 171269)\n[PASS] test_MaximumBuyRevertsWithoutArithmeticOverflowOrBalanceChanges() (gas: 187144)\n[PASS] test_NetOnlyAllowanceCannotPayGrossBuy() (gas: 149071)\n[PASS] test_PoolSelfTransferIsIncomingAndAlwaysExempt() (gas: 98129)\n[PASS] test_RoundingAtSmallestTaxBoundary() (gas: 255229)\n[PASS] test_RuntimeContainsNoForbiddenOpcodes() (gas: 606973)\n[PASS] test_SellViaTransferFromSettlesFullGrossAmount() (gas: 185196)\n[PASS] test_TransferFromUsesSourceAndSpendsGrossAllowance() (gas: 205915)\n[PASS] test_WalletAndTreasuryTransfersAreUntaxed() (gas: 228375)\n[PASS] test_WalletSelfTransferAndZeroBuyPreserveBalances() (gas: 130945)\n[PASS] test_WholeSupplyBelongsToDeployerAndDistributionIsExternal() (gas: 269591)\n[PASS] test_ZeroRecipientCannotBurnOrChargeTax() (gas: 102198)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 97.98ms (192.97ms CPU time)\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Test\n[PASS] testFuzz_RealV4Roundtrip(bool,uint96) (runs: 1000, μ: 1332841, ~: 1328715)\n[PASS] test_ExactOutputBuyQuotesGrossButPaysNet() (gas: 1082990)\n[PASS] test_LiquidityWithdrawalAlsoFollowsSourceBasedTax() (gas: 949472)\n[PASS] test_SeedBuySellWithSFPTAsCurrency0() (gas: 1327566)\n[PASS] test_SeedBuySellWithSFPTAsCurrency1() (gas: 1337759)\n[PASS] test_SlippageMustUseReceivedBalanceAndRevertsAtomically() (gas: 1075347)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 97.95ms (101.96ms CPU time)\n\nRan 2 test suites in 98.64ms (195.94ms CPU time): 25 tests passed, 0 failed, 0 skipped (25 total tests)\n","passed":true},{"durationMs":142,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SFPTToken.approve(address,uint256)\",\"SFPTToken.transfer(address,uint256)\",\"SFPTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":5,\"DESIGN.md\":95,\"README.md\":82,\"VALIDATION.md\":74,\"dist/404.html\":25,\"dist/app.js\":258,\"dist/assets/fonts/DM-Sans-LICENSE.txt\":93,\"dist/assets/fonts/IBM-Plex-Mono-LICENSE.txt\":93,\"dist/assets/fonts/Space-Grotesk-LICENSE.txt\":93,\"dist/assets/fonts/dm-sans.woff2\":139,\"dist/assets/fonts/ibm-plex-mono.woff2\":58,\"dist/assets/fonts/space-grotesk.woff2\":105,\"dist/assets/logo.jpg\":50,\"dist/core.js\":61,\"dist/docs/SFPTToken.sol\":31,\"dist/docs/index.html\":33,\"dist/index.html\":121,\"dist/room.js\":273,\"dist/styles.css\":16,\"dist/vendor/THREE-LICENSE.txt\":21,\"dist/vendor/three.module.min.js\":6,\"foundry.toml\":17,\"launch.json\":24,\"logos/PROMPTS.md\":9,\"logos/README.md\":15,\"logos/logo-1.png\":3099,\"logos/logo-2.png\":2812,\"logos/logo-3.png\":3038,\"logos/logo-4.png\":6054,\"logos/logo-5.png\":4449,\"logos/preview.png\":246,\"site/404.html\":25,\"site/app.js\":258,\"site/assets/fonts/DM-Sans-LICENSE.txt\":93,\"site/assets/fonts/IBM-Plex-Mono-LICENSE.txt\":93,\"site/assets/fonts/Space-Grotesk-LICENSE.txt\":93,\"site/assets/fonts/dm-sans.woff2\":139,\"site/assets/fonts/ibm-plex-mono.woff2\":58,\"site/assets/fonts/space-grotesk.woff2\":105,\"site/assets/logo.jpg\":50,\"site/core.js\":61,\"site/dependencies.lock\":58,\"site/docs/SFPTToken.sol\":31,\"site/docs/index.html\":33,\"site/index.html\":121,\"site/room.js\":273,\"site/styles.css\":16,\"site/vendor/THREE-LICENSE.txt\":21,\"site/vendor/three.module.min.d.ts\":32,\"site/vendor/three.module.min.js\":6,\"src/SFPTToken.sol\":31,\"test/SFPTToken.t.sol\":297,\"test/UniswapV4.t.sol\":201,\"test/support/V4Router.sol\":82,\"tools/build_site.py\":44,\"tools/check_logos.py\":107,\"tools/preview_site.py\":40,\"tools/validate_site.mjs\":197,\"tools/vendor/png.py\":2372,\"tools/vendor/pypng-LICENCE\":21},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"3b5bf290e60e9a4473bf51ef4efea2af466dd81bc6b7574db560b8670e479abf","verifiedTreeHash":"1043dfdcc9fca98b62a8a2fd327dc92d9ea031b3","verifierVersion":"0.1.0+0e08a464"},{"checks":[{"durationMs":2512,"exitCode":0,"name":"build","output":"Compiling 75 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.18s\nCompiler run successful!\n","passed":true},{"durationMs":325,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Test\n[PASS] testFuzz_RealV4Roundtrip(bool,uint96) (runs: 1000, μ: 1333276, ~: 1337914)\n[PASS] test_ExactOutputBuyQuotesGrossButPaysNet() (gas: 1082990)\n[PASS] test_LiquidityWithdrawalAlsoFollowsSourceBasedTax() (gas: 949472)\n[PASS] test_SeedBuySellWithSFPTAsCurrency0() (gas: 1327566)\n[PASS] test_SeedBuySellWithSFPTAsCurrency1() (gas: 1337759)\n[PASS] test_SlippageMustUseReceivedBalanceAndRevertsAtomically() (gas: 1075347)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 175.31ms (176.17ms CPU time)\n\nRan 17 tests for test/SFPTToken.t.sol:SFPTTokenTest\n[PASS] testFuzz_BuyConservesSupplyAndTaxRoundsDown(uint256) (runs: 1000, μ: 168565, ~: 170819)\n[PASS] testFuzz_BuyWalletTransferSellRoundtrip(uint256) (runs: 1000, μ: 291888, ~: 294661)\n[PASS] test_BuySplitsGrossDebitIntoTwoTransferEvents() (gas: 159769)\n[PASS] test_BuyWithTreasuryAsRecipientConservesFullAmount() (gas: 121049)\n[PASS] test_DeployerHasNoAdministrativeEntryPoints() (gas: 540561)\n[PASS] test_InsufficientGrossBalanceRollsBackTaxAndAllowance() (gas: 202128)\n[PASS] test_ManagerAsSpenderDoesNotTaxWalletTransfer() (gas: 171269)\n[PASS] test_NetOnlyAllowanceCannotPayGrossBuy() (gas: 149071)\n[PASS] test_PoolSelfTransferIsIncomingAndAlwaysExempt() (gas: 98129)\n[PASS] test_RoundingAtSmallestTaxBoundary() (gas: 255251)\n[PASS] test_RuntimeContainsNoForbiddenOpcodes() (gas: 606973)\n[PASS] test_SellViaTransferFromSettlesFullGrossAmount() (gas: 185184)\n[PASS] test_TransferFromUsesSourceAndSpendsGrossAllowance() (gas: 205935)\n[PASS] test_WalletAndTreasuryTransfersAreUntaxed() (gas: 228375)\n[PASS] test_WalletSelfTransferAndZeroBuyPreserveBalances() (gas: 130945)\n[PASS] test_WholeSupplyBelongsToDeployerAndDistributionIsExternal() (gas: 269591)\n[PASS] test_ZeroRecipientCannotBurnOrChargeTax() (gas: 102198)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 175.35ms (217.87ms CPU time)\n\nRan 2 test suites in 180.90ms (350.66ms CPU time): 23 tests passed, 0 failed, 0 skipped (23 total tests)\n","passed":true},{"durationMs":174,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SFPTToken.approve(address,uint256)\",\"SFPTToken.transfer(address,uint256)\",\"SFPTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":5,\"README.md\":29,\"foundry.toml\":17,\"launch.json\":24,\"logos/PROMPTS.md\":9,\"logos/README.md\":15,\"logos/logo-1.png\":3099,\"logos/logo-2.png\":2812,\"logos/logo-3.png\":3038,\"logos/logo-4.png\":6054,\"logos/logo-5.png\":4449,\"logos/preview.png\":246,\"src/SFPTToken.sol\":31,\"test/SFPTToken.t.sol\":258,\"test/UniswapV4.t.sol\":201,\"test/support/V4Router.sol\":82,\"tools/check_logos.py\":107,\"tools/vendor/png.py\":2372,\"tools/vendor/pypng-LICENCE\":21},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":1355,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":761,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/SFPTToken.sol:9: Large Numeric Literal (2 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c12182ae163adcd0047d5abbb8ceb423a84ae20fb75cd66240937c437a101841","verifiedTreeHash":"0e1cd07201143434282db4bfd1c6aab9826281ec","verifierVersion":"0.1.0+46c92320"},{"checks":[{"durationMs":1578,"exitCode":0,"name":"build","output":"Compiling 75 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.46s\nCompiler run successful!\n","passed":true},{"durationMs":202,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Test\n[PASS] testFuzz_RealV4Roundtrip(bool,uint96) (runs: 1000, μ: 1332900, ~: 1328715)\n[PASS] test_ExactOutputBuyQuotesGrossButPaysNet() (gas: 1082990)\n[PASS] test_LiquidityWithdrawalAlsoFollowsSourceBasedTax() (gas: 949472)\n[PASS] test_SeedBuySellWithSFPTAsCurrency0() (gas: 1327566)\n[PASS] test_SeedBuySellWithSFPTAsCurrency1() (gas: 1337759)\n[PASS] test_SlippageMustUseReceivedBalanceAndRevertsAtomically() (gas: 1075347)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 109.22ms (113.43ms CPU time)\n\nRan 17 tests for test/SFPTToken.t.sol:SFPTTokenTest\n[PASS] testFuzz_BuyConservesSupplyAndTaxRoundsDown(uint256) (runs: 1000, μ: 168221, ~: 170843)\n[PASS] testFuzz_BuyWalletTransferSellRoundtrip(uint256) (runs: 1000, μ: 291192, ~: 294709)\n[PASS] test_BuySplitsGrossDebitIntoTwoTransferEvents() (gas: 159769)\n[PASS] test_BuyWithTreasuryAsRecipientConservesFullAmount() (gas: 121049)\n[PASS] test_DeployerHasNoAdministrativeEntryPoints() (gas: 540561)\n[PASS] test_InsufficientGrossBalanceRollsBackTaxAndAllowance() (gas: 202128)\n[PASS] test_ManagerAsSpenderDoesNotTaxWalletTransfer() (gas: 171269)\n[PASS] test_NetOnlyAllowanceCannotPayGrossBuy() (gas: 149071)\n[PASS] test_PoolSelfTransferIsIncomingAndAlwaysExempt() (gas: 98129)\n[PASS] test_RoundingAtSmallestTaxBoundary() (gas: 255251)\n[PASS] test_RuntimeContainsNoForbiddenOpcodes() (gas: 606973)\n[PASS] test_SellViaTransferFromSettlesFullGrossAmount() (gas: 185184)\n[PASS] test_TransferFromUsesSourceAndSpendsGrossAllowance() (gas: 205935)\n[PASS] test_WalletAndTreasuryTransfersAreUntaxed() (gas: 228375)\n[PASS] test_WalletSelfTransferAndZeroBuyPreserveBalances() (gas: 130945)\n[PASS] test_WholeSupplyBelongsToDeployerAndDistributionIsExternal() (gas: 269591)\n[PASS] test_ZeroRecipientCannotBurnOrChargeTax() (gas: 102198)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 109.24ms (197.25ms CPU time)\n\nRan 2 test suites in 110.02ms (218.46ms CPU time): 23 tests passed, 0 failed, 0 skipped (23 total tests)\n","passed":true},{"durationMs":124,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SFPTToken.approve(address,uint256)\",\"SFPTToken.transfer(address,uint256)\",\"SFPTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":5,\"DESIGN.md\":95,\"README.md\":77,\"VALIDATION.md\":74,\"dist/404.html\":25,\"dist/app.js\":258,\"dist/assets/fonts/DM-Sans-LICENSE.txt\":93,\"dist/assets/fonts/IBM-Plex-Mono-LICENSE.txt\":93,\"dist/assets/fonts/Space-Grotesk-LICENSE.txt\":93,\"dist/assets/fonts/dm-sans.woff2\":139,\"dist/assets/fonts/ibm-plex-mono.woff2\":58,\"dist/assets/fonts/space-grotesk.woff2\":105,\"dist/assets/logo.jpg\":50,\"dist/core.js\":61,\"dist/docs/SFPTToken.sol\":31,\"dist/docs/index.html\":33,\"dist/index.html\":121,\"dist/room.js\":273,\"dist/styles.css\":16,\"dist/vendor/THREE-LICENSE.txt\":21,\"dist/vendor/three.module.min.js\":6,\"foundry.toml\":17,\"launch.json\":24,\"logos/PROMPTS.md\":9,\"logos/README.md\":15,\"logos/logo-1.png\":3099,\"logos/logo-2.png\":2812,\"logos/logo-3.png\":3038,\"logos/logo-4.png\":6054,\"logos/logo-5.png\":4449,\"logos/preview.png\":246,\"site/404.html\":25,\"site/app.js\":258,\"site/assets/fonts/DM-Sans-LICENSE.txt\":93,\"site/assets/fonts/IBM-Plex-Mono-LICENSE.txt\":93,\"site/assets/fonts/Space-Grotesk-LICENSE.txt\":93,\"site/assets/fonts/dm-sans.woff2\":139,\"site/assets/fonts/ibm-plex-mono.woff2\":58,\"site/assets/fonts/space-grotesk.woff2\":105,\"site/assets/logo.jpg\":50,\"site/core.js\":61,\"site/dependencies.lock\":58,\"site/docs/SFPTToken.sol\":31,\"site/docs/index.html\":33,\"site/index.html\":121,\"site/room.js\":273,\"site/styles.css\":16,\"site/vendor/THREE-LICENSE.txt\":21,\"site/vendor/three.module.min.d.ts\":32,\"site/vendor/three.module.min.js\":6,\"src/SFPTToken.sol\":31,\"test/SFPTToken.t.sol\":258,\"test/UniswapV4.t.sol\":201,\"test/support/V4Router.sol\":82,\"tools/build_site.py\":44,\"tools/check_logos.py\":107,\"tools/preview_site.py\":40,\"tools/validate_site.mjs\":197,\"tools/vendor/png.py\":2372,\"tools/vendor/pypng-LICENCE\":21},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"d13fcd90215ff428b75f6f349f153e97477d2f9ff8bfb406f7b5320ffb6a8a2e","verifiedTreeHash":"4f96015f6e537ba90bd26573277ecc3fdf1cea6f","verifierVersion":"0.1.0+0e08a464"},{"checks":[{"durationMs":2222,"exitCode":0,"name":"build","output":"Compiling 77 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.03s\nCompiler run successful!\n","passed":true},{"durationMs":1169,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 25 tests for test/SFPTToken.t.sol:SFPTTokenTest\n[PASS] testFuzz_BuyConservesSupplyAndTaxRoundsDown(uint256) (runs: 256, μ: 167809, ~: 170956)\n[PASS] testFuzz_BuyWalletTransferSellRoundtrip(uint256) (runs: 256, μ: 290980, ~: 294824)\n[PASS] testFuzz_DelegatedBuyHandlesAliasedRecipients(uint256,uint256,uint8) (runs: 256, μ: 210475, ~: 208302)\n[PASS] testFuzz_FailedBuyCannotLeavePartialTaxCredit(uint256,bool) (runs: 256, μ: 189034, ~: 163435)\n[PASS] testFuzz_ZeroBuyRecipientCannotSpendAllowanceOrBurn(uint256,bool) (runs: 256, μ: 171850, ~: 173714)\n[PASS] test_BuySplitsGrossDebitIntoTwoTransferEvents() (gas: 159829)\n[PASS] test_BuySucceedsWhenTreasuryRejectsCalls() (gas: 291274)\n[PASS] test_BuyWithTreasuryAsRecipientConservesFullAmount() (gas: 121107)\n[PASS] test_ConstructorEmitsOnlyOneMintToItsActualDeployer() (gas: 23516)\n[PASS] test_DeployerHasNoAdministrativeEntryPoints() (gas: 540781)\n[PASS] test_InsufficientGrossBalanceRollsBackTaxAndAllowance() (gas: 202348)\n[PASS] test_ManagerAsSpenderDoesNotTaxWalletTransfer() (gas: 171356)\n[PASS] test_MaximumBuyRevertsWithoutArithmeticOverflowOrBalanceChanges() (gas: 187353)\n[PASS] test_NetOnlyAllowanceCannotPayGrossBuy() (gas: 149221)\n[PASS] test_NoLaunchRoleHasAdministrativePowers() (gas: 1886218)\n[PASS] test_PoolSelfTransferIsIncomingAndAlwaysExempt() (gas: 98187)\n[PASS] test_RoundingAtSmallestTaxBoundary() (gas: 255367)\n[PASS] test_RuntimeContainsNoForbiddenOpcodes() (gas: 606973)\n[PASS] test_SellViaTransferFromSettlesFullGrossAmount() (gas: 185331)\n[PASS] test_SpentBuyAllowanceCannotBeReplayedAndRevocationTakesEffect() (gas: 349944)\n[PASS] test_TransferFromUsesSourceAndSpendsGrossAllowance() (gas: 206094)\n[PASS] test_WalletAndTreasuryTransfersAreUntaxed() (gas: 228491)\n[PASS] test_WalletSelfTransferAndZeroBuyPreserveBalances() (gas: 131032)\n[PASS] test_WholeSupplyBelongsToDeployerAndDistributionIsExternal() (gas: 269924)\n[PASS] test_ZeroRecipientCannotBurnOrChargeTax() (gas: 102256)\nSuite result: ok. 25 passed; 0 failed; 0 skipped; finished in 89.75ms (91.95ms CPU time)\n\nRan 10 tests for test/UniswapV4.t.sol:UniswapV4Test\n[PASS] testFuzz_ExactOutputBuyEnforcesNetMinimumAtOneWei(bool,uint96) (runs: 256, μ: 2048228, ~: 2045051)\n[PASS] testFuzz_FailedPaymentRollsBackSwapAndAllowsRetry(bool,bool,bool) (runs: 256, μ: 2150416, ~: 2133533)\n[PASS] testFuzz_RealV4Roundtrip(bool,uint96) (runs: 256, μ: 1420422, ~: 1416216)\n[PASS] test_ExactOutputBuyQuotesGrossButPaysNet() (gas: 1170444)\n[PASS] test_LiquidityWithdrawalAlsoFollowsSourceBasedTax() (gas: 1054047)\n[PASS] test_PoolFeeCollectionWithSFPTAsCurrency0() (gas: 2388557)\n[PASS] test_PoolFeeCollectionWithSFPTAsCurrency1() (gas: 2398771)\n[PASS] test_SeedBuySellWithSFPTAsCurrency0() (gas: 1415043)\n[PASS] test_SeedBuySellWithSFPTAsCurrency1() (gas: 1425214)\n[PASS] test_SlippageMustUseReceivedBalanceAndRevertsAtomically() (gas: 1162810)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 101.02ms (278.47ms CPU time)\n\nRan 1 test for test/SFPTInvariant.t.sol:SFPTInvariantTest\n[PASS]\nSFPTInvariantTest invariants:\n[PASS] invariant_AllowancesFollowGrossSpendingAndRevertsAreAtomic\n[PASS] invariant_FixedSupplyAndEveryBalanceMatchTheLedger\n[PASS] invariant_LaunchParametersNeverChange\n SFPTInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭-------------+------------------+-------+---------+----------╮\n| Contract    | Selector         | Calls | Reverts | Discards |\n+=============================================================+\n| SFPTHandler | approve          | 387   | 0       | 0        |\n|-------------+------------------+-------+---------+----------|\n| SFPTHandler | approvedTransfer | 384   | 0       | 0        |\n|-------------+------------------+-------+---------+----------|\n| SFPTHandler | rejectedTransfer | 451   | 0       | 0        |\n|-------------+------------------+-------+---------+----------|\n| SFPTHandler | transfer         | 412   | 0       | 0        |\n|-------------+------------------+-------+---------+----------|\n| SFPTHandler | transferFrom     | 414   | 0       | 0        |\n╰-------------+------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.07s (1.07s CPU time)\n\nRan 3 test suites in 1.07s (1.26s CPU time): 36 tests passed, 0 failed, 0 skipped (36 total tests)\n","passed":true},{"durationMs":139,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SFPTToken.approve(address,uint256)\",\"SFPTToken.transfer(address,uint256)\",\"SFPTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":5,\"DESIGN.md\":95,\"README.md\":82,\"VALIDATION.md\":74,\"dist/404.html\":25,\"dist/app.js\":258,\"dist/assets/fonts/DM-Sans-LICENSE.txt\":93,\"dist/assets/fonts/IBM-Plex-Mono-LICENSE.txt\":93,\"dist/assets/fonts/Space-Grotesk-LICENSE.txt\":93,\"dist/assets/fonts/dm-sans.woff2\":139,\"dist/assets/fonts/ibm-plex-mono.woff2\":58,\"dist/assets/fonts/space-grotesk.woff2\":105,\"dist/assets/logo.jpg\":50,\"dist/core.js\":61,\"dist/docs/SFPTToken.sol\":31,\"dist/docs/index.html\":33,\"dist/index.html\":121,\"dist/room.js\":273,\"dist/styles.css\":16,\"dist/vendor/THREE-LICENSE.txt\":21,\"dist/vendor/three.module.min.js\":6,\"foundry.toml\":17,\"launch.json\":24,\"logos/PROMPTS.md\":9,\"logos/README.md\":15,\"logos/logo-1.png\":3099,\"logos/logo-2.png\":2812,\"logos/logo-3.png\":3038,\"logos/logo-4.png\":6054,\"logos/logo-5.png\":4449,\"logos/preview.png\":246,\"site/404.html\":25,\"site/app.js\":258,\"site/assets/fonts/DM-Sans-LICENSE.txt\":93,\"site/assets/fonts/IBM-Plex-Mono-LICENSE.txt\":93,\"site/assets/fonts/Space-Grotesk-LICENSE.txt\":93,\"site/assets/fonts/dm-sans.woff2\":139,\"site/assets/fonts/ibm-plex-mono.woff2\":58,\"site/assets/fonts/space-grotesk.woff2\":105,\"site/assets/logo.jpg\":50,\"site/core.js\":61,\"site/dependencies.lock\":58,\"site/docs/SFPTToken.sol\":31,\"site/docs/index.html\":33,\"site/index.html\":121,\"site/room.js\":273,\"site/styles.css\":16,\"site/vendor/THREE-LICENSE.txt\":21,\"site/vendor/three.module.min.d.ts\":32,\"site/vendor/three.module.min.js\":6,\"src/SFPTToken.sol\":31,\"test/README.md\":29,\"test/SFPTInvariant.t.sol\":63,\"test/SFPTToken.t.sol\":433,\"test/UniswapV4.t.sol\":346,\"test/support/SFPTHandler.sol\":135,\"test/support/V4Router.sol\":82,\"tools/build_site.py\":44,\"tools/check_logos.py\":107,\"tools/preview_site.py\":40,\"tools/validate_site.mjs\":197,\"tools/vendor/png.py\":2372,\"tools/vendor/pypng-LICENCE\":21},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"e2706d7158a40b426a90c006eafb2aa8b6d7ffeee653dfbcf9b94ea78705d5bc","verifiedTreeHash":"0d60d066af4959e9547f327580f44051f29456d9","verifierVersion":"0.1.0+0e08a464"},{"checks":[{"durationMs":2086,"exitCode":0,"name":"build","output":"Compiling 77 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.95s\nCompiler run successful!\n","passed":true},{"durationMs":1034,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 25 tests for test/SFPTToken.t.sol:SFPTTokenTest\n[PASS] testFuzz_BuyConservesSupplyAndTaxRoundsDown(uint256) (runs: 256, μ: 167647, ~: 170968)\n[PASS] testFuzz_BuyWalletTransferSellRoundtrip(uint256) (runs: 256, μ: 290961, ~: 294848)\n[PASS] testFuzz_DelegatedBuyHandlesAliasedRecipients(uint256,uint256,uint8) (runs: 256, μ: 210235, ~: 208404)\n[PASS] testFuzz_FailedBuyCannotLeavePartialTaxCredit(uint256,bool) (runs: 256, μ: 187310, ~: 163435)\n[PASS] testFuzz_ZeroBuyRecipientCannotSpendAllowanceOrBurn(uint256,bool) (runs: 256, μ: 172656, ~: 173714)\n[PASS] test_BuySplitsGrossDebitIntoTwoTransferEvents() (gas: 159829)\n[PASS] test_BuySucceedsWhenTreasuryRejectsCalls() (gas: 291274)\n[PASS] test_BuyWithTreasuryAsRecipientConservesFullAmount() (gas: 121107)\n[PASS] test_ConstructorEmitsOnlyOneMintToItsActualDeployer() (gas: 23516)\n[PASS] test_DeployerHasNoAdministrativeEntryPoints() (gas: 540781)\n[PASS] test_InsufficientGrossBalanceRollsBackTaxAndAllowance() (gas: 202348)\n[PASS] test_ManagerAsSpenderDoesNotTaxWalletTransfer() (gas: 171356)\n[PASS] test_MaximumBuyRevertsWithoutArithmeticOverflowOrBalanceChanges() (gas: 187353)\n[PASS] test_NetOnlyAllowanceCannotPayGrossBuy() (gas: 149221)\n[PASS] test_NoLaunchRoleHasAdministrativePowers() (gas: 1886218)\n[PASS] test_PoolSelfTransferIsIncomingAndAlwaysExempt() (gas: 98187)\n[PASS] test_RoundingAtSmallestTaxBoundary() (gas: 255367)\n[PASS] test_RuntimeContainsNoForbiddenOpcodes() (gas: 606973)\n[PASS] test_SellViaTransferFromSettlesFullGrossAmount() (gas: 185331)\n[PASS] test_SpentBuyAllowanceCannotBeReplayedAndRevocationTakesEffect() (gas: 349944)\n[PASS] test_TransferFromUsesSourceAndSpendsGrossAllowance() (gas: 206094)\n[PASS] test_WalletAndTreasuryTransfersAreUntaxed() (gas: 228491)\n[PASS] test_WalletSelfTransferAndZeroBuyPreserveBalances() (gas: 131032)\n[PASS] test_WholeSupplyBelongsToDeployerAndDistributionIsExternal() (gas: 269924)\n[PASS] test_ZeroRecipientCannotBurnOrChargeTax() (gas: 102256)\nSuite result: ok. 25 passed; 0 failed; 0 skipped; finished in 90.52ms (160.80ms CPU time)\n\nRan 10 tests for test/UniswapV4.t.sol:UniswapV4Test\n[PASS] testFuzz_ExactOutputBuyEnforcesNetMinimumAtOneWei(bool,uint96) (runs: 256, μ: 2048285, ~: 2045051)\n[PASS] testFuzz_FailedPaymentRollsBackSwapAndAllowsRetry(bool,bool,bool) (runs: 256, μ: 2152381, ~: 2158251)\n[PASS] testFuzz_RealV4Roundtrip(bool,uint96) (runs: 256, μ: 1420537, ~: 1416217)\n[PASS] test_ExactOutputBuyQuotesGrossButPaysNet() (gas: 1170444)\n[PASS] test_LiquidityWithdrawalAlsoFollowsSourceBasedTax() (gas: 1054047)\n[PASS] test_PoolFeeCollectionWithSFPTAsCurrency0() (gas: 2388557)\n[PASS] test_PoolFeeCollectionWithSFPTAsCurrency1() (gas: 2398771)\n[PASS] test_SeedBuySellWithSFPTAsCurrency0() (gas: 1415043)\n[PASS] test_SeedBuySellWithSFPTAsCurrency1() (gas: 1425214)\n[PASS] test_SlippageMustUseReceivedBalanceAndRevertsAtomically() (gas: 1162810)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 107.78ms (295.37ms CPU time)\n\nRan 1 test for test/SFPTInvariant.t.sol:SFPTInvariantTest\n[PASS]\nSFPTInvariantTest invariants:\n[PASS] invariant_AllowancesFollowGrossSpendingAndRevertsAreAtomic\n[PASS] invariant_FixedSupplyAndEveryBalanceMatchTheLedger\n[PASS] invariant_LaunchParametersNeverChange\n SFPTInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭-------------+------------------+-------+---------+----------╮\n| Contract    | Selector         | Calls | Reverts | Discards |\n+=============================================================+\n| SFPTHandler | approve          | 419   | 0       | 0        |\n|-------------+------------------+-------+---------+----------|\n| SFPTHandler | approvedTransfer | 414   | 0       | 0        |\n|-------------+------------------+-------+---------+----------|\n| SFPTHandler | rejectedTransfer | 397   | 0       | 0        |\n|-------------+------------------+-------+---------+----------|\n| SFPTHandler | transfer         | 395   | 0       | 0        |\n|-------------+------------------+-------+---------+----------|\n| SFPTHandler | transferFrom     | 423   | 0       | 0        |\n╰-------------+------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 941.25ms (939.42ms CPU time)\n\nRan 3 test suites in 942.67ms (1.14s CPU time): 36 tests passed, 0 failed, 0 skipped (36 total tests)\n","passed":true},{"durationMs":134,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SFPTToken.approve(address,uint256)\",\"SFPTToken.transfer(address,uint256)\",\"SFPTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":5,\"DESIGN.md\":95,\"README.md\":82,\"VALIDATION.md\":74,\"dist/404.html\":25,\"dist/app.js\":258,\"dist/assets/fonts/DM-Sans-LICENSE.txt\":93,\"dist/assets/fonts/IBM-Plex-Mono-LICENSE.txt\":93,\"dist/assets/fonts/Space-Grotesk-LICENSE.txt\":93,\"dist/assets/fonts/dm-sans.woff2\":139,\"dist/assets/fonts/ibm-plex-mono.woff2\":58,\"dist/assets/fonts/space-grotesk.woff2\":105,\"dist/assets/logo.jpg\":50,\"dist/core.js\":61,\"dist/docs/SFPTToken.sol\":31,\"dist/docs/index.html\":33,\"dist/index.html\":121,\"dist/room.js\":273,\"dist/styles.css\":16,\"dist/vendor/THREE-LICENSE.txt\":21,\"dist/vendor/three.module.min.js\":6,\"foundry.toml\":17,\"launch.json\":24,\"logos/PROMPTS.md\":9,\"logos/README.md\":15,\"logos/logo-1.png\":3099,\"logos/logo-2.png\":2812,\"logos/logo-3.png\":3038,\"logos/logo-4.png\":6054,\"logos/logo-5.png\":4449,\"logos/preview.png\":246,\"site/404.html\":25,\"site/app.js\":258,\"site/assets/fonts/DM-Sans-LICENSE.txt\":93,\"site/assets/fonts/IBM-Plex-Mono-LICENSE.txt\":93,\"site/assets/fonts/Space-Grotesk-LICENSE.txt\":93,\"site/assets/fonts/dm-sans.woff2\":139,\"site/assets/fonts/ibm-plex-mono.woff2\":58,\"site/assets/fonts/space-grotesk.woff2\":105,\"site/assets/logo.jpg\":50,\"site/core.js\":61,\"site/dependencies.lock\":58,\"site/docs/SFPTToken.sol\":31,\"site/docs/index.html\":33,\"site/index.html\":121,\"site/room.js\":273,\"site/styles.css\":16,\"site/vendor/THREE-LICENSE.txt\":21,\"site/vendor/three.module.min.d.ts\":32,\"site/vendor/three.module.min.js\":6,\"src/SFPTToken.sol\":31,\"test/README.md\":29,\"test/SFPTInvariant.t.sol\":63,\"test/SFPTToken.t.sol\":433,\"test/UniswapV4.t.sol\":346,\"test/support/SFPTHandler.sol\":135,\"test/support/V4Router.sol\":82,\"tools/build_site.py\":44,\"tools/check_logos.py\":107,\"tools/preview_site.py\":40,\"tools/validate_site.mjs\":197,\"tools/vendor/png.py\":2372,\"tools/vendor/pypng-LICENCE\":21},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"e5f1eee56b77c1875206610ff1ce8ea6a1f91ee51844ac5dfe25b5b2fe1c31bd","verifiedTreeHash":"cbe36360b389921615a7699a7bb20d21d2ac5b3c","verifierVersion":"0.1.0+0e08a464"}]}