{"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":"8f8003e9-b967-4ca8-ba26-f47c8419c5f8","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"391c021694dc88c09323b4ea10ed76435ad6f093b838ff209ef5a662c7e87172","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"3cfe8da18cfb716633369e8ba995ecc26dcee72a6e1db6380b2c3af1d6eba050","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"d807719911b4eb4f41ed45523c101a1bf0be506918f83332076f6f39731513df","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"b89279670f5a00f5d26286edee00c97dd158b997031350a01cafe6e0329ad227","skillId":"audit-judge","subagents":4,"tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"b89279670f5a00f5d26286edee00c97dd158b997031350a01cafe6e0329ad227","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"649b6a5f1f3eadec60a1693d5bf90113a8ec72f820b21f2bbcb02d522beb138c","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"5d9b3bb6be23bc8e89413f9a351a6165d9c40866a5aea1ac45535d77e144151f","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","subagents":3,"tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"bc5bfc8455464381f2db18badb2b55cf8bec1e535c019349a0378fa990741171","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"93c442f7f6e07ee555a5f02d142580924246a8edb6d5591de3ed0974dcc7a87b","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"15b04fc8f60521936b9e2b37c09a804685ec689fc98cd5b04510d986d3106a15","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"15b04fc8f60521936b9e2b37c09a804685ec689fc98cd5b04510d986d3106a15","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"dd04eb51ec9a202334cf93daa6656d196f0005d8f722d92991524578da6cc8ef","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"cedbbd91f67f56abc4931cdb0d0479a586ab66506474e251fce224fae6109b50","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"1ddb4d02eb75e52d5f38cfd5c9bb54f332687b81929c68880cf1e8a6ab27254d","skillId":"write-foundry-tests","subagents":4,"tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"1ddb4d02eb75e52d5f38cfd5c9bb54f332687b81929c68880cf1e8a6ab27254d","skillId":"write-foundry-tests","state":"accepted"}],"objective":"A custom token: AIDIVN (ADVN).\nToken name: AIDIVN\nToken symbol: ADVN\nToken supply: 1,000,000,000 with 18 decimals, all minted once to the deployer in the constructor.\nWhat it does: A 0.5% transfered from every trade fee to Jensen Huang (0xc59b0c072f73ceea3dc354031165501c0ff25023) and a 1% burn of supply from every fee. Thank you for all you have done to the industry Jensen!","parentJobId":null,"planHash":"e594cc9f237c29d2ee3e1dc93ba5c7acf4203beabca24287e4c1034f3d100843","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"8f8003e9-b967-4ca8-ba26-f47c8419c5f8","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-3251-aidivn"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51486","feedbackHash":"fe505aaafeefdbacab8f16cea1cbf95e06b3358b0b3fccdffdc656df6c1a6025","nodeKey":"audit_economics","submissionHash":"391c021694dc88c09323b4ea10ed76435ad6f093b838ff209ef5a662c7e87172","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51018","feedbackHash":"adedecc282006a4521cfe1796bcaa4147b964e053bdd0bcadcfd3783810dae4a","nodeKey":"audit_flow","submissionHash":"3cfe8da18cfb716633369e8ba995ecc26dcee72a6e1db6380b2c3af1d6eba050","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51277","feedbackHash":"eaab104fd31117d831667ac707e7d22b80891faf1e16647a79b2425849024b6e","nodeKey":"audit_judge","submissionHash":"3b2f839f22b72c94253ac364cdc4c1d4a7b05d8c86381214fb16f4908601510b","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51522","feedbackHash":"b644d0310c0d70d77bfa9537db8adf04e313f5abbc136e89414bb3da4b2cfa00","nodeKey":"audit_judge","submissionHash":"d807719911b4eb4f41ed45523c101a1bf0be506918f83332076f6f39731513df","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"54235","feedbackHash":"f35e4823fb58c0fc5c6c095d2fa2cabaf455b7388e7133238554f6cb8c0a526f","nodeKey":"audit_math","submissionHash":"649b6a5f1f3eadec60a1693d5bf90113a8ec72f820b21f2bbcb02d522beb138c","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52599","feedbackHash":"3f1d94640099ef439975e83113d7785c69c8494dee517ef29235fbd449cb9164","nodeKey":"audit_permissions","submissionHash":"5d9b3bb6be23bc8e89413f9a351a6165d9c40866a5aea1ac45535d77e144151f","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52681","feedbackHash":"5483621a8cd519ed5b159071648ba934a14fb788f4503428b9f90b8109401dde","nodeKey":"build_contract_project","submissionHash":"93c442f7f6e07ee555a5f02d142580924246a8edb6d5591de3ed0974dcc7a87b","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51304","feedbackHash":"79c9578aefcbd6ac46872aae2545c2e07c68c90a83e7a8d837a8c93102c166f9","nodeKey":"build_contract_project","submissionHash":"0f82b00d6bd897d7a949d8fb390edfcb6d47315f3b6c0163b3f8f322e08136d8","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51868","feedbackHash":"458a2fe5f47223dca2e73f2d266bb2a5a5e1b99e8543853adf8ffa9301b9558a","nodeKey":"manifest","submissionHash":"ef4dffcada5c39651f71cbed800283f9e17a873c88d2d585f27af8fc4f80e181","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52624","feedbackHash":"354a1c6cb702cefb2e69d5d5aad4aa6151c3aaa779c700b4bc8360efaa3b1adf","nodeKey":"manifest","submissionHash":"dd04eb51ec9a202334cf93daa6656d196f0005d8f722d92991524578da6cc8ef","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51188","feedbackHash":"de9dcff5e587fb86b95b3df5e633cc4e243bb9369158d66056d8caa7c7242168","nodeKey":"write_foundry_tests","submissionHash":"cedbbd91f67f56abc4931cdb0d0479a586ab66506474e251fce224fae6109b50","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"54147","feedbackHash":"1c1b2f3b77aa4bfaba59c516adadca0e2056036ce3c9c3806ef71235e2c0cbe0","nodeKey":"write_foundry_tests","submissionHash":"b9f28add9c78eff79c436f6879928fc346741be55f070c620467b5261ff63827","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"468eac8a30f44d75b397c022dd321e548ad9ab48e3f43db11a04361cb2251e04","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"408e1c0e4e9f05ed04e1bf754ccec62330952a39e7d385b4190fcdb274cb6b17","device":"4be5e039e1c77ce3","findings":[],"hash":"0f82b00d6bd897d7a949d8fb390edfcb6d47315f3b6c0163b3f8f322e08136d8","nodeId":"32078e99-5d01-4b36-b0a2-1d37b52a20ba","outcome":"completed","summary":"The deliverable is complete and verified from a clean copy of the tree.\n\n**What was built**\n\n- `src/ADVNToken.sol`: `AIDIVN` / `ADVN`, 18 decimals, 1,000,000,000 tokens minted once to `msg.sender` (the launch factory). Constructor takes `$factory`, `$poolManager`, `$launchNumber`, stores them and calls nothing. No owner, mint, pause, blocklist or upgrade.\n- Every taxed transfer sends 0.5% to Jensen Huang's address and burns 1%. The recipient gets 98.5%. A `TradeTaxed` event records each split.\n- Untaxed flows are exactly the launch flows: the factory sending, the launch's MerkleDistributor sending (resolved through `distributorOf` at transfer time, failure-tolerant), and anything sent into the Uniswap v4 PoolManager. Tokens leaving the PoolManager are taxed, so buys from the launch pool pay the fee and burn.\n\n**Key assumption, documented in README and REVIEW**\n\nSells into the v4 pool cannot be taxed without a hook, because v4 settlement requires the PoolManager to receive exactly the declared amount. The brief's \"1% burn of supply from every fee\" is read as 1% of the transferred amount, with the alternative reading noted and one constant to change.\n\n**Verification**\n\n| Check | Result |\n|---|---|\n| `forge build --offline --sizes` | ADVNToken 3,179 bytes runtime |\n| `forge test --offline` | 43 passed (unit, fuzz, 3 invariants, 6 real-PoolManager flow tests) |\n| Verifier fuzz seed and a second seed with 1000 runs | all pass |\n| `forge fmt --check` | clean |\n| Slither, low excluded and high-only | 0 results both ways |\n| Clean-copy rebuild of only src, test, lib and config | identical results |\n\nLibraries are vendored as plain files under `lib/` with no nested `.git`. README covers rules, interface, manifest constructor values, assumptions, operational responsibilities and offline build steps. REVIEW lists five low or informational findings with dispositions. No `launch.json` was written.","treeHash":"01d26d5f54cd645430d7e004394fe31d35fb25da","usage":{"cachedInputTokens":1722387,"cost":{"source":"runtime","usdMicros":4915688},"inputTokens":674,"model":"claude-fable-5-1","outputTokens":50637,"runtime":"claude","turns":22,"wallClockMs":635646}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"0e78515c4d95885a","findings":[{"citation":"resolved","description":"The tax is applied only inside ERC-20 _update, and every transfer whose destination is the PoolManager is exempt (`to == POOL_MANAGER`). The design therefore relies on the PoolManager paying buyers with a plain ERC-20 `transfer` (README: 'Buys from the pool are taxed because the PoolManager pays the trader with a plain transfer'). That is not a guarantee v4 gives: any unlocker may settle a positive delta with `PoolManager.mint(to, currencyId, amount)` (ERC-6909 claims) instead of `take`, and may pay a negative delta with `PoolManager.burn(...)` instead of transferring tokens in. No ERC-20 transfer from the PoolManager happens, so no fee is paid to FEE_RECIPIENT and nothing is burned. Consequences, all by an unprivileged trader with no special state: (1) a buy from the launch pool pays 0 fee and burns 0 (expected 0.5% and 1% of the swap output); (2) the trader can later sell by burning claims, so a whole buy/sell cycle is untaxed, while a retail trader using take/transfer pays 1.5% on every buy; (3) claims are ERC-6909 tokens transferable on the PoolManager, so ADVN value moves wallet-to-wallet untaxed, and anyone can also wrap ERC-20 ADVN into claims untaxed (sync -> transfer to POOL_MANAGER, exempt -> settle -> mint) and hand them on; only a final `take` back to ERC-20 is taxed, and a holder who exits by selling into the pool never pays it. Economic effect: the fee stream to Jensen Huang and the deflationary burn, the token's two stated economics, are optional for sophisticated traders, bots and routers that use claim settlement, and fall only on users of plain take/transfer flows. Economic Security guide: 'find where the code uses assumed amounts/behaviour instead of actual'; Flow Gap seam periphery x first principles: the exemption is correct for v4 settlement in isolation but defeats the stated 'every trade is taxed' purpose. Not loss of funds and not fixable by the token alone, hence medium. Fix / scope decision for the requester: (a) if every pool trade must be taxed, only a v4 hook (afterSwap taking the fee on the ADVN side, or charging the swap delta) can enforce it, which is outside this launch kind and needs a scope decision; otherwise (b) correct the README/launch notes so they do not claim buys are taxed, and state that the tax applies to ERC-20 transfers out of the PoolManager only and is avoidable through ERC-6909 claim settlement. Rounding note from the same guide pass: fee and burn floor, so amount 199 pays fee 0 and burns 1, amount 99 pays nothing; dust only, not reported separately.","line":76,"path":"src/ADVNToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {IUnlockCallback} from \"v4-core/src/interfaces/callback/IUnlockCallback.sol\";\nimport {IHooks} from \"v4-core/src/interfaces/IHooks.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {BalanceDelta} from \"v4-core/src/types/BalanceDelta.sol\";\nimport {ModifyLiquidityParams, SwapParams} from \"v4-core/src/types/PoolOperation.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {ADVNToken} from \"src/ADVNToken.sol\";\n\n/// @notice The launch factory: deploys the token, seeds the pool single-sided, answers distributorOf.\ncontract SeedFactory is IUnlockCallback {\n    IPoolManager internal immutable manager;\n    mapping(uint64 => address) public distributorOf;\n\n    constructor(IPoolManager manager_) {\n        manager = manager_;\n    }\n\n    function deployToken(uint64 launchNumber) external returns (ADVNToken) {\n        return new ADVNToken(address(this), address(manager), launchNumber);\n    }\n\n    function seed(PoolKey calldata key, int24 tickLower, int24 tickUpper, uint128 liquidity) external {\n        manager.unlock(abi.encode(key, tickLower, tickUpper, liquidity));\n    }\n\n    function unlockCallback(bytes calldata data) external override returns (bytes memory) {\n        require(msg.sender == address(manager), \"not the pool manager\");\n        (PoolKey memory key, int24 tickLower, int24 tickUpper, uint128 liquidity) =\n            abi.decode(data, (PoolKey, int24, int24, uint128));\n        (BalanceDelta delta,) = manager.modifyLiquidity(\n            key, ModifyLiquidityParams(tickLower, tickUpper, int256(uint256(liquidity)), bytes32(0)), \"\"\n        );\n        require(delta.amount0() == 0, \"single-sided seed takes no ETH\");\n        uint256 owed = uint256(uint128(-delta.amount1()));\n        manager.sync(key.currency1);\n        require(IERC20(Currency.unwrap(key.currency1)).transfer(address(manager), owed), \"transfer failed\");\n        manager.settle();\n        return \"\";\n    }\n}\n\n/// @notice An ordinary trader that never takes ADVN out of the PoolManager as ERC-20: it keeps what\n///         it buys as ERC-6909 claims (`mint`) and pays for what it sells by burning claims (`burn`).\n///         Nothing here is privileged; any router or bot can do the same.\ncontract ClaimTrader is IUnlockCallback {\n    IPoolManager internal immutable manager;\n\n    constructor(IPoolManager manager_) {\n        manager = manager_;\n    }\n\n    receive() external payable {}\n\n    function buyAsClaims(PoolKey calldata key, uint256 ethIn) external returns (uint256 bought) {\n        return abi.decode(manager.unlock(abi.encode(uint8(0), key, ethIn)), (uint256));\n    }\n\n    function sellFromClaims(PoolKey calldata key, uint256 tokensIn) external returns (uint256 ethOut) {\n        return abi.decode(manager.unlock(abi.encode(uint8(1), key, tokensIn)), (uint256));\n    }\n\n    function giveClaims(address to, uint256 id, uint256 amount) external {\n        manager.transfer(to, id, amount);\n    }\n\n    function unlockCallback(bytes calldata data) external override returns (bytes memory) {\n        require(msg.sender == address(manager), \"not the pool manager\");\n        (uint8 kind, PoolKey memory key, uint256 amount) = abi.decode(data, (uint8, PoolKey, uint256));\n        uint256 tokenId = uint256(uint160(Currency.unwrap(key.currency1)));\n        if (kind == 0) {\n            // Buy: exact ETH in, ADVN out, credited as claims instead of transferred.\n            BalanceDelta delta =\n                manager.swap(key, SwapParams(true, -int256(amount), TickMath.MIN_SQRT_PRICE + 1), \"\");\n            manager.settle{value: uint256(uint128(-delta.amount0()))}();\n            uint256 out = uint256(uint128(delta.amount1()));\n            manager.mint(address(this), tokenId, out);\n            return abi.encode(out);\n        }\n        // Sell: exact ADVN in paid by burning claims, ETH out.\n        BalanceDelta sell = manager.swap(key, SwapParams(false, -int256(amount), TickMath.MAX_SQRT_PRICE - 1), \"\");\n        manager.burn(address(this), tokenId, uint256(uint128(-sell.amount1())));\n        uint256 ethOut = uint256(uint128(sell.amount0()));\n        manager.take(key.currency0, address(this), ethOut);\n        return abi.encode(ethOut);\n    }\n}\n\n/// @notice A buy from the launch pool settled as ERC-6909 claims pays no fee and burns nothing,\n///         and the claims can be sold back or handed to anyone without ever touching the token.\ncontract ClaimBypassTest is Test {\n    uint256 constant SUPPLY = 1_000_000_000 * 1e18;\n    uint64 constant LAUNCH_NUMBER = 3;\n    uint160 constant SQRT_PRICE_1_1 = 79228162514264337593543950336;\n    int24 constant TICK_LOWER = -887_220;\n    int24 constant TICK_UPPER = -60;\n    uint128 constant SEED_LIQUIDITY = 1e26;\n    address constant JENSEN = 0xc59b0c072f73ceEA3Dc354031165501c0Ff25023;\n\n    PoolManager manager;\n    SeedFactory factory;\n    ADVNToken token;\n    ClaimTrader trader;\n    PoolKey key;\n\n    function setUp() public {\n        manager = new PoolManager(address(this));\n        factory = new SeedFactory(manager);\n        token = factory.deployToken(LAUNCH_NUMBER);\n        trader = new ClaimTrader(manager);\n        vm.deal(address(trader), 100 ether);\n        key = PoolKey(Currency.wrap(address(0)), Currency.wrap(address(token)), 12_500, 60, IHooks(address(0)));\n        manager.initialize(key, SQRT_PRICE_1_1);\n        factory.seed(key, TICK_LOWER, TICK_UPPER, SEED_LIQUIDITY);\n    }\n\n    function test_buySettledAsClaimsIsTaxedLikeAnyOtherBuy() public {\n        uint256 supplyBefore = token.totalSupply();\n        uint256 poolBefore = token.balanceOf(address(manager));\n\n        // An ordinary trader buys with 1 ETH and keeps the output as ERC-6909 claims.\n        uint256 gross = trader.buyAsClaims(key, 1 ether);\n        assertGt(gross, 0, \"the pool paid out tokens\");\n        assertEq(manager.balanceOf(address(trader), uint256(uint160(address(token)))), gross, \"claims for the whole output\");\n        assertEq(token.balanceOf(address(manager)), poolBefore, \"no ERC-20 left the PoolManager\");\n\n        // The trader can sell everything back by burning claims, and get ETH, still without an ERC-20 transfer.\n        uint256 ethBefore = address(trader).balance;\n        uint256 ethOut = trader.sellFromClaims(key, gross);\n        assertGt(ethOut, 0);\n        assertEq(address(trader).balance, ethBefore + ethOut, \"the round trip paid out ETH\");\n\n        // What the token promises for every buy from the pool: 0.5% to Jensen and 1% burned.\n        (uint256 fee, uint256 burned,) = token.previewTransfer(gross);\n        assertGt(fee, 0);\n        assertGt(burned, 0);\n        assertEq(token.balanceOf(JENSEN), fee, \"the buy paid Jensen no fee\");\n        assertEq(token.totalSupply(), supplyBefore - burned, \"the buy burned nothing\");\n    }\n\n    function test_claimsMoveBetweenWalletsUntaxed() public {\n        address bob = makeAddr(\"bob\");\n        uint256 gross = trader.buyAsClaims(key, 1 ether);\n        uint256 id = uint256(uint160(address(token)));\n        trader.giveClaims(bob, id, gross);\n        assertEq(manager.balanceOf(bob, id), gross, \"bob holds the whole amount as claims\");\n        // A wallet-to-wallet move of `gross` ADVN is a taxed transfer per the token's rules.\n        (uint256 fee,,) = token.previewTransfer(gross);\n        assertEq(token.balanceOf(JENSEN), fee, \"the wallet-to-wallet move paid no fee\");\n    }\n}","reproduction":"State: token deployed by the factory, pool ETH/ADVN (fee 12500, spacing 60) initialised at sqrtPrice 2^96 and seeded single-sided by the factory with liquidity 1e26 in ticks [-887220, -60] (same as test/LaunchFlow.t.sol). Calls by an ordinary contract T (not factory, not distributor): manager.unlock -> in unlockCallback: swap(key, zeroForOne=true, amountSpecified=-1e18, limit MIN_SQRT_PRICE+1) -> settle{value: 1 ether}() -> mint(T, uint256(uint160(address(token))), amount1). Observed: manager.balanceOf(T, id) == amount1 == 981593024297300372 (gross swap output), token.balanceOf(manager) unchanged, token.balanceOf(FEE_RECIPIENT) == 0, totalSupply unchanged. Expected per README/NatSpec for a buy from the pool: FEE_RECIPIENT receives previewTransfer(amount1).fee == 4907965121486501 and totalSupply falls by previewTransfer(amount1).burned == 9815930242973003. Then T sells: swap(key, false, -amount1) -> burn(T, id, amount1) -> take(ETH, T, amount0): T gets ETH back, still fee 0 / burn 0. Also T calls manager.transfer(bob, id, amount1): bob holds the full amount as claims, no fee. Run: forge test --offline --match-path test/scratch/ClaimBypass.t.sol (2 tests fail on this code: 'the buy paid Jensen no fee: 0 != 4907965121486501', 'the wallet-to-wallet move paid no fee: 0 != 4907965121486501').","severity":"medium","snippet":"    function isExempt(address from, address to) public view returns (bool) {\n        if (from == FACTORY || to == POOL_MANAGER) return true;\n        address launchDistributor = distributor();\n        return launchDistributor != address(0) && from == launchDistributor;\n    }","title":"Trade tax (0.5% fee + 1% burn) is skipped entirely for any Uniswap v4 trade settled as ERC-6909 claims; buys, round trips and wallet-to-wallet moves can all avoid it"}],"hash":"391c021694dc88c09323b4ea10ed76435ad6f093b838ff209ef5a662c7e87172","nodeId":"4a86a3f6-54a0-44af-ae18-fec43eb55a31","outcome":"completed","summary":"The review is complete and the findings file is written and validated.\n\n**Outcome:** one substantiated finding, severity medium, with a Foundry proof that fails on the current code. The token's accounting is otherwise sound in my area.\n\n**Finding 1 (medium): the trade tax can be skipped on every Uniswap v4 trade.** The tax lives only in ERC-20 `_update`, and anything sent to the PoolManager is exempt. Uniswap v4 lets any unlocker settle a buy as ERC-6909 claims with `mint` instead of `take`, and pay a sell by burning claims. No ERC-20 transfer from the PoolManager happens, so the 0.5% fee to Jensen Huang and the 1% burn never fire. I reproduced it against the vendored real PoolManager with the same seed as the project's own launch tests:\n\n```\n1 ETH buy settled as claims: gross output 981593024297300372 ADVN\nexpected fee to Jensen        4907965121486501   observed 0\nexpected supply decrease      9815930242973003   observed 0\n```\n\nThe same trader then sold the claims back for ETH and handed claims to another wallet, both untaxed. Anyone can also wrap ERC-20 ADVN into claims untaxed, since the transfer into the PoolManager is exempt. The practical effect is that the fee stream and the burn fall only on users of plain take/transfer flows, while bots and routers using claim settlement avoid them. The README statement that buys are taxed because the PoolManager pays with a plain transfer is not a guarantee v4 gives. The token cannot fix this alone. The requester must either accept and document it, or ask for a v4 hook, which is a scope decision outside this launch kind.\n\n**What holds, with the reasoning recorded in the coverage rows:**\n- Sum of balances equals total supply, and supply only shrinks through burns. The sender is always debited the full amount.\n- Launch flows move exactly what they say. Seed, swarm share, distributor claim and sells into the pool settle exactly.\n- Pool solvency is intact. A `take` of X reduces the PoolManager's balance by exactly X.\n- Preview matches execution. Fee and burn round down, so dust under 200 units escapes the fee, which is documented and not worth a separate finding.\n- Fee recipient and rates match the brief. No owner, minter, setter or pause exists.\n\n**Files:** findings and nine coverage rows are in `.imd-findings.json`, and the proof test is at `test/scratch/ClaimBypass.t.sol`. No source, test or configuration file was changed. The existing suite of 43 tests still passes.","treeHash":null,"usage":{"cachedInputTokens":415525,"cost":{"source":"runtime","usdMicros":2849334},"inputTokens":226,"model":"claude-fable-5-1","outputTokens":21104,"runtime":"claude","turns":18,"wallClockMs":300039}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"15bd92bc67806379","findings":[{"citation":"resolved","description":"Merged from audit_economics (medium), audit_permissions (medium), audit_math (low) and the two audit_flow info items on claims and on sells: one root cause. The fee and burn live in ERC-20 _update (line 92) and every transfer whose destination is the PoolManager is exempt at line 77. Uniswap v4 lets any unlocker settle a positive ADVN delta with PoolManager.mint (ERC-6909 claims) instead of take, pay a negative delta with PoolManager.burn instead of an ERC-20 transfer in, and move claims between accounts with the PoolManager's own transfer(receiver, id, amount). None of these calls the token, so _update never runs. Consequences for an unprivileged trader with a custom unlock callback (bots, aggregators, any contract router): a buy from the launch pool pays 0 to FEE_RECIPIENT and burns 0 (README: 'Buys from the pool are taxed'); a full buy/sell round trip is untaxed because sells into the PoolManager are exempt by design; ERC-20 holdings can be wrapped into claims untaxed (sync, transfer to POOL_MANAGER which is exempt, settle, mint) and passed on without the 1.5% the README promises for wallet-to-wallet moves ('taxed in both directions'). The tax falls only on users whose router takes ERC-20 out of the PoolManager. Impact: the fee stream to Jensen Huang and the deflationary burn, the brief's two economics, are optional for sophisticated flow; no holder funds are lost, so medium (broken stated guarantee). The sell exemption is required by the launch floor (Token.protected.t.sol lines 277-278 sell the whole bought balance; v4 settle credits exactly balanceOf - reserves) and is documented in REVIEW.md item 1; the claim-settlement bypass is not documented anywhere. Fix is a requester scope decision, not a token-only change: (a) tax pool trades in a Uniswap v4 hook (afterSwap charging the ADVN side), which this launch kind does not deploy, or (b) keep the token and correct README 'Limits' and launch.json notes to say the tax applies only to ERC-20 transfers leaving the PoolManager and ordinary wallet transfers, and that buys, sells and holder moves settled as ERC-6909 claims are untaxed. No proof is attached because no token-only change can make a proof pass; the specialists' proofs (Proof_75cb98bdc9ba.t.sol, Proof_d9208913675c.t.sol) were run and fail on this code exactly as stated.","line":77,"path":"src/ADVNToken.sol","reproduction":"State: PoolManager deployed; ADVNToken(factory, manager, 3) deployed by a factory contract; pool ETH/ADVN (fee 12500, tickSpacing 60, no hook) initialised at sqrtPriceX96 = 2^96 and seeded by the factory single-sided with liquidity 1e26 over ticks [-887220, -60] (as in test/LaunchFlow.t.sol). Trader T is an ordinary contract with 100 ETH. T calls manager.unlock and in unlockCallback: swap(key, zeroForOne=true, amountSpecified=-1e18, sqrtPriceLimit=MIN_SQRT_PRICE+1); settle{value: 1 ether}(); manager.mint(T, uint256(uint160(address(token))), amount1). Expected per README/NatSpec for a buy from the pool: FEE_RECIPIENT balance == previewTransfer(amount1).fee == 4907965121486501 and totalSupply falls by 9815930242973003. Actual: manager.balanceOf(T, id) == 981593024297300372 (the gross output), token.balanceOf(manager) unchanged, token.balanceOf(FEE_RECIPIENT) == 0, totalSupply unchanged. Then T unlocks again: swap(key, false, -981593024297300372), manager.burn(T, id, amount), take(ETH, T, amount0): T receives ETH, FEE_RECIPIENT still 0, supply still unchanged. Also manager.transfer(bob, id, 981593024297300372) from T: bob holds the full amount as claims, fee 0. Verified by running forge test --offline --match-path 'test/scratch/Proof_75cb98bdc9ba.t.sol': both tests fail ('the buy paid Jensen no fee: 0 != 4907965121486501', 'the wallet-to-wallet move paid no fee: 0 != 4907965121486501'); Proof_d9208913675c.t.sol fails the same way. The sell half: test/LaunchFlow.t.sol::test_buyIsTaxedOnTheWayOutAndSellIsExactOnTheWayIn passes and asserts FEE_RECIPIENT and totalSupply unchanged across the sell.","severity":"medium","snippet":"        if (from == FACTORY || to == POOL_MANAGER) return true;","title":"The trade tax reaches only ERC-20 transfers out of the PoolManager: v4 buys settled as ERC-6909 claims, claim-to-claim moves and all sells pay no fee and burn nothing"},{"citation":"resolved","description":"Merged from audit_flow (low), audit_math (info) and write_foundry_tests (low). Line 70 guards a failed call and a short answer, and the README ('Assumptions') promises the lookup 'never reverts a transfer'. A successful 32-byte answer with any of the top 96 bits set is not guarded: Solidity 0.8's abi.decode validates the address and reverts with empty data. isExempt (line 78) runs the lookup on every transfer that is not from FACTORY and not into POOL_MANAGER, so such an answer would revert every wallet-to-wallet transfer and every take out of the PoolManager (every buy) while the factory kept answering that way. Precondition: a factory that does not return a canonical address. FACTORY is immutable and the real ProjectFactory's distributorOf is a mapping(uint64 => address) getter (the floor's LaunchProbe models it the same way), so this is not reachable in the launch as specified; it is a robustness gap and a documentation mismatch, hence low. Minimal fix that keeps the intended behaviour: decode the word as uint256 and treat anything above type(uint160).max as 'no distributor', e.g. uint256 word = abi.decode(data, (uint256)); if (word > type(uint160).max) return address(0); return address(uint160(word));","line":71,"path":"src/ADVNToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {ADVNToken} from \"src/ADVNToken.sol\";\n\ncontract NonCanonicalFactory {\n    function deploy(address manager) external returns (ADVNToken) {\n        return new ADVNToken(address(this), manager, 1);\n    }\n\n    function send(ADVNToken token, address to, uint256 amount) external {\n        require(token.transfer(to, amount));\n    }\n\n    fallback() external {\n        // One full ABI word with bit 160 set is not a canonical address encoding.\n        assembly (\"memory-safe\") {\n            mstore(0, shl(160, 1))\n            return(0, 32)\n        }\n    }\n}\n\ncontract DistributorResponseProof is Test {\n    function test_malformedLookupMustNotFreezeAnOrdinaryTransfer() public {\n        NonCanonicalFactory factory = new NonCanonicalFactory();\n        ADVNToken token = factory.deploy(makeAddr(\"proof pool manager\"));\n        address alice = makeAddr(\"proof alice\");\n        address bob = makeAddr(\"proof bob\");\n        factory.send(token, alice, 200);\n        vm.prank(alice);\n        assertTrue(token.transfer(bob, 200), \"invalid lookup should fall back to ordinary taxation\");\n        assertEq(token.balanceOf(alice), 0);\n        assertEq(token.balanceOf(bob), 197);\n        assertEq(token.balanceOf(0xc59b0c072f73ceEA3Dc354031165501c0Ff25023), 1);\n        assertEq(token.totalSupply(), 1_000_000_000e18 - 2);\n    }\n}","reproduction":"Deploy a factory whose fallback returns the 32-byte word uint256(1) << 160 for any call. From it deploy ADVNToken(factory, 0x900C-like pool manager, 1); factory.transfer(alice, 200) succeeds (from == FACTORY, no lookup). alice.transfer(bob, 200): expected per README, a taxed transfer (bob 197, FEE_RECIPIENT 1, supply 1e27 - 2); actual, the call reverts with empty revert data inside abi.decode(data, (address)). token.distributor() and token.isExempt(alice, bob) revert the same way; alice.transfer(POOL_MANAGER, 200) still succeeds. Run: forge test --offline --match-path test/scratch/Proof_94382f07a028.t.sol -> [FAIL: EvmError: Revert] test_malformedLookupMustNotFreezeAnOrdinaryTransfer.","severity":"low","snippet":"        return abi.decode(data, (address));","title":"distributor() reverts, and with it every taxed transfer, when the factory answers distributorOf with a 32-byte word that is not a clean address"},{"citation":"resolved","description":"From write_foundry_tests (low), recalibrated to info. previewTransfer is a public pure view with no documented input domain; it multiplies before dividing, so amount * BURN_BPS overflows (Panic 0x11) once amount >= 2^256/100 (about 1.16e75), with amount * FEE_BPS overflowing from 2^256/50. The advertised percentages fit for any uint256. No transfer can reach this: _update checks balanceOf(from) >= value at line 98 before calling the preview, and the supply is 1e27. Only an off-chain or integrator call with an absurd amount reverts. Fix if wanted: compute fee = amount / 200 and burned = amount / 100 (identical results for every amount, since 50/10000 = 1/200 and 100/10000 = 1/100), or use Math.mulDiv.","line":85,"path":"src/ADVNToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {ADVNToken} from \"src/ADVNToken.sol\";\n\ncontract PreviewOverflowProof is Test {\n    function test_previewDoesNotOverflowWhenAllResultsFit() public {\n        ADVNToken token = new ADVNToken(address(this), makeAddr(\"proof pool manager\"), 1);\n        uint256 amount = type(uint256).max / 100 + 1;\n        (uint256 fee, uint256 burned, uint256 received) = token.previewTransfer(amount);\n        assertEq(fee, amount / 200);\n        assertEq(burned, amount / 100);\n        assertEq(received, amount - amount / 200 - amount / 100);\n    }\n}","reproduction":"Deploy ADVNToken(nonzero factory, nonzero pool manager, 1). Call previewTransfer(type(uint256).max / 100 + 1) = previewTransfer(1157920892373161954235709850086879078532699846656405640394575840079131296400). Expected: fee = amount/200, burned = amount/100, received = amount - fee - burned. Actual: Panic(0x11) at amount * BURN_BPS. Run: forge test --offline --match-path test/scratch/Proof_7d1582d2be49.t.sol -> [FAIL: panic: arithmetic underflow or overflow (0x11)].","severity":"info","snippet":"        burned = amount * BURN_BPS / BPS_DENOMINATOR;","title":"previewTransfer overflows for amounts of 2^256/100 and above although every result fits in uint256"},{"citation":"resolved","description":"From audit_flow (info). The brief says 'a 0.5% transfered from every trade fee to Jensen Huang ... and a 1% burn of supply from every fee'. The build burns 100 bps of each taxed amount, so a taxed transfer costs 1.5% in total. The other reading burns 1% of the 0.5% fee (0.005% of the amount). The author chose the first reading and documents it (README 'Reading of the brief', REVIEW.md item 2); the code, previewTransfer and all tests are consistent with it. Not a code defect; recorded so the requester confirms the intended deflation rate before release, since BURN_BPS is immutable after deployment.","line":31,"path":"src/ADVNToken.sol","reproduction":"alice holds 10_000e18 (sent by the factory). alice.transfer(bob, 1_000e18). Actual (test/ADVNToken.t.sol::test_walletTransferPaysFeeAndBurns, passes): bob receives 985e18, FEE_RECIPIENT receives 5e18, totalSupply falls by 10e18. Under the alternative reading: bob would receive 994.95e18 and the supply would fall by 0.05e18.","severity":"info","snippet":"    uint256 public constant BURN_BPS = 100;","title":"Burn base is 1% of the transferred amount; the brief's wording also admits 1% of the fee, a 200x difference the requester should confirm"}],"hash":"3b2f839f22b72c94253ac364cdc4c1d4a7b05d8c86381214fb16f4908601510b","nodeId":"cbf7bbb7-197c-4688-aa24-3b9fa40fd351","outcome":"completed","summary":"The review is complete. The findings file is written and validated against the tree, with every snippet matching its cited line.\n\n**Outcome:** four findings kept from the eleven specialist reports, none above medium, and the three entry points all answered.\n\n- **Medium, line 77 of src/ADVNToken.sol.** The trade tax only fires on ERC-20 transfers leaving the PoolManager. A Uniswap v4 trader who settles with ERC-6909 claims (mint instead of take, burn instead of transfer in) buys, sells and moves ADVN with no fee to Jensen Huang and no burn. Sells are exempt by design and documented, but the claim bypass is not. I merged five reports from economics, permissions, math and flow into this one. Both specialist proofs fail on the code as stated, with 0 paid against an expected 4907965121486501 wei of fee on a 1 ETH buy. No proof is attached because no token-only change can fix it; the requester must choose between a v4 hook (outside this launch kind) and correcting the README and manifest notes.\n- **Low, line 71.** If the factory ever answers distributorOf with a 32-byte word that is not a clean address, abi.decode reverts and every taxed transfer and every buy reverts with it, contrary to the README's \"never reverts\" promise. Three reports merged. The real factory is a mapping getter, so this is a robustness gap only. The tester's proof is attached and fails here.\n- **Info, line 85.** previewTransfer overflows for amounts of 2^256/100 and above even though the results fit. Unreachable from any transfer. Proof attached.\n- **Info, line 31.** The burn is 1% of the transferred amount; the brief's wording also admits 1% of the fee. Documented by the author, but the requester should confirm since the constant is immutable.\n\n**Dropped:** the preview-versus-exempt-flow note (the view is documented as the taxed preview) and the dust rounding note (documented, at most 2 wei per transfer). The aderyn large-literal line is style only.\n\n**My own pass** found nothing further. I checked self-transfers, fee-recipient sends, allowance accounting, zero-value and zero-receiver transfers, the distributor exemption boundaries, a factory with no code, the distributorOf(uint64) selector against the floor's probe, and contract sizes. The full project suite passes with 74 tests. Coverage rows mark approve as holds and transfer and transferFrom as finding 1, with four invariant rows all holding.","treeHash":null,"usage":{"cachedInputTokens":530688,"cost":{"source":"runtime","usdMicros":2513635},"inputTokens":258,"model":"claude-fable-5-1","outputTokens":18611,"runtime":"claude","turns":9,"wallClockMs":275552}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"30a6c1a419ef4f9c","findings":[{"citation":"resolved","description":"Execution Trace / untrusted return values. `distributor()` guards `!ok` and `data.length < 32` (line 70) and the README (line 110) states that a failed lookup 'never reverts a transfer'. The remaining case is not guarded: a 32-byte answer whose upper 96 bits are non-zero. Solidity 0.8's ABI decoder validates `address` and reverts on such a word, and because `isExempt` is called from `_update` on every non-factory, non-PoolManager transfer, that revert propagates into `transfer` and `transferFrom`: every taxed transfer (including a buyer's `take` out of the PoolManager) would fail while the factory keeps answering that way. The precondition is a factory that does not return a clean address, which the real ProjectFactory (a mapping getter) does not do, so the impact is a robustness gap and a documentation mismatch rather than a live loss. A minimal fix keeps the intended behaviour: decode defensively, e.g. `uint256 word = abi.decode(data, (uint256)); if (word > type(uint160).max) return address(0); return address(uint160(word));`.","line":71,"path":"src/ADVNToken.sol","reproduction":"State: factory contract whose `distributorOf(uint64)` returns the word `(1 << 160) | 0xD157` (any non-zero upper bits). Deploy ADVNToken(factory, 0x900C, 1) from that factory; factory.transfer(alice, 1000e18) succeeds (exempt, no lookup). Then alice.transfer(bob, 1e18): expected per README, a taxed transfer (bob gets 0.985e18); actual, the call reverts (abi.decode address validation). `token.distributor()` reverts too. Reproduced in test/scratch/Leads.t.sol::test_lead_dirtyAddressAnswerRevertsEveryTaxedTransfer (passes, i.e. the revert happens).","severity":"low","snippet":"        return abi.decode(data, (address));","title":"distributor() reverts every taxed transfer when the factory answers a 32-byte word that is not a clean address, contrary to the documented 'never reverts' guarantee"},{"citation":"resolved","description":"First Principles / assumption that `to == POOL_MANAGER` means a swap or liquidity settlement. Anyone can `unlock` the PoolManager, `sync` ADVN, transfer in (exempt by this line), `settle`, and `mint` themselves ERC-6909 claims for the same amount. Those claims are transferable with the PoolManager's own `transfer(receiver, id, amount)` with no ADVN `_update` at all, so any number of holder-to-holder hops pay neither the 0.5% to FEE_RECIPIENT nor the 1% burn. Tax is only paid once, when the final holder `burn`s claims and `take`s (tokens leave the PoolManager, taxed). This is inherent to any transfer-tax token on Uniswap v4 and needs no change to the token; it is reported because README.md line 57 claims transfers through other venues 'are taxed in both directions', which is not true of this venue, and so the fee recipient's and the burn's coverage of 'every trade' is narrower than documented. Suggested disposition: document it; no code change is compatible with the launch floor (a tax on `to == POOL_MANAGER` fails the sell check).","line":77,"path":"src/ADVNToken.sol","reproduction":"State: real PoolManager at POOL_MANAGER, PlainFactory, token with 1000e18 at contract A. Sequence: A.unlock -> sync(ADVN), ADVN.transfer(manager, 1000e18), settle(), mint(A, uint160(ADVN), 1000e18). Then manager.transfer(B, uint160(ADVN), 1000e18) from A. Expected under README line 57: 5e18 to FEE_RECIPIENT and 10e18 burned on the A->B move. Actual: FEE_RECIPIENT balance 0, totalSupply unchanged, B holds 1000e18 claims. B.unlock -> burn + take(1000e18): B receives 985e18, FEE_RECIPIENT 5e18, 10e18 burned (taxed once on exit only). Reproduced in test/scratch/Leads.t.sol::test_lead_claimTransfersInsideThePoolManagerAreUntaxed.","severity":"info","snippet":"        if (from == FACTORY || to == POOL_MANAGER) return true;","title":"Holder-to-holder moves as ERC-6909 claims inside the PoolManager pay no fee and burn nothing; README says every non-launch venue is taxed in both directions"},{"citation":"resolved","description":"Brief vs behaviour. The brief asks for 0.5% to Jensen Huang and a 1% burn on every trade. Buys (PoolManager `take` -> ADVN.transfer(trader, out)) are taxed; sells (trader -> PoolManager) are exempt because `isExempt` returns true for `to == POOL_MANAGER`. The exemption is required: v4 `settle` credits exactly `balanceOf(manager) - reserves`, so a tax taken out of the amount would leave the swap unsettled (CurrencyNotSettled) and a tax taken on top would fail the protected floor's sell of the whole bought balance (Token.protected.t.sol lines 277-278). The author records this in REVIEW.md item 1 and the README. Reported so the judge and requester see the deviation explicitly: roughly half of trading volume pays no fee and burns nothing. The only way to tax sells is a v4 hook, which this launch kind does not deploy; this is a scope decision for the requester, not a code defect.","line":93,"path":"src/ADVNToken.sol","reproduction":"State: pool seeded by the factory (test/LaunchFlow.t.sol::test_buyIsTaxedOnTheWayOutAndSellIsExactOnTheWayIn). Trader buys with 1 ETH: trader receives 98.5% of the gross output, FEE_RECIPIENT receives 0.5%, 1% burned. Trader then sells its whole balance `received` into the pool: expected under a literal 'every trade' reading, a further 0.5% fee and 1% burn; actual, FEE_RECIPIENT balance unchanged (assertEq at line 192) and totalSupply unchanged (line 193). The existing test passes, confirming the behaviour.","severity":"info","snippet":"        if (from == address(0) || isExempt(from, to)) {","title":"Sells into the launch pool are untaxed, so 'every trade' is only half-covered; forced by the v4 settlement floor"},{"citation":"resolved","description":"Specification ambiguity, already noted by the author in REVIEW.md item 2 and README 'Reading of the brief'. The implementation burns 100 bps of each taxed amount (so a taxed transfer costs 1.5% in total). The alternative reading burns 1% of the 0.5% fee (0.005% of the amount). Both are internally consistent; the requester should confirm which one they meant before release because it changes the deflation rate by a factor of 200. No code defect under the chosen reading; `previewTransfer` and all tests agree with it.","line":31,"path":"src/ADVNToken.sol","reproduction":"Input: alice (funded 10_000e18 by the factory) calls transfer(bob, 1_000e18). Actual: bob receives 985e18, FEE_RECIPIENT receives 5e18, totalSupply drops by 10e18 (test/ADVNToken.t.sol::test_walletTransferPaysFeeAndBurns). Under the other reading the burn would be 0.05e18 and bob would receive 994.95e18.","severity":"info","snippet":"    uint256 public constant BURN_BPS = 100;","title":"Burn base is read as 1% of the transferred amount; the brief's wording ('1% burn of supply from every fee') also admits 1% of the fee"}],"hash":"3cfe8da18cfb716633369e8ba995ecc26dcee72a6e1db6380b2c3af1d6eba050","nodeId":"413350b4-a07e-487e-9ea1-7d737d58b33e","outcome":"completed","summary":"The review is complete. The findings file is written and validated, every cited snippet matches its line in the tree, and no tracked file was changed (test/scratch/ holds my reproduction tests only).\n\n**Outcome:** the control-flow area of `ADVNToken` holds. No critical, high or medium defect. The three entry points were traced through OpenZeppelin's `_transfer`/`_update` into the overridden tax path, and the launch flows were confirmed against a real Uniswap v4 PoolManager by the existing test suite, which passes in full.\n\n**Findings written to `.imd-findings.json`:**\n\n- **Low.** The factory lookup decodes the answer with `abi.decode(data, (address))`. A 32-byte word with non-zero upper bits reverts, and that revert propagates into every taxed `transfer` and `transferFrom`. The README promises the lookup never reverts a transfer. The real factory returns a clean mapping value, so this is a robustness and documentation gap, not a live loss. Reproduced in `test/scratch/Leads.t.sol`.\n- **Info.** Holders can wrap ADVN into ERC-6909 claims inside the PoolManager and move claims between each other with no fee and no burn. Tax is paid only once on exit. The README says every non-launch venue is taxed both ways, which this venue is not. Reproduced against a real PoolManager.\n- **Info.** Sells into the pool are untaxed, so roughly half of trading volume pays nothing. This is forced by v4 exact settlement and the protected floor's whole-balance sell check. The author already documents it; reported so the requester decides on it explicitly.\n- **Info.** The brief's \"1% burn of supply from every fee\" is read as 1% of the transferred amount. The alternative reading differs by a factor of 200. The author flagged this too.\n\n**Coverage:** all three entry points answered. `approve` holds. `transfer` and `transferFrom` reference finding 1. Five invariant rows hold (fixed supply, exact launch flows, empty-chain constructor, no forbidden opcodes, periphery). One row is honestly unreached: the real ProjectFactory's `distributorOf` behaviour, since its source is not in this tree.","treeHash":null,"usage":{"cachedInputTokens":673886,"cost":{"source":"runtime","usdMicros":2971114},"inputTokens":290,"model":"claude-fable-5-1","outputTokens":22361,"runtime":"claude","turns":23,"wallClockMs":354841}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"a315ee4cb81c640c","findings":[{"citation":"resolved","description":"Asymmetry / trust gap between the two sides of the PoolManager boundary. The token charges its 0.5% fee and 1% burn only when ERC-20 tokens physically leave the PoolManager (a `take`), and exempts any transfer into it. But Uniswap v4 lets a swapper settle a positive delta with `PoolManager.mint` (ERC-6909 claims) instead of `take`, and pay a negative delta with `PoolManager.burn` instead of an ERC-20 transfer. Neither causes an ADVN ERC-20 transfer, so `_update` never runs and no tax applies. Any trader with a custom unlock callback (MEV/arbitrage bots, aggregators, any contract router) can buy ADVN, hold it as claims, move it between wallets with ERC-6909 `transfer`, and sell it back, paying no fee to 0xc59b...5023 and burning nothing. Wallet holdings can also be moved into claims untaxed (`sync`, transfer to the PoolManager, `settle`, `mint`), so the tax on wallet-to-wallet transfers is avoidable in the same way. The tax only reaches someone who eventually turns claims back into ERC-20 with `take`. Because sells into the pool are already untaxed (README 'Limits'), a buy-then-sell round trip through claims pays nothing at all. The requester's 'fee from every trade' and 'burn from every fee' therefore apply only to traders who use a router that `take`s to the user. The README does not list this bypass among its limits. Impact: the fee recipient's income and the burn are lost on all volume routed this way. No holder funds are lost, so this is medium (a broken guarantee). Fix tradeoff: the token cannot see ERC-6909 movements. Enforcing the fee on in-pool trading needs a v4 hook that charges in beforeSwap/afterSwap (a scope/launch-kind decision). Otherwise the README should state that the tax applies only to ERC-20 transfers and can be avoided through ERC-6909 claims.","line":77,"path":"src/ADVNToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {IUnlockCallback} from \"v4-core/src/interfaces/callback/IUnlockCallback.sol\";\nimport {IHooks} from \"v4-core/src/interfaces/IHooks.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {BalanceDelta} from \"v4-core/src/types/BalanceDelta.sol\";\nimport {ModifyLiquidityParams, SwapParams} from \"v4-core/src/types/PoolOperation.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {ADVNToken} from \"src/ADVNToken.sol\";\n\ncontract Factory is IUnlockCallback {\n    IPoolManager immutable manager;\n    mapping(uint64 => address) public distributorOf;\n    constructor(IPoolManager m) { manager = m; }\n    function deployToken() external returns (ADVNToken) { return new ADVNToken(address(this), address(manager), 1); }\n    function seed(PoolKey calldata key) external { manager.unlock(abi.encode(key)); }\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        PoolKey memory key = abi.decode(data, (PoolKey));\n        (BalanceDelta d,) = manager.modifyLiquidity(key, ModifyLiquidityParams(-887_220, -60, 1e26, bytes32(0)), \"\");\n        manager.sync(key.currency1);\n        ADVNToken(Currency.unwrap(key.currency1)).transfer(address(manager), uint256(uint128(-d.amount1())));\n        manager.settle();\n        return \"\";\n    }\n}\n\n/// Buys ADVN and keeps the output as ERC-6909 claims instead of `take`; sells by burning claims.\ncontract ClaimsTrader is IUnlockCallback {\n    IPoolManager immutable manager;\n    constructor(IPoolManager m) { manager = m; }\n    receive() external payable {}\n    function swap(PoolKey calldata key, bool zeroForOne, int256 amt) external returns (BalanceDelta) {\n        return abi.decode(manager.unlock(abi.encode(key, zeroForOne, amt)), (BalanceDelta));\n    }\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        (PoolKey memory key, bool zeroForOne, int256 amt) = abi.decode(data, (PoolKey, bool, int256));\n        uint160 limit = zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1;\n        BalanceDelta d = manager.swap(key, SwapParams(zeroForOne, amt, limit), \"\");\n        uint256 id = uint256(uint160(Currency.unwrap(key.currency1)));\n        if (zeroForOne) {\n            manager.settle{value: uint256(uint128(-d.amount0()))}();\n            manager.mint(address(this), id, uint256(uint128(d.amount1()))); // keep ADVN as claims: no ERC-20 transfer\n        } else {\n            manager.burn(address(this), id, uint256(uint128(-d.amount1()))); // pay ADVN with claims\n            manager.take(key.currency0, address(this), uint256(uint128(d.amount0())));\n        }\n        return abi.encode(d);\n    }\n}\n\ncontract ClaimsBypassTest is Test {\n    address constant JENSEN = 0xc59b0c072f73ceEA3Dc354031165501c0Ff25023;\n    PoolManager manager;\n    ADVNToken token;\n    PoolKey key;\n    ClaimsTrader trader;\n\n    function setUp() public {\n        manager = new PoolManager(address(this));\n        Factory factory = new Factory(manager);\n        token = factory.deployToken();\n        key = PoolKey(Currency.wrap(address(0)), Currency.wrap(address(token)), 12_500, 60, IHooks(address(0)));\n        manager.initialize(key, 79228162514264337593543950336);\n        factory.seed(key);\n        trader = new ClaimsTrader(manager);\n        vm.deal(address(trader), 10 ether);\n    }\n\n    /// A 1 ETH buy, held as ERC-6909 claims and later sold back, must pay the 0.5% fee and 1% burn.\n    function test_buyHeldAsClaimsPaysTheTradeFee() public {\n        uint256 supplyBefore = token.totalSupply();\n        BalanceDelta buy = trader.swap(key, true, -1 ether);\n        uint256 gross = uint256(uint128(buy.amount1()));\n        assertGt(gross, 0, \"bought nothing\");\n        uint256 id = uint256(uint160(address(token)));\n        assertEq(manager.balanceOf(address(trader), id), gross, \"trader holds 100% of the output as claims\");\n        trader.swap(key, false, -int256(gross)); // sell everything back with the claims\n        (uint256 fee, uint256 burned,) = token.previewTransfer(gross);\n        assertEq(token.balanceOf(JENSEN), fee, \"the buy paid no fee to the fee recipient\");\n        assertEq(token.totalSupply(), supplyBefore - burned, \"the buy burned nothing\");\n    }\n}","reproduction":"Set up a v4 PoolManager and an ADVN/ETH pool (fee 12500, tickSpacing 60, sqrtPrice 2^96), seeded single-sided by the factory with liquidity 1e26 over ticks [-887220,-60]. A trader contract calls unlock: swap(zeroForOne=true, amountSpecified=-1 ether), settle{value:1 ether}(), then manager.mint(trader, uint160(ADVN), amount1) instead of take. It then unlocks again: swap(zeroForOne=false, -amount1), manager.burn(trader, uint160(ADVN), amount1), take(ETH). Expected: the fee recipient receives previewTransfer(amount1).fee = 4907965121486501 and totalSupply drops by the 1% burn. Actual: the fee recipient's balance stays 0 and totalSupply is unchanged. The attached test fails with 'the buy paid no fee to the fee recipient: 0 != 4907965121486501'.","severity":"medium","snippet":"        if (from == FACTORY || to == POOL_MANAGER) return true;","title":"Trade fee and burn can be skipped entirely by holding ADVN as Uniswap v4 ERC-6909 claims (untaxed PoolManager inflow, tax only on ERC-20 outflow)"}],"hash":"5d9b3bb6be23bc8e89413f9a351a6165d9c40866a5aea1ac45535d77e144151f","nodeId":"df272470-0200-47de-926a-05bd19ffff4b","outcome":"completed","summary":"The permissions review is finished with one finding: medium severity, reproduced with a Foundry test that fails on the current code. It's written to `.imd-findings.json` with a coverage row for each of the three entry points and three invariant rows. No project files were changed. The scratch test I wrote under `test/scratch/` is deleted, and its full source is in the finding's `proof` field.\n\n**Finding 1 (medium): any trader with their own contract can skip the 0.5% fee and the 1% burn** (`src/ADVNToken.sol:77`)\n- **How it works:** the token taxes a transfer only when ADVN actually leaves the Uniswap v4 pool, and it never taxes ADVN going in (line 77). But v4 lets a swapper keep what they bought as claim tokens held inside the pool, instead of withdrawing it, and pay for a sale with those claims. Neither step moves ADVN itself, so the token's tax code never runs.\n- **What that allows:** a trader using their own contract, such as a bot or an aggregator, can buy, hold, pass claims to other wallets and sell back without paying anything to Jensen Huang's address or burning anything. Sells are already untaxed, so a buy-and-sell round trip done this way costs nothing.\n- **Who still pays:** only people who eventually withdraw real ADVN from the pool, which is what ordinary routers do for retail buyers.\n- **Reproduced:** a 1 ETH buy kept as claims and then sold back left the fee recipient with 0, where a normal buy would have sent them 4907965121486501 minor units (about 0.0049 ADVN). Total supply didn't drop either. The README's list of limits doesn't mention this.\n- **Fix:** the token can't see claim-token movements, so enforcing the fee on these trades would need a v4 hook that charges on swaps. This launch type doesn't deploy one, so that's a scope decision for the requester. The alternative is to document the bypass in the README.\n\n**Coverage:**\n- `approve` holds: it's the standard OpenZeppelin version and doesn't touch the tax or the exemptions.\n- `transfer` and `transferFrom` are marked as finding 1. The tax and its exemptions (the factory sending, the distributor sending, anything sent into the pool) otherwise behave correctly.\n- There's no owner and no admin function, and the supply can't grow after the constructor. The launch flows move exact amounts. A taxed transfer splits correctly into 98.5% / 0.5% / 1%, and the burn lowers the total supply.\n\n**Left out:**\n- I didn't report that sells are untaxed, because the README already documents it.\n- Swaps through routers that withdraw to themselves before forwarding to the user would be taxed twice. That's in the economics area, not mine, so I didn't reproduce it.\n- The static-analysis tool's large-number-literal note isn't a defect.","treeHash":null,"usage":{"cachedInputTokens":403120,"cost":{"source":"runtime","usdMicros":746612},"inputTokens":18,"model":"claude-opus-5-5","outputTokens":12859,"runtime":"claude","turns":9,"wallClockMs":143210}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"bc39660800b5f882","findings":[{"citation":"resolved","description":"The tax is implemented in ERC-20 _update, so it only fires when the PoolManager actually transfers tokens out (take) or a holder transfers in. Uniswap v4 lets a swapper settle a positive token delta by minting ERC-6909 claim tokens (PoolManager.mint) and a negative delta by burning them (PoolManager.burn). Neither path calls the token contract, so a trader who buys into claims and later sells from claims pays no fee to Jensen and burns nothing, while a trader who takes ERC-20 tokens on the same buy pays 1.5%. Claims can also be transferred between accounts on the PoolManager (ERC-6909 transfer) without any ADVN transfer. The brief asks for a fee on every trade; this is a documented limitation of a transfer-level tax on a v4 pool (REVIEW.md already accepts that sells cannot be taxed), and the token alone cannot close it. Only a pool hook could tax claim settlement, which this launch kind does not deploy, so this is reported as a trust/design limitation for the author and judge rather than a code defect with a local fix. Outside the math area; reported because it is a reproducible gap against the brief.","line":77,"path":"src/ADVNToken.sol","reproduction":"Deploy PoolManager, token (factory = seeder, POOL_MANAGER = manager), initialise ETH/ADVN pool at sqrtPrice 2^96, seed single-sided liquidity 1e26 in ticks [-887220, -60]. Trader with 100 ETH calls unlock and swap(zeroForOne=true, amountSpecified=-1 ether), then settles ETH with settle{value} and the positive ADVN delta with manager.mint(trader, currency1.toId(), amount). Expected per brief: Jensen's balance rises by 0.5% of the output and totalSupply falls by 1%. Actual: token.balanceOf(JENSEN) == 0, totalSupply unchanged, trader holds the full gross output as claims. Trader then swaps back (oneForZero, exact input = gross) settling with manager.burn: still no fee, no burn. Test test/scratch/ClaimsBypass.t.sol test_buyAndSellWithClaimsPaysNoFeeAndBurnsNothing passes against the current code, confirming the gap.","severity":"low","snippet":"        if (from == FACTORY || to == POOL_MANAGER) return true;","title":"A buy or sell settled as Uniswap v4 ERC-6909 claims never touches the token, so the 0.5% fee and 1% burn are not taken"},{"citation":"resolved","description":"Both divisions truncate toward zero, the opposite of the usual fee-rounds-up rule. For amount < 200 the fee is 0; for amount < 100 the burn is 0 as well, so the transfer moves whole. The recipient's share is computed as the remainder, so value is always conserved (fee + burned + received == amount, fuzzed over 2000 runs). With 18 decimals the leak is at most 2 wei per transfer and splitting a meaningful transfer into sub-200-wei pieces costs far more gas than the 1.5% saved, so there is no economic exploit. Recorded so the author can decide whether to round the fee up (e.g. Math.mulDiv with Rounding.Ceil) or keep the current behaviour, which REVIEW.md already accepts.","line":84,"path":"src/ADVNToken.sol","reproduction":"factory.move(token, alice, 1000); alice.transfer(bob, 199) -> bob receives 198, Jensen receives 0, totalSupply falls by 1 (fee = 199*50/10000 = 0, burn = 199*100/10000 = 1). alice.transfer(bob, 99) -> bob receives 99, nothing to Jensen, nothing burned. Expected under exact arithmetic: fee 0.995 and 0.495, burn 1.99 and 0.99. See test/scratch/MathAudit.t.sol test_dustBelow200PaysNoFee_below100PaysNothing.","severity":"info","snippet":"        fee = amount * FEE_BPS / BPS_DENOMINATOR;\n        burned = amount * BURN_BPS / BPS_DENOMINATOR;","title":"Fee and burn round down: transfers under 200 wei pay no fee, under 100 wei pay nothing"},{"citation":"resolved","description":"The view takes only an amount and always applies the tax, while _update exempts transfers from FACTORY, from the recorded distributor, and into POOL_MANAGER. An integrator or front end that quotes previewTransfer for a claim from the distributor or for a sell into the pool understates what the recipient receives by 1.5%. The function is documented as the preview of a taxed transfer, so this is a view/write seam to be aware of rather than a loss; a from/to-aware overload (previewTransfer(from, to, amount) returning (0,0,amount) when isExempt) would remove the ambiguity.","line":83,"path":"src/ADVNToken.sol","reproduction":"token.previewTransfer(1000e18) returns (5e18, 10e18, 985e18). factory.move(token, alice, 1000e18) delivers 1000e18 to alice (exempt). alice.transfer(POOL_MANAGER, 1000e18) delivers 1000e18 to the PoolManager (exempt). Expected if the preview were authoritative: 985e18 in both cases. See test/scratch/MathAudit.t.sol test_previewDisagreesWithExemptTransfer.","severity":"info","snippet":"    function previewTransfer(uint256 amount) public pure returns (uint256 fee, uint256 burned, uint256 received) {","title":"previewTransfer reports a fee and burn for flows that are actually exempt"},{"citation":"resolved","description":"The lookup is defensive against no code, a revert and a short answer (all degrade to 'not exempt'), but abi.decode(data, (address)) panics when the returned word has any of its top 96 bits set. Because distributor() runs inside every non-exempt _update, such an answer would make every wallet-to-wallet transfer and every buy out of the pool revert; only factory sends and sends into the PoolManager would still work. FACTORY is immutable and the real factory's distributorOf(uint64) returns a Solidity address, so this is not reachable with the launch as specified. It is recorded as the one boundary corner the code does not degrade gracefully on; masking the word (address(uint160(uint256(bytes32(data))))) would make the lookup total.","line":71,"path":"src/ADVNToken.sol","reproduction":"Deploy the token with a factory whose fallback returns 32 bytes of 0xff. factory.move(token, alice, 1000e18) succeeds (exempt). alice.transfer(bob, 1e18) reverts (abi.decode panic) instead of transferring taxed. alice.transfer(POOL_MANAGER, 1e18) still succeeds. See test/scratch/MathAudit.t.sol test_dirtyWordFactoryBricksTaxedTransfers.","severity":"info","snippet":"        return abi.decode(data, (address));","title":"distributor() reverts, and with it every taxed transfer, if the factory ever answers distributorOf with a 32-byte word that is not a clean address"}],"hash":"649b6a5f1f3eadec60a1693d5bf90113a8ec72f820b21f2bbcb02d522beb138c","nodeId":"4b4b2062-2efc-48c9-ae59-820ab9599bee","outcome":"completed","summary":"The review is complete. The findings file is valid JSON, every snippet matches the tree line for line, and no source or configuration file was changed.\n\n**Outcome: the math in ADVNToken holds.** I found no defect in the Math Precision, Boundary or Numerical Gap areas that loses funds or breaks a guarantee. The findings file carries one low and three informational items, each with a reproduction I ran.\n\nWhat I checked in the assigned area, all against `src/ADVNToken.sol`:\n\n- **Overflow.** The explicit balance check runs before the two basis-point multiplications, so the operand is bounded by the 1e27 supply and `amount * 100` cannot overflow. A transfer of the maximum uint256 reverts with the standard insufficient-balance error, not a panic.\n- **Conservation.** Fee plus burn plus received equals the value exactly, the sender is debited exactly the value, and the sum of balances plus burns equals the initial supply. Confirmed by a 2000-run fuzz and the project's own invariant suite.\n- **Edges.** Zero, whole-balance, balance-plus-one, self-transfer, transfers to and from the fee recipient, and the gross-allowance semantics of transferFrom all behave as intended.\n- **External boundary.** The factory lookup degrades to \"not exempt\" on no code, revert and short return.\n\nFindings written to `.imd-findings.json`:\n\n1. **Low.** A Uniswap v4 trade settled as ERC-6909 claims never calls the token, so a buy-then-sell entirely in claims pays no fee and burns nothing. Reproduced against a real PoolManager. This is outside the math area and cannot be fixed inside the token, so it is reported as a design limitation for the judge.\n2. **Info.** Fee and burn round down. Transfers under 200 wei pay no fee and under 100 wei pay nothing. Not economically exploitable at 18 decimals.\n3. **Info.** The amount-only preview function reports a tax for flows that are actually exempt.\n4. **Info.** The distributor lookup panics on a 32-byte word that is not a clean address, which would block all taxed transfers. Unreachable with the real factory.\n\nCoverage records all three ABI entry points as holds, plus four invariant and flow rows. The two scratch test files under `test/scratch/` hold the reproductions and are not part of the submission.","treeHash":null,"usage":{"cachedInputTokens":567568,"cost":{"source":"runtime","usdMicros":2706989},"inputTokens":258,"model":"claude-fable-5-1","outputTokens":21288,"runtime":"claude","turns":16,"wallClockMs":438639}},{"artifacts":[],"attempt":1,"bundleHash":"417a7f5e101016a8670b25429709f69d0525c39eb215e21cdaabfd2c0da1cca3","device":"1a7606be97f168d4","findings":[],"hash":"93c442f7f6e07ee555a5f02d142580924246a8edb6d5591de3ed0974dcc7a87b","nodeId":"32078e99-5d01-4b36-b0a2-1d37b52a20ba","outcome":"completed","summary":"The revision is complete. All four findings are answered in `.imd-responses.json`, the build, tests and formatter pass, and the token's exemption rule and tax logic are unchanged.\n\n**What I reproduced**\n\n- The ERC-6909 claims bypass: a buy settled with the PoolManager's mint paid no fee and burned nothing against a real v4 PoolManager. A claim-paid sell and a claim-to-claim move were untaxed too.\n- The malformed factory answer: a 32-byte word with a high bit set made every ordinary transfer revert inside the address decode.\n- The preview overflow: amounts of 2^256/100 and above panicked.\n- The burn-base reading: the behaviour matches the documented 1%-of-amount choice. The finding itself says this is not a code defect.\n\n**What changed**\n\n- `src/ADVNToken.sol`: the distributor lookup decodes the factory's answer as a word and treats anything above 160 bits as no distributor, so it can never revert a transfer. The preview divides by the exact reciprocals (200 and 100), which gives identical results everywhere the old formula was defined and is defined for every input. NatSpec now states the ERC-6909 limit.\n- Tests: a `MalformedAnswerFactory` mock with a transfer test, two preview tests covering the full range, and four v4 flow tests with a claims-settling router that pin the documented behaviour, including that redeeming claims as ERC-20 is taxed.\n- `README.md` and `REVIEW.md`: the \"Limits\" section now says the tax reaches only ERC-20 transfers out of the PoolManager and ordinary ERC-20 transfers, that claims-settled buys, sells, round trips and holder moves are untaxed, and that taxing all pool trades needs a v4 hook as a separate launch. The burn-base confirmation is flagged for the requester.\n\n**Verdicts filed**\n\n- Claims bypass: fixed via the finding's option (b). No token-only change can tax a path that never calls the token, and taxing transfers into the PoolManager breaks every sell against the floor.\n- Malformed lookup: fixed.\n- Preview overflow: fixed.\n- Burn base: disputed as not a defect, with the requester confirmation made explicit in the docs.\n\n**Checks run**\n\n| Check | Result |\n|---|---|\n| `forge build --offline` | clean |\n| `forge test --offline` with the verifier's fuzz seed | 50 passed, 0 failed |\n| `forge test --offline --fuzz-seed 0x1234 --fuzz-runs 1000` | 50 passed, 0 failed |\n| `forge fmt --check` | clean |\n\nSlither is not installed on this machine, so it was not run for this revision. The changes touch none of the six refusal detectors. Two decisions remain the requester's and are listed in the README and REVIEW open items: whether to order a v4 hook launch so claims-settled pool trades also pay the fee and burn, and whether the burn base is 1% of the amount as built.","treeHash":"8cefa6ad49ae4740eb305d54f368f0c0a423cc8c","usage":{"cachedInputTokens":1034889,"cost":{"source":"runtime","usdMicros":3881700},"inputTokens":418,"model":"claude-fable-5-1","outputTokens":33931,"runtime":"claude","turns":48,"wallClockMs":498878}},{"artifacts":[],"attempt":1,"bundleHash":"21a808c843d305122f35523c59ee86984d7bd663361df17f2c8cce2784cc8687","device":"b1efa7993dd1f00e","findings":[{"description":"distributor() handles a reverted call or a short response as an unknown distributor, but a successful 32-byte response with nonzero bits above bit 159 reaches abi.decode(address), which reverts. Thus an invalid registry response can block distributor(), isExempt(), and transfers that need the lookup, instead of degrading to ordinary taxation. This is a conditional robustness issue: it requires a faulty or incompatible factory; a canonical address returned by the normal ABI-conforming registry cannot trigger it. Factory-origin transfers and transfers into the PoolManager bypass the lookup and remain possible. Validate the returned address word and treat noncanonical data as an unknown distributor to preserve the fallback behavior.","line":71,"path":"src/ADVNToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {ADVNToken} from \"src/ADVNToken.sol\";\n\ncontract NonCanonicalFactory {\n    function deploy(address manager) external returns (ADVNToken) {\n        return new ADVNToken(address(this), manager, 1);\n    }\n\n    function send(ADVNToken token, address to, uint256 amount) external {\n        require(token.transfer(to, amount));\n    }\n\n    fallback() external {\n        // One full ABI word with bit 160 set is not a canonical address encoding.\n        assembly (\"memory-safe\") {\n            mstore(0, shl(160, 1))\n            return(0, 32)\n        }\n    }\n}\n\ncontract DistributorResponseProof is Test {\n    function test_malformedLookupMustNotFreezeAnOrdinaryTransfer() public {\n        NonCanonicalFactory factory = new NonCanonicalFactory();\n        ADVNToken token = factory.deploy(makeAddr(\"proof pool manager\"));\n        address alice = makeAddr(\"proof alice\");\n        address bob = makeAddr(\"proof bob\");\n        factory.send(token, alice, 200);\n        vm.prank(alice);\n        assertTrue(token.transfer(bob, 200), \"invalid lookup should fall back to ordinary taxation\");\n        assertEq(token.balanceOf(alice), 0);\n        assertEq(token.balanceOf(bob), 197);\n        assertEq(token.balanceOf(0xc59b0c072f73ceEA3Dc354031165501c0Ff25023), 1);\n        assertEq(token.totalSupply(), 1_000_000_000e18 - 2);\n    }\n}","reproduction":"Deploy NonCanonicalFactory from the proof, whose fallback returns exactly the word uint256(1) << 160. Deploy the token through it, fund Alice with 200 minor units using the exempt factory transfer, then have Alice transfer 200 to Bob. Expected under the invalid-lookup fallback policy: success, Alice=0, Bob=197, Jensen=1, totalSupply=1e27-2. Actual: the last call reverts with empty revert data in abi.decode; no payment is made. Ran forge test --offline --match-path 'test/scratch/*Proof.t.sol' -vvvv; the malformed lookup test fails with EvmError: Revert.","severity":"low","title":"A noncanonical distributor response can block ordinary transfers"},{"description":"The public pure preview multiplies before dividing. For amount = type(uint256).max / 100 + 1, the fee multiplication still fits but the burn multiplication overflows. The advertised percentage results all fit in uint256 and can be calculated as amount/200, amount/100, and their remainder. The function declares no restricted input domain. This is a view-function boundary issue, not an asset-loss or ordinary-transfer issue: the first overflowing amount is much greater than the fixed 1e27 supply, and _update checks the sender balance before invoking previewTransfer. Use overflow-safe percentage arithmetic, or explicitly define and validate a restricted preview domain.","line":85,"path":"src/ADVNToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {ADVNToken} from \"src/ADVNToken.sol\";\n\ncontract PreviewOverflowProof is Test {\n    function test_previewDoesNotOverflowWhenAllResultsFit() public {\n        ADVNToken token = new ADVNToken(address(this), makeAddr(\"proof pool manager\"), 1);\n        uint256 amount = type(uint256).max / 100 + 1;\n        (uint256 fee, uint256 burned, uint256 received) = token.previewTransfer(amount);\n        assertEq(fee, amount / 200);\n        assertEq(burned, amount / 100);\n        assertEq(received, amount - amount / 200 - amount / 100);\n    }\n}","reproduction":"Deploy ADVNToken with a nonzero factory and pool manager. Call previewTransfer(type(uint256).max / 100 + 1), i.e. amount=1157920892373161954235709850086879078532699846656405640394575840079131296400. Expected: fee=amount/200, burned=amount/100, received=amount-fee-burned. Actual: Panic(0x11) at amount * BURN_BPS. Ran forge test --offline --match-path 'test/scratch/*Proof.t.sol' -vvvv; the preview test fails with arithmetic underflow or overflow (0x11).","severity":"low","title":"previewTransfer overflows for large uint256 inputs despite representable results"}],"hash":"b9f28add9c78eff79c436f6879928fc346741be55f070c620467b5261ff63827","nodeId":"63079cff-3b2e-4199-9f7f-7cecd8417f64","outcome":"completed","summary":"Added failure-path, fuzz, swap rollback, and stateful invariant tests.\n\nOffline build and full suite pass with the required seed: **74 passed, 0 failed**. The new invariant campaign exercised **16,384 calls**.\n\nRecorded two low-severity findings with reproduced proofs in `.imd-findings.json`: malformed factory responses blocking transfers, and preview overflow for amounts far above supply.","treeHash":"12e2eeedcf204238856cd36be42d74a898424be9","usage":{"cachedInputTokens":1506944,"cost":{"source":"estimated","usdMicros":3630374},"inputTokens":88138,"model":"gpt-6-astra","outputTokens":24841,"runtime":"codex","turns":7,"wallClockMs":664576}},{"artifacts":[],"attempt":1,"bundleHash":"28c9899dfee883e4d0fe4fc0e4c417ac37d6b72c269b0e558a68799874faebfd","device":"0b0761c9b10fe0bb","findings":[],"hash":"cedbbd91f67f56abc4931cdb0d0479a586ab66506474e251fce224fae6109b50","nodeId":"63079cff-3b2e-4199-9f7f-7cecd8417f64","outcome":"completed","summary":"The implementation fixed both defects I reported last round, so this revision adds regression tests for those fixes. It files no new findings.\n\n`forge build` succeeds, and `forge test` with the verifier's fuzz seed passes all 85 tests: 81 that were already there and 4 new ones.\n\n**What changed in `src/ADVNToken.sol`:**\n- **Distributor lookup:** if the factory returns a malformed 32-byte answer (bits set above the 160-bit address range), it now counts as \"no distributor\". Before, it reverted and froze transfers.\n- **`previewTransfer`:** it now divides by 200 and 100. Before, it overflowed for very large inputs.\n\nThe 81 existing tests needed no changes.\n\n**New tests, in `test/ADVNToken.adversarial.t.sol`:**\n- `testFuzz_dirtyDistributorWordNeverFreezesOrExemptsTransfers`: puts random high bits on the real distributor's address. While the answer is malformed, transfers still go through and the distributor pays the fee and burn like anyone else. Once the answer is clean again, its exemption comes back.\n- `test_distributorWordBoundaryAndTrailingData`: checks the exact edge (`2^160 − 1` is still an address, `2^160` is not) and that answers longer than 32 bytes are read by their first word.\n- `testFuzz_previewIsTotalAndFloorsOverWholeDomain`: covers every `uint256` with no bounds. Each levy rounds down at its rate, and fee plus burn plus amount received always equals the input.\n- `test_previewEdgeExamplesAboveFormerOverflowPoint`: fixed examples at `max/100`, `max/100 + 1`, `max − 1` and `max`, including the exact remainders at `2^256 − 1`.\n\n`test/TESTING.md` still pointed to an `.imd-findings.json` that no longer exists, so I rewrote its findings section. It now records that both findings are fixed and names the tests that cover each one. It also notes two open questions that the implementer's `REVIEW.md` already documents and that I did not re-file:\n- Pool trades settled as Uniswap v4 claims skip the tax (item 6).\n- The requester still needs to confirm what the 1% burn is taken from: the transferred amount or the fee (item 2).\n\nI only changed files under `test/`, and nothing is committed. The untracked dotfiles in the repository root were not created by me.","treeHash":"8645af1fae11304218ed422aad02d4637d2048a7","usage":{"cachedInputTokens":331781,"cost":{"source":"runtime","usdMicros":544389},"inputTokens":19,"model":"claude-opus-5-5","outputTokens":7333,"runtime":"claude","turns":10,"wallClockMs":124413}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fd7c32744e171d7d","findings":[],"hash":"d807719911b4eb4f41ed45523c101a1bf0be506918f83332076f6f39731513df","nodeId":"cbf7bbb7-197c-4688-aa24-3b9fa40fd351","outcome":"completed","summary":"All four round-one findings are settled, and the review found no new defect. The findings file holds an empty findings list and a nine-row coverage record.\n\n**What I settled**\n\n- **Claims-settled v4 trades untaxed (medium).** The author took the documentation option the finding allowed. The token NatSpec, README Limits, launch.json notes and REVIEW.md item 6 now say the tax reaches only ERC-20 transfers out of the PoolManager and ordinary transfers, and that claims-settled buys, sells, round trips and claim moves are untaxed. The two specialist proofs still fail on this code, which is expected since no token-only change can pass them. The author's four new claim tests in test/LaunchFlow.t.sol pass and pin the documented behaviour.\n- **distributor() reverting on a dirty word (low).** Fixed. The answer is decoded as a word and anything above the address range becomes \"no distributor\". The author's reproduction with a factory returning 1 shifted by 160 now gives a taxed transfer instead of a revert.\n- **previewTransfer overflow (info).** Fixed by dividing by the exact reciprocals. Defined for every uint256, with a full-range fuzz against the basis-point formula.\n- **Burn base reading (info).** Dropped. Not a code defect, and the README and REVIEW.md now flag in bold that the requester must confirm the burn base before release.\n\n**Checks run**\n\n- The project suite passes in full: 85 tests across unit, launch-flow, adversarial and two invariant suites.\n- The protected floor tests could not be compiled here because they import service sources not in this tree. The transfer logic they exercise is unchanged since last round.\n- The manifest has schema keys only, the supply matches the constructor mint, and the contract is far under the size limits.\n\n**Coverage.** All three entry points hold, with one-line reasons in the record. No finding carries a proof because there are no findings.","treeHash":null,"usage":{"cachedInputTokens":422458,"cost":{"source":"runtime","usdMicros":1612976},"inputTokens":226,"model":"claude-fable-5-1","outputTokens":6799,"runtime":"claude","turns":8,"wallClockMs":136971}},{"artifacts":[],"attempt":1,"bundleHash":"8e40d5b334205c7d6ab3d3c123b043219a83841ee5d1d8d6d94bb626ed571b1c","device":"af4be7a5238dbcbf","findings":[],"hash":"dd04eb51ec9a202334cf93daa6656d196f0005d8f722d92991524578da6cc8ef","nodeId":"09b694a0-b7d9-4942-a7fa-182fe2231d86","outcome":"completed","summary":"I updated `launch.json`. The only change is one sentence in `notes`; nothing else in the repository was touched. I left the change uncommitted.\n\n**What changed:** The old notes said buys and liquidity withdrawals from the PoolManager are always taxed. That is no longer accurate: the accepted revision of `src/ADVNToken.sol` (finding 6 in `REVIEW.md`) shows that trades settled as Uniswap v4 ERC-6909 claims skip the tax. The fee and the burn only apply once those claims are turned back into ordinary tokens. The notes now say that taxing those trades would need a v4 hook, which this launch does not deploy. They are 1,344 characters, under the 4,000 limit.\n\n**Already correct and left as they were:**\n- **Token:** contract `ADVNToken`, name AIDIVN, symbol ADVN, 18 decimals.\n- **Constructor arguments:** `[\"$factory\",\"$poolManager\",\"$launchNumber\"]`, matching the constructor's `(address, address, uint64)` in order.\n- **Total supply:** `\"1000000000000000000000000000\"`, which is exactly what the constructor mints to the deployer (`1_000_000_000 * 1e18`).\n- **Contracts:** an empty list, because the accepted tree has no application contracts.\n- **Pool:** native ETH (the zero address), fee 12500, tick spacing 60, initial price `79228162514264337593543950336`.\n- **Economics:** copied verbatim from the job.\n\n**Checks:** The file parses as JSON. `forge build` compiles cleanly, and `forge test` with the verifier's fuzz seed passed all 50 tests in 3 suites. Nothing I can run here validates the manifest against the schema, so I checked its keys and formats by reading it.\n\n**Still open for you:** The review also leaves an open question about the burn. It is built as 1% of the amount transferred; your wording could also mean 1% of the fee.","treeHash":"eb66288423288065896e33e5b8dfdca9fbee282c","usage":{"cachedInputTokens":76416,"cost":{"source":"runtime","usdMicros":188921},"inputTokens":8,"model":"claude-opus-5-5","outputTokens":2062,"runtime":"claude","turns":4,"wallClockMs":33334}},{"artifacts":[],"attempt":1,"bundleHash":"6ac12b44a1646af47eeba843541694792faf2a74dbec686e041b0ed5e5ef5e7b","device":"5d0460745287d96a","findings":[],"hash":"ef4dffcada5c39651f71cbed800283f9e17a873c88d2d585f27af8fc4f80e181","nodeId":"09b694a0-b7d9-4942-a7fa-182fe2231d86","outcome":"completed","summary":"Created [launch.json](/root/.identitymd/work/8f8003e9-b967-4ca8-ba26-f47c8419c5f8/09b694a0-b7d9-4942-a7fa-182fe2231d86/launch.json) matching the accepted constructor, supply, required economics, and pool settings.\n\nOnly the manifest changed. `forge build` succeeded; all 43 tests passed with the supplied fuzz seed.","treeHash":"4472aa73e993ceb1045c57f86f7c1a2c1aea9bd9","usage":{"cachedInputTokens":187520,"cost":{"source":"estimated","usdMicros":679140},"inputTokens":33527,"model":"gpt-6-astra","outputTokens":3127,"runtime":"codex","turns":3,"wallClockMs":92173}}],"verification":[{"checks":[{"durationMs":1983,"exitCode":0,"name":"build","output":"Compiling 74 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.89s\nCompiler run successful!\n","passed":true},{"durationMs":564,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 36 tests for test/ADVNToken.t.sol:ADVNTokenTest\n[PASS] testFuzz_exemptFlowsMoveExactly(uint256,address) (runs: 256, μ: 258897, ~: 259430)\n[PASS] testFuzz_taxNeverExceedsOnePointFivePercent(uint256) (runs: 256, μ: 7265, ~: 6997)\n[PASS] testFuzz_taxedTransferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 113570, ~: 113552)\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 256, μ: 244999, ~: 253513)\n[PASS] test_constructorDoesNotNeedCodeAtTheLaunchAddresses() (gas: 911497)\n[PASS] test_constructorRejectsZeroFactory() (gas: 216623)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 218975)\n[PASS] test_distributorIsOrdinaryUntilTheFactoryRecordsIt() (gas: 193956)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 74369)\n[PASS] test_distributorTransfersAreUntaxedOnceRecorded() (gas: 215336)\n[PASS] test_dustBelowTheRoundingThresholdMovesWhole() (gas: 347809)\n[PASS] test_exemptTransferMoreThanBalanceReverts() (gas: 104040)\n[PASS] test_factoryCannotMoveAHoldersBalance() (gas: 110717)\n[PASS] test_factoryTransfersAreUntaxed() (gas: 81177)\n[PASS] test_feeRecipientPaysTaxLikeAnyoneElse() (gas: 165987)\n[PASS] test_isExemptView() (gas: 152535)\n[PASS] test_launchParametersAreRecorded() (gas: 39954)\n[PASS] test_metadata() (gas: 28985)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 37575)\n[PASS] test_noMintOrAdminEntryPoints() (gas: 155293)\n[PASS] test_previewTransfer() (gas: 6298)\n[PASS] test_selfTransferIsTaxed() (gas: 160637)\n[PASS] test_tokensLeavingThePoolManagerAreTaxed() (gas: 190281)\n[PASS] test_transferFromIntoThePoolManagerIsUntaxed() (gas: 191673)\n[PASS] test_transferFromIsTaxed() (gas: 264894)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 108688)\n[PASS] test_transferMoreThanBalanceReverts() (gas: 112195)\n[PASS] test_transferToFeeRecipientIsTaxed() (gas: 155433)\n[PASS] test_transferToZeroAddressReverts() (gas: 101290)\n[PASS] test_transfersIntoThePoolManagerAreUntaxed() (gas: 153258)\n[PASS] test_transfersWorkWhenTheFactoryAnswersShort() (gas: 2276412)\n[PASS] test_transfersWorkWhenTheFactoryHasNoCode() (gas: 1066970)\n[PASS] test_transfersWorkWhenTheFactoryLookupReverts() (gas: 2304216)\n[PASS] test_walletTransferPaysFeeAndBurns() (gas: 205111)\n[PASS] test_wholeBalanceCanBeSentDespiteTheTax() (gas: 181807)\n[PASS] test_zeroTransferIsAllowedAndMovesNothing() (gas: 137184)\nSuite result: ok. 36 passed; 0 failed; 0 skipped; finished in 19.66ms (55.21ms CPU time)\n\nRan 6 tests for test/LaunchFlow.t.sol:LaunchFlowTest\n[PASS] testFuzz_anyBuySizeSettlesAndTaxes(uint256) (runs: 256, μ: 631377, ~: 631581)\n[PASS] test_buyIsTaxedOnTheWayOutAndSellIsExactOnTheWayIn() (gas: 651227)\n[PASS] test_buyThenSellSeveralTimesNeverReverts() (gas: 1661564)\n[PASS] test_liquidityWithdrawalIsTaxedOnTheWayOut() (gas: 421760)\n[PASS] test_seedTakesExactlyWhatItSays() (gas: 272741)\n[PASS] test_swarmShareAndClaimsMoveWhole() (gas: 144945)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 41.20ms (48.06ms CPU time)\n\nRan 1 test for test/ADVNToken.invariant.t.sol:ADVNTokenInvariantTest\n[PASS]\nADVNTokenInvariantTest invariants:\n[PASS] invariant_balancesMatchTheIndependentLedger\n[PASS] invariant_feesAndBurnsAccountForTheMissingSupply\n[PASS] invariant_supplyNeverGrowsAndShrinksOnlyByBurns\n ADVNTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 1009  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 1039  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 432.64ms (431.18ms CPU time)\n\nRan 3 test suites in 435.26ms (493.49ms CPU time): 43 tests passed, 0 failed, 0 skipped (43 total tests)\n","passed":true},{"durationMs":50,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ADVNToken.approve(address,uint256)\",\"ADVNToken.transfer(address,uint256)\",\"ADVNToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":152,\"REVIEW.md\":52,\"foundry.toml\":21,\"remappings.txt\":4,\"src/ADVNToken.sol\":105,\"test/ADVNToken.invariant.t.sol\":125,\"test/ADVNToken.t.sol\":412,\"test/LaunchFlow.t.sol\":234,\"test/mocks/MockFactory.sol\":56},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":441,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":232,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/ADVNToken.sol:34: Large Numeric Literal (2 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"0f82b00d6bd897d7a949d8fb390edfcb6d47315f3b6c0163b3f8f322e08136d8","verifiedTreeHash":"01d26d5f54cd645430d7e004394fe31d35fb25da","verifierVersion":"0.1.0+435fe828"},{"checks":[{"durationMs":2080,"exitCode":0,"name":"build","output":"Compiling 74 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.99s\nCompiler run successful!\n","passed":true},{"durationMs":558,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 39 tests for test/ADVNToken.t.sol:ADVNTokenTest\n[PASS] testFuzz_exemptFlowsMoveExactly(uint256,address) (runs: 256, μ: 258905, ~: 259448)\n[PASS] testFuzz_previewTransferMatchesTheBasisPointFormula(uint256) (runs: 256, μ: 7064, ~: 7089)\n[PASS] testFuzz_taxNeverExceedsOnePointFivePercent(uint256) (runs: 256, μ: 7233, ~: 6950)\n[PASS] testFuzz_taxedTransferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 113486, ~: 113545)\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 256, μ: 244686, ~: 253403)\n[PASS] test_constructorDoesNotNeedCodeAtTheLaunchAddresses() (gas: 907238)\n[PASS] test_constructorRejectsZeroFactory() (gas: 216191)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 218520)\n[PASS] test_distributorIsOrdinaryUntilTheFactoryRecordsIt() (gas: 193834)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 74317)\n[PASS] test_distributorTransfersAreUntaxedOnceRecorded() (gas: 215312)\n[PASS] test_dustBelowTheRoundingThresholdMovesWhole() (gas: 347543)\n[PASS] test_exemptTransferMoreThanBalanceReverts() (gas: 104036)\n[PASS] test_factoryCannotMoveAHoldersBalance() (gas: 110747)\n[PASS] test_factoryTransfersAreUntaxed() (gas: 81306)\n[PASS] test_feeRecipientPaysTaxLikeAnyoneElse() (gas: 165895)\n[PASS] test_isExemptView() (gas: 152411)\n[PASS] test_launchParametersAreRecorded() (gas: 61218)\n[PASS] test_metadata() (gas: 29073)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 37587)\n[PASS] test_noMintOrAdminEntryPoints() (gas: 155293)\n[PASS] test_previewTransfer() (gas: 6316)\n[PASS] test_previewTransferIsDefinedForEveryAmount() (gas: 13480)\n[PASS] test_selfTransferIsTaxed() (gas: 160567)\n[PASS] test_tokensLeavingThePoolManagerAreTaxed() (gas: 190240)\n[PASS] test_transferFromIntoThePoolManagerIsUntaxed() (gas: 191716)\n[PASS] test_transferFromIsTaxed() (gas: 264805)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 108712)\n[PASS] test_transferMoreThanBalanceReverts() (gas: 112161)\n[PASS] test_transferToFeeRecipientIsTaxed() (gas: 155444)\n[PASS] test_transferToZeroAddressReverts() (gas: 101264)\n[PASS] test_transfersIntoThePoolManagerAreUntaxed() (gas: 153317)\n[PASS] test_transfersWorkWhenTheFactoryAnswersANonAddressWord() (gas: 2424160)\n[PASS] test_transfersWorkWhenTheFactoryAnswersShort() (gas: 2266282)\n[PASS] test_transfersWorkWhenTheFactoryHasNoCode() (gas: 1062660)\n[PASS] test_transfersWorkWhenTheFactoryLookupReverts() (gas: 2294086)\n[PASS] test_walletTransferPaysFeeAndBurns() (gas: 205047)\n[PASS] test_wholeBalanceCanBeSentDespiteTheTax() (gas: 181738)\n[PASS] test_zeroTransferIsAllowedAndMovesNothing() (gas: 137070)\nSuite result: ok. 39 passed; 0 failed; 0 skipped; finished in 23.10ms (69.86ms CPU time)\n\nRan 10 tests for test/LaunchFlow.t.sol:LaunchFlowTest\n[PASS] testFuzz_anyBuySizeSettlesAndTaxes(uint256) (runs: 256, μ: 631308, ~: 631515)\n[PASS] test_buyIsTaxedOnTheWayOutAndSellIsExactOnTheWayIn() (gas: 651177)\n[PASS] test_buySettledAsClaimsIsUntaxedUntilRedeemedAsErc20() (gas: 1876214)\n[PASS] test_buyThenSellSeveralTimesNeverReverts() (gas: 1661400)\n[PASS] test_claimRoundTripIsUntaxed() (gas: 1775062)\n[PASS] test_claimToClaimMoveIsUntaxedAndRedemptionIsTaxed() (gas: 3113074)\n[PASS] test_liquidityWithdrawalIsTaxedOnTheWayOut() (gas: 421654)\n[PASS] test_seedTakesExactlyWhatItSays() (gas: 272793)\n[PASS] test_swarmShareAndClaimsMoveWhole() (gas: 145058)\n[PASS] test_wrappingErc20IntoClaimsIsUntaxedAndUnwrappingIsTaxed() (gas: 1815459)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 52.49ms (57.87ms CPU time)\n\nRan 1 test for test/ADVNToken.invariant.t.sol:ADVNTokenInvariantTest\n[PASS]\nADVNTokenInvariantTest invariants:\n[PASS] invariant_balancesMatchTheIndependentLedger\n[PASS] invariant_feesAndBurnsAccountForTheMissingSupply\n[PASS] invariant_supplyNeverGrowsAndShrinksOnlyByBurns\n ADVNTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 1009  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 1039  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 448.23ms (445.89ms CPU time)\n\nRan 3 test suites in 449.97ms (523.82ms CPU time): 50 tests passed, 0 failed, 0 skipped (50 total tests)\n","passed":true},{"durationMs":47,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ADVNToken.approve(address,uint256)\",\"ADVNToken.transfer(address,uint256)\",\"ADVNToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":186,\"REVIEW.md\":73,\"foundry.toml\":21,\"remappings.txt\":4,\"src/ADVNToken.sol\":120,\"test/ADVNToken.invariant.t.sol\":125,\"test/ADVNToken.t.sol\":458,\"test/LaunchFlow.t.sol\":398,\"test/mocks/MockFactory.sol\":75},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":471,"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/ADVNToken.sol:40: Large Numeric Literal (2 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"93c442f7f6e07ee555a5f02d142580924246a8edb6d5591de3ed0974dcc7a87b","verifiedTreeHash":"8cefa6ad49ae4740eb305d54f368f0c0a423cc8c","verifierVersion":"0.1.0+435fe828"},{"checks":[{"durationMs":3011,"exitCode":0,"name":"build","output":"Compiling 76 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.89s\nCompiler run successful!\n","passed":true},{"durationMs":12585,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 8 tests for test/LaunchFlow.t.sol:LaunchFlowTest\n[PASS] testFuzz_anyBuySizeSettlesAndTaxes(uint256) (runs: 256, μ: 631400, ~: 631581)\n[PASS] test_buyIsTaxedOnTheWayOutAndSellIsExactOnTheWayIn() (gas: 651227)\n[PASS] test_buyThenSellSeveralTimesNeverReverts() (gas: 1661564)\n[PASS] test_liquidityWithdrawalIsTaxedOnTheWayOut() (gas: 421738)\n[PASS] test_seedTakesExactlyWhatItSays() (gas: 272719)\n[PASS] test_sellAboveBalanceRollsBackTheEarlierEtherPayout() (gas: 827631)\n[PASS] test_swarmShareAndClaimsMoveWhole() (gas: 144999)\n[PASS] test_unfundedBuyRollsBackAndTheNextFundedBuySucceeds() (gas: 740932)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 108.83ms (109.87ms CPU time)\n\nRan 27 tests for test/ADVNToken.adversarial.t.sol:ADVNTokenAdversarialTest\n[PASS] testFuzz_failedDelegatedSpendIsAtomic(uint256,uint256,bool) (runs: 1000, μ: 364832, ~: 363228)\n[PASS] testFuzz_previewAdvancesByOneWholeFeeQuantum(uint256) (runs: 1000, μ: 13430, ~: 13173)\n[PASS] testFuzz_roundTripCannotCreateValue(uint256,uint8) (runs: 1000, μ: 1111909, ~: 946263)\n[PASS] testFuzz_splittingPaymentSavesAtMostOneUnitOfEachLevy(uint256,uint256) (runs: 1000, μ: 20374, ~: 20418)\n[PASS] test_allowanceMustCoverGrossAmountEvenIfItCoversNetReceipt() (gas: 354898)\n[PASS] test_approvalOverwriteAndRevocationDoNotMoveTokens() (gas: 550280)\n[PASS] test_approveZeroSpenderRevertsWithoutChangingExistingAllowance() (gas: 297089)\n[PASS] test_constructorEmitsExactlyOneMint() (gas: 799456)\n[PASS] test_constructorMintsToActualDeployerEvenWhenFactoryArgumentDiffers() (gas: 925861)\n[PASS] test_directTransferDoesNotConsumeApproval() (gas: 227071)\n[PASS] test_distributorLookupIsScopedToLaunchAndIsNotCached() (gas: 1245918)\n[PASS] test_entireInitialSupplyCanBeTransferredAndTaxed() (gas: 192264)\n[PASS] test_everyShortDistributorResponseFallsBackToTaxation() (gas: 3348194)\n[PASS] test_feeRecipientSelfTransferBurnsExactlyOnce() (gas: 134272)\n[PASS] test_finiteApprovalIsSpentOnGrossAndCannotBeReused() (gas: 546371)\n[PASS] test_infiniteApprovalSurvivesRepeatedSpendsThenCanBeRevoked() (gas: 688688)\n[PASS] test_maximumTransferFailsWithBalanceErrorBeforeTaxArithmetic() (gas: 431400)\n[PASS] test_revertingLookupRecoversWithoutResettingTheToken() (gas: 232629)\n[PASS] test_roundingBoundaryExamples() (gas: 1223977)\n[PASS] test_selfTransferRequiresFullGrossBalanceIncludingFeeRecipient() (gas: 394548)\n[PASS] test_transferEventsDescribeRecipientFeeAndSupplyBurn() (gas: 174440)\n[PASS] test_transferFromInsufficientBalanceRollsBackSpentAllowance() (gas: 366784)\n[PASS] test_transferFromSelfStillRequiresApproval() (gas: 468230)\n[PASS] test_transferFromZeroRecipientRollsBackSpentAllowance() (gas: 355667)\n[PASS] test_zeroCallerCannotApproveOrTransfer() (gas: 261836)\n[PASS] test_zeroRecipientIsRejectedEvenForZeroAmountAndExemptSender() (gas: 267286)\n[PASS] test_zeroTransferFromNeedsNoPositiveAllowanceOrBalance() (gas: 256830)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 114.19ms (463.35ms CPU time)\n\nRan 36 tests for test/ADVNToken.t.sol:ADVNTokenTest\n[PASS] testFuzz_exemptFlowsMoveExactly(uint256,address) (runs: 256, μ: 259125, ~: 259430)\n[PASS] testFuzz_taxNeverExceedsOnePointFivePercent(uint256) (runs: 256, μ: 7268, ~: 6997)\n[PASS] testFuzz_taxedTransferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 113303, ~: 113540)\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 256, μ: 244569, ~: 253513)\n[PASS] test_constructorDoesNotNeedCodeAtTheLaunchAddresses() (gas: 911497)\n[PASS] test_constructorRejectsZeroFactory() (gas: 216623)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 218975)\n[PASS] test_distributorIsOrdinaryUntilTheFactoryRecordsIt() (gas: 193956)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 74369)\n[PASS] test_distributorTransfersAreUntaxedOnceRecorded() (gas: 215336)\n[PASS] test_dustBelowTheRoundingThresholdMovesWhole() (gas: 347809)\n[PASS] test_exemptTransferMoreThanBalanceReverts() (gas: 104040)\n[PASS] test_factoryCannotMoveAHoldersBalance() (gas: 110717)\n[PASS] test_factoryTransfersAreUntaxed() (gas: 81177)\n[PASS] test_feeRecipientPaysTaxLikeAnyoneElse() (gas: 165987)\n[PASS] test_isExemptView() (gas: 152535)\n[PASS] test_launchParametersAreRecorded() (gas: 39954)\n[PASS] test_metadata() (gas: 28985)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 37575)\n[PASS] test_noMintOrAdminEntryPoints() (gas: 155293)\n[PASS] test_previewTransfer() (gas: 6298)\n[PASS] test_selfTransferIsTaxed() (gas: 160637)\n[PASS] test_tokensLeavingThePoolManagerAreTaxed() (gas: 190281)\n[PASS] test_transferFromIntoThePoolManagerIsUntaxed() (gas: 191673)\n[PASS] test_transferFromIsTaxed() (gas: 264894)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 108688)\n[PASS] test_transferMoreThanBalanceReverts() (gas: 112195)\n[PASS] test_transferToFeeRecipientIsTaxed() (gas: 155433)\n[PASS] test_transferToZeroAddressReverts() (gas: 101290)\n[PASS] test_transfersIntoThePoolManagerAreUntaxed() (gas: 153258)\n[PASS] test_transfersWorkWhenTheFactoryAnswersShort() (gas: 2276412)\n[PASS] test_transfersWorkWhenTheFactoryHasNoCode() (gas: 1066970)\n[PASS] test_transfersWorkWhenTheFactoryLookupReverts() (gas: 2304216)\n[PASS] test_walletTransferPaysFeeAndBurns() (gas: 205111)\n[PASS] test_wholeBalanceCanBeSentDespiteTheTax() (gas: 181807)\n[PASS] test_zeroTransferIsAllowedAndMovesNothing() (gas: 137184)\nSuite result: ok. 36 passed; 0 failed; 0 skipped; finished in 114.29ms (240.37ms CPU time)\n\nRan 1 test for test/ADVNToken.invariant.t.sol:ADVNTokenInvariantTest\n[PASS]\nADVNTokenInvariantTest invariants:\n[PASS] invariant_balancesMatchTheIndependentLedger\n[PASS] invariant_feesAndBurnsAccountForTheMissingSupply\n[PASS] invariant_supplyNeverGrowsAndShrinksOnlyByBurns\n ADVNTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 1009  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 1039  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 520.45ms (517.93ms CPU time)\n\nRan 2 tests for test/ADVNToken.allowances.invariant.t.sol:ADVNTokenAllowanceInvariantTest\n[PASS]\nADVNTokenAllowanceInvariantTest invariants:\n[PASS] invariant_allAllowancesMatchIndependentApprovalHistory\n[PASS] invariant_allBalancesAndSupplyMatchTheLedger\n[PASS] invariant_registryChangesOnlyAffectTheCurrentDistributor\n[PASS] invariant_roundingErrorIsBoundedAcrossTheWholeSequence\n ADVNTokenAllowanceInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------------------+----------------------+-------+---------+----------╮\n| Contract                 | Selector             | Calls | Reverts | Discards |\n+==============================================================================+\n| AllowanceSequenceHandler | approve              | 2336  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | registerDistributor  | 2290  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | rejectedTransferFrom | 2377  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | revoke               | 2347  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | transfer             | 2319  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | transferAll          | 2379  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | transferFrom         | 2336  | 0       | 0        |\n╰--------------------------+----------------------+-------+---------+----------╯\n\n[PASS] test_handlerExercisesSuccessfulAndRejectedSpendsWithoutAutoApproving() (gas: 5137294)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 12.46s (12.46s CPU time)\n\nRan 5 test suites in 12.46s (13.31s CPU time): 74 tests passed, 0 failed, 0 skipped (74 total tests)\n","passed":true},{"durationMs":84,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ADVNToken.approve(address,uint256)\",\"ADVNToken.transfer(address,uint256)\",\"ADVNToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":152,\"REVIEW.md\":52,\"foundry.toml\":21,\"remappings.txt\":4,\"src/ADVNToken.sol\":105,\"test/ADVNToken.adversarial.t.sol\":438,\"test/ADVNToken.allowances.invariant.t.sol\":297,\"test/ADVNToken.invariant.t.sol\":125,\"test/ADVNToken.t.sol\":412,\"test/LaunchFlow.t.sol\":281,\"test/TESTING.md\":88,\"test/mocks/MockFactory.sol\":56},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"b9f28add9c78eff79c436f6879928fc346741be55f070c620467b5261ff63827","verifiedTreeHash":"12e2eeedcf204238856cd36be42d74a898424be9","verifierVersion":"0.1.0+435fe828"},{"checks":[{"durationMs":3025,"exitCode":0,"name":"build","output":"Compiling 76 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.93s\nCompiler run successful!\n","passed":true},{"durationMs":12126,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 12 tests for test/LaunchFlow.t.sol:LaunchFlowTest\n[PASS] testFuzz_anyBuySizeSettlesAndTaxes(uint256) (runs: 256, μ: 631346, ~: 631515)\n[PASS] test_buyIsTaxedOnTheWayOutAndSellIsExactOnTheWayIn() (gas: 651200)\n[PASS] test_buySettledAsClaimsIsUntaxedUntilRedeemedAsErc20() (gas: 1876192)\n[PASS] test_buyThenSellSeveralTimesNeverReverts() (gas: 1661400)\n[PASS] test_claimRoundTripIsUntaxed() (gas: 1775062)\n[PASS] test_claimToClaimMoveIsUntaxedAndRedemptionIsTaxed() (gas: 3113097)\n[PASS] test_liquidityWithdrawalIsTaxedOnTheWayOut() (gas: 421632)\n[PASS] test_seedTakesExactlyWhatItSays() (gas: 272771)\n[PASS] test_sellAboveBalanceRollsBackTheEarlierEtherPayout() (gas: 827711)\n[PASS] test_swarmShareAndClaimsMoveWhole() (gas: 145036)\n[PASS] test_unfundedBuyRollsBackAndTheNextFundedBuySucceeds() (gas: 741135)\n[PASS] test_wrappingErc20IntoClaimsIsUntaxedAndUnwrappingIsTaxed() (gas: 1815459)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 124.81ms (129.49ms CPU time)\n\nRan 39 tests for test/ADVNToken.t.sol:ADVNTokenTest\n[PASS] testFuzz_exemptFlowsMoveExactly(uint256,address) (runs: 256, μ: 259106, ~: 259412)\n[PASS] testFuzz_previewTransferMatchesTheBasisPointFormula(uint256) (runs: 256, μ: 7064, ~: 7089)\n[PASS] testFuzz_taxNeverExceedsOnePointFivePercent(uint256) (runs: 256, μ: 7236, ~: 6950)\n[PASS] testFuzz_taxedTransferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 113313, ~: 113540)\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 256, μ: 243532, ~: 253403)\n[PASS] test_constructorDoesNotNeedCodeAtTheLaunchAddresses() (gas: 907238)\n[PASS] test_constructorRejectsZeroFactory() (gas: 216191)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 218520)\n[PASS] test_distributorIsOrdinaryUntilTheFactoryRecordsIt() (gas: 193834)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 74317)\n[PASS] test_distributorTransfersAreUntaxedOnceRecorded() (gas: 215312)\n[PASS] test_dustBelowTheRoundingThresholdMovesWhole() (gas: 347543)\n[PASS] test_exemptTransferMoreThanBalanceReverts() (gas: 104036)\n[PASS] test_factoryCannotMoveAHoldersBalance() (gas: 110747)\n[PASS] test_factoryTransfersAreUntaxed() (gas: 81306)\n[PASS] test_feeRecipientPaysTaxLikeAnyoneElse() (gas: 165895)\n[PASS] test_isExemptView() (gas: 152411)\n[PASS] test_launchParametersAreRecorded() (gas: 61218)\n[PASS] test_metadata() (gas: 29073)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 37587)\n[PASS] test_noMintOrAdminEntryPoints() (gas: 155293)\n[PASS] test_previewTransfer() (gas: 6316)\n[PASS] test_previewTransferIsDefinedForEveryAmount() (gas: 13480)\n[PASS] test_selfTransferIsTaxed() (gas: 160567)\n[PASS] test_tokensLeavingThePoolManagerAreTaxed() (gas: 190240)\n[PASS] test_transferFromIntoThePoolManagerIsUntaxed() (gas: 191716)\n[PASS] test_transferFromIsTaxed() (gas: 264805)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 108712)\n[PASS] test_transferMoreThanBalanceReverts() (gas: 112161)\n[PASS] test_transferToFeeRecipientIsTaxed() (gas: 155444)\n[PASS] test_transferToZeroAddressReverts() (gas: 101264)\n[PASS] test_transfersIntoThePoolManagerAreUntaxed() (gas: 153317)\n[PASS] test_transfersWorkWhenTheFactoryAnswersANonAddressWord() (gas: 2424160)\n[PASS] test_transfersWorkWhenTheFactoryAnswersShort() (gas: 2266282)\n[PASS] test_transfersWorkWhenTheFactoryHasNoCode() (gas: 1062660)\n[PASS] test_transfersWorkWhenTheFactoryLookupReverts() (gas: 2294086)\n[PASS] test_walletTransferPaysFeeAndBurns() (gas: 205047)\n[PASS] test_wholeBalanceCanBeSentDespiteTheTax() (gas: 181738)\n[PASS] test_zeroTransferIsAllowedAndMovesNothing() (gas: 137070)\nSuite result: ok. 39 passed; 0 failed; 0 skipped; finished in 128.83ms (364.52ms CPU time)\n\nRan 31 tests for test/ADVNToken.adversarial.t.sol:ADVNTokenAdversarialTest\n[PASS] testFuzz_dirtyDistributorWordNeverFreezesOrExemptsTransfers(uint256) (runs: 1000, μ: 394257, ~: 394001)\n[PASS] testFuzz_failedDelegatedSpendIsAtomic(uint256,uint256,bool) (runs: 1000, μ: 364938, ~: 363376)\n[PASS] testFuzz_previewAdvancesByOneWholeFeeQuantum(uint256) (runs: 1000, μ: 13298, ~: 13033)\n[PASS] testFuzz_previewIsTotalAndFloorsOverWholeDomain(uint256) (runs: 1000, μ: 7429, ~: 7429)\n[PASS] testFuzz_roundTripCannotCreateValue(uint256,uint8) (runs: 1000, μ: 1113580, ~: 945860)\n[PASS] testFuzz_splittingPaymentSavesAtMostOneUnitOfEachLevy(uint256,uint256) (runs: 1000, μ: 20144, ~: 20186)\n[PASS] test_allowanceMustCoverGrossAmountEvenIfItCoversNetReceipt() (gas: 355068)\n[PASS] test_approvalOverwriteAndRevocationDoNotMoveTokens() (gas: 550515)\n[PASS] test_approveZeroSpenderRevertsWithoutChangingExistingAllowance() (gas: 297232)\n[PASS] test_constructorEmitsExactlyOneMint() (gas: 795659)\n[PASS] test_constructorMintsToActualDeployerEvenWhenFactoryArgumentDiffers() (gas: 921612)\n[PASS] test_directTransferDoesNotConsumeApproval() (gas: 227002)\n[PASS] test_distributorLookupIsScopedToLaunchAndIsNotCached() (gas: 1241919)\n[PASS] test_distributorWordBoundaryAndTrailingData() (gas: 75769)\n[PASS] test_entireInitialSupplyCanBeTransferredAndTaxed() (gas: 192178)\n[PASS] test_everyShortDistributorResponseFallsBackToTaxation() (gas: 3346534)\n[PASS] test_feeRecipientSelfTransferBurnsExactlyOnce() (gas: 134218)\n[PASS] test_finiteApprovalIsSpentOnGrossAndCannotBeReused() (gas: 546363)\n[PASS] test_infiniteApprovalSurvivesRepeatedSpendsThenCanBeRevoked() (gas: 688617)\n[PASS] test_maximumTransferFailsWithBalanceErrorBeforeTaxArithmetic() (gas: 431506)\n[PASS] test_previewEdgeExamplesAboveFormerOverflowPoint() (gas: 45472)\n[PASS] test_revertingLookupRecoversWithoutResettingTheToken() (gas: 232587)\n[PASS] test_roundingBoundaryExamples() (gas: 1223570)\n[PASS] test_selfTransferRequiresFullGrossBalanceIncludingFeeRecipient() (gas: 394614)\n[PASS] test_transferEventsDescribeRecipientFeeAndSupplyBurn() (gas: 174374)\n[PASS] test_transferFromInsufficientBalanceRollsBackSpentAllowance() (gas: 366880)\n[PASS] test_transferFromSelfStillRequiresApproval() (gas: 468303)\n[PASS] test_transferFromZeroRecipientRollsBackSpentAllowance() (gas: 355837)\n[PASS] test_zeroCallerCannotApproveOrTransfer() (gas: 261994)\n[PASS] test_zeroRecipientIsRejectedEvenForZeroAmountAndExemptSender() (gas: 267422)\n[PASS] test_zeroTransferFromNeedsNoPositiveAllowanceOrBalance() (gas: 256976)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 129.91ms (739.55ms CPU time)\n\nRan 1 test for test/ADVNToken.invariant.t.sol:ADVNTokenInvariantTest\n[PASS]\nADVNTokenInvariantTest invariants:\n[PASS] invariant_balancesMatchTheIndependentLedger\n[PASS] invariant_feesAndBurnsAccountForTheMissingSupply\n[PASS] invariant_supplyNeverGrowsAndShrinksOnlyByBurns\n ADVNTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 1009  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 1039  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 700.12ms (698.25ms CPU time)\n\nRan 2 tests for test/ADVNToken.allowances.invariant.t.sol:ADVNTokenAllowanceInvariantTest\n[PASS]\nADVNTokenAllowanceInvariantTest invariants:\n[PASS] invariant_allAllowancesMatchIndependentApprovalHistory\n[PASS] invariant_allBalancesAndSupplyMatchTheLedger\n[PASS] invariant_registryChangesOnlyAffectTheCurrentDistributor\n[PASS] invariant_roundingErrorIsBoundedAcrossTheWholeSequence\n ADVNTokenAllowanceInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭--------------------------+----------------------+-------+---------+----------╮\n| Contract                 | Selector             | Calls | Reverts | Discards |\n+==============================================================================+\n| AllowanceSequenceHandler | approve              | 2336  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | registerDistributor  | 2290  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | rejectedTransferFrom | 2377  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | revoke               | 2347  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | transfer             | 2319  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | transferAll          | 2379  | 0       | 0        |\n|--------------------------+----------------------+-------+---------+----------|\n| AllowanceSequenceHandler | transferFrom         | 2336  | 0       | 0        |\n╰--------------------------+----------------------+-------+---------+----------╯\n\n[PASS] test_handlerExercisesSuccessfulAndRejectedSpendsWithoutAutoApproving() (gas: 5137433)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 12.02s (12.02s CPU time)\n\nRan 5 test suites in 12.02s (13.10s CPU time): 85 tests passed, 0 failed, 0 skipped (85 total tests)\n","passed":true},{"durationMs":57,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ADVNToken.approve(address,uint256)\",\"ADVNToken.transfer(address,uint256)\",\"ADVNToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":186,\"REVIEW.md\":73,\"foundry.toml\":21,\"remappings.txt\":4,\"src/ADVNToken.sol\":120,\"test/ADVNToken.adversarial.t.sol\":508,\"test/ADVNToken.allowances.invariant.t.sol\":297,\"test/ADVNToken.invariant.t.sol\":125,\"test/ADVNToken.t.sol\":458,\"test/LaunchFlow.t.sol\":445,\"test/TESTING.md\":98,\"test/mocks/MockFactory.sol\":75},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"cedbbd91f67f56abc4931cdb0d0479a586ab66506474e251fce224fae6109b50","verifiedTreeHash":"8645af1fae11304218ed422aad02d4637d2048a7","verifierVersion":"0.1.0+435fe828"},{"checks":[{"durationMs":2282,"exitCode":0,"name":"build","output":"Compiling 74 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.18s\nCompiler run successful!\n","passed":true},{"durationMs":552,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 39 tests for test/ADVNToken.t.sol:ADVNTokenTest\n[PASS] testFuzz_exemptFlowsMoveExactly(uint256,address) (runs: 256, μ: 258905, ~: 259448)\n[PASS] testFuzz_previewTransferMatchesTheBasisPointFormula(uint256) (runs: 256, μ: 7064, ~: 7089)\n[PASS] testFuzz_taxNeverExceedsOnePointFivePercent(uint256) (runs: 256, μ: 7233, ~: 6950)\n[PASS] testFuzz_taxedTransferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 113486, ~: 113545)\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 256, μ: 244686, ~: 253403)\n[PASS] test_constructorDoesNotNeedCodeAtTheLaunchAddresses() (gas: 907238)\n[PASS] test_constructorRejectsZeroFactory() (gas: 216191)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 218520)\n[PASS] test_distributorIsOrdinaryUntilTheFactoryRecordsIt() (gas: 193834)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 74317)\n[PASS] test_distributorTransfersAreUntaxedOnceRecorded() (gas: 215312)\n[PASS] test_dustBelowTheRoundingThresholdMovesWhole() (gas: 347543)\n[PASS] test_exemptTransferMoreThanBalanceReverts() (gas: 104036)\n[PASS] test_factoryCannotMoveAHoldersBalance() (gas: 110747)\n[PASS] test_factoryTransfersAreUntaxed() (gas: 81306)\n[PASS] test_feeRecipientPaysTaxLikeAnyoneElse() (gas: 165895)\n[PASS] test_isExemptView() (gas: 152411)\n[PASS] test_launchParametersAreRecorded() (gas: 61218)\n[PASS] test_metadata() (gas: 29073)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 37587)\n[PASS] test_noMintOrAdminEntryPoints() (gas: 155293)\n[PASS] test_previewTransfer() (gas: 6316)\n[PASS] test_previewTransferIsDefinedForEveryAmount() (gas: 13480)\n[PASS] test_selfTransferIsTaxed() (gas: 160567)\n[PASS] test_tokensLeavingThePoolManagerAreTaxed() (gas: 190240)\n[PASS] test_transferFromIntoThePoolManagerIsUntaxed() (gas: 191716)\n[PASS] test_transferFromIsTaxed() (gas: 264805)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 108712)\n[PASS] test_transferMoreThanBalanceReverts() (gas: 112161)\n[PASS] test_transferToFeeRecipientIsTaxed() (gas: 155444)\n[PASS] test_transferToZeroAddressReverts() (gas: 101264)\n[PASS] test_transfersIntoThePoolManagerAreUntaxed() (gas: 153317)\n[PASS] test_transfersWorkWhenTheFactoryAnswersANonAddressWord() (gas: 2424160)\n[PASS] test_transfersWorkWhenTheFactoryAnswersShort() (gas: 2266282)\n[PASS] test_transfersWorkWhenTheFactoryHasNoCode() (gas: 1062660)\n[PASS] test_transfersWorkWhenTheFactoryLookupReverts() (gas: 2294086)\n[PASS] test_walletTransferPaysFeeAndBurns() (gas: 205047)\n[PASS] test_wholeBalanceCanBeSentDespiteTheTax() (gas: 181738)\n[PASS] test_zeroTransferIsAllowedAndMovesNothing() (gas: 137070)\nSuite result: ok. 39 passed; 0 failed; 0 skipped; finished in 15.87ms (54.73ms CPU time)\n\nRan 10 tests for test/LaunchFlow.t.sol:LaunchFlowTest\n[PASS] testFuzz_anyBuySizeSettlesAndTaxes(uint256) (runs: 256, μ: 631308, ~: 631515)\n[PASS] test_buyIsTaxedOnTheWayOutAndSellIsExactOnTheWayIn() (gas: 651177)\n[PASS] test_buySettledAsClaimsIsUntaxedUntilRedeemedAsErc20() (gas: 1876214)\n[PASS] test_buyThenSellSeveralTimesNeverReverts() (gas: 1661400)\n[PASS] test_claimRoundTripIsUntaxed() (gas: 1775062)\n[PASS] test_claimToClaimMoveIsUntaxedAndRedemptionIsTaxed() (gas: 3113074)\n[PASS] test_liquidityWithdrawalIsTaxedOnTheWayOut() (gas: 421654)\n[PASS] test_seedTakesExactlyWhatItSays() (gas: 272793)\n[PASS] test_swarmShareAndClaimsMoveWhole() (gas: 145058)\n[PASS] test_wrappingErc20IntoClaimsIsUntaxedAndUnwrappingIsTaxed() (gas: 1815459)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 55.06ms (61.14ms CPU time)\n\nRan 1 test for test/ADVNToken.invariant.t.sol:ADVNTokenInvariantTest\n[PASS]\nADVNTokenInvariantTest invariants:\n[PASS] invariant_balancesMatchTheIndependentLedger\n[PASS] invariant_feesAndBurnsAccountForTheMissingSupply\n[PASS] invariant_supplyNeverGrowsAndShrinksOnlyByBurns\n ADVNTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 1009  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 1039  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 444.28ms (442.46ms CPU time)\n\nRan 3 test suites in 445.83ms (515.21ms CPU time): 50 tests passed, 0 failed, 0 skipped (50 total tests)\n","passed":true},{"durationMs":42,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ADVNToken.approve(address,uint256)\",\"ADVNToken.transfer(address,uint256)\",\"ADVNToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":186,\"REVIEW.md\":73,\"foundry.toml\":21,\"launch.json\":28,\"remappings.txt\":4,\"src/ADVNToken.sol\":120,\"test/ADVNToken.invariant.t.sol\":125,\"test/ADVNToken.t.sol\":458,\"test/LaunchFlow.t.sol\":398,\"test/mocks/MockFactory.sol\":75},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"dd04eb51ec9a202334cf93daa6656d196f0005d8f722d92991524578da6cc8ef","verifiedTreeHash":"eb66288423288065896e33e5b8dfdca9fbee282c","verifierVersion":"0.1.0+435fe828"},{"checks":[{"durationMs":1994,"exitCode":0,"name":"build","output":"Compiling 74 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.90s\nCompiler run successful!\n","passed":true},{"durationMs":524,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 36 tests for test/ADVNToken.t.sol:ADVNTokenTest\n[PASS] testFuzz_exemptFlowsMoveExactly(uint256,address) (runs: 256, μ: 258897, ~: 259430)\n[PASS] testFuzz_taxNeverExceedsOnePointFivePercent(uint256) (runs: 256, μ: 7265, ~: 6997)\n[PASS] testFuzz_taxedTransferAboveBalanceReverts(uint256,uint256) (runs: 256, μ: 113570, ~: 113552)\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 256, μ: 244999, ~: 253513)\n[PASS] test_constructorDoesNotNeedCodeAtTheLaunchAddresses() (gas: 911497)\n[PASS] test_constructorRejectsZeroFactory() (gas: 216623)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 218975)\n[PASS] test_distributorIsOrdinaryUntilTheFactoryRecordsIt() (gas: 193956)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 74369)\n[PASS] test_distributorTransfersAreUntaxedOnceRecorded() (gas: 215336)\n[PASS] test_dustBelowTheRoundingThresholdMovesWhole() (gas: 347809)\n[PASS] test_exemptTransferMoreThanBalanceReverts() (gas: 104040)\n[PASS] test_factoryCannotMoveAHoldersBalance() (gas: 110717)\n[PASS] test_factoryTransfersAreUntaxed() (gas: 81177)\n[PASS] test_feeRecipientPaysTaxLikeAnyoneElse() (gas: 165987)\n[PASS] test_isExemptView() (gas: 152535)\n[PASS] test_launchParametersAreRecorded() (gas: 39954)\n[PASS] test_metadata() (gas: 28985)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 37575)\n[PASS] test_noMintOrAdminEntryPoints() (gas: 155293)\n[PASS] test_previewTransfer() (gas: 6298)\n[PASS] test_selfTransferIsTaxed() (gas: 160637)\n[PASS] test_tokensLeavingThePoolManagerAreTaxed() (gas: 190281)\n[PASS] test_transferFromIntoThePoolManagerIsUntaxed() (gas: 191673)\n[PASS] test_transferFromIsTaxed() (gas: 264894)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 108688)\n[PASS] test_transferMoreThanBalanceReverts() (gas: 112195)\n[PASS] test_transferToFeeRecipientIsTaxed() (gas: 155433)\n[PASS] test_transferToZeroAddressReverts() (gas: 101290)\n[PASS] test_transfersIntoThePoolManagerAreUntaxed() (gas: 153258)\n[PASS] test_transfersWorkWhenTheFactoryAnswersShort() (gas: 2276412)\n[PASS] test_transfersWorkWhenTheFactoryHasNoCode() (gas: 1066970)\n[PASS] test_transfersWorkWhenTheFactoryLookupReverts() (gas: 2304216)\n[PASS] test_walletTransferPaysFeeAndBurns() (gas: 205111)\n[PASS] test_wholeBalanceCanBeSentDespiteTheTax() (gas: 181807)\n[PASS] test_zeroTransferIsAllowedAndMovesNothing() (gas: 137184)\nSuite result: ok. 36 passed; 0 failed; 0 skipped; finished in 32.93ms (44.97ms CPU time)\n\nRan 6 tests for test/LaunchFlow.t.sol:LaunchFlowTest\n[PASS] testFuzz_anyBuySizeSettlesAndTaxes(uint256) (runs: 256, μ: 631377, ~: 631581)\n[PASS] test_buyIsTaxedOnTheWayOutAndSellIsExactOnTheWayIn() (gas: 651227)\n[PASS] test_buyThenSellSeveralTimesNeverReverts() (gas: 1661564)\n[PASS] test_liquidityWithdrawalIsTaxedOnTheWayOut() (gas: 421760)\n[PASS] test_seedTakesExactlyWhatItSays() (gas: 272741)\n[PASS] test_swarmShareAndClaimsMoveWhole() (gas: 144945)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 37.52ms (40.25ms CPU time)\n\nRan 1 test for test/ADVNToken.invariant.t.sol:ADVNTokenInvariantTest\n[PASS]\nADVNTokenInvariantTest invariants:\n[PASS] invariant_balancesMatchTheIndependentLedger\n[PASS] invariant_feesAndBurnsAccountForTheMissingSupply\n[PASS] invariant_supplyNeverGrowsAndShrinksOnlyByBurns\n ADVNTokenInvariantTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 1009  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 1039  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 419.57ms (418.09ms CPU time)\n\nRan 3 test suites in 421.24ms (490.02ms CPU time): 43 tests passed, 0 failed, 0 skipped (43 total tests)\n","passed":true},{"durationMs":46,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"ADVNToken.approve(address,uint256)\",\"ADVNToken.transfer(address,uint256)\",\"ADVNToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":152,\"REVIEW.md\":52,\"foundry.toml\":21,\"launch.json\":28,\"remappings.txt\":4,\"src/ADVNToken.sol\":105,\"test/ADVNToken.invariant.t.sol\":125,\"test/ADVNToken.t.sol\":412,\"test/LaunchFlow.t.sol\":234,\"test/mocks/MockFactory.sol\":56},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"ef4dffcada5c39651f71cbed800283f9e17a873c88d2d585f27af8fc4f80e181","verifiedTreeHash":"4472aa73e993ceb1045c57f86f7c1a2c1aea9bd9","verifierVersion":"0.1.0+435fe828"}]}