{"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":"1c2f094a-ca53-48ad-b80e-c0885e73aecf","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"af61e9bb808837fe2021c5bfb02477c3d8807791d41d94105429bb656e4be4c6","dependsOn":["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":"624f32994c3871ba4501f9315bf04bad715f11291cc1d0f60a3f9d6ebbb75139","dependsOn":["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":"3985b9c38a054ed89c1c1989cbbc40b61680da5a4f35f8f6f1fa2788a52e00e4","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"e3925e656c21dd6cbffdba1449a9c29103837cbc02da2dbd68ab21ca0816f0d3","dependsOn":["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":"0d7f3825b2fd56532b9bbb74397fd3c27dacca61b5d428d89d671046df59d51d","dependsOn":["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":"bd761f76ae1f9176cae950068eec74b71947473b6796ec575440a3b27f4b0c30","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"587567a5ef71546b5973ceaf6ef1dbbd590f49503b5ac9a6973ed86b89584857","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"587567a5ef71546b5973ceaf6ef1dbbd590f49503b5ac9a6973ed86b89584857","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"d2c5ac5ee37baffb1d2645b3b2e48669e1aa7563785c69364fa6c4454c974a46","dependsOn":["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":"fe0e4181c9f9ad5a81a341bc040eef056f5635be932707590ba2f51786fb182d","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: SIMDTEST (SIMDTEST).\nToken name: SIMDTEST\nToken symbol: SIMDTEST\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. Total supply is fixed at 1,000,000,000 SIMDTEST tokens with 18 decimals.\n2. 10% of supply (100,000,000 tokens) is allocated and distributed via the swarm's Merkle distributor off-chain; no contract mints or sends this portion.\n3. 90% of supply (900,000,000 tokens) seeds the Uniswap v4 pool with PoolManager at 0x000000000004444c5dc75cB358380D2e3dE08A90.\n4. A fee of 3% applies only to token buys, defined as transfers FROM the PoolManager; the recipient receives amount minus fee.\n5. The 3% fee tokens are retained in the token contract and accrue as dividends.\n6. Holders except the PoolManager, token contract, and burn address receive pro rata dividends based on their token balances.\n7. Dividends can be claimed any time through the claim() function.\n8. Transfers TO the PoolManager (sells and pool seed) are never taxed to avoid CurrencyNotSettled errors in Uniswap v4 settling.\n9. All wallet-to-wallet transfers are fee-free.\n10. Pool fee for Uniswap v4 is fixed at 1.25% (12500 bps) set in launch configuration (off-contract).\n\nWho can call what:\n- No owner or admin privileges.\n- All parameters (fees, allocations) are immutable constants.\n- Anyone can call claim() to receive accrued dividends.\n\nTests:\n1. Transfer tokens from PoolManager to a wallet: verify 3% fee deduction and dividend accrual in the token contract.\n2. Transfer tokens to PoolManager: verify no fees are charged and balances update correctly.\n3. Wallet-to-wallet transfer: verify no fees and balances update exactly.\n4. Claim dividends from an eligible holder: verify dividends match expected accrual proportion.\n5. Uniswap v4 swap tests on mainnet fork: verify settlement succeeds with no CurrencyNotSettled errors.\n6. Confirm total supply remains constant and the 10% swarm allocation is unminted by contract.\n\nAddresses:\n- PoolManager: 0x000000000004444c5dc75cB358380D2e3dE08A90\n- Paired currency: IMD 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7\n\nSIMD fee splitter rules apply externally: 1% creator fee split 0.5% to $SIMD holders and 0.5% to IMD seat agents.\n\nNo selfdestruct, delegatecall, proxies, or dynamic fees. No owner powers; all logic embedded in the SIMDTESTToken contract.\n\nBuild requirements (mandatory):\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.\n- Token contract: SIMDTESTToken. 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 mints tokens or sends the swarm allocation.\n- Chain: Ethereum mainnet (chainId 1). Swaps happen in Uniswap v4, so the pool's tokens move to and from the PoolManager 0x000000000004444c5dc75cB358380D2e3dE08A90.\n- launch.json pool: pairedCurrency 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7, fee 3000, tickSpacing 60, initialPrice derived from initialMarketCapWei / totalSupply as sqrtPriceX96 with the currencies sorted by address (provenance only; the launch factory sets the real opening price). 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":"664c57b30d2cf3c95c3661f7d3e4346d807e1f73272533dbaf64d3cdf8ae00bf","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"1c2f094a-ca53-48ad-b80e-c0885e73aecf","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-987-simdtest"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52131","feedbackHash":"5d33e0a461187beb46cf21fd050739148ed91172105b6b4fc378b82166dd9f7a","nodeKey":"audit_economics","submissionHash":"af61e9bb808837fe2021c5bfb02477c3d8807791d41d94105429bb656e4be4c6","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52129","feedbackHash":"9fb508ee1b1d0f80239fe1d4f19178a4017d9e017b86ad204c6356212d4a6cc4","nodeKey":"audit_flow","submissionHash":"624f32994c3871ba4501f9315bf04bad715f11291cc1d0f60a3f9d6ebbb75139","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51741","feedbackHash":"8f30eb38425334b78350073ce0ad93923ae13d012c72207366017eb8d44f32c5","nodeKey":"audit_judge","submissionHash":"3985b9c38a054ed89c1c1989cbbc40b61680da5a4f35f8f6f1fa2788a52e00e4","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51375","feedbackHash":"2f88fbb7194a7e18509694399b93401e2d23b06e4b7baec406c9eca08550d7be","nodeKey":"audit_judge","submissionHash":"8afc0ad36aa2a0c97a2973c0f90abd25b34674f3ad7e99525c92c7d4d2ed3f51","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51162","feedbackHash":"e66b2775c4c9746015ce96c48e6a8b7a6b5879707e2185bb054fe9df8ca951e8","nodeKey":"audit_math","submissionHash":"e3925e656c21dd6cbffdba1449a9c29103837cbc02da2dbd68ab21ca0816f0d3","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51232","feedbackHash":"ab21b4e0190681fe6190c6491a6c0df58edc57d09396424c213bb8e7f12759bf","nodeKey":"audit_permissions","submissionHash":"0d7f3825b2fd56532b9bbb74397fd3c27dacca61b5d428d89d671046df59d51d","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52211","feedbackHash":"a1ad351e300aabc59c8f10f0ccf339173afcd7f36651592e32b12a1b5ae6eb46","nodeKey":"build_contract_project","submissionHash":"c655887ccfd191979fa4009d1d6bc5caa0afbb7187fbf2bb38c481e09ff84ab6","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52085","feedbackHash":"15e4a82120afa0849b826244ee73292734b9f73aa654c88e2c69b349c06c6d5d","nodeKey":"build_contract_project","submissionHash":"4d3cb0e832e18cf402a589ccdb66010e6e051692f0d3d2e6d6a136f36c9fa5ec","tag1":"verification:checks","tag2":"acceptance-v2","value":0},{"agentId":"52013","feedbackHash":"d10f420f0f0e0629ebdebbbf3787528f638ad79ecf3b7fd9a1d913441d714586","nodeKey":"build_contract_project","submissionHash":"bd761f76ae1f9176cae950068eec74b71947473b6796ec575440a3b27f4b0c30","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52014","feedbackHash":"988ceba47bb35fd96762b97d8db892f16de319a1015e25337422666b0de742cf","nodeKey":"build_contract_project","submissionHash":"1053fe016c360bc8f85fdfc5ca278266dc00eab712f7afb7ebc83b36391d6fb2","tag1":"verification:checks","tag2":"acceptance-v2","value":0},{"agentId":"51620","feedbackHash":"661fd3cb1a83a35d8588a809d017da02d9ee5965e889b16a4cb0bc8eee72a950","nodeKey":"manifest","submissionHash":"ab1415a0d97781a91243c0fecf8d9193272b90f2593a5e4fbf8cc3a5b61af21e","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51414","feedbackHash":"eed9bc87ef0deb7c501a7550e4b62b10d7ac63ddb7ed2805dc0412a62568356b","nodeKey":"manifest","submissionHash":"d2c5ac5ee37baffb1d2645b3b2e48669e1aa7563785c69364fa6c4454c974a46","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52142","feedbackHash":"c411d474caa32c68d84fe6f19cf1715874a01d5a30c1074605348a37f1b45c21","nodeKey":"write_foundry_tests","submissionHash":"fe0e4181c9f9ad5a81a341bc040eef056f5635be932707590ba2f51786fb182d","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51751","feedbackHash":"72d62753cf59d306c3db4564efc049ac2206225cd68c4f5ab97ecde9b265b99a","nodeKey":"write_foundry_tests","submissionHash":"b9376f9ca4b41cedf4653f62e7c86b122abfdb72a2cd1f17709d7a588dd7cc0c","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"91c3fd329d5e1e0f06b1c4ecbdaab32bbd47abd2a6ec862a72f9a0d43278c2bb","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"a18a0c6087e1362f","findings":[{"citation":"resolved","description":"Area: Asymmetry / Trust Gap (economics x asymmetry). The dividend index pays every non-excluded balance pro rata, and claim() (line 87-88) pays only msg.sender. The exclusion set is the PoolManager, the token itself, 0xdead and address(0). It does not exclude the launch MerkleDistributor, which the factory funds with 100,000,000 SIMDTEST (the swarm's 10%) before the pool is seeded, and which is a contract that only transfers tokens to claimants and has no code path that calls SIMDTESTToken.claim(). At launch the only eligible balance is the distributor's (900M are in the PoolManager, the integer remainder is at 0xdead), so the first buys' 3% fees are credited almost entirely to the distributor, and every later buy keeps crediting whatever the distributor still holds. _accrue() checkpoints credit on every balance change, so when a contributor later claims their swarm tokens the earned dividend stays on the distributor's account (no retroactive entitlement for the claimant). Nobody can trigger claim() for the distributor, so those fee tokens stay in the token contract permanently: they are neither paid to the holders the brief names (item 6) nor to the swarm contributors. The README documents this as a limitation, but the custom-token-launch rules explicitly provide the mechanism to avoid it: constructor args $factory and $launchNumber plus distributorOf(launchNumber) at transfer time, exactly so a token can treat the distributor like the factory and PoolManager. The same lock applies to any router, vault or multisig-less contract that holds SIMDTEST without a claim() call. Minimal fix that preserves the design: take $factory and $launchNumber as constructor args, and treat factory.distributorOf(launchNumber) (and the factory) as dividend-excluded in isDividendExcluded() and eligibleSupply(), so dividends flow only to accounts that can claim them.","line":69,"path":"src/SIMDTESTToken.sol","reproduction":"State: token deployed; factory transfers 100,000,000e18 to a distributor contract D that only exposes transfer-based payouts; factory transfers 900,000,000e18 to POOL_MANAGER (0x000000000004444c5dc75cB358380D2e3dE08A90). Call: vm.prank(POOL_MANAGER); token.transfer(BUYER, 1_000_000e18). Actual: fee = 30_000e18 moves to the token; eligibleSupply() = 100_970_000e18; withdrawableDividendOf(D) = 30_000e18 * 100_000_000 / 100_970_000 ~= 29_711.8e18 (over 100x the buyer's own 288e18 share). Then D.payout(CONTRIBUTOR, 100_000_000e18): withdrawableDividendOf(CONTRIBUTOR) == 0, withdrawableDividendOf(D) unchanged at ~29_711.8e18; vm.prank(CONTRIBUTOR); token.claim() returns 0; balanceOf(token) stays 30_000e18 and totalDividendsClaimed stays 0 with no call that can ever release D's credit. Expected per brief item 6: the 3% fee reaches holders who can claim it (or the distributor is exempt so the fee goes to real holders). Verified with a local Foundry test (test/scratch/DistributorLock.t.sol, not kept) that passes on the current code with exactly these numbers.","severity":"medium","snippet":"    function isDividendExcluded(address account) public view returns (bool) {\n        return account == POOL_MANAGER || account == address(this) || account == BURN_ADDRESS\n            || account == address(0);\n    }","title":"Dividends credited to the MerkleDistributor (and any claim-less contract holder) are locked in the token forever; the distributor is not exempt although the launch framework offers $factory/$launchNum"},{"citation":"resolved","description":"Area: Asymmetry (branch pair take-settled buy vs. claim-settled buy). The fee fires only when an ERC-20 transfer leaves the PoolManager. Uniswap v4 lets a swapper receive output as ERC-6909 claim tokens via PoolManager.mint(to, id, amount) and pay input via PoolManager.burn(from, id, amount); neither touches SIMDTESTToken, so from == POOL_MANAGER never happens. A trader can therefore buy, hold (claims are transferable between accounts inside the manager) and sell SIMDTEST with zero token fee, while a trader using take() pays 3%. Dividends to holders (brief item 5-6) shrink by whatever volume migrates to the claim path. This matches the brief's literal definition of a buy ('transfers FROM the PoolManager') and is noted in the README, and a fix would need a hook or router-level enforcement that the brief forbids, so it is reported as a design-level asymmetry for the author to confirm or accept, not as a code bug. Trust assumption to record: the 3% dividend fee is only collected from flows that physically withdraw tokens from the PoolManager.","line":107,"path":"src/SIMDTESTToken.sol","reproduction":"Local PoolManager built at 0x000000000004444c5dc75cB358380D2e3dE08A90, pool SIMDTEST/IMD fee 3000 tickSpacing 60 seeded single-sided with 900M as the factory does. Inside unlock: swap(pair -> token, exactIn 0.5e18 pair) then manager.mint(self, uint256(uint160(token)), outputAmount) and settle the pair. Actual: PoolManager.balanceOf(self, id) == outputAmount, token.balanceOf(self) == 0, token.totalFeesCollected() == 0, withdrawableDividendOf(DISTRIBUTOR) == 0. Second unlock: manager.burn(self, id, outputAmount), swap(token -> pair, exactIn outputAmount), take(pair). Actual: totalFeesCollected() still 0 and the trader recovers > 99% of the pair spent (only the pool's 0.3% each way). Control: the same 0.5e18 buy settled with take(token, self, out) gives totalFeesCollected() == out * 300 / 10000. Verified with test/scratch/V4Paths.t.sol (test_claimTokenRoundTripPaysNoBuyFee, test_takeBuyPaysFee), not kept.","severity":"low","snippet":"        uint256 fee = from == POOL_MANAGER && to != POOL_MANAGER ? amount * BUY_FEE_BPS / BPS : 0;","title":"Buy fee is bypassed entirely by trading through PoolManager ERC-6909 claims (mint/burn), an untaxed path asymmetric with take()"},{"citation":"resolved","description":"Area: Asymmetry (operation pair add-liquidity vs. remove-liquidity). The pool has no hook restricting liquidity, so anyone may add SIMDTEST liquidity after launch. Adding settles into the PoolManager untaxed (to == POOL_MANAGER). Removing uses take(), an outgoing PoolManager transfer, so 3% of the LP's own principal is diverted to the dividend pool and credited to every other holder as if it were a purchase. The flow is not a buy economically, but the code cannot distinguish it from one. This is consistent with the brief's address-based definition and is described in the README, so it is reported as a user-class asymmetry the author should confirm (and that integration docs should state), not as a code bug. If undesired it cannot be fixed inside the token without a hook; the realistic mitigation is documentation and front-end warnings for LPs.","line":106,"path":"src/SIMDTESTToken.sol","reproduction":"Same local PoolManager fixture as finding 2. An outside holder with `held` SIMDTEST adds single-sided liquidity in [lower, upper] (modifyLiquidity with positive liquidityDelta, salt 'lp'), paying `deposited` tokens via sync/transfer/settle. Actual: totalFeesCollected() unchanged by the deposit. Then modifyLiquidity with -liquidityDelta and take(token, self, out). Actual: totalFeesCollected() increases by out * 300 / 10000 and balanceOf(self) == held - deposited + out - out*300/10000, i.e. the LP lost 3% of its withdrawn principal to dividends. Expected (economically): an LP's own tokens come back whole. Verified with test/scratch/V4Paths.t.sol (test_liquidityRemovalIsTaxedAsABuy), not kept.","severity":"low","snippet":"        // Destination takes precedence: ALL transfers into the manager settle at face value.\n        uint256 fee = from == POOL_MANAGER && to != POOL_MANAGER ? amount * BUY_FEE_BPS / BPS : 0;","title":"Third-party liquidity removal is taxed as a buy: LPs deposit at face value but get back only 97% of their own tokens"}],"hash":"0d7f3825b2fd56532b9bbb74397fd3c27dacca61b5d428d89d671046df59d51d","nodeId":"35a64f1a-f5ad-49f4-bfa8-943897d43cb1","outcome":"completed","summary":"The review is complete. The findings file is written and valid, the scratch tests are removed, and the working tree has no stray files (the findings file is excluded by the repo's own git exclude rules, as the harness expects).\n\n**Outcome.** The token's permission model is sound: no owner, no admin paths, no proxy, and the four entry points guard exactly what they should. The defects I found are all in the dividend eligibility set and in the asymmetry of the PoolManager-based fee rule, which is where the Asymmetry and Trust Gap guides pointed.\n\n**Findings written to `.imd-findings.json`:**\n\n1. **Medium. Dividends credited to the MerkleDistributor are locked forever.** The exclusion set in `isDividendExcluded()` omits the launch distributor, which holds the swarm's 100M tokens and is the only eligible balance at launch. The first buys' fees are credited almost entirely to it, and since `claim()` pays only the caller and the distributor has no claim path, those fee tokens stay in the token contract permanently. Reproduced locally: a 1M-token buy credits the distributor roughly 29,712 tokens that nobody can ever release, and a contributor who later claims from the distributor inherits none of it. The launch framework offers `$factory`, `$launchNumber` and `distributorOf` precisely to exempt it, so a minimal fix exists that keeps the design intact.\n\n2. **Low. ERC-6909 claim path bypasses the 3% fee entirely.** A trader who settles buys with `PoolManager.mint` and sells with `PoolManager.burn` never triggers an outgoing PoolManager transfer. Reproduced on a local PoolManager: a full round trip leaves `totalFeesCollected` at zero, while the same buy via `take` pays 3%. This matches the brief's literal definition of a buy and is noted in the README, so I reported it as a design asymmetry to confirm, not a code bug.\n\n3. **Low. Third-party liquidity removal is taxed as a buy.** Adding liquidity is untaxed, removing it via `take` loses 3% of the LP's own principal to dividends. Reproduced locally. Also consistent with the brief's definition, reported as a user-class asymmetry.\n\n**Coverage.** All four entry points have rows, plus four invariant rows. `approve` and `transferFrom` hold. `claim` and `transfer` carry findings. Dividend solvency, no-retroactive-entitlement, the fixed supply, the absence of privileged paths, and the launch flows all hold. Both aderyn leads were cosmetic and did not reproduce as defects.\n\nNo critical or high findings, so no proof files were attached. forge-std is not vendored in this repo, which would have blocked a conforming proof had one been needed; worth noting for the author.","treeHash":null,"usage":{"cachedInputTokens":806117,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":30231,"runtime":"claude","turns":24,"wallClockMs":419095}},{"artifacts":[],"attempt":2,"bundleHash":"de6418404dac3578e925d71baa9bcd4ac41ea0d374752f5762271ed0e61aa4a5","device":"b5d96cb4e4dd8f0e","findings":[],"hash":"1053fe016c360bc8f85fdfc5ca278266dc00eab712f7afb7ebc83b36391d6fb2","nodeId":"3e4a2f10-6ab7-41d3-9694-c8bb26285e15","outcome":"completed","summary":"Implemented the token, Foundry project, launch manifest, vendored dependencies, tests, and documentation. `launch.json` omits `chainId` and uses the mandatory fee `3000`.\n\nVerified:\n- `forge build` passes.\n- `forge test`: 31 offline tests pass.\n- Five mainnet-fork tests pass.\n- `forge fmt --check` passes.\n\nREADME documents dividend semantics, price provenance, and launch responsibilities.","treeHash":"25cbe16aa9a28822cf0a52fb17307ecb365bb890","usage":{"cachedInputTokens":1279744,"inputTokens":93019,"model":"gpt-6-astra","outputTokens":25102,"runtime":"codex","turns":6,"wallClockMs":1070519}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"523a0aade61e8902","findings":[],"hash":"3985b9c38a054ed89c1c1989cbbc40b61680da5a4f35f8f6f1fa2788a52e00e4","nodeId":"ce408ef1-c619-489c-b2d8-1d25629436d4","outcome":"completed","summary":"Wrote [.imd-findings.json](/home/imd/agents/1571/data/work/1c2f094a-ca53-48ad-b80e-c0885e73aecf/ce408ef1-c619-489c-b2d8-1d25629436d4/.imd-findings.json): no findings; all four entry points marked `holds`.\n\n- Distributor dividend stranding: fixed.\n- New-buyer fee rebate: fixed.\n- Uniswap advisory: reproduced; consistent with the specified transfer-based fee.\n\nBuild succeeded. All 51 existing local tests and both adapted primary-proof tests passed. Four mainnet tests skipped because no RPC was configured; the external protected harness was not run.\n\nNo production files changed.","treeHash":null,"usage":{"cachedInputTokens":939904,"inputTokens":105491,"model":"gpt-6-astra","outputTokens":6547,"runtime":"codex","turns":4,"wallClockMs":219343}},{"artifacts":[],"attempt":1,"bundleHash":"48968aeb5c28265c65051f4a98d53ed52ae44c76edd0d83b7a0e6df1911a8b3f","device":"7ffab1989aa9150f","findings":[],"hash":"4d3cb0e832e18cf402a589ccdb66010e6e051692f0d3d2e6d6a136f36c9fa5ec","nodeId":"3e4a2f10-6ab7-41d3-9694-c8bb26285e15","outcome":"completed","summary":"Implemented the fixed-supply token, 3% buy fee, claimable dividends, launch configuration, vendored dependencies, and documentation.\n\nValidation: `forge build`, `forge test`, and `forge fmt --check` pass. **25 tests passed**; the mainnet fork test remains unverified because RPC requests failed with HTTP 504/429.\n\nThe manifest uses mandatory pool fee `3000`; the conflicting 1.25% description is documented.\n\nSee [README](./README.md) and [verification results](./VERIFICATION.md).","treeHash":"ad2c9462f44666adc6ca61ec8ec3dcd2d094e2f0","usage":{"cachedInputTokens":1496064,"inputTokens":89961,"model":"gpt-6-astra","outputTokens":26924,"runtime":"codex","turns":6,"wallClockMs":809584}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"63c29c49a249ab7e","findings":[{"citation":"resolved","description":"The brief says fee tokens 'accrue as dividends' for holders, and the launch rules say the factory sends 10% of supply (100,000,000 SIMDTEST) to the launch's MerkleDistributor before seeding the pool, with the remainder going to 0xdead. The token takes no constructor arguments ($factory/$launchNumber) and never calls distributorOf(launchNumber), so the distributor is an ordinary eligible holder (isDividendExcluded only names POOL_MANAGER, this, BURN_ADDRESS and address(0); eligibleSupply() at line 75 subtracts only those). At launch the pool holds 900,000,000 (excluded), 0xdead holds the remainder (excluded), and the distributor holds 100,000,000, i.e. essentially the entire eligible supply. _distribute (line 140) therefore credits almost all of every buy fee to the distributor: with a 1,000,000-token first buy the buyer's own 30,000-token fee is split 288.2 tokens to the buyer and 29,711.8 tokens (99.03%) to the distributor. The distributor is the platform's reserved contract; unless it can invoke an arbitrary token's claim() (a generic Merkle distributor cannot), that credit is unreachable. Because _accrue keeps earned credit when balance leaves (line 126-127, documented at line 78), the credit remains with the distributor address even after every contributor claims their tokens, and there is no sweep or redistribution path, so the tokens sit in the contract permanently. The effect persists for the life of the launch in proportion to whatever unclaimed swarm balance the distributor still holds. Impact: the 3% buy fee that the brief promises to holders is mostly not received by any holder; it is a hidden burn that the economics do not state. Fix (needs a scope decision, since it changes constructor arguments): take $factory and $launchNumber as constructor args, and treat IFactory(factory).distributorOf(launchNumber) (and the factory itself) as dividend-excluded in isDividendExcluded/eligibleSupply/_accrue, as the launch rules explicitly allow; or document in launch.json notes that the distributor's share is forfeited.","line":70,"path":"src/SIMDTESTToken.sol","reproduction":"State: fresh SIMDTESTToken; deployer transfers 100_000_000 ether to a distributor contract D (a contract with a transfer-out function but no way to call claim()), and 900_000_000 ether to POOL_MANAGER (0x000000000004444c5dc75cB358380D2e3dE08A90). Call: vm.prank(POOL_MANAGER); token.transfer(BUYER, 1_000_000 ether). Expected (brief items 5-6): the 30_000 ether fee accrues to real holders. Actual: withdrawableDividendOf(BUYER) = 288204417153609983163 (288.2 tokens, 0.96%), withdrawableDividendOf(D) = 29711795582846390016836 (99.03%). Then D.transfer(CONTRIB, 100_000_000 ether): balanceOf(D)=0, withdrawableDividendOf(D) is unchanged at 29711.79e18, withdrawableDividendOf(CONTRIB)=0, and vm.prank(CONTRIB); token.claim() returns 0. After BUYER claims, balanceOf(address(token)) = 30_000e18 - 288.2e18 with no function able to move the rest. Verified with a Foundry test on this tree (test/scratch, not kept).","severity":"medium","snippet":"        return account == POOL_MANAGER || account == address(this) || account == BURN_ADDRESS\n            || account == address(0);","title":"Swarm MerkleDistributor's 10% is dividend-eligible, so ~99% of every early buy fee is credited to an address that cannot call claim() and is stranded in the token forever"},{"citation":"resolved","description":"The fee is keyed purely on from == POOL_MANAGER. Uniswap v4's singleton pays out swap output, liquidity removal and collected LP fees through the same take() -> transfer path, so an LP who removes liquidity (including the factory, if it ever unwinds the seed) receives 97% of what the PoolManager accounts as owed, and exact-output buyers receive 97% of the amount the swap delta reports. This matches the brief's literal definition ('defined as transfers FROM the PoolManager') and the README documents it, so it is recorded as an economic trust assumption rather than a defect. Routers whose minimum-output check reads the swap delta instead of the recipient's balance change will not catch the 3% shortfall.","line":107,"path":"src/SIMDTESTToken.sol","reproduction":"Using the project's local v4 fixture (test/UniswapV4.t.sol): after the single-sided seed, unlock and call manager.modifyLiquidity(key, ModifyLiquidityParams(lower, upper, -int256(uint256(liquidity)), 0), '') then manager.take(tokenCurrency, LP, uint128(delta)). Expected by a generic LP: balanceOf(LP) increases by delta. Actual: balanceOf(LP) increases by delta - floor(delta*300/10000) and balanceOf(address(token)) increases by the fee; the PoolManager settles because its own balance fell by the full delta. Likewise test_ExactOutputBuySettlesGrossButRecipientGetsNet already shows a 100 ether exact-output swap delivering 97 ether.","severity":"info","snippet":"        uint256 fee = from == POOL_MANAGER && to != POOL_MANAGER ? amount * BUY_FEE_BPS / BPS : 0;","title":"Every token transfer out of the PoolManager is taxed 3%, including liquidity withdrawals and the factory's own seeded position, not only swap buys"}],"hash":"624f32994c3871ba4501f9315bf04bad715f11291cc1d0f60a3f9d6ebbb75139","nodeId":"314d9e22-39ad-4bfe-92f1-fd6795149f33","outcome":"completed","summary":"Review complete. The findings file is written and the scratch test is removed; the tree has no tracked changes.\n\n**Outcome.** One medium finding, one informational note, and coverage rows for all four entry points plus four invariants, in `.imd-findings.json`.\n\n**Medium: the swarm distributor's 10% earns dividends nobody can claim.** The token takes no launch addresses and never looks up the distributor, so the MerkleDistributor is an ordinary eligible holder. At launch it holds essentially the entire eligible supply, since the pool and the burn address are excluded. A scratch test on this tree confirmed the split for a first buy of 1,000,000 tokens:\n\n| Recipient of the 30,000-token fee | Credited |\n| --- | --- |\n| Buyer | 288.2 tokens (0.96%) |\n| Distributor | 29,711.8 tokens (99.03%) |\n\nEarned credit stays with an address after its balance leaves, so the distributor keeps that credit even after every contributor claims their tokens. Unless the platform's distributor can call an arbitrary token's claim function, those fee tokens are stranded permanently, and there is no sweep. The brief promises the fee to holders, so this is a broken guarantee rather than a loss to a specific victim. The fix needs a scope decision: accept the factory and launch number as constructor arguments and exclude the distributor, which the launch rules explicitly allow.\n\n**Info: every transfer out of the PoolManager is taxed.** Liquidity removals and exact-output buys deliver 97% of the accounted amount. This matches the brief's literal definition and the README, so it is recorded as a trust assumption.\n\n**What holds.** Allowance handling, atomic reverts, the fee-free sell and seed paths through v4 sync, transfer and settle, supply conservation, dividend solvency, the exclusion predicate being identical in accrual and denominator, and the absence of forbidden opcodes. Overflow in the accrual multiply needs cumulative fees above 2^128 wei, which is unreachable. The price tool and manifest provenance check out. Build and all 41 existing tests pass.\n\n**Not reached.** The real MerkleDistributor and factory source were not available, so the claim that the distributor cannot invoke claim rests on the platform's generic distributor design. The mainnet-fork test file was not run.","treeHash":null,"usage":{"cachedInputTokens":622727,"inputTokens":258,"model":"claude-fable-5-1","outputTokens":23380,"runtime":"claude","turns":25,"wallClockMs":372147}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"24282732aac890f7","findings":[],"hash":"78b193da1a3c388296d9bacad0cd7414b12459a508545b6fe245350063748f35","nodeId":"8f8e5668-0f8e-4e41-b385-3128657cb9aa","outcome":"failed","summary":"could not restore accepted work: accepted work conflicts with a dependency, which plan validation should have prevented: ","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"codex","turns":0,"wallClockMs":493}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f01afe38b46a5f7e","findings":[],"hash":"862ea35475f8d6785d2dd24d58303a5fa030d7bb317de7dc725a7336d0b6bbf8","nodeId":"6e5527fa-b264-49c6-860f-e311a59227a9","outcome":"failed","summary":"could not restore accepted work: accepted work conflicts with a dependency, which plan validation should have prevented: ","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"codex","turns":0,"wallClockMs":210}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"93c37f17670e4d98","findings":[{"citation":"resolved","description":"isDividendExcluded() (line 69-72) and eligibleSupply() (line 75) exclude only the PoolManager, the token itself, 0xdead and address(0). The launch factory forwards 10% of supply (100,000,000 SIMDTEST) to the launch's reserved MerkleDistributor before it seeds the pool and burns the remainder, so right after launch the distributor holds essentially the entire eligible supply (900M sits in the PoolManager and the rounding remainder at 0xdead, both excluded). _distribute() (line 140) splits every buy fee pro rata over eligibleSupply(), so nearly all of each early fee is credited to _magnifiedCredit[distributor]. claim() (line 87-99) pays only msg.sender, and the MerkleDistributor is fixed launch infrastructure whose only token interaction is transferring claims out; it has no path that calls SIMDTESTToken.claim(). By design (line 78, line 126-127) earned credit stays with the address when the balance leaves, so contributors who later claim their swarm tokens inherit none of it. There is no sweep. The result is that the 3% buy fee the brief promises to holders (items 5-7) is mostly a hidden, permanent burn for as long as the distributor holds unclaimed swarm tokens, and the unclaimed part of the seat/contributor allocation keeps earning stranded credit indefinitely. The shipped test test/UniswapV4.t.sol:139 (assertGt(token.withdrawableDividendOf(DISTRIBUTOR), 0)) encodes this behaviour, and README line 112-116 pushes the requirement onto the distributor, which the requester cannot change. The custom-token launch rules provide exactly the mechanism to avoid this: constructor args $factory, $poolManager, $launchNumber and factory.distributorOf(launchNumber) at transfer time. Merged from audit_permissions #1, audit_math #1, audit_flow #1 and audit_economics #1 (same root cause). Minimal fix that preserves the design: take $factory, $poolManager and $launchNumber as constructor arguments (manifest token.constructorArgs), and treat the factory and IFactory(factory).distributorOf(launchNumber) as excluded in isDividendExcluded() and eligibleSupply(). Note that once the distributor is excluded, eligible supply at launch is zero and the first buyer receives its whole fee back under the current post-net snapshot (see finding 2), so fix both together.","line":70,"path":"src/SIMDTESTToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {SIMDTESTToken} from \"src/SIMDTESTToken.sol\";\n\n/// @dev The swarm's MerkleDistributor as the launch supplies it: its only token interaction is\n/// transferring claims out. It has no code path that calls SIMDTESTToken.claim().\ncontract DistributorStub {\n    function release(SIMDTESTToken token, address to, uint256 amount) external {\n        require(token.transfer(to, amount), \"release failed\");\n    }\n}\n\n/// @dev This contract plays the launch factory: it deploys the token (msg.sender in the\n/// constructor), forwards the swarm's 10% to the distributor, seeds the PoolManager and burns the\n/// remainder, exactly in the factory's order. It answers distributorOf(launchNumber) the way\n/// ProjectFactory does, so a fixed token that takes $factory/$poolManager/$launchNumber and looks\n/// the distributor up at transfer time can be exercised here by changing only the deployment line.\ncontract DistributorStrandedTest is Test {\n    address constant POOL_MANAGER = 0x000000000004444c5dc75cB358380D2e3dE08A90;\n    address constant BUYER_A = address(0xB0B);\n    address constant BUYER_B = address(0xB0B2);\n    address constant CONTRIBUTOR = address(0xC0DE);\n    uint64 constant LAUNCH_NUMBER = 1;\n\n    SIMDTESTToken token;\n    DistributorStub distributor;\n\n    function distributorOf(uint64) external view returns (address) {\n        return address(distributor);\n    }\n\n    function setUp() public {\n        distributor = new DistributorStub();\n        // Fixed constructor: pass address(this), POOL_MANAGER and LAUNCH_NUMBER in its argument order.\n        token = new SIMDTESTToken();\n        uint256 supply = token.totalSupply();\n        token.transfer(address(distributor), supply / 10);\n        token.transfer(POOL_MANAGER, supply * 9 / 10);\n        token.transfer(token.BURN_ADDRESS(), token.balanceOf(address(this)));\n    }\n\n    /// @dev Right after launch the distributor holds the entire eligible supply, so the fee of the\n    /// first buy (1,000,000 gross, fee 30,000) is credited ~99% to an address that cannot claim it.\n    function test_noBuyFeeIsCreditedToTheDistributor() public {\n        vm.prank(POOL_MANAGER);\n        token.transfer(BUYER_A, 1_000_000 ether);\n        assertEq(token.totalFeesCollected(), 30_000 ether, \"fee of a 1,000,000 gross buy\");\n        assertEq(\n            token.withdrawableDividendOf(address(distributor)),\n            0,\n            \"buy fee credited to the Merkle distributor, which has no claim() path\"\n        );\n    }\n\n    /// @dev After two buys, the distributor paying out all swarm claims, and every claim-capable\n    /// holder claiming, the fee reserve must be either paid out or still queued for distribution.\n    /// On the current code ~99% of both fees stays in the token with no account able to claim it.\n    function test_feeReserveIsNotStrandedOnceEveryClaimantHasClaimed() public {\n        vm.prank(POOL_MANAGER);\n        token.transfer(BUYER_A, 1_000_000 ether);\n        vm.prank(POOL_MANAGER);\n        token.transfer(BUYER_B, 2_000_000 ether);\n\n        distributor.release(token, CONTRIBUTOR, token.balanceOf(address(distributor)));\n        assertEq(token.balanceOf(address(distributor)), 0);\n\n        vm.prank(BUYER_A);\n        token.claim();\n        vm.prank(BUYER_B);\n        token.claim();\n        vm.prank(CONTRIBUTOR);\n        token.claim();\n\n        uint256 stranded = token.balanceOf(address(token)) - token.queuedDividends();\n        assertLe(stranded, 2, \"fee tokens stranded in the contract with no claimant\");\n    }\n}","reproduction":"State: this test contract deploys the token (so it is the factory / constructor msg.sender), transfers 100_000_000e18 to a DistributorStub contract whose only function forwards tokens, transfers 900_000_000e18 to POOL_MANAGER 0x000000000004444c5dc75cB358380D2e3dE08A90 and the remainder to 0xdead. Call: vm.prank(POOL_MANAGER); token.transfer(BUYER_A, 1_000_000e18). Expected (brief items 5-7): fee 30_000e18 is claimable by holders who can claim; withdrawableDividendOf(distributor) == 0. Actual: totalFeesCollected == 30_000e18, withdrawableDividendOf(distributor) == 29711795582846390016836 (29,711.8 tokens, 99.04% of the fee), withdrawableDividendOf(BUYER_A) == 288.2e18. Second buy vm.prank(POOL_MANAGER); token.transfer(BUYER_B, 2_000_000e18), then distributor forwards its whole 100M to CONTRIBUTOR, then BUYER_A, BUYER_B and CONTRIBUTOR each call claim(): balanceOf(address(token)) - queuedDividends() == 88015167461186687364034 (88,015 of the 90,000 fee tokens) with no account able to claim it; withdrawableDividendOf(CONTRIBUTOR) == 0 and withdrawableDividendOf(distributor) is unchanged. Run: forge test --match-path test/scratch/DistributorStranded.t.sol (both tests fail on this code; both pass on a copy of the token that takes (factory, poolManager, launchNumber) and excludes factory.distributorOf(launchNumber)). The specialist proofs .imd/reads/proofs/Proof_02876c77fb6f.t.sol and Proof_b80f6773e8a4.t.sol were also run and fail here for the same reason (29711795582846390016836 != 0 and 273473108477666362807657 != 0 respectively).","severity":"high","snippet":"        return account == POOL_MANAGER || account == address(this) || account == BURN_ADDRESS","title":"Swarm MerkleDistributor is dividend-eligible, so ~99% of early buy fees are credited to an account that can never call claim() and are stranded in the token forever"},{"citation":"resolved","description":"_transfer() (line 108-112) moves the fee and then the net amount to the buyer before calling _distribute(), and _distribute() divides by eligibleSupply() at that moment, which already includes the buyer's new balance. The buyer therefore receives fee * net / (eligibleBefore + net) of its own fee as a dividend. While eligible supply is small relative to buys, which is the launch state (100M of eligible supply against a 900M pool, and 0 eligible once finding 1 is fixed), large buyers pay far less than the 3% the brief states (item 4) and existing holders receive correspondingly less (items 5-6). The README documents the ordering but the brief does not state that buyers earn on their own fee. A second effect of the same ordering: when a router takes the output to itself and then sweeps it to the user (take to router, then transfer), the rebate is credited to the router's address, which cannot claim, and is stranded as in finding 1. Fix that preserves the design: snapshot eligibleSupply() (or subtract the buyer's net) before updating the index, and keep queuedDividends when no prior holder is eligible. If the author instead intends buyers to earn on their own fee, say so in the brief/launch.json notes. From audit_economics #2; reproduced.","line":140,"path":"src/SIMDTESTToken.sol","reproduction":"State: fresh token; factory (test) transfers 100_000_000e18 to an ordinary wallet HOLDER and 900_000_000e18 to POOL_MANAGER. Call: vm.prank(POOL_MANAGER); token.transfer(WHALE, 400_000_000e18). Expected (brief item 4-6): WHALE bears the 12_000_000e18 fee and it is split among holders as of before the buy, i.e. withdrawableDividendOf(HOLDER) == 12_000_000e18 and withdrawableDividendOf(WHALE) == 0. Actual: totalFeesCollected == 12_000_000e18, balanceOf(WHALE) == 388_000_000e18, withdrawableDividendOf(WHALE) == 9540983606557377049180327 (9,540,983.6 tokens), withdrawableDividendOf(HOLDER) == 2459016393442622950819672; vm.prank(WHALE); token.claim() returns 9540983606557377049180327, so the whale's effective fee is 2,459,016 tokens = 0.61% of the buy. Second case (state after finding 1 is fixed, simulated by HOLDER sending its 100M to 0xdead so eligibleSupply() == 0): vm.prank(POOL_MANAGER); token.transfer(WHALE, 1_000_000e18) gives withdrawableDividendOf(WHALE) == 29999999999999999999999, i.e. the first buyer gets the entire 30,000 fee back minus 1 wei of index dust. Run: forge test --match-path test/scratch/BuyerRebate.t.sol -vv (logs the numbers above).","severity":"medium","snippet":"        magnifiedDividendPerShare += amount * MAGNITUDE / eligible;","title":"Fee is distributed after the buyer's net balance is credited, so a buyer recaptures fee * net / (eligibleBefore + net) of its own 3% fee; the first buyer after launch (once the distributor is excluded"},{"citation":"resolved","description":"The only fee trigger is from == POOL_MANAGER on an ERC-20 transfer. Uniswap v4 lets a swapper settle its positive delta with PoolManager.mint(to, id, amount) (ERC-6909 claim tokens) instead of take(), and pay a later input with PoolManager.burn(); neither touches SIMDTESTToken, so a trader can buy, hold and sell SIMDTEST inside the manager with zero token fee while a trader who uses take() pays 3%. In the other direction, the pool has no hook restricting liquidity, so any LP who adds SIMDTEST liquidity (settled untaxed, to == POOL_MANAGER) and later removes it through take() loses 3% of its own principal to the dividend pool, credited to every other holder as if it were a purchase; the same applies to an exact-output buy, whose recipient gets 97% of the swap delta, and to the factory's own seeded position if it is ever unwound. Both match the brief's literal definition (item 4, 'transfers FROM the PoolManager') and the README documents them, and a fix would need a hook or router-level enforcement that the brief forbids, so this is a design-level trust assumption for the author to confirm and for integration docs to state (routers must check the recipient's balance change, not the swap delta), not a code bug. Merged from audit_permissions #2 and #3 and audit_flow #2 (same root cause).","line":107,"path":"src/SIMDTESTToken.sol","reproduction":"Local PoolManager built at 0x000000000004444c5dc75cB358380D2e3dE08A90 (chainId 1), pool SIMDTEST/pair fee 3000 tickSpacing 60 seeded single-sided with 900M as the factory does, 100M at the distributor, remainder burned. (a) Inside unlock: swap pair -> token exactIn 0.5e18, settle the pair, then manager.mint(self, uint256(uint160(token)), out). Actual: PoolManager.balanceOf(self, id) == out, token.balanceOf(self) == 0, token.totalFeesCollected() == 0, withdrawableDividendOf(distributor) == 0. Second unlock: swap token -> pair exactIn out, manager.burn(self, id, out), take(pair). Actual: totalFeesCollected() still 0 and the trader lost only 0.002995e18 of the 0.5e18 pair spent (the pool's 0.3% each way). Control: the same 0.5e18 buy settled with take(token, self, out) gives totalFeesCollected() == out * 300 / 10000. (b) After a taxed buy, the trader adds single-sided liquidity in [lower, upper] (modifyLiquidity +liquidity/20000, salt 1), paying 44980185324335605180974 tokens via sync/transfer/settle: totalFeesCollected() unchanged. Then modifyLiquidity with -liquidity/20000 and take(token, self, out): totalFeesCollected() increases by out * 300 / 10000 and the LP receives 43630779764605537025544 back, 3% less than it deposited. Run: forge test --match-path test/scratch/V4Paths.t.sol -vv (test_claimTokenRoundTripPaysNoBuyFee, test_liquidityRemovalIsTaxedAsABuy, test_takeBuyPaysFee).","severity":"low","snippet":"        uint256 fee = from == POOL_MANAGER && to != POOL_MANAGER ? amount * BUY_FEE_BPS / BPS : 0;","title":"Fee is keyed on ERC-20 transfers out of the PoolManager, which is neither necessary nor sufficient for a buy: ERC-6909 claim-settled trades pay no fee, while liquidity withdrawals pay 3%"}],"hash":"8afc0ad36aa2a0c97a2973c0f90abd25b34674f3ad7e99525c92c7d4d2ed3f51","nodeId":"ce408ef1-c619-489c-b2d8-1d25629436d4","outcome":"completed","summary":"The review is done. The findings file is written at the repository root, the scratch tests are removed, and no project file was changed.\n\n**Outcome:** three findings survive, merged from the nine specialist reports. The two specialist proofs and my own tests all ran against a build of this tree.\n\n1. **High, distributor stranding** (merged from all four specialists). The dividend exclusion set at `src/SIMDTESTToken.sol:70` omits the swarm's MerkleDistributor, which holds nearly the whole eligible supply right after launch and has no path to call claim(). Reproduced: a 1,000,000-token first buy credits 29,711.8 of its 30,000-token fee to the distributor. After two buys, full swarm payout, and every claimant claiming, 88,015 of 90,000 fee tokens remain in the contract with no claimant. I attached my own proof instead of the specialists', because theirs asserts the buyer receives the whole fee, which would break if the author also fixes finding 2. Mine passes on a locally fixed copy that takes factory, PoolManager and launch number and excludes the distributor.\n\n2. **Medium, buyer self-rebate** (audit_economics). The index update at line 140 divides by eligible supply after the buyer's net balance is credited. Reproduced: a 400M-token buy against 100M eligible gets 9.54M of its 12M fee back, an effective fee of 0.61%. With zero prior eligible supply, which is the launch state once finding 1 is fixed, the first buyer gets the entire fee back minus one wei. I recommended fixing both together.\n\n3. **Low, address-based fee definition** (merged from audit_permissions and audit_flow). Verified on a local v4 PoolManager: a buy and sell settled through ERC-6909 claims pays zero token fee, while an LP removing liquidity receives 3% less than deposited. Both follow the brief's literal definition and need a hook to change, so this is recorded as a trust assumption for the author to confirm.\n\n**Dropped:** the fee rounding-down note. Thirty-three wei per transfer is not a defect.\n\n**Coverage:** all four entry points answered. Transfer and transferFrom point to finding 1. Approve and claim hold. Four invariant rows were added for supply, launch flows, dividend overflow and solvency, and manifest consistency. The manifest will need constructor arguments once finding 1 is fixed.","treeHash":null,"usage":{"cachedInputTokens":899794,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":30695,"runtime":"claude","turns":21,"wallClockMs":428777}},{"artifacts":[],"attempt":1,"bundleHash":"9504d4e4223df686b3f22c87d1c93e02bdb098ecc594a2ecb974f4b153b0e268","device":"7df8c87bdf5d7822","findings":[],"hash":"ab1415a0d97781a91243c0fecf8d9193272b90f2593a5e4fbf8cc3a5b61af21e","nodeId":"8f8e5668-0f8e-4e41-b385-3128657cb9aa","outcome":"completed","summary":"Updated only `launch.json`, preserving the exact supply, constructor arguments, economics, and required pool settings while clarifying behavior and price provenance.\n\nValidation passed: supplied schema, constructor ABI, and `forge build`. `forge test`: **41 passed, 0 failed, 2 skipped**. Mainnet fork suites skipped because no RPC was configured.","treeHash":"1d11d7d11b4cf9109e9fe2d34afdb7c6828186a3","usage":{"cachedInputTokens":317568,"inputTokens":32971,"model":"gpt-6-astra","outputTokens":4359,"runtime":"codex","turns":4,"wallClockMs":138747}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"de319b702da6aa2e","findings":[{"citation":"resolved","description":"isDividendExcluded() excludes only PoolManager, the token, the burn address and address(0). The launch factory sends the swarm's 10% (100,000,000 SIMDTEST) to its reserved MerkleDistributor before seeding the pool. The distributor is therefore an eligible holder and, right after launch, holds almost all eligible supply (everything else is in the PoolManager). Every buy fee is split pro rata over eligibleSupply(), so most early fees are credited to the distributor's _magnifiedCredit. Only msg.sender can claim that credit through claim(), and the factory's MerkleDistributor is a fixed contract that only forwards Merkle claims. It never calls SIMDTESTToken.claim(). When Merkle claimants later receive their tokens, _move() accrues the credit to the distributor first, so claimants inherit none of it. Those tokens stay in the token contract permanently: they are fee revenue meant for holders (spec items 5-7) but go to an account that cannot collect them. README line 114 assumes the distributor 'must support calling claim()', but the distributor is reserved launch infrastructure that the requester cannot change. The custom-token launch rules also say the distributor should be exempt. The shipped test UniswapV4.t.sol:139 asserts withdrawableDividendOf(DISTRIBUTOR) > 0, which encodes the bug. Lenses: periphery (the distributor's fixed interface) x first principles (fees must reach holders who can claim them).","line":70,"path":"src/SIMDTESTToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {SIMDTESTToken} from \"src/SIMDTESTToken.sol\";\n\n/// Stand-in for the factory's MerkleDistributor: it can only forward tokens to Merkle claimants.\n/// It has no way to call SIMDTESTToken.claim(), so anything credited to it is locked forever.\ncontract DistributorStub {\n    function release(SIMDTESTToken token, address to, uint256 amount) external {\n        token.transfer(to, amount);\n    }\n}\n\ncontract DistributorLockTest is Test {\n    address constant MANAGER = 0x000000000004444c5dc75cB358380D2e3dE08A90;\n    address constant BUYER = address(0xB0B);\n\n    function test_BuyFeesMustNotAccrueToTheUnclaimableSwarmDistributor() public {\n        // This test contract plays the launch factory: it receives the full supply.\n        SIMDTESTToken token = new SIMDTESTToken();\n        DistributorStub distributor = new DistributorStub();\n\n        // Launch flow: 10% to the swarm distributor, 90% seeds the PoolManager.\n        token.transfer(address(distributor), 100_000_000 ether);\n        token.transfer(MANAGER, 900_000_000 ether);\n\n        // First buy: 10,000,000 SIMDTEST out of the PoolManager. Fee = 300,000 SIMDTEST.\n        vm.prank(MANAGER);\n        token.transfer(BUYER, 10_000_000 ether);\n        uint256 fee = token.totalFeesCollected();\n        assertEq(fee, 300_000 ether);\n\n        // The distributor cannot call claim(); everything credited to it is permanently locked.\n        uint256 locked = token.withdrawableDividendOf(address(distributor));\n        emit log_named_decimal_uint(\"fee locked on distributor\", locked, 18);\n        emit log_named_decimal_uint(\"fee claimable by buyer\", token.withdrawableDividendOf(BUYER), 18);\n\n        // Merkle claims later move the tokens out, but the credit stays behind on the distributor.\n        distributor.release(token, address(0xC1A1), 100_000_000 ether);\n        assertEq(token.withdrawableDividendOf(address(0xC1A1)), 0);\n\n        // Expected: holder dividends go to holders that can claim them, nothing is stranded.\n        assertEq(token.withdrawableDividendOf(address(distributor)), 0, \"buy fees stranded on distributor\");\n    }\n}","reproduction":"State: the factory (constructor msg.sender) transfers 100,000,000e18 to the distributor, then 900,000,000e18 to PoolManager 0x000000000004444c5dc75cB358380D2e3dE08A90. Call: PoolManager.transfer(buyer, 10,000,000e18), i.e. a buy. Fee = 300,000e18. Actual: withdrawableDividendOf(distributor) = 273,473.108e18 (91.2% of the fee) and the buyer gets 26,526.89e18. The distributor then releases all 100M to a claimant; the claimant's withdrawable is 0 and the distributor's 273,473e18 credit stays, unclaimable forever. Expected: the distributor (and the factory) are excluded like PoolManager, so the fee goes only to holders who can claim. Fix: take $factory and $launchNumber as constructor args and exclude factory.distributorOf(launchNumber) (and the factory) in isDividendExcluded and eligibleSupply. Alternatively, record as excluded the first recipient of a transfer from the constructor's msg.sender (the factory sends the swarm share first).","severity":"high","snippet":"        return account == POOL_MANAGER || account == address(this) || account == BURN_ADDRESS\n            || account == address(0);","title":"Buy-fee dividends accrue to the swarm MerkleDistributor, which can never call claim(); most early fees are permanently locked"},{"citation":"resolved","description":"_transfer() moves the net amount to the buyer before _distribute(), and _distribute() divides by eligibleSupply() at that point, which already includes the buyer's new balance. The buyer therefore gets fee * net / (eligible_before + net) of its own fee back. When eligible supply is small, which is the case from launch until the swarm allocation is claimed (eligible is about 100M against a 900M pool), a large buyer avoids most of the 3% tax that spec item 4 says applies to every buy. The rebate comes out of what existing holders would otherwise receive (spec items 5-6). If finding 1 is fixed by excluding the distributor, eligible supply at launch is 0 and the first buyer recaptures 100% of its own fee (plus any queuedDividends). The README documents the ordering, but it contradicts the stated 3% buy fee paid to holders as dividends.","line":140,"path":"src/SIMDTESTToken.sol","reproduction":"State: 100,000,000e18 at a distributor/holder, 900,000,000e18 in the PoolManager. Call: PoolManager.transfer(whale, 400,000,000e18). Fee = 12,000,000e18; the whale receives 388,000,000e18; then whale.claim() returns 9,540,983.6e18. The whale's net cost is 2,459,016e18 = 0.61% instead of 3%, and pre-existing holders receive 2.46M instead of 12M. Expected: the buyer bears the full 12,000,000e18 fee and it is split among holders as of before the buy. Fix: snapshot eligibleSupply() before crediting the buyer's net (or exclude the buyer's net from the index update), and keep queued fees when no prior holder is eligible.","severity":"medium","snippet":"        magnifiedDividendPerShare += amount * MAGNITUDE / eligible;","title":"Fee is distributed after the buyer's net is credited, so large buyers recapture most of their own 3% buy fee"}],"hash":"af61e9bb808837fe2021c5bfb02477c3d8807791d41d94105429bb656e4be4c6","nodeId":"7975700b-c0cd-417f-97e2-9c1e46412bee","outcome":"completed","summary":"I found two economic defects and wrote them to `.imd-findings.json`. I changed no project files; the scratch tests are deleted.\n\n**1. High: buy-fee dividends get stuck on the swarm's Merkle distributor** (`src/SIMDTESTToken.sol:70`)\n- **Cause:** the token excludes only the PoolManager, itself, the burn address and the zero address from dividends. The distributor holds 100M tokens from launch, so it counts as an ordinary holder.\n- **Effect:** right after launch it holds almost all of the eligible supply, so it is credited with most of each buy fee. It can never call `claim()`, and when it hands tokens to Merkle claimants the credit stays behind on it. Those fees are locked in the token contract for good.\n- **Reproduction:** the first buy is 10,000,000 SIMDTEST out of the PoolManager, so the fee is 300,000. Of that, 273,473 (91%) goes to the distributor and only 26,527 to the buyer. After the distributor releases all its tokens, the claimant can withdraw 0 and the 273,473 stays stranded.\n- **Proof:** the finding includes a Foundry test that fails on the current code for exactly this reason.\n- **Fix:** exclude the distributor and the factory. Either take the factory address and launch number as constructor arguments and look up `distributorOf(launchNumber)`, or treat the factory's first recipient as excluded.\n- **Existing test:** `test/UniswapV4.t.sol:139` currently asserts that the distributor earns dividends, which builds the bug into the suite. It will need updating with the fix.\n\n**2. Medium: large buyers get most of their own 3% fee back** (`src/SIMDTESTToken.sol:140`)\n- **Cause:** the fee is shared out only after the buyer's tokens are counted as eligible.\n- **Reproduction:** a 400,000,000 buy against 100M already eligible pays a 12M fee, then claims 9.54M of it back. The real cost is 0.61% instead of 3%, and the other holders get 2.46M instead of 12M.\n- **Interaction with finding 1:** if the distributor is excluded, nothing is eligible at launch, so the first buyer would get its whole fee back.\n- **Status:** the README describes this ordering as intended, but it contradicts the 3% buy fee paid to holders. No proof test, since only high and critical findings need one.\n\n**Coverage record:**\n- `transfer`, `transferFrom` and `claim()` are marked as findings (#1, with `transfer`/`transferFrom` also hitting #2); `approve` holds.\n- Three invariants hold:\n  - The supply stays fixed.\n  - Claimable dividends never exceed the fee reserve, including overflow bounds.\n  - The PoolManager loses exactly the gross amount on buys and receives exactly the amount sent on sells.\n\n**Other notes:**\n- I ruled out other leads: overflow in the dividend index, shortfalls in v4 settlement, and the PoolManager's flash-accounting route. The two static-analysis items (aderyn, low) have no economic impact, so I left them out.\n- The project doesn't include forge-std. To run the proof I pointed a command-line remapping at a copy already on this machine; the verifier will need forge-std available the same way.\n- The spec's \"1.25% (12500)\" pool fee conflicts with the required `fee 3000` in `launch.json`. I treated the build requirement as authoritative and didn't report it.","treeHash":null,"usage":{"cachedInputTokens":729487,"inputTokens":26,"model":"claude-opus-5-5","outputTokens":17895,"runtime":"claude","turns":13,"wallClockMs":205176}},{"artifacts":[],"attempt":1,"bundleHash":"df19e1734e0e9a8b5bb379f164715075fc2142633cfebdb9ed669cd0255573c2","device":"500cef6ec1073663","findings":[],"hash":"b9376f9ca4b41cedf4653f62e7c86b122abfdb72a2cd1f17709d7a588dd7cc0c","nodeId":"6e5527fa-b264-49c6-860f-e311a59227a9","outcome":"completed","summary":"Added failure-path tests, 1,000-run fuzz tests, independent dividend invariants, and expanded Uniswap v4 coverage under `test/`.\n\nValidation: `forge build` passed; `forge test` reported **41 passed, 0 failed, 2 skipped**, including 20,480 invariant calls.\n\nLive mainnet fork verification remains pending RPC configuration. Setup is documented in [TESTING.md](/root/.identitymd/work/1c2f094a-ca53-48ad-b80e-c0885e73aecf/6e5527fa-b264-49c6-860f-e311a59227a9/test/TESTING.md). No reproducible implementation defects found.","treeHash":"9885d413f65be21fea787242260a8a58a76c0845","usage":{"cachedInputTokens":564864,"inputTokens":65700,"model":"gpt-6-astra","outputTokens":16568,"runtime":"codex","turns":6,"wallClockMs":494577}},{"artifacts":[],"attempt":1,"bundleHash":"45a8d383231d3657df2b136d64dd24989e74eb0e9ba479a82c7d9135a2e5967f","device":"95e219c7eba8a53f","findings":[],"hash":"bd761f76ae1f9176cae950068eec74b71947473b6796ec575440a3b27f4b0c30","nodeId":"3e4a2f10-6ab7-41d3-9694-c8bb26285e15","outcome":"completed","summary":"Fixed both dividend defects: factory/distributor balances are excluded, and buys distribute fees using pre-buy balances, queuing fees when no eligible holder exists.\n\nUpdated the manifest, documentation, regression tests, and `.imd-responses.json`. Recorded the advisory as intended transfer-tax behavior.\n\nPassed `forge build`, `forge test`, formatting and manifest checks, plus all 12 mainnet-fork integration tests.","treeHash":"33e45e618ff5b4427fded27c73ade2a0361b630c","usage":{"cachedInputTokens":1015424,"inputTokens":80723,"model":"gpt-6-astra","outputTokens":16173,"runtime":"codex","turns":6,"wallClockMs":725712}},{"artifacts":[],"attempt":3,"bundleHash":"badfae909e49976f5659a4657b2abfdc7e3f54c1a08a998066bf286c608682d4","device":"26d42bb29b53b9d8","findings":[],"hash":"c655887ccfd191979fa4009d1d6bc5caa0afbb7187fbf2bb38c481e09ff84ab6","nodeId":"3e4a2f10-6ab7-41d3-9694-c8bb26285e15","outcome":"completed","summary":"Implemented SIMDTESTToken, launch manifest, vendored dependencies, tests, and documentation.\n\n- `forge build` passed.\n- `forge test`: 27 passed.\n- `forge fmt --check` passed.\n- Eight mainnet-fork tests passed using the live PoolManager and a test IMD fixture.\n\nThe manifest includes string `notes`, omits `chainId`, and uses mandatory pool fee `3000`. Assumptions and launch responsibilities are documented in `README.md`.","treeHash":"e87f6de3ac777d5cc376015da59a2782250573af","usage":{"cachedInputTokens":1139328,"inputTokens":77467,"model":"gpt-6-astra","outputTokens":23722,"runtime":"codex","turns":5,"wallClockMs":710361}},{"artifacts":[],"attempt":1,"bundleHash":"407f46289b3a7f4db79e6fcf0ac9cc10f4109a0e114989ffab57bebb18845a27","device":"9ef5559b56f3a7a2","findings":[],"hash":"d2c5ac5ee37baffb1d2645b3b2e48669e1aa7563785c69364fa6c4454c974a46","nodeId":"8f8e5668-0f8e-4e41-b385-3128657cb9aa","outcome":"completed","summary":"Updated only [launch.json](/home/seat16/.identitymd/work/1c2f094a-ca53-48ad-b80e-c0885e73aecf/8f8e5668-0f8e-4e41-b385-3128657cb9aa/launch.json), preserving exact economics and constructor arguments and clarifying dividend behavior.\n\nSchema, ABI, supply, and price checks passed. Offline build and both test runs passed: 51 passed, 4 optional mainnet-fork tests skipped per run.","treeHash":"5ca652ca57edb404c7156f63876088802909e804","usage":{"cachedInputTokens":282112,"inputTokens":43993,"model":"gpt-6-astra","outputTokens":4458,"runtime":"codex","turns":4,"wallClockMs":124558}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"771f83f312eace21","findings":[{"citation":"resolved","description":"isDividendExcluded() only excludes the PoolManager, the token itself, 0xdead and address(0). The launch factory forwards 100,000,000 SIMDTEST (10% of supply) to the swarm's MerkleDistributor before seeding the pool, and that contract's only token interaction is transferring claims out; it has no path to call SIMDTESTToken.claim(). Because _distribute() (line 140) splits every buy fee pro rata over eligibleSupply() (line 75), which includes the distributor's balance, the distributor is credited the lion's share of every fee while it holds the swarm allocation. That credit is unreachable by anyone: _magnifiedCredit[distributor] is only paid out by claim() from msg.sender == distributor, and by design (line 78) credit survives when the balance is transferred away, so contributors who later claim their swarm share receive none of it either. The tokens sit in the token contract's balance with no claimant, and there is no sweep. Numerically at launch: distributor 100,000,000, pool 900,000,000. First buy of 1,000,000 gross -> fee 30,000, eligible = 100,000,000 + 970,000; buyer's share = 30,000 * 970,000 / 100,970,000 = 288.2 tokens, distributor's share = 29,711.8 tokens (99.04%) stranded. The stranded fraction only falls as contributors claim from the distributor, and any unclaimed swarm share keeps earning stranded dividends indefinitely. This contradicts spec items 5-6 (fees 'accrue as dividends' to holders) and the launch guide, which provides $factory/$launchNumber constructor arguments and distributorOf(launchNumber) precisely so a token can exempt the distributor. Fix: take $factory, $poolManager and $launchNumber as constructor arguments (manifest token.constructorArgs), resolve IFactory(factory).distributorOf(launchNumber) and treat it as excluded in isDividendExcluded()/eligibleSupply()/_accrue() (and exclude the factory itself); the proof test already acts as the factory and answers distributorOf(uint64), so only its deployment line needs the new arguments.","line":70,"path":"src/SIMDTESTToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {SIMDTESTToken} from \"src/SIMDTESTToken.sol\";\n\n/// @dev The swarm's Merkle distributor as the launch provides it: a contract whose only token\n/// interaction is transferring claims out. It has no way to call SIMDTESTToken.claim().\ncontract DistributorStub {\n    function release(SIMDTESTToken token, address to, uint256 amount) external {\n        require(token.transfer(to, amount), \"release failed\");\n    }\n}\n\n/// @dev This test contract plays the launch factory: it deploys the token (so it is msg.sender in\n/// the constructor), forwards the swarm's 10% to the distributor and seeds the PoolManager.\n/// It also answers distributorOf(launchNumber) the way ProjectFactory does, so a fixed token that\n/// looks the distributor up at transfer time (or takes it from constructor arguments) can be\n/// exercised here unchanged apart from the deployment line.\ncontract DistributorDividendsStrandedTest is Test {\n    address constant POOL_MANAGER = 0x000000000004444c5dc75cB358380D2e3dE08A90;\n    address constant BUYER = address(0xB0B);\n    address constant CONTRIBUTOR = address(0xC0DE);\n    uint64 constant LAUNCH_NUMBER = 1;\n\n    SIMDTESTToken token;\n    DistributorStub distributor;\n\n    function distributorOf(uint64) external view returns (address) {\n        return address(distributor);\n    }\n\n    function setUp() public {\n        distributor = new DistributorStub();\n        // If the fix adds constructor arguments ($factory, $poolManager, $launchNumber), pass\n        // address(this), POOL_MANAGER and LAUNCH_NUMBER here in the order the fixed constructor takes.\n        token = new SIMDTESTToken();\n        uint256 supply = token.totalSupply();\n        token.transfer(address(distributor), supply / 10); // swarm share, as the factory forwards it\n        token.transfer(POOL_MANAGER, supply - supply / 10); // pool seed (direct stand-in for the v4 settle)\n    }\n\n    /// @dev Right after launch the distributor holds 100,000,000 tokens and the first buyer 970,000,\n    /// so the 30,000-token fee of a 1,000,000 gross buy is credited ~99% to the distributor.\n    /// A distributor cannot call claim(), so that credit is unreachable by anyone, forever.\n    function test_buyFeeIsFullyClaimableByHoldersWhoCanClaim() public {\n        vm.prank(POOL_MANAGER);\n        token.transfer(BUYER, 1_000_000 ether);\n        uint256 fee = token.totalFeesCollected();\n        assertEq(fee, 30_000 ether, \"fee of a 1,000,000 gross buy\");\n\n        assertEq(\n            token.withdrawableDividendOf(address(distributor)),\n            0,\n            \"dividends credited to the Merkle distributor, which has no claim() path\"\n        );\n        assertApproxEqAbs(\n            token.withdrawableDividendOf(BUYER), fee, 1, \"the retained fee is not claimable by the holders who can claim\"\n        );\n    }\n\n    /// @dev Even after the distributor pays every claim out, the credit stays on the distributor\n    /// (credit survives a transfer-out by design) and the reserve can never be emptied.\n    function test_reserveIsNotStrandedAfterDistributorEmpties() public {\n        vm.prank(POOL_MANAGER);\n        token.transfer(BUYER, 1_000_000 ether);\n\n        distributor.release(token, CONTRIBUTOR, token.balanceOf(address(distributor)));\n        assertEq(token.balanceOf(address(distributor)), 0);\n\n        vm.prank(BUYER);\n        token.claim();\n        vm.prank(CONTRIBUTOR);\n        token.claim();\n\n        // Every claim-capable holder has claimed. Only sub-wei index dust may remain.\n        assertLe(token.balanceOf(address(token)), 1, \"fee tokens stranded in the contract with no claimant\");\n    }\n}","reproduction":"State: token deployed by the factory; factory transfers 100_000_000e18 to the distributor contract and 900_000_000e18 to POOL_MANAGER (no fee on either). Input: vm.prank(POOL_MANAGER); token.transfer(BUYER, 1_000_000e18). Expected: totalFeesCollected == 30_000e18 and the whole fee is claimable by holders who can claim (withdrawableDividendOf(BUYER) ~= 30_000e18, withdrawableDividendOf(distributor) == 0). Actual: withdrawableDividendOf(distributor) == 29711795582846390016836 (29,711.8 tokens) and withdrawableDividendOf(BUYER) == 288.2 tokens. Then distributor.transfer(CONTRIBUTOR, 100_000_000e18); BUYER.claim(); CONTRIBUTOR.claim() -> balanceOf(token) is still 29711795582846390016837 with no account able to claim it. Run: forge test --match-path test/scratch/DistributorDividendsStranded.t.sol (2 tests fail on this code; pass once the distributor is excluded).","severity":"high","snippet":"        return account == POOL_MANAGER || account == address(this) || account == BURN_ADDRESS\n            || account == address(0);","title":"Merkle distributor (10% of supply, cannot call claim()) is dividend-eligible, so ~99% of early buy fees are credited to it and stranded forever"},{"citation":"resolved","description":"The Math Precision checklist asks that fees round up; here fee = floor(amount * 300 / 10000), so any PoolManager-outgoing transfer of 1..33 wei pays no fee and every larger buy underpays by up to 1 wei. With 18 decimals this is 3.3e-17 tokens per transfer and cannot be amplified (33 wei per transaction, gas-bound), so there is no economic impact; recorded for coverage of the zero-rounding check and because the README documents this rounding direction. No change needed unless the author prefers fee rounding up (fee = (amount * 300 + 9999) / 10000).","line":107,"path":"src/SIMDTESTToken.sol","reproduction":"vm.prank(POOL_MANAGER); token.transfer(ALICE, 33) -> balanceOf(ALICE) == 33, totalFeesCollected == 0 (expected under round-up: fee 1, ALICE 32). token.transfer(BOB, 34) from POOL_MANAGER -> fee 1, BOB 33. Existing test test_DustFeeRoundsDown in test/SIMDTESTToken.t.sol shows the same values.","severity":"info","snippet":"        uint256 fee = from == POOL_MANAGER && to != POOL_MANAGER ? amount * BUY_FEE_BPS / BPS : 0;","title":"Buy fee rounds down, so PoolManager transfers below 34 wei are untaxed (dust only)"}],"hash":"e3925e656c21dd6cbffdba1449a9c29103837cbc02da2dbd68ab21ca0816f0d3","nodeId":"875635f8-4567-41a4-bc6a-c06e69852856","outcome":"completed","summary":"The review is complete and written to `.imd-findings.json` (2 findings, 10 coverage rows, snippets verified against the source lines). The existing 41-test suite passes locally. No project files were changed; only `.imd-findings.json` and the scratch proof under `test/scratch/` were created.\n\n**Findings**\n\n- **High: the Merkle distributor earns and strands dividends.** The exclusion list in `src/SIMDTESTToken.sol:70` covers only the PoolManager, the token, 0xdead and address(0). The swarm's distributor holds 100,000,000 tokens from launch, is a plain contract with no way to call `claim()`, and credit survives its transfers out by design. On the first buy of 1,000,000 gross, the 30,000-token fee splits 29,711.8 to the distributor and 288.2 to the buyer, and the distributor's share can never leave the contract. The proof test fails on the current code and passes on a throwaway patched copy that excludes the distributor. The fix needs the launch's constructor arguments (factory, pool manager, launch number) plus a `distributorOf` lookup, which the launch guide provides for this purpose. The proof's deployment line will need the new arguments once the constructor changes. This is as much an economic defect as a math one, so I reported it despite it sitting partly outside the assigned area.\n- **Info: buy fee rounds down.** Transfers from the PoolManager under 34 wei pay no fee and larger buys underpay by at most 1 wei. Recorded for completeness of the zero-rounding check. The impact is nil and the README documents it.\n\n**What held under the Math Precision, Boundary and Numerical Gap guides**\n\n- No overflow in the magnified index or credit math: accounts are checkpointed before every balance change, and eligible supply is at least the holder's balance during each distribution, so credit is bounded by total fees times 2^128.\n- Solvency holds: index increments and claims both floor, fractional credit is retained, and queued fees stay reserved.\n- All sentinel branches (from or to the PoolManager, to the token, to 0xdead, zero and max amounts) behave as documented; launch flows to the distributor and PoolManager are exact.\n- Opening price provenance recomputed by integer square root matches both values in `launch.json`.\n\n**Not reached:** the mainnet-fork swap test was not re-run (local v4 PoolManager tests pass), and the production IMD token's transfer behaviour was not examined.","treeHash":null,"usage":{"cachedInputTokens":1054240,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":30490,"runtime":"claude","turns":25,"wallClockMs":469878}},{"artifacts":[],"attempt":1,"bundleHash":"b30d0a019450688e938ded85ab9e8a0e20f32bb78e05f306900ae6305dd30450","device":"0499829b879ec3d5","findings":[],"hash":"fe0e4181c9f9ad5a81a341bc040eef056f5635be932707590ba2f51786fb182d","nodeId":"6e5527fa-b264-49c6-860f-e311a59227a9","outcome":"completed","summary":"Added adversarial, fuzz, invariant, and optional mainnet fork tests under `test/`.\n\nValidation: `forge build` succeeded; `forge test` reported **51 passed, 0 failed, 4 skipped**, including 20,480 invariant calls.\n\nLive fork execution remains unverified: public RPC endpoints returned HTTP 403. No configuration or production files changed.","treeHash":"46128b7f4aad7d386d2212d78969369ac8c1e922","usage":{"cachedInputTokens":740864,"inputTokens":59435,"model":"gpt-6-astra","outputTokens":15503,"runtime":"codex","turns":5,"wallClockMs":462301}}],"verification":[{"checks":[{"durationMs":1315,"exitCode":0,"name":"build","output":"Compiling 51 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.25s\nCompiler run successful!\n","passed":true},{"durationMs":525,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 5 tests for test/UniswapV4.t.sol:UniswapV4TokenOneTest\n[PASS] test_buyThenSellSettleWithNetBuyOutput() (gas: 602671)\n[PASS] test_distributorClaimAndDividendClaimAfterBuyAreExact() (gas: 496387)\n[PASS] test_exactOutputBuyMeansGrossOutputBeforeTax() (gas: 307406)\n[PASS] test_oneWeiUnderpaymentTriggersCurrencyNotSettledAndRollsBack() (gas: 556107)\n[PASS] test_seedAndSwarmTransfersArriveWhole() (gas: 53591)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 1.90ms (1.86ms CPU time)\n\nRan 5 tests for test/UniswapV4.t.sol:UniswapV4LocalTest\n[PASS] test_buyThenSellSettleWithNetBuyOutput() (gas: 601962)\n[PASS] test_distributorClaimAndDividendClaimAfterBuyAreExact() (gas: 495381)\n[PASS] test_exactOutputBuyMeansGrossOutputBeforeTax() (gas: 307848)\n[PASS] test_oneWeiUnderpaymentTriggersCurrencyNotSettledAndRollsBack() (gas: 555411)\n[PASS] test_seedAndSwarmTransfersArriveWhole() (gas: 53591)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 1.97ms (1.76ms CPU time)\n\nRan 1 test for test/UniswapV4.t.sol:UniswapV4MainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 2.88ms (0.00ns CPU time)\n\nRan 21 tests for test/SIMDTESTToken.t.sol:SIMDTESTTokenTest\n[PASS] testFuzz_buyConservesBalancesAndDividendBacking(uint256) (runs: 256, μ: 641050, ~: 665945)\n[PASS] testFuzz_sequencesPreserveSupplyAndClaimSolvency(uint256) (runs: 256, μ: 13036384, ~: 13029638)\n[PASS] test_buyCollectsThreePercentAndAllocatesToPostTransferBalances() (gas: 446039)\n[PASS] test_claimIsProRataFeeFreeAndCannotBeRepeated() (gas: 525732)\n[PASS] test_claimedTokensParticipateOnlyInSubsequentFees() (gas: 595350)\n[PASS] test_constructorMintsOnceOnlyToDeployer() (gas: 45319)\n[PASS] test_directDonationsAreNotNewDividends() (gas: 94350)\n[PASS] test_excludedBalancesDoNotDiluteOrReceiveDividends() (gas: 425029)\n[PASS] test_feeRoundsDownInMinorUnits() (gas: 428668)\n[PASS] test_infiniteAllowanceAndRevocation() (gas: 197798)\n[PASS] test_invalidTransfersRevertWithoutChangingState() (gas: 210579)\n[PASS] test_largeHistoricalIndexDoesNotOverflowNewBalances() (gas: 542352)\n[PASS] test_newHolderCannotClaimHistoricalFees() (gas: 749446)\n[PASS] test_noEligibleHolderDefersFeesUntilNextEligibleBalance() (gas: 419645)\n[PASS] test_noMintBurnAdminOrUpgradeEntryPoints() (gas: 559446)\n[PASS] test_repeatedClaimsPreserveFractionalEntitlements() (gas: 914931)\n[PASS] test_runtimeContainsNoForbiddenOpcodes() (gas: 698849)\n[PASS] test_selfAndZeroTransfersPreserveBalancesAndClaims() (gas: 698937)\n[PASS] test_sellAndWalletTransfersAreExactAndKeepPastDividends() (gas: 804484)\n[PASS] test_swarmDistributionAndPoolSeedAreExternalAndExact() (gas: 265869)\n[PASS] test_transferFromUsesFromForTaxAndGrossAllowance() (gas: 587558)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 466.73ms (499.38ms CPU time)\n\nRan 4 test suites in 467.43ms (473.48ms CPU time): 31 tests passed, 0 failed, 1 skipped (32 total tests)\n","passed":true},{"durationMs":36,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SIMDTESTToken.approve(address,uint256)\",\"SIMDTESTToken.claim()\",\"SIMDTESTToken.transfer(address,uint256)\",\"SIMDTESTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":5,\"README.md\":176,\"foundry.toml\":19,\"launch.json\":23,\"src/SIMDTESTToken.sol\":137,\"test/SIMDTESTToken.t.sol\":350,\"test/UniswapV4.t.sol\":198,\"test/helpers/TestBase.sol\":33,\"test/helpers/V4Harness.sol\":85,\"tools/initial_price.py\":43},\"excluded\":[\"vendor/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":398,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":234,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/SIMDTESTToken.sol:10: Large Numeric Literal (2 places)\n[low] unused-public-function at src/SIMDTESTToken.sol:77: Public Function Not Used Internally","passed":true}],"detail":"launch.json is not a valid launch manifest: notes: Invalid input: expected string, received undefined","evaluation":"checks","profile":"foundry","status":"rejected","submissionHash":"1053fe016c360bc8f85fdfc5ca278266dc00eab712f7afb7ebc83b36391d6fb2","verifiedTreeHash":"25cbe16aa9a28822cf0a52fb17307ecb365bb890","verifierVersion":"0.1.0+ad90ce4c"},{"checks":[{"durationMs":1968,"exitCode":0,"name":"build","output":"Compiling 70 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.86s\nCompiler run successful!\n","passed":true},{"durationMs":1300,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/MainnetFork.t.sol:MainnetForkTest\n[SKIP] test_MainnetForkBuyAndSell() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 390.57µs (45.31µs CPU time)\n\nRan 7 tests for test/UniswapV4.t.sol:UniswapV4Test\n[PASS] test_ExactOutputBuyDeliversNetOfTax() (gas: 361567)\n[PASS] test_NetSlippageCheckRevertsAndRollsBackFee() (gas: 365005)\n[PASS] test_OppositeCurrencyOrderAlsoSettles() (gas: 2215394)\n[PASS] test_RealV4BuyAndSellSettle() (gas: 697827)\n[PASS] test_RejectsForgedUnlockCallback() (gas: 32188)\n[PASS] test_SingleSidedSeedSettlesAndAllocationIsExact() (gas: 65775)\n[PASS] test_UnderpaymentRevertsWithCurrencyNotSettledAndRollsBackFee() (gas: 376905)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 1.72ms (2.13ms CPU time)\n\nRan 17 tests for test/SIMDTESTToken.t.sol:SIMDTESTTokenTest\n[PASS] testFuzz_BuyConservationAndClaims(uint256) (runs: 512, μ: 770356, ~: 804291)\nLogs:\n  Bound result 1100\n\n[PASS] testFuzz_TransferCannotDuplicateEarnedDividends(uint256,uint256) (runs: 512, μ: 668676, ~: 668834)\nLogs:\n  Bound result 685407102677700145547221466\n  Bound result 60313654573540473243837377\n\n[PASS] test_BuyRetainsThreePercentAndAccruesProRataIncludingBuyer() (gas: 464271)\n[PASS] test_ClaimPaysCallerAndCannotRepeatHistoricalClaim() (gas: 711770)\n[PASS] test_ConstructorMintsExactlyOnceWithoutDistributing() (gas: 87086)\n[PASS] test_ExcludedBalancesAndDonationsEarnNothing() (gas: 591954)\n[PASS] test_FailedTransferFromRollsBackAllowanceAndDividends() (gas: 495123)\n[PASS] test_InfiniteAllowanceAndRevocation() (gas: 196981)\n[PASS] test_NoAdminMintBurnOrUpgradeEntryPoints() (gas: 380747)\n[PASS] test_RevertOnInvalidAddressesOrInsufficientFunds() (gas: 148081)\n[PASS] test_RuntimeHasNoForbiddenOpcodes() (gas: 1183372)\n[PASS] test_SellAndWalletTransfersAreFeeFree() (gas: 363996)\n[PASS] test_SwarmAndSeedArriveWhole() (gas: 262054)\n[PASS] test_TransferFromTaxUsesSourceAndConsumesGrossAllowance() (gas: 590588)\n[PASS] test_TransferPreservesPastCreditAndNewHolderCannotTakeIt() (gas: 793709)\n[PASS] test_ZeroEligibleSupplyDoesNotBlockTransfersOrRewardFutureHolders() (gas: 347238)\n[PASS] test_ZeroSelfAndDustTransfers() (gas: 711372)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 40.58ms (83.18ms CPU time)\n\nRan 1 test for test/DividendInvariant.t.sol:DividendInvariantTest\n[PASS] invariant_SupplyConservationEligibilityAndReserveSolvency() (runs: 128, calls: 8192, reverts: 0)\n\n╭-----------------+----------+-------+---------+----------╮\n| Contract        | Selector | Calls | Reverts | Discards |\n+=========================================================+\n| DividendHandler | buy      | 2654  | 0       | 0        |\n|-----------------+----------+-------+---------+----------|\n| DividendHandler | claim    | 2799  | 0       | 0        |\n|-----------------+----------+-------+---------+----------|\n| DividendHandler | move     | 2739  | 0       | 0        |\n╰-----------------+----------+-------+---------+----------╯\n\nLogs:\n  Bound result 5270724187523965593206894\n  Bound result 884\n  Bound result 28142141643098\n  Bound result 1829\n  Bound result 6086\n  Bound result 30000000000000000000\n  Bound result 11198327191237803356771474\n  Bound result 4999999819972585649547632\n  Bound result 739\n  Bound result 75000000000000000000000000\n  Bound result 10154595034125817160933775\n  Bound result 244\n  Bound result 123000000000000000000\n  Bound result 612019361097507510230939660\n  Bound result 188328742523085909365814139\n  Bound result 3089\n  Bound result 3519159\n  Bound result 693\n  Bound result 317\n  Bound result 66\n  Bound result 2\n  Bound result 24576\n  Bound result 286\n  Bound result 300\n  Bound result 10000000000000000000\n  Bound result 25387360710291849668558490\n  Bound result 1399\n  Bound result 30000000000000000000\n  Bound result 335030918802399391206494645\n  Bound result 5723461197701786866166483\n  Bound result 1087609889787622244274140\n  Bound result 3000000000000000000\n  Bound result 2553\n  Bound result 3\n  Bound result 66\n  Bound result 0\n  Bound result 4212\n  Bound result 1000000000000000000\n  Bound result 5769\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.22s (1.22s CPU time)\n\nRan 4 test suites in 1.22s (1.26s CPU time): 25 tests passed, 0 failed, 1 skipped (26 total tests)\n","passed":true},{"durationMs":39,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SIMDTESTToken.approve(address,uint256)\",\"SIMDTESTToken.claim()\",\"SIMDTESTToken.transfer(address,uint256)\",\"SIMDTESTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"DEPENDENCIES.md\":11,\"README.md\":78,\"VERIFICATION.md\":41,\"foundry.toml\":22,\"launch.json\":25,\"src/SIMDTESTToken.sol\":126,\"test/DividendInvariant.t.sol\":90,\"test/MainnetFork.t.sol\":23,\"test/SIMDTESTToken.t.sol\":312,\"test/UniswapV4.t.sol\":170,\"test/helpers/V4Actor.sol\":123,\"test/test_launch_price.py\":38,\"tools/launch_price.py\":64},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":333,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":228,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/SIMDTESTToken.sol:11: Large Numeric Literal (2 places)\n[low] unused-public-function at src/SIMDTESTToken.sol:73: Public Function Not Used Internally","passed":true}],"detail":"launch.json is not a valid launch manifest: (root): Unrecognized key: \"chainId\"","evaluation":"checks","profile":"foundry","status":"rejected","submissionHash":"4d3cb0e832e18cf402a589ccdb66010e6e051692f0d3d2e6d6a136f36c9fa5ec","verifiedTreeHash":"ad2c9462f44666adc6ca61ec8ec3dcd2d094e2f0","verifierVersion":"0.1.0+ad90ce4c"},{"checks":[{"durationMs":1811,"exitCode":0,"name":"build","output":"Compiling 53 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.75s\nCompiler run successful!\n","passed":true},{"durationMs":4924,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/UniswapV4Fork.t.sol:UniswapV4MainnetToken1ForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 572.19µs (0.00ns CPU time)\n\nRan 1 test for test/UniswapV4Fork.t.sol:UniswapV4MainnetToken0ForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 577.15µs (0.00ns CPU time)\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Token1Test\n[PASS] testFuzz_BuySellAndClaimSettleAtBoundedSwapSizes(uint80) (runs: 1000, μ: 803908, ~: 803838)\n[PASS] test_CallbackRejectsNonManager() (gas: 27286)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 321161)\n[PASS] test_SellWithoutApprovalRevertsAndPreservesDividendCredits() (gas: 530246)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 683262)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 583431)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 112.16ms (112.33ms CPU time)\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Token0Test\n[PASS] testFuzz_BuySellAndClaimSettleAtBoundedSwapSizes(uint80) (runs: 1000, μ: 803434, ~: 803442)\n[PASS] test_CallbackRejectsNonManager() (gas: 27286)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 321603)\n[PASS] test_SellWithoutApprovalRevertsAndPreservesDividendCredits() (gas: 513364)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 682565)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 582722)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 115.81ms (115.86ms CPU time)\n\nRan 9 tests for test/SIMDTESTAdversarial.t.sol:SIMDTESTAdversarialTest\n[PASS] testFuzz_ProRataClaimsExcludeReservesAndBurnedBalances(uint96,uint96,uint96,uint96) (runs: 1000, μ: 810182, ~: 839760)\n[PASS] testFuzz_RejectedDelegatedBuyDoesNotSpendAllowanceOrAccrueDividends(uint256) (runs: 1000, μ: 858514, ~: 858869)\n[PASS] test_EmptyAndExcludedClaimsCannotRedirectAnotherHoldersCredit() (gas: 2236725)\n[PASS] test_InvalidReceiverRollsBackGrossAllowanceAndPendingDividends() (gas: 1141854)\n[PASS] test_MaximumAmountsFailBeforeFeeMathAndRestoreAllowance() (gas: 1722021)\n[PASS] test_PoolManagerCallerDoesNotTaxTransferFromAnOrdinaryWallet() (gas: 547174)\n[PASS] test_RevokingApprovalPreventsSpendEvenByDeployer() (gas: 1160145)\n[PASS] test_SwarmClaimsPreservePreviouslyEarnedDistributorDividends() (gas: 575327)\n[PASS] test_TransferAndClaimLogsReconcileWithBalancesWithoutMintEvents() (gas: 368123)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 117.66ms (234.98ms CPU time)\n\nRan 19 tests for test/SIMDTESTToken.t.sol:SIMDTESTTokenTest\n[PASS] testFuzz_BuyAndClaimConserveSupply(uint256) (runs: 256, μ: 350944, ~: 364519)\n[PASS] testFuzz_CheckpointsPreserveFractions(uint96) (runs: 256, μ: 1465090, ~: 1465073)\n[PASS] testFuzz_StatefulConservationAndDividendSolvency(uint256) (runs: 256, μ: 23132025, ~: 23122038)\n[PASS] test_BuyTaxesThreePercentAndAccruesProRataAfterPurchase() (gas: 410975)\n[PASS] test_ClaimPaysOnceAndDoesNotMint() (gas: 410920)\n[PASS] test_ClaimedTokensOnlyEarnFutureDividends() (gas: 466288)\n[PASS] test_ConstructorMintsEverythingOnlyToDeployer() (gas: 45463)\n[PASS] test_DustFeeRoundsDown() (gas: 285867)\n[PASS] test_ExcludedBalancesAndDonationsDoNotEarn() (gas: 466511)\n[PASS] test_FactoryAndSwarmFlowsAreExact() (gas: 228341)\n[PASS] test_InvalidTransfersAndApprovalsRevertAtomically() (gas: 239896)\n[PASS] test_NoAdminMintBurnOrBalanceSeizure() (gas: 700724)\n[PASS] test_RuntimeHasNoForbiddenOpcodes() (gas: 731607)\n[PASS] test_SellerKeepsPastDividendsAndStopsEarningOnSoldTokens() (gas: 428527)\n[PASS] test_SellsAndWalletTransfersAreUntaxed() (gas: 225364)\n[PASS] test_TransferCannotMoveOrDuplicateEarnedDividends() (gas: 637772)\n[PASS] test_TransferFromConsumesGrossAllowanceAndUsesFromForTax() (gas: 428935)\n[PASS] test_ZeroAndSelfTransfersDoNotChangeEntitlements() (gas: 408232)\n[PASS] test_ZeroEligibleSupplyQueuesFeesUntilNextTaxedBuy() (gas: 336794)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 643.66ms (785.15ms CPU time)\n\nRan 1 test for test/SIMDTESTInvariant.t.sol:SIMDTESTInvariantTest\n[PASS] invariant_LedgerConservationAndDividendSolvency() (runs: 256, calls: 20480, reverts: 0)\n\n╭-----------------+-----------------+-------+---------+----------╮\n| Contract        | Selector        | Calls | Reverts | Discards |\n+================================================================+\n| SIMDTESTHandler | buy             | 3361  | 0       | 0        |\n|-----------------+-----------------+-------+---------+----------|\n| SIMDTESTHandler | claim           | 3393  | 0       | 0        |\n|-----------------+-----------------+-------+---------+----------|\n| SIMDTESTHandler | delegatedMove   | 3441  | 0       | 0        |\n|-----------------+-----------------+-------+---------+----------|\n| SIMDTESTHandler | move            | 3421  | 0       | 0        |\n|-----------------+-----------------+-------+---------+----------|\n| SIMDTESTHandler | rejectOverspend | 3438  | 0       | 0        |\n|-----------------+-----------------+-------+---------+----------|\n| SIMDTESTHandler | sell            | 3426  | 0       | 0        |\n╰-----------------+-----------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.87s (4.87s CPU time)\n\nRan 7 test suites in 4.87s (5.86s CPU time): 41 tests passed, 0 failed, 2 skipped (43 total tests)\n","passed":true},{"durationMs":30,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SIMDTESTToken.approve(address,uint256)\",\"SIMDTESTToken.claim()\",\"SIMDTESTToken.transfer(address,uint256)\",\"SIMDTESTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":168,\"foundry.toml\":17,\"launch.json\":24,\"src/SIMDTESTToken.sol\":143,\"test/SIMDTESTAdversarial.t.sol\":261,\"test/SIMDTESTInvariant.t.sol\":228,\"test/SIMDTESTToken.t.sol\":330,\"test/TESTING.md\":59,\"test/UniswapV4.t.sol\":309,\"test/UniswapV4Fork.t.sol\":67,\"test/helpers/TestBase.sol\":50,\"tools/launch_price.py\":63},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"ab1415a0d97781a91243c0fecf8d9193272b90f2593a5e4fbf8cc3a5b61af21e","verifiedTreeHash":"1d11d7d11b4cf9109e9fe2d34afdb7c6828186a3","verifierVersion":"0.1.0+ad90ce4c"},{"checks":[{"durationMs":1865,"exitCode":0,"name":"build","output":"Compiling 53 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.79s\nCompiler run successful!\n","passed":true},{"durationMs":5160,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/UniswapV4Fork.t.sol:UniswapV4MainnetToken1ForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 592.91µs (0.00ns CPU time)\n\nRan 1 test for test/UniswapV4Fork.t.sol:UniswapV4MainnetToken0ForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 665.03µs (0.00ns CPU time)\n\nRan 9 tests for test/SIMDTESTAdversarial.t.sol:SIMDTESTAdversarialTest\n[PASS] testFuzz_ProRataClaimsExcludeReservesAndBurnedBalances(uint96,uint96,uint96,uint96) (runs: 1000, μ: 807734, ~: 839760)\n[PASS] testFuzz_RejectedDelegatedBuyDoesNotSpendAllowanceOrAccrueDividends(uint256) (runs: 1000, μ: 858472, ~: 858881)\n[PASS] test_EmptyAndExcludedClaimsCannotRedirectAnotherHoldersCredit() (gas: 2236725)\n[PASS] test_InvalidReceiverRollsBackGrossAllowanceAndPendingDividends() (gas: 1141854)\n[PASS] test_MaximumAmountsFailBeforeFeeMathAndRestoreAllowance() (gas: 1722021)\n[PASS] test_PoolManagerCallerDoesNotTaxTransferFromAnOrdinaryWallet() (gas: 547174)\n[PASS] test_RevokingApprovalPreventsSpendEvenByDeployer() (gas: 1160145)\n[PASS] test_SwarmClaimsPreservePreviouslyEarnedDistributorDividends() (gas: 575327)\n[PASS] test_TransferAndClaimLogsReconcileWithBalancesWithoutMintEvents() (gas: 368123)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 132.28ms (264.04ms CPU time)\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Token0Test\n[PASS] testFuzz_BuySellAndClaimSettleAtBoundedSwapSizes(uint80) (runs: 1000, μ: 803429, ~: 803442)\n[PASS] test_CallbackRejectsNonManager() (gas: 27286)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 321603)\n[PASS] test_SellWithoutApprovalRevertsAndPreservesDividendCredits() (gas: 513364)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 682565)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 582722)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 133.92ms (134.20ms CPU time)\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Token1Test\n[PASS] testFuzz_BuySellAndClaimSettleAtBoundedSwapSizes(uint80) (runs: 1000, μ: 803913, ~: 803838)\n[PASS] test_CallbackRejectsNonManager() (gas: 27286)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 321161)\n[PASS] test_SellWithoutApprovalRevertsAndPreservesDividendCredits() (gas: 530246)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 683262)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 583431)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 134.17ms (134.28ms CPU time)\n\nRan 19 tests for test/SIMDTESTToken.t.sol:SIMDTESTTokenTest\n[PASS] testFuzz_BuyAndClaimConserveSupply(uint256) (runs: 256, μ: 343006, ~: 364513)\n[PASS] testFuzz_CheckpointsPreserveFractions(uint96) (runs: 256, μ: 1465090, ~: 1465061)\n[PASS] testFuzz_StatefulConservationAndDividendSolvency(uint256) (runs: 256, μ: 23140670, ~: 23154945)\n[PASS] test_BuyTaxesThreePercentAndAccruesProRataAfterPurchase() (gas: 410975)\n[PASS] test_ClaimPaysOnceAndDoesNotMint() (gas: 410920)\n[PASS] test_ClaimedTokensOnlyEarnFutureDividends() (gas: 466288)\n[PASS] test_ConstructorMintsEverythingOnlyToDeployer() (gas: 45463)\n[PASS] test_DustFeeRoundsDown() (gas: 285867)\n[PASS] test_ExcludedBalancesAndDonationsDoNotEarn() (gas: 466511)\n[PASS] test_FactoryAndSwarmFlowsAreExact() (gas: 228341)\n[PASS] test_InvalidTransfersAndApprovalsRevertAtomically() (gas: 239896)\n[PASS] test_NoAdminMintBurnOrBalanceSeizure() (gas: 700724)\n[PASS] test_RuntimeHasNoForbiddenOpcodes() (gas: 731607)\n[PASS] test_SellerKeepsPastDividendsAndStopsEarningOnSoldTokens() (gas: 428527)\n[PASS] test_SellsAndWalletTransfersAreUntaxed() (gas: 225364)\n[PASS] test_TransferCannotMoveOrDuplicateEarnedDividends() (gas: 637772)\n[PASS] test_TransferFromConsumesGrossAllowanceAndUsesFromForTax() (gas: 428935)\n[PASS] test_ZeroAndSelfTransfersDoNotChangeEntitlements() (gas: 408232)\n[PASS] test_ZeroEligibleSupplyQueuesFeesUntilNextTaxedBuy() (gas: 336794)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 666.40ms (780.95ms CPU time)\n\nRan 1 test for test/SIMDTESTInvariant.t.sol:SIMDTESTInvariantTest\n[PASS] invariant_LedgerConservationAndDividendSolvency() (runs: 256, calls: 20480, reverts: 0)\n\n╭-----------------+-----------------+-------+---------+----------╮\n| Contract        | Selector        | Calls | Reverts | Discards |\n+================================================================+\n| SIMDTESTHandler | buy             | 3462  | 0       | 0        |\n|-----------------+-----------------+-------+---------+----------|\n| SIMDTESTHandler | claim           | 3461  | 0       | 0        |\n|-----------------+-----------------+-------+---------+----------|\n| SIMDTESTHandler | delegatedMove   | 3346  | 0       | 0        |\n|-----------------+-----------------+-------+---------+----------|\n| SIMDTESTHandler | move            | 3347  | 0       | 0        |\n|-----------------+-----------------+-------+---------+----------|\n| SIMDTESTHandler | rejectOverspend | 3440  | 0       | 0        |\n|-----------------+-----------------+-------+---------+----------|\n| SIMDTESTHandler | sell            | 3424  | 0       | 0        |\n╰-----------------+-----------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.10s (5.10s CPU time)\n\nRan 7 test suites in 5.10s (6.17s CPU time): 41 tests passed, 0 failed, 2 skipped (43 total tests)\n","passed":true},{"durationMs":29,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SIMDTESTToken.approve(address,uint256)\",\"SIMDTESTToken.claim()\",\"SIMDTESTToken.transfer(address,uint256)\",\"SIMDTESTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":168,\"foundry.toml\":17,\"launch.json\":24,\"src/SIMDTESTToken.sol\":143,\"test/SIMDTESTAdversarial.t.sol\":261,\"test/SIMDTESTInvariant.t.sol\":228,\"test/SIMDTESTToken.t.sol\":330,\"test/TESTING.md\":59,\"test/UniswapV4.t.sol\":309,\"test/UniswapV4Fork.t.sol\":67,\"test/helpers/TestBase.sol\":50,\"tools/launch_price.py\":63},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"b9376f9ca4b41cedf4653f62e7c86b122abfdb72a2cd1f17709d7a588dd7cc0c","verifiedTreeHash":"9885d413f65be21fea787242260a8a58a76c0845","verifierVersion":"0.1.0+ad90ce4c"},{"checks":[{"durationMs":1270,"exitCode":0,"name":"build","output":"Compiling 51 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.19s\nCompiler run successful!\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n   ╭▸ src/SIMDTESTToken.sol:50:17\n   │\n50 │     constructor(address factory_, address poolManager_, uint64 launchNumber_) {\n   │                 ━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\n","passed":true},{"durationMs":829,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Token0Test\n[PASS] test_CallbackRejectsNonManager() (gas: 27219)\n[PASS] test_ClaimTokenRoundTripDoesNotTransferOrTax() (gas: 709461)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 327645)\n[PASS] test_LiquidityRemovalTaxesTheOutgoingTransfer() (gas: 865702)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 668970)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 551412)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 11.87ms (2.77ms CPU time)\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Token1Test\n[PASS] test_CallbackRejectsNonManager() (gas: 27219)\n[PASS] test_ClaimTokenRoundTripDoesNotTransferOrTax() (gas: 710997)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 327203)\n[PASS] test_LiquidityRemovalTaxesTheOutgoingTransfer() (gas: 866102)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 669667)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 552121)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 13.20ms (3.50ms CPU time)\n\nRan 10 tests for test/DividendRevision.t.sol:DividendRevisionTest\n[PASS] test_ConstructorRejectsMismatchedLaunchInfrastructure() (gas: 3875)\n[PASS] test_DistributorHasNoUnclaimableCredit() (gas: 283089)\n[PASS] test_ExistingBuyerEarnsOnlyOnPreviouslyHeldTokens() (gas: 416657)\n[PASS] test_FactoryRemainderDoesNotEarnDividends() (gas: 343528)\n[PASS] test_FeesAreNotStrandedAfterAllHoldersClaim() (gas: 704618)\n[PASS] test_FirstBuyerFeeStaysQueued() (gas: 301837)\n[PASS] test_OverlappingExclusionsNeverDoubleSubtract() (gas: 122116)\n[PASS] test_RegistrationAfterDeploymentAndBindingCannotChange() (gas: 744535)\n[PASS] test_RouterSweepReceivesNoRetroactiveDividend() (gas: 738910)\n[PASS] test_WhaleCannotReclaimItsOwnBuyFee() (gas: 335822)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 13.25ms (4.07ms CPU time)\n\nRan 19 tests for test/SIMDTESTToken.t.sol:SIMDTESTTokenTest\n[PASS] testFuzz_BuyAndClaimConserveSupply(uint256) (runs: 256, μ: 292352, ~: 298448)\n[PASS] testFuzz_CheckpointsPreserveFractions(uint96) (runs: 256, μ: 1615134, ~: 1615107)\n[PASS] testFuzz_StatefulConservationAndDividendSolvency(uint256) (runs: 256, μ: 24934856, ~: 24945311)\n[PASS] test_BuyTaxesThreePercentAndAccruesProRataBeforePurchase() (gas: 463186)\n[PASS] test_ClaimPaysOnceAndDoesNotMint() (gas: 526495)\n[PASS] test_ClaimedTokensOnlyEarnFutureDividends() (gas: 606344)\n[PASS] test_ConstructorMintsEverythingOnlyToDeployer() (gas: 45351)\n[PASS] test_DustFeeRoundsDown() (gas: 332258)\n[PASS] test_ExcludedBalancesAndDonationsDoNotEarn() (gas: 708435)\n[PASS] test_FactoryAndSwarmFlowsAreExact() (gas: 231940)\n[PASS] test_InvalidTransfersAndApprovalsRevertAtomically() (gas: 239618)\n[PASS] test_NoAdminMintBurnOrBalanceSeizure() (gas: 721701)\n[PASS] test_RuntimeHasNoForbiddenOpcodes() (gas: 868989)\n[PASS] test_SellerKeepsPastDividendsAndStopsEarningOnSoldTokens() (gas: 538806)\n[PASS] test_SellsAndWalletTransfersAreUntaxed() (gas: 249283)\n[PASS] test_TransferCannotMoveOrDuplicateEarnedDividends() (gas: 759434)\n[PASS] test_TransferFromConsumesGrossAllowanceAndUsesFromForTax() (gas: 413702)\n[PASS] test_ZeroAndSelfTransfersDoNotChangeEntitlements() (gas: 508175)\n[PASS] test_ZeroEligibleSupplyQueuesFeesUntilNextTaxedBuy() (gas: 566193)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 753.05ms (844.35ms CPU time)\n\nRan 4 test suites in 753.75ms (791.36ms CPU time): 41 tests passed, 0 failed, 0 skipped (41 total tests)\n","passed":true},{"durationMs":29,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SIMDTESTToken.approve(address,uint256)\",\"SIMDTESTToken.claim()\",\"SIMDTESTToken.transfer(address,uint256)\",\"SIMDTESTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":199,\"foundry.toml\":17,\"launch.json\":28,\"src/SIMDTESTToken.sol\":178,\"test/DividendRevision.t.sol\":153,\"test/SIMDTESTToken.t.sol\":354,\"test/UniswapV4.t.sol\":316,\"test/helpers/TestBase.sol\":37,\"tools/launch_price.py\":64},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":384,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":228,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/SIMDTESTToken.sol:14: Large Numeric Literal (2 places)\n[low] unused-public-function at src/SIMDTESTToken.sol:105: Public Function Not Used Internally","passed":true},{"durationMs":89,"exitCode":0,"name":"proof 2d1196e49933","output":"Owed nothing: on the tree this revision started from the proof did not compile or run, so it never reproduced the finding.\n\nError: Compiler run failed:\nError (6275): Source \"forge-std/Test.sol\" not found: File not found. Searched the following locations: \"/tmp/imd-verify-yWFdUn/repo\".\nParserError: Source \"forge-std/Test.sol\" not found: File not found. Searched the following locations: \"/tmp/imd-verify-yWFdUn/repo\".\n --> test/imd-proof-67d1d6cf/Proof_2d1196e49933.t.sol:4:1:\n  |\n4 | import {Test} from \"forge-std/Test.sol\";\n  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"bd761f76ae1f9176cae950068eec74b71947473b6796ec575440a3b27f4b0c30","verifiedTreeHash":"33e45e618ff5b4427fded27c73ade2a0361b630c","verifierVersion":"0.1.0+ad90ce4c"},{"checks":[{"durationMs":1271,"exitCode":0,"name":"build","output":"Compiling 50 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.21s\nCompiler run successful!\n","passed":true},{"durationMs":906,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/UniswapV4.t.sol:UniswapV4Token1Test\n[PASS] test_CallbackRejectsNonManager() (gas: 27240)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 321183)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 683227)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 583300)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.75ms (1.40ms CPU time)\n\nRan 4 tests for test/UniswapV4.t.sol:UniswapV4Token0Test\n[PASS] test_CallbackRejectsNonManager() (gas: 27240)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 321625)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 682530)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 582591)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 57.93ms (1.31ms CPU time)\n\nRan 19 tests for test/SIMDTESTToken.t.sol:SIMDTESTTokenTest\n[PASS] testFuzz_BuyAndClaimConserveSupply(uint256) (runs: 256, μ: 348521, ~: 364513)\n[PASS] testFuzz_CheckpointsPreserveFractions(uint96) (runs: 256, μ: 1465095, ~: 1465073)\n[PASS] testFuzz_StatefulConservationAndDividendSolvency(uint256) (runs: 256, μ: 23134897, ~: 23141496)\n[PASS] test_BuyTaxesThreePercentAndAccruesProRataAfterPurchase() (gas: 410975)\n[PASS] test_ClaimPaysOnceAndDoesNotMint() (gas: 410920)\n[PASS] test_ClaimedTokensOnlyEarnFutureDividends() (gas: 466288)\n[PASS] test_ConstructorMintsEverythingOnlyToDeployer() (gas: 45463)\n[PASS] test_DustFeeRoundsDown() (gas: 285867)\n[PASS] test_ExcludedBalancesAndDonationsDoNotEarn() (gas: 466511)\n[PASS] test_FactoryAndSwarmFlowsAreExact() (gas: 228341)\n[PASS] test_InvalidTransfersAndApprovalsRevertAtomically() (gas: 239896)\n[PASS] test_NoAdminMintBurnOrBalanceSeizure() (gas: 700724)\n[PASS] test_RuntimeHasNoForbiddenOpcodes() (gas: 731607)\n[PASS] test_SellerKeepsPastDividendsAndStopsEarningOnSoldTokens() (gas: 428527)\n[PASS] test_SellsAndWalletTransfersAreUntaxed() (gas: 225364)\n[PASS] test_TransferCannotMoveOrDuplicateEarnedDividends() (gas: 637772)\n[PASS] test_TransferFromConsumesGrossAllowanceAndUsesFromForTax() (gas: 428935)\n[PASS] test_ZeroAndSelfTransfersDoNotChangeEntitlements() (gas: 408232)\n[PASS] test_ZeroEligibleSupplyQueuesFeesUntilNextTaxedBuy() (gas: 336794)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 842.25ms (957.54ms CPU time)\n\nRan 3 test suites in 842.87ms (901.94ms CPU time): 27 tests passed, 0 failed, 0 skipped (27 total tests)\n","passed":true},{"durationMs":37,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SIMDTESTToken.approve(address,uint256)\",\"SIMDTESTToken.claim()\",\"SIMDTESTToken.transfer(address,uint256)\",\"SIMDTESTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":168,\"foundry.toml\":17,\"launch.json\":24,\"src/SIMDTESTToken.sol\":143,\"test/SIMDTESTToken.t.sol\":330,\"test/UniswapV4.t.sol\":245,\"test/helpers/TestBase.sol\":37,\"tools/launch_price.py\":63},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":407,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":303,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/SIMDTESTToken.sol:10: Large Numeric Literal (2 places)\n[low] unused-public-function at src/SIMDTESTToken.sol:79: Public Function Not Used Internally","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c655887ccfd191979fa4009d1d6bc5caa0afbb7187fbf2bb38c481e09ff84ab6","verifiedTreeHash":"e87f6de3ac777d5cc376015da59a2782250573af","verifierVersion":"0.1.0+ad90ce4c"},{"checks":[{"durationMs":1734,"exitCode":0,"name":"build","output":"Compiling 54 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.65s\nCompiler run successful!\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n   ╭▸ src/SIMDTESTToken.sol:50:17\n   │\n50 │     constructor(address factory_, address poolManager_, uint64 launchNumber_) {\n   │                 ━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\n","passed":true},{"durationMs":5400,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Token1Test\n[PASS] test_CallbackRejectsNonManager() (gas: 27219)\n[PASS] test_ClaimTokenRoundTripDoesNotTransferOrTax() (gas: 710997)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 327203)\n[PASS] test_LiquidityRemovalTaxesTheOutgoingTransfer() (gas: 866102)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 669667)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 552121)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 2.47ms (1.66ms CPU time)\n\nRan 10 tests for test/DividendRevision.t.sol:DividendRevisionTest\n[PASS] test_ConstructorRejectsMismatchedLaunchInfrastructure() (gas: 3875)\n[PASS] test_DistributorHasNoUnclaimableCredit() (gas: 283089)\n[PASS] test_ExistingBuyerEarnsOnlyOnPreviouslyHeldTokens() (gas: 416657)\n[PASS] test_FactoryRemainderDoesNotEarnDividends() (gas: 343528)\n[PASS] test_FeesAreNotStrandedAfterAllHoldersClaim() (gas: 704618)\n[PASS] test_FirstBuyerFeeStaysQueued() (gas: 301837)\n[PASS] test_OverlappingExclusionsNeverDoubleSubtract() (gas: 122116)\n[PASS] test_RegistrationAfterDeploymentAndBindingCannotChange() (gas: 744535)\n[PASS] test_RouterSweepReceivesNoRetroactiveDividend() (gas: 738910)\n[PASS] test_WhaleCannotReclaimItsOwnBuyFee() (gas: 335822)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 123.68ms (1.46ms CPU time)\n\nRan 4 tests for test/SIMDTESTMainnetFork.t.sol:SIMDTESTMainnetForkTest\n[SKIP] test_MainnetToken0SeedBuySell() (gas: 0)\n[SKIP] test_MainnetToken0UnderpaymentRollsBack() (gas: 0)\n[SKIP] test_MainnetToken1SeedBuySell() (gas: 0)\n[SKIP] test_MainnetToken1UnderpaymentRollsBack() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 4 skipped; finished in 125.03ms (172.48µs CPU time)\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Token0Test\n[PASS] test_CallbackRejectsNonManager() (gas: 27219)\n[PASS] test_ClaimTokenRoundTripDoesNotTransferOrTax() (gas: 709461)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 327645)\n[PASS] test_LiquidityRemovalTaxesTheOutgoingTransfer() (gas: 865702)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 668970)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 551412)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 139.75ms (2.92ms CPU time)\n\nRan 19 tests for test/SIMDTESTToken.t.sol:SIMDTESTTokenTest\n[PASS] testFuzz_BuyAndClaimConserveSupply(uint256) (runs: 256, μ: 291661, ~: 298448)\n[PASS] testFuzz_CheckpointsPreserveFractions(uint96) (runs: 256, μ: 1615137, ~: 1615107)\n[PASS] testFuzz_StatefulConservationAndDividendSolvency(uint256) (runs: 256, μ: 24940911, ~: 24946966)\n[PASS] test_BuyTaxesThreePercentAndAccruesProRataBeforePurchase() (gas: 463186)\n[PASS] test_ClaimPaysOnceAndDoesNotMint() (gas: 526495)\n[PASS] test_ClaimedTokensOnlyEarnFutureDividends() (gas: 606344)\n[PASS] test_ConstructorMintsEverythingOnlyToDeployer() (gas: 45351)\n[PASS] test_DustFeeRoundsDown() (gas: 332258)\n[PASS] test_ExcludedBalancesAndDonationsDoNotEarn() (gas: 708435)\n[PASS] test_FactoryAndSwarmFlowsAreExact() (gas: 231940)\n[PASS] test_InvalidTransfersAndApprovalsRevertAtomically() (gas: 239618)\n[PASS] test_NoAdminMintBurnOrBalanceSeizure() (gas: 721701)\n[PASS] test_RuntimeHasNoForbiddenOpcodes() (gas: 868989)\n[PASS] test_SellerKeepsPastDividendsAndStopsEarningOnSoldTokens() (gas: 538806)\n[PASS] test_SellsAndWalletTransfersAreUntaxed() (gas: 249283)\n[PASS] test_TransferCannotMoveOrDuplicateEarnedDividends() (gas: 759434)\n[PASS] test_TransferFromConsumesGrossAllowanceAndUsesFromForTax() (gas: 413702)\n[PASS] test_ZeroAndSelfTransfersDoNotChangeEntitlements() (gas: 508175)\n[PASS] test_ZeroEligibleSupplyQueuesFeesUntilNextTaxedBuy() (gas: 566193)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 807.86ms (910.51ms CPU time)\n\nRan 9 tests for test/SIMDTESTAdversarial.t.sol:SIMDTESTAdversarialTest\n[PASS] testFuzz_FailedDelegatedBuyPreservesDividendsAndAllowance(uint256,uint8) (runs: 1000, μ: 618595, ~: 618573)\n[PASS] testFuzz_ProRataClaimsUsePreBuyBalances(uint256,uint256,uint256,bool) (runs: 1000, μ: 713112, ~: 724060)\n[PASS] testFuzz_SplitBuysLoseLessThanOneFeeUnitPerSplit(uint256,uint8) (runs: 1000, μ: 1051067, ~: 823817)\n[PASS] test_BuyAndClaimEventsMatchActualReserveMovement() (gas: 471510)\n[PASS] test_ConstructorEmitsOnlyOneMintAndNeverSendsAllocations() (gas: 21133)\n[PASS] test_ManagerAsSpenderDoesNotTaxWalletTokens() (gas: 554426)\n[PASS] test_MaximumTransferInputsFailWithoutArithmeticPanic() (gas: 635231)\n[PASS] test_OneWeiHolderCanClaimLargestPracticalDistribution() (gas: 559752)\n[PASS] test_RevokedApprovalCannotMoveBalanceOrAccruedCredit() (gas: 638211)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 810.95ms (1.72s CPU time)\n\nRan 1 test for test/SIMDTESTInvariant.t.sol:SIMDTESTInvariantTest\n[PASS]\nSIMDTESTInvariantTest invariants:\n[PASS] invariant_BalancesAndSupplyMatchIndependentLedger\n[PASS] invariant_ExcludedAddressesNeverEarn\n[PASS] invariant_ReserveCoversEveryClaimAndQueuedFee\n SIMDTESTInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭-----------------+-----------------------+-------+---------+----------╮\n| Contract        | Selector              | Calls | Reverts | Discards |\n+======================================================================+\n| SIMDTESTHandler | buy                   | 2958  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | claim                 | 2917  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | forwardFactoryBalance | 2897  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | rejectedOverspend     | 2904  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | releaseSwarm          | 3046  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | sell                  | 2824  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | walletTransfer        | 2934  | 0       | 0        |\n╰-----------------+-----------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.32s (5.32s CPU time)\n\nRan 7 test suites in 5.32s (7.33s CPU time): 51 tests passed, 0 failed, 4 skipped (55 total tests)\n","passed":true},{"durationMs":45,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SIMDTESTToken.approve(address,uint256)\",\"SIMDTESTToken.claim()\",\"SIMDTESTToken.transfer(address,uint256)\",\"SIMDTESTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":199,\"foundry.toml\":17,\"launch.json\":28,\"src/SIMDTESTToken.sol\":178,\"test/DividendRevision.t.sol\":153,\"test/SIMDTESTAdversarial.t.sol\":277,\"test/SIMDTESTInvariant.t.sol\":238,\"test/SIMDTESTMainnetFork.t.sol\":64,\"test/SIMDTESTToken.t.sol\":354,\"test/TESTING.md\":40,\"test/UniswapV4.t.sol\":316,\"test/helpers/TestBase.sol\":37,\"tools/launch_price.py\":64},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"d2c5ac5ee37baffb1d2645b3b2e48669e1aa7563785c69364fa6c4454c974a46","verifiedTreeHash":"5ca652ca57edb404c7156f63876088802909e804","verifierVersion":"0.1.0+ad90ce4c"},{"checks":[{"durationMs":1573,"exitCode":0,"name":"build","output":"Compiling 54 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.50s\nCompiler run successful!\nwarning[missing-zero-check]: address parameter is used in a state write or value transfer without a zero-address check\n   ╭▸ src/SIMDTESTToken.sol:50:17\n   │\n50 │     constructor(address factory_, address poolManager_, uint64 launchNumber_) {\n   │                 ━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-zero-check\n\n","passed":true},{"durationMs":5145,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/SIMDTESTMainnetFork.t.sol:SIMDTESTMainnetForkTest\n[SKIP] test_MainnetToken0SeedBuySell() (gas: 0)\n[SKIP] test_MainnetToken0UnderpaymentRollsBack() (gas: 0)\n[SKIP] test_MainnetToken1SeedBuySell() (gas: 0)\n[SKIP] test_MainnetToken1UnderpaymentRollsBack() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 4 skipped; finished in 985.05µs (298.62µs CPU time)\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Token1Test\n[PASS] test_CallbackRejectsNonManager() (gas: 27219)\n[PASS] test_ClaimTokenRoundTripDoesNotTransferOrTax() (gas: 710997)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 327203)\n[PASS] test_LiquidityRemovalTaxesTheOutgoingTransfer() (gas: 866102)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 669667)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 552121)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 130.27ms (2.84ms CPU time)\n\nRan 9 tests for test/SIMDTESTAdversarial.t.sol:SIMDTESTAdversarialTest\n[PASS] testFuzz_FailedDelegatedBuyPreservesDividendsAndAllowance(uint256,uint8) (runs: 1000, μ: 618602, ~: 618573)\n[PASS] testFuzz_ProRataClaimsUsePreBuyBalances(uint256,uint256,uint256,bool) (runs: 1000, μ: 713045, ~: 724024)\n[PASS] testFuzz_SplitBuysLoseLessThanOneFeeUnitPerSplit(uint256,uint8) (runs: 1000, μ: 1037090, ~: 744515)\n[PASS] test_BuyAndClaimEventsMatchActualReserveMovement() (gas: 471510)\n[PASS] test_ConstructorEmitsOnlyOneMintAndNeverSendsAllocations() (gas: 21133)\n[PASS] test_ManagerAsSpenderDoesNotTaxWalletTokens() (gas: 554426)\n[PASS] test_MaximumTransferInputsFailWithoutArithmeticPanic() (gas: 635231)\n[PASS] test_OneWeiHolderCanClaimLargestPracticalDistribution() (gas: 559752)\n[PASS] test_RevokedApprovalCannotMoveBalanceOrAccruedCredit() (gas: 638211)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 136.61ms (390.17ms CPU time)\n\nRan 6 tests for test/UniswapV4.t.sol:UniswapV4Token0Test\n[PASS] test_CallbackRejectsNonManager() (gas: 27219)\n[PASS] test_ClaimTokenRoundTripDoesNotTransferOrTax() (gas: 709461)\n[PASS] test_ExactOutputBuySettlesGrossButRecipientGetsNet() (gas: 327645)\n[PASS] test_LiquidityRemovalTaxesTheOutgoingTransfer() (gas: 865702)\n[PASS] test_SingleSidedSeedAndSwapsSettleWithoutShortfall() (gas: 668970)\n[PASS] test_UnderpaidSellRevertsCurrencyNotSettledAndRollsBack() (gas: 551412)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 724.02ms (4.93ms CPU time)\n\nRan 19 tests for test/SIMDTESTToken.t.sol:SIMDTESTTokenTest\n[PASS] testFuzz_BuyAndClaimConserveSupply(uint256) (runs: 256, μ: 293230, ~: 298478)\n[PASS] testFuzz_CheckpointsPreserveFractions(uint96) (runs: 256, μ: 1615143, ~: 1615131)\n[PASS] testFuzz_StatefulConservationAndDividendSolvency(uint256) (runs: 256, μ: 24927037, ~: 24934466)\n[PASS] test_BuyTaxesThreePercentAndAccruesProRataBeforePurchase() (gas: 463186)\n[PASS] test_ClaimPaysOnceAndDoesNotMint() (gas: 526495)\n[PASS] test_ClaimedTokensOnlyEarnFutureDividends() (gas: 606344)\n[PASS] test_ConstructorMintsEverythingOnlyToDeployer() (gas: 45351)\n[PASS] test_DustFeeRoundsDown() (gas: 332258)\n[PASS] test_ExcludedBalancesAndDonationsDoNotEarn() (gas: 708435)\n[PASS] test_FactoryAndSwarmFlowsAreExact() (gas: 231940)\n[PASS] test_InvalidTransfersAndApprovalsRevertAtomically() (gas: 239618)\n[PASS] test_NoAdminMintBurnOrBalanceSeizure() (gas: 721701)\n[PASS] test_RuntimeHasNoForbiddenOpcodes() (gas: 868989)\n[PASS] test_SellerKeepsPastDividendsAndStopsEarningOnSoldTokens() (gas: 538806)\n[PASS] test_SellsAndWalletTransfersAreUntaxed() (gas: 249283)\n[PASS] test_TransferCannotMoveOrDuplicateEarnedDividends() (gas: 759434)\n[PASS] test_TransferFromConsumesGrossAllowanceAndUsesFromForTax() (gas: 413702)\n[PASS] test_ZeroAndSelfTransfersDoNotChangeEntitlements() (gas: 508175)\n[PASS] test_ZeroEligibleSupplyQueuesFeesUntilNextTaxedBuy() (gas: 566193)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 724.14ms (1.00s CPU time)\n\nRan 10 tests for test/DividendRevision.t.sol:DividendRevisionTest\n[PASS] test_ConstructorRejectsMismatchedLaunchInfrastructure() (gas: 3875)\n[PASS] test_DistributorHasNoUnclaimableCredit() (gas: 283089)\n[PASS] test_ExistingBuyerEarnsOnlyOnPreviouslyHeldTokens() (gas: 416657)\n[PASS] test_FactoryRemainderDoesNotEarnDividends() (gas: 343528)\n[PASS] test_FeesAreNotStrandedAfterAllHoldersClaim() (gas: 704618)\n[PASS] test_FirstBuyerFeeStaysQueued() (gas: 301837)\n[PASS] test_OverlappingExclusionsNeverDoubleSubtract() (gas: 122116)\n[PASS] test_RegistrationAfterDeploymentAndBindingCannotChange() (gas: 744535)\n[PASS] test_RouterSweepReceivesNoRetroactiveDividend() (gas: 738910)\n[PASS] test_WhaleCannotReclaimItsOwnBuyFee() (gas: 335822)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 724.19ms (2.39ms CPU time)\n\nRan 1 test for test/SIMDTESTInvariant.t.sol:SIMDTESTInvariantTest\n[PASS]\nSIMDTESTInvariantTest invariants:\n[PASS] invariant_BalancesAndSupplyMatchIndependentLedger\n[PASS] invariant_ExcludedAddressesNeverEarn\n[PASS] invariant_ReserveCoversEveryClaimAndQueuedFee\n SIMDTESTInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭-----------------+-----------------------+-------+---------+----------╮\n| Contract        | Selector              | Calls | Reverts | Discards |\n+======================================================================+\n| SIMDTESTHandler | buy                   | 2919  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | claim                 | 2966  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | forwardFactoryBalance | 2895  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | rejectedOverspend     | 2868  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | releaseSwarm          | 2943  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | sell                  | 2926  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| SIMDTESTHandler | walletTransfer        | 2963  | 0       | 0        |\n╰-----------------+-----------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.08s (5.08s CPU time)\n\nRan 7 test suites in 5.08s (7.52s CPU time): 51 tests passed, 0 failed, 4 skipped (55 total tests)\n","passed":true},{"durationMs":30,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SIMDTESTToken.approve(address,uint256)\",\"SIMDTESTToken.claim()\",\"SIMDTESTToken.transfer(address,uint256)\",\"SIMDTESTToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":199,\"foundry.toml\":17,\"launch.json\":28,\"src/SIMDTESTToken.sol\":178,\"test/DividendRevision.t.sol\":153,\"test/SIMDTESTAdversarial.t.sol\":277,\"test/SIMDTESTInvariant.t.sol\":238,\"test/SIMDTESTMainnetFork.t.sol\":64,\"test/SIMDTESTToken.t.sol\":354,\"test/TESTING.md\":40,\"test/UniswapV4.t.sol\":316,\"test/helpers/TestBase.sol\":37,\"tools/launch_price.py\":64},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"fe0e4181c9f9ad5a81a341bc040eef056f5635be932707590ba2f51786fb182d","verifiedTreeHash":"46128b7f4aad7d386d2212d78969369ac8c1e922","verifierVersion":"0.1.0+ad90ce4c"}]}