{"assessments":[],"deployments":[{"attestationHash":"325ddfa111dc16b372cb1770f4ee7413c0feaa9fe7166357c45b0f3355c56377","chainId":1,"contracts":[{"address":"0x784ff9a3ac5d88a30bfff6f7f2a270161fbe6000","blockNumber":26402046,"name":"PoolInitializationGuard","role":"hook","txHash":"0xf2ad29dc3f5c1c8da1209a8651499693e1d4e9ef44047a38b1888bb0b140ae3b"},{"address":"0x040db82c01b0b91c50047e33c48447ba7d54e47f","blockNumber":26402046,"name":"MerkleDistributor","role":"distributor","txHash":"0xf2ad29dc3f5c1c8da1209a8651499693e1d4e9ef44047a38b1888bb0b140ae3b"},{"address":"0x0f3bcdb7680e36d205ab91498d46a9c7cabcf35f","blockNumber":26402046,"name":"NvidiaToken","role":"token","txHash":"0xf2ad29dc3f5c1c8da1209a8651499693e1d4e9ef44047a38b1888bb0b140ae3b"}],"id":"bb9d8903-9449-4c48-9365-232cde68da42","manifestHash":"2cb23484958f24123b788c641d739a9e25f0d53ba2a467fafa5f997fe701f198","status":"live"}],"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":"7351149b-34cf-4269-bf62-4373de033dfd","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"0d97e333c22843c40bebdfa8c543221252166bb4353677f87332d5f919fcc236","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":"dd596b07fe573ac5dde504503d1262dfac23ad31e815b35c2d9c32b68917981c","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":"8e416852c59b5fe53e4e667b7d747aae68bbd077d898d409295740a871650c47","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":"c6d7daa68dcaba0214310833365c11b0888e439cbb98255467fca63db7330771","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":"ee2314143010d170c7b4c7a9644c4ecd8b60e51ecb77db8fa20bd6904f16a0d4","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":"821543a16fbfd78b2e3e3a157f8791ee9877be9419543ebe59c77974e6975af3","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":"5f404680082cfdfda47f4889a772ab8712ae7b2301f9ed545a574fce7f88ede1","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"a45b9e97ef67f49efb5cf3fc90ec7958502719a43aa2923b559776868116699f","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: Nvidia (ADVN).\nToken name: Nvidia\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":"a4e0e4cd64d4b233d5ae22ed3129f63cc127bdd130b96571e9075ef458c3a16b","previousHash":"71409aca8cb3a8797444a7c59bffd2aac693d0b3837b5df855c04a13e40d3db3","projectId":"7351149b-34cf-4269-bf62-4373de033dfd","publication":{"commit":"3571fa827d80327e8a13207b9015b2372e42bf46","deliveredAt":"2026-11-12T23:06:04.272Z","repoUrl":"https://github.com/identity-md-launches/launch-3250-nvidia"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[],"site":null,"snapshotHash":"3557e1b266ddf49162f6070c95ea50083b8c24f8c32826b43e3ac639b106be9b","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"ef31844bb462de78","findings":[{"citation":"resolved","description":"The exemption keys on the PoolManager address, not on the launch pool. Uniswap v4's PoolManager (mainnet 0x000000000004444c5dc75cB358380D2e3dE08A90, code present) is a permissionless settlement contract: any account may call unlock(bytes), and inside its unlockCallback call sync(currency), transfer tokens to the manager, settle() to be credited the balance delta, and take(currency, to, amount) to have the manager transfer that amount to any address. It may also mint(to, id, amount) ERC-6909 claim tokens, which transfer freely inside the manager with no ERC-20 transfer at all, and are later burned and taken. Every ERC-20 leg of these flows has from == poolManager or to == poolManager, so _isLaunchFlow returns true and no tribute is paid and nothing is burned. Consequences, all reachable by an unprivileged holder for gas only: (1) any wallet-to-wallet transfer, OTC settlement, exchange deposit or bridge deposit can skip the 1.5% by routing through the manager, so the economic guarantee the README states (wallet-to-wallet transfers, exchange deposits and transfers to other venues are taxed) does not hold once a 20-line router exists; (2) every Uniswap v4 pool for ADVN trades untaxed, not just the launch pool, so README line 48 ('Trades on any other venue are [taxed]') is wrong for every v4 venue, including third-party pools with arbitrary hooks; (3) ERC-6909 claims on the manager are an untaxed wrapped ADVN that can be transferred and traded indefinitely without touching the tax path. Who loses: the tribute recipient loses 0.5% of all routed volume and all holders lose the 1% deflation; the only parties still paying the tax are those who do not know about the route. The exemption itself cannot be removed at the token level: the launch floor (Token.protected.t.sol test_theSeedAndASwapEachWaySucceed) requires exact settlement into and out of the PoolManager, and the pass-through uses exactly those two legs, so the token cannot distinguish a swap from a pass-through. This is therefore a design limitation the requester must accept knowingly rather than a code fix: at minimum the README should state that the tax is avoidable by anyone via the v4 PoolManager and that all v4 pools are untaxed; if the requester wants a tax that cannot be bypassed, it needs a v4 hook on the launch pool, which this launch does not deploy. Severity medium: no funds are lost or misdirected, but the token's stated economic guarantee is broken for anyone who chooses to break it.","line":133,"path":"src/NvidiaToken.sol","reproduction":"State: token deployed with poolManager = the v4 PoolManager; alice holds 1_000_000e18 ADVN (received from the factory). Direct path: alice.transfer(bob, 1000e18) gives bob 985e18, TRIBUTE_RECIPIENT 5e18, totalSupply drops by 10e18. Bypass path, same alice and bob: alice approves a router contract R for 1000e18 and calls R.send(bob, 1000e18). R calls poolManager.unlock(data); in R.unlockCallback: poolManager.sync(Currency.wrap(address(token))); token.transferFrom(alice, poolManager, 1000e18) [to == poolManager, untaxed]; poolManager.settle() credits R +1000e18; poolManager.take(Currency.wrap(address(token)), bob, 1000e18) [from == poolManager, untaxed]; unlock returns with R's delta at zero. Expected per the brief and README: bob receives 985e18, 5e18 tribute, 10e18 burned. Actual: bob receives 1000e18, TRIBUTE_RECIPIENT balance unchanged (0), totalSupply unchanged (1_000_000_000e18), manager balance back to 0. Demonstrated locally with test/scratch/PoolManagerPassThrough.t.sol, where a minimal manager at the exempt address implements v4's sync/settle/take accounting: test_directTransferIsTaxed shows 985/5/10 and test_transferThroughPoolManagerIsUntaxed shows 1000/0/0 for the same sender, receiver and amount. Variant with no ERC-20 leg at all: alice deposits once as above and calls mint(alice, uint256(uint160(token)), 1000e18); the ERC-6909 claim is then transferred to bob inside the manager (ERC-6909 transfer, no tax), and bob later burns it and takes 1000e18 to any address.","severity":"medium","snippet":"        if (from == factory || to == factory || from == poolManager || to == poolManager) return true;","title":"PoolManager exemption makes the tax optional: anyone can move ADVN wallet-to-wallet untaxed through Uniswap v4's unlock/settle/take, and every v4 pool (not only the launch pool) trades untaxed"},{"citation":"resolved","description":"The address matches the brief character for character (checksum form of 0xc59b0c072f73ceea3dc354031165501c0ff25023), so the code copies it correctly. But on Ethereum mainnet (chain 1, queried at 'latest' on 2026-11-13) eth_getCode returns 0x, eth_getBalance returns 0 and eth_getTransactionCount returns 0: the address has no contract, holds no ETH and has never sent a transaction. There is no on-chain evidence that anyone, let alone the intended recipient, controls its key, and nothing in the brief or repository documents how the address was obtained. Because TRIBUTE_RECIPIENT is a constant with no setter (by design, no admin), a wrong or uncontrolled address means 0.5% of every taxed transfer for the life of the token is sent to a sink nobody can spend from. This is not a code defect; it is an unverified economic input that the README already flags at line 91 as something the requester should confirm. Recommendation before admission: obtain proof of control from the requester (a message signed by that key, or a dust transaction from it), and record that evidence with the launch. Changing the design (a claimable escrow or a setter) would contradict the no-admin requirement and is not proposed.","line":40,"path":"src/NvidiaToken.sol","reproduction":"State: any holder alice with 1000e18 ADVN. Call: alice.transfer(bob, 1000e18). Actual: 5e18 ADVN is credited to 0xc59b0c072f73ceEA3Dc354031165501c0Ff25023, an address whose mainnet state is code=0x, balance=0 wei, nonce=0. Expected: the 0.5% reaches a wallet that the intended recipient can spend from. If the key is not held by the intended recipient, there is no call on the token (no setter, no owner, no sweep) that can redirect past or future tribute; the balance at that address only grows.","severity":"low","snippet":"    address public constant TRIBUTE_RECIPIENT = 0xc59b0c072f73ceEA3Dc354031165501c0Ff25023;","title":"Tribute recipient is a never-used mainnet address (no code, zero balance, nonce 0) hard-coded as a constant with no recovery path; if it is wrong, 0.5% of every taxed transfer is stranded forever"},{"citation":"resolved","description":"Two readings of the brief diverge from what ships. (1) The brief taxes 'every trade'; the implementation taxes every transfer except launch flows, and launch-pool swaps settle through the PoolManager, which must be exempt for the floor's exact seed and swap checks to pass. At launch the only venue is the v4 pool, so the token's primary trading flow pays no tribute and burns nothing, while non-trade transfers (wallet to wallet) pay 1.5%. The README documents this at assumption 2 and names the only remedy (a v4 hook, which this launch does not deploy). (2) 'A 1% burn of supply from every fee' is implemented as 1% of the transferred amount on top of the 0.5% tribute (BURN_BPS = 100, total 1.5%); the literal reading, 1% of the 0.5% fee (0.005% of the amount), is documented as rejected at README assumption 3. Neither is a code defect, and the fix for (1) is outside this launch's reach, but both change the token's economics materially and should be confirmed by the requester in writing before admission so the judge does not treat the shipped behaviour as a mistake later.","line":114,"path":"src/NvidiaToken.sol","reproduction":"(1) State: launch pool seeded; a trader holds 1 ETH. Call: trader buys ADVN from the launch pool via the PoolManager and later sells it back. Expected under a literal reading of the brief: 0.5% of each trade to TRIBUTE_RECIPIENT and 1% burned. Actual: PoolManager -> trader and trader -> PoolManager are exempt (line 133), TRIBUTE_RECIPIENT balance unchanged, totalSupply unchanged. (2) State: alice holds 1000e18. Call: alice.transfer(bob, 1000e18). Actual: tribute 5e18, burned 10e18, bob 985e18. Under the literal 'burn 1% of the fee' reading: tribute 5e18, burned 0.05e18, bob 994.95e18.","severity":"info","snippet":"        if (from == address(0) || to == address(0) || value == 0 || _isLaunchFlow(from, to)) {","title":"Brief says the fee comes 'from every trade', but trades in the launch pool (the only venue at launch) are untaxed by necessity, and '1% burn of supply from every fee' is read as 1% of the amount; both"},{"citation":"resolved","description":"UniswapV3Pool.swap requires that the pool's balance of the input token increases by at least the full computed input inside the swap callback (require(balance0Before.add(uint256(amount0)) <= balance0(), 'IIA'), and the symmetric check for token1). A taxed ADVN transfer delivers 98.5% of the amount, so every swap that pays ADVN into a v3 pool reverts regardless of which router function is used; v3 has no fee-on-transfer variant. Buys (pool -> trader) succeed with the trader receiving 98.5%. The guidance on this line is therefore correct for v2 and wrong for v3, and a v3 pool for ADVN would be buy-only, trapping anyone who provides liquidity to it against sells. This is inherent to the requested fee-on-transfer design and not a code defect; only the README sentence needs correcting so integrators and the requester are not misled.","line":92,"path":"README.md","reproduction":"State: a v3 ADVN/WETH pool exists with liquidity; alice holds 1000e18 ADVN approved to the v3 SwapRouter. Call: exactInputSingle(tokenIn = ADVN, tokenOut = WETH, amountIn = 1000e18). Trace: pool computes amount0 = 1000e18 owed, calls uniswapV3SwapCallback, router does ADVN.transferFrom(alice, pool, 1000e18); the taxed path (from = alice, to = pool, neither exempt) credits the pool 985e18 and sends 5e18 to TRIBUTE_RECIPIENT and burns 10e18. Pool checks balance0Before + 1000e18 <= balance0(): 985e18 < 1000e18, reverts 'IIA'. Expected per the README: the swap goes through with the fee-on-transfer function. Actual: no such function exists and every v3 sell reverts.","severity":"info","snippet":"- **Integrators.** Exchanges, bridges, routers and vaults that assume `balanceOf(to)` increases by exactly `amount` will see 98.5% arrive. Deposit flows should read the balance delta. Uniswap v2/v3 style venues need their \"supporting fee on transfer tokens\" swap functions. Trades in the launch's v4 pool are exact.","title":"README tells integrators that v2/v3 venues work with 'supporting fee on transfer' swap functions, but Uniswap v3 has none: selling ADVN into any v3 pool reverts, only buying works"}],"hash":"0d97e333c22843c40bebdfa8c543221252166bb4353677f87332d5f919fcc236","nodeId":"e639f38b-6c7a-4624-a23b-14f242ca4bc4","outcome":"completed","summary":"The review is complete. The findings file is valid, all four cited snippets match the tree, and all three entry points plus six invariants have coverage rows. No source or config files were changed; the only new files are the findings file and one scratch test.\n\n**Outcome: one medium, one low, two info findings on the economics of `NvidiaToken`. No critical or high defect.**\n\nThe token's arithmetic, conservation and launch flows hold. Supply is minted once, the three-way split sums exactly to the amount after a whole-amount balance check, totalSupply only shrinks by the burn, and the factory, PoolManager and distributor flows move exactly what they say. All 38 repository tests pass.\n\nFindings written to `.imd-findings.json`:\n\n- **Medium. The tax is optional.** The exemption keys on the PoolManager address, and Uniswap v4's PoolManager is permissionless. Any holder can unlock it, transfer ADVN in, settle, and take to any address, so a wallet-to-wallet transfer, exchange deposit or OTC settlement pays no tribute and burns nothing. ERC-6909 claims on the manager are an untaxed wrapped ADVN, and every v4 pool trades untaxed, not just the launch pool. I demonstrated this with a scratch test: the same sender, receiver and amount yield 985 to the receiver, 5 tribute and 10 burned directly, and 1000, 0 and 0 when routed through the manager. The token cannot fix this without failing the launch floor's exact swap checks, so it is a design limitation the requester must accept and the README must disclose.\n- **Low. The tribute address has never been used.** On mainnet it has no code, zero balance and nonce zero. The code copies the brief exactly, but there is no evidence anyone controls the key, and the constant has no setter. Proof of control should be obtained before admission.\n- **Info. Brief versus implementation.** Fees are stated as \"from every trade\", yet launch-pool trades are necessarily untaxed, and \"1% burn of supply from every fee\" is read as 1% of the amount. Both are disclosed assumptions that need the requester's written confirmation.\n- **Info. README v3 guidance is wrong.** Uniswap v3 has no fee-on-transfer swap path, so selling ADVN into any v3 pool reverts. Only buying works.\n\nCoverage: all three entry points answered, with transfer and transferFrom pointing at finding 1 and approve holding. Passes I could not complete: no test against the real v4-core PoolManager, since it is not vendored and a submitted proof may import only the project and forge-std, so the pass-through is shown with a minimal manager that mirrors v4's sync, settle and take accounting. No proof field was attached because no finding is high or critical.","treeHash":null,"usage":{"cachedInputTokens":876443,"chain":[{"calls":4,"chainId":1,"failed":0,"own":4,"public":0,"refused":0}],"cost":{"source":"runtime","usdMicros":3667040},"inputTokens":354,"model":"claude-fable-5-1","outputTokens":28913,"runtime":"claude","turns":18,"wallClockMs":418253}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"1731fbfe0c4574fb","findings":[{"citation":"resolved","description":"Merged from audit_flow, audit_math, audit_permissions and audit_economics (same root cause, line 133). _isLaunchFlow exempts a transfer when EITHER side is the PoolManager address. Uniswap v4's PoolManager is a permissionless singleton: inside unlock() any caller may sync(currency), transfer tokens in, settle() for a credit, and take(currency, to, amount) to pay that credit out to any address, with no pool, no swap and no pool fee. Both ERC-20 legs (holder -> PoolManager, PoolManager -> recipient) hit line 133 and skip splitTransfer, so a wallet-to-wallet payment moves 100% with tribute 0 and burn 0. The ERC-6909 claim the PoolManager mints after settle is likewise an untaxed, freely transferable wrapper of ADVN, and every third-party v4 pool for ADVN (any hook, any pair) trades untaxed. This contradicts the NatSpec (lines 19-21), README assumption 1 and the brief: the only parties who pay the 1.5% are those who do not route through a 20-line helper. Loser: the tribute recipient (0.5% of routed volume) and the deflation (1%). No holder loses funds, so medium. Reproduced: the audit_flow proof fails on this tree ('tribute skipped: 0 != 5000000000000000000000'). Fix verified in a scratch copy of the token: dropping `from == poolManager` and keeping `to == poolManager` makes that proof pass and keeps the launch floor passing, because the floor only needs tokens ENTERING the PoolManager to be exact (the seed is factory -> PoolManager, already exempt as from == factory; a sell is trader -> PoolManager). PoolManager.take() does not check its own balance after paying out, and the tax on an outbound transfer is deducted entirely from the PoolManager's balance (net + tribute + burned == amount), so its flash accounting still nets to zero; the floor's buy check is only `bought > 0` and the sell-back of `bought` is exact. With that change buys from the launch pool (and LP withdrawals and takes) pay the tax, which is closer to the brief's 'from every trade', while the pass-through route pays 1.5% on its take leg. The audit_economics claim that the exemption cannot be removed at the token level is therefore only half right: the inbound leg must stay exempt, the outbound leg need not. The residual untaxed path after the fix is ERC-6909 claim transfers inside the PoolManager, which end in a taxed take. This changes README assumption 2 and the existing tests that encode the two-way exemption (test_poolManagerBothWaysIsUntaxed, testFuzz_launchFlowsAreExact outbound case, the invariant handler's model); if the requester prefers to keep pool buys untaxed instead, the README and manifest notes must state plainly that the tax is avoidable by anyone via the PoolManager and that all v4 pools are untaxed.","line":133,"path":"src/NvidiaToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {NvidiaToken} from \"src/NvidiaToken.sol\";\n\ninterface IERC20Min {\n    function balanceOf(address) external view returns (uint256);\n    function transfer(address, uint256) external returns (bool);\n}\n\ninterface IUnlockCallbackMin {\n    function unlockCallback(bytes calldata) external returns (bytes memory);\n}\n\n/// @dev The part of Uniswap v4's PoolManager flash accounting the route uses, with v4's semantics:\n/// sync() snapshots the reserve, settle() credits the caller with balance - snapshot, take() pays out\n/// and debits the caller, and unlock() requires every delta to net to zero.\ncontract MiniPoolManager {\n    address syncedCurrency;\n    uint256 syncedReserve;\n    mapping(address => mapping(address => int256)) public delta;\n    address locker;\n\n    function unlock(bytes calldata data) external returns (bytes memory r) {\n        locker = msg.sender;\n        r = IUnlockCallbackMin(msg.sender).unlockCallback(data);\n        locker = address(0);\n    }\n\n    function sync(address currency) external {\n        syncedCurrency = currency;\n        syncedReserve = IERC20Min(currency).balanceOf(address(this));\n    }\n\n    function settle() external returns (uint256 paid) {\n        paid = IERC20Min(syncedCurrency).balanceOf(address(this)) - syncedReserve;\n        delta[msg.sender][syncedCurrency] += int256(paid);\n        syncedCurrency = address(0);\n    }\n\n    function take(address currency, address to, uint256 amount) external {\n        delta[msg.sender][currency] -= int256(amount);\n        require(IERC20Min(currency).transfer(to, amount), \"transfer failed\");\n    }\n}\n\n/// @dev Any holder's helper: moves tokens to a recipient through the PoolManager's escrow.\ncontract EscrowRoute is IUnlockCallbackMin {\n    MiniPoolManager immutable pm;\n    NvidiaToken immutable token;\n\n    constructor(MiniPoolManager pm_, NvidiaToken token_) {\n        pm = pm_;\n        token = token_;\n    }\n\n    function send(address to, uint256 amount) external {\n        pm.unlock(abi.encode(to, amount));\n    }\n\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        (address to, uint256 amount) = abi.decode(data, (address, uint256));\n        pm.sync(address(token));\n        token.transfer(address(pm), amount); // to == poolManager: untaxed\n        pm.settle();\n        pm.take(address(token), to, amount); // from == poolManager: untaxed\n        require(pm.delta(address(this), address(token)) == 0, \"unsettled\");\n        return \"\";\n    }\n}\n\ncontract PmBypassTest is Test {\n    NvidiaToken token;\n    MiniPoolManager pm;\n    address constant BOB = address(0xB0B);\n\n    function setUp() public {\n        pm = new MiniPoolManager();\n        token = new NvidiaToken(address(this), address(pm), 1);\n    }\n\n    /// A wallet-to-wallet transfer of 1,000,000 ADVN routed through the PoolManager must still pay\n    /// the 0.5% tribute and the 1% burn; today Bob receives the full amount and Jensen receives 0.\n    function test_walletToWalletViaPoolManagerStillPaysTax() public {\n        uint256 amount = 1_000_000e18;\n        EscrowRoute route = new EscrowRoute(pm, token);\n        token.transfer(address(route), amount); // from the factory: untaxed seed of the holder\n\n        uint256 supplyBefore = token.totalSupply();\n        route.send(BOB, amount);\n\n        (uint256 net, uint256 tribute, uint256 burned) = token.splitTransfer(amount);\n        assertEq(token.balanceOf(token.TRIBUTE_RECIPIENT()), tribute, \"tribute skipped\");\n        assertEq(supplyBefore - token.totalSupply(), burned, \"burn skipped\");\n        assertEq(token.balanceOf(BOB), net, \"receiver got the untaxed amount\");\n    }\n}","reproduction":"State: NvidiaToken deployed with factory_ = F and poolManager_ = PM, where PM implements v4 flash accounting (sync/settle/take/unlock; the attached proof uses a minimal manager with exactly those semantics, the audit_math specialist also ran it against the mainnet PoolManager runtime bytecode). F transfers 1,000,000e18 ADVN to a helper contract H (from == factory, untaxed). Call H.send(Bob, 1_000_000e18): inside PM.unlock -> H.unlockCallback: PM.sync(ADVN); ADVN.transfer(PM, 1e24) [to == poolManager, untaxed]; PM.settle() credits +1e24; PM.take(ADVN, Bob, 1e24) [from == poolManager, untaxed]; H's delta nets to zero. Expected (a wallet-to-wallet transfer per NatSpec/README): Bob 985,000e18, TRIBUTE_RECIPIENT +5,000e18, totalSupply -10,000e18, one TransferTaxed event. Actual: Bob 1,000,000e18, TRIBUTE_RECIPIENT 0, totalSupply unchanged, no TransferTaxed. Compare the direct call H -> Bob transfer(Bob, 1e24): 985,000e18 / 5,000e18 / -10,000e18. `forge test --match-path test/scratch/Proof_e19edd803c55.t.sol` fails with 'tribute skipped: 0 != 5000000000000000000000'; the same test against a copy of the token with `from == poolManager` removed from line 133 passes.","severity":"medium","snippet":"        if (from == factory || to == factory || from == poolManager || to == poolManager) return true;","title":"Blanket PoolManager exemption makes the tax optional: any holder can move ADVN wallet-to-wallet untaxed through the v4 PoolManager (sync/transfer/settle/take or ERC-6909 claims), and every v4 pool tra"},{"citation":"resolved","description":"Merged from audit_math (line 148) and write_foundry_tests (line 150): same root cause, the staticcall on every non-launch transfer until a non-zero distributor is cached. NatSpec lines 145-146 and README line 43 promise that any failure (no code, revert, malformed answer) reads as 'not known yet' so ordinary transfers never depend on the factory. Three answers break that promise. (a) Exactly 32 bytes with any of the top 96 bits set pass the length check and then abi.decode(data,(address)) reverts (ABI coder v2 validates address words), so transfer, transferFrom and isExempt all revert with empty data. (b) The staticcall forwards all remaining gas (63/64); a factory that burns it (INVALID) leaves 1/64 for the three balance writes: a 1e18 transfer fails at 1,000,000 and 4,000,000 gas and succeeds only at 6,000,000 gas using 5,993,293. (c) Return data is copied in full to memory before the length check; a 600,000-byte answer makes the transfer fail at 500,000 gas and cost 1,635,830 gas at a 3,000,000 limit. Reachability: the launch factory returns a clean address from a mapping getter, and once a distributor is cached the factory is never called again, so none of this occurs with a well-behaved factory. The exposure is a misbehaving or proxied factory while distributorOf(launchNumber) is still zero, or any deployment where it stays zero. Low: no funds lost, transfers blocked only under that precondition. The existing MalformedFactory test covers only a 16-byte answer. Minimal fix preserving behaviour: cap the call gas (factory.staticcall{gas: 50_000}), keep the length check, decode as uint256 and return address(0) when the word exceeds type(uint160).max.","line":148,"path":"src/NvidiaToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {NvidiaToken} from \"src/NvidiaToken.sol\";\n\n/// @notice A factory whose `distributorOf` answers with exactly 32 bytes that are not an address:\n/// the right length, the wrong shape (high 96 bits set).\ncontract NonAddressWordFactory {\n    fallback() external {\n        assembly (\"memory-safe\") {\n            mstore(0, not(0))\n            return(0, 32)\n        }\n    }\n}\n\n/// @notice The token says a malformed answer from the factory reads as \"distributor not known yet\",\n/// so ordinary transfers never depend on the factory. A 32-byte answer that is not an address must\n/// therefore leave ordinary transfers working and taxed, and `isExempt` answering false.\ncontract FactoryLookupProofTest is Test {\n    address constant POOL_MANAGER = address(0x4444);\n    address constant ALICE = address(0xA11CE);\n    address constant BOB = address(0xB0B);\n\n    NvidiaToken token;\n\n    function setUp() public {\n        address factory = address(new NonAddressWordFactory());\n        vm.prank(factory);\n        token = new NvidiaToken(factory, POOL_MANAGER, 7);\n        // from == factory: a launch flow, moves exactly and never asks the factory anything.\n        vm.prank(factory);\n        token.transfer(ALICE, 1_000e18);\n        assertEq(token.balanceOf(ALICE), 1_000e18);\n    }\n\n    function test_nonAddressWordFromFactoryReadsAsNotKnownYet_transfer() public {\n        vm.prank(ALICE);\n        token.transfer(BOB, 100e18);\n        assertEq(token.balanceOf(BOB), 98.5e18, \"the ordinary transfer did not deliver 98.5%\");\n        assertEq(token.balanceOf(token.TRIBUTE_RECIPIENT()), 0.5e18, \"the tribute was not paid\");\n        assertEq(token.totalSupply(), token.INITIAL_SUPPLY() - 1e18, \"the burn did not happen\");\n        assertEq(token.distributor(), address(0), \"a non-address word was cached as the distributor\");\n    }\n\n    function test_nonAddressWordFromFactoryReadsAsNotKnownYet_isExempt() public view {\n        assertFalse(token.isExempt(BOB));\n    }\n}","reproduction":"Deploy NvidiaToken(factory_ = F, poolManager_ = 0x4444, launchNumber_ = 7) with msg.sender = F, then F transfers 1,000e18 to Alice (launch flow, no lookup). (a) F = a contract whose fallback returns the 32-byte word 0xff..ff: Alice calls transfer(Bob, 100e18). Expected: Bob 98.5e18, tribute 0.5e18, totalSupply -1e18, distributor still zero, isExempt(Bob) == false. Actual: transfer reverts (EvmError: Revert), isExempt(Bob) reverts. `forge test --match-path test/scratch/Proof_f49c4315347a.t.sol` fails both tests; the write_foundry_tests proof (word 1<<160, transfer of 1000 wei) fails the same way. (b) F = a contract whose fallback executes INVALID: Alice's transfer(Bob, 1e18) with 1,000,000 or 4,000,000 gas returns false; with 6,000,000 it succeeds using 5,993,293 gas (expected about 100,000). (c) F = a contract whose fallback returns 600,000 zero bytes: the transfer fails at 500,000 gas and uses 1,635,830 gas at 3,000,000. (b) and (c) verified in a scratch test on this tree.","severity":"low","snippet":"        (bool ok, bytes memory data) = factory.staticcall(abi.encodeCall(ILaunchFactory.distributorOf, (launchNumber)));\n        if (!ok || data.length != 32) return address(0);\n        return abi.decode(data, (address));","title":"Distributor lookup is not failure-tolerant as documented: a 32-byte non-address answer reverts every ordinary transfer and isExempt, and a gas-burning or oversized answer from the factory blocks trans"},{"citation":"resolved","description":"Merged from audit_math and write_foundry_tests. The public pure quote helper multiplies before dividing; amount * BURN_BPS overflows once amount > type(uint256).max / 100 (about 1.157e75) and reverts with Panic(0x11), although amount / 200, amount / 100 and the net all fit. README line 31 says the helper 'returns the three parts for any amount'. No transfer can reach this: _update checks balanceOf(from) >= value first and balances are bounded by the 1e27 supply. Effect limited to integrators probing the quote with a sentinel such as type(uint256).max. Fix: Math.mulDiv(amount, BPS, 10_000) from the vendored OpenZeppelin, or divide by the reduced denominators (200 and 100), or narrow the README sentence.","line":94,"path":"src/NvidiaToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {NvidiaToken} from \"src/NvidiaToken.sol\";\n\ncontract SplitOverflowProofTest is Test {\n    function test_previewAcceptsMaximumUint256WithoutIntermediateOverflow() public {\n        NvidiaToken token = new NvidiaToken(address(this), makeAddr(\"pool\"), 1);\n        uint256 amount = type(uint256).max;\n        // All three mathematically correct outputs fit, although amount * 50 does not.\n        (uint256 net, uint256 tribute, uint256 burned) = token.splitTransfer(amount);\n        assertEq(tribute, amount / 200);\n        assertEq(burned, amount / 100);\n        assertEq(net, amount - amount / 200 - amount / 100);\n        assertEq(net + tribute + burned, amount);\n    }\n}","reproduction":"Deploy NvidiaToken(address(1), 0x4444, 1). Call splitTransfer(type(uint256).max). Expected per README: (net, tribute, burned) with tribute = amount / 200, burned = amount / 100, net = amount - tribute - burned. Actual: revert Panic(0x11). Boundary verified in a scratch test: splitTransfer(type(uint256).max / 100) returns, splitTransfer(type(uint256).max / 100 + 1) reverts. `forge test --match-path test/scratch/Proof_647ae4e40a8b.t.sol` fails with 'panic: arithmetic underflow or overflow (0x11)'.","severity":"low","snippet":"        tribute = (amount * TRIBUTE_BPS) / BPS_DENOMINATOR;\n        burned = (amount * BURN_BPS) / BPS_DENOMINATOR;","title":"splitTransfer panics for amounts above type(uint256).max / 100 although the README says it returns the parts for any amount"},{"citation":"resolved","description":"From audit_math, reproduced. vm.envUint returns uint256 and the explicit uint64 cast drops the high bits silently, so a value of 2^64 or more deploys a token bound to a different launch number, whose distributor the token would then exempt. The script is documented as local-only and the production launch passes $launchNumber through the ABI decoder, which rejects an out-of-range word, so informational. Fix: require(value <= type(uint64).max) before the cast, or SafeCast.toUint64.","line":30,"path":"script/DeployNvidiaToken.s.sol","reproduction":"Set ADVN_FACTORY and ADVN_POOL_MANAGER to any non-zero addresses and ADVN_LAUNCH_NUMBER=18446744073709551621 (2^64 + 5); call DeployNvidiaToken.run(). Expected: revert, the value does not fit a uint64. Actual: the token deploys and launchNumber() == 5. Verified in a scratch test with vm.setEnv.","severity":"info","snippet":"            launchNumber: uint64(vm.envUint(\"ADVN_LAUNCH_NUMBER\"))","title":"Local deploy script truncates ADVN_LAUNCH_NUMBER to 64 bits without a bounds check"},{"citation":"resolved","description":"From audit_economics, reproduced against the code and the floor. (1) The brief taxes 'every trade'; at launch the only venue is the v4 pool, whose swaps settle through the exempt PoolManager, so the token's primary trading flow pays no tribute and burns nothing while wallet-to-wallet transfers pay 1.5%. The README's claim that this is required 'in both directions' is too strong: only tokens entering the PoolManager must arrive whole (see finding 1); taxing the outbound leg would tax pool buys without a hook. (2) '1% burn of supply from every fee' is implemented as BURN_BPS = 100 of the amount, total 1.5%; the literal reading (1% of the 0.5% fee, 0.005% of the amount) is documented as rejected in assumption 3. Neither is a code defect, but both materially set the token's economics and should be confirmed by the requester in writing before admission.","line":48,"path":"README.md","reproduction":"(1) State: launch pool seeded per the floor test; a trader buys ADVN through the PoolManager and sells it back. Expected under a literal reading of the brief: 0.5% of each trade to TRIBUTE_RECIPIENT and 1% burned. Actual: PoolManager -> trader and trader -> PoolManager both match line 133, TRIBUTE_RECIPIENT unchanged, totalSupply unchanged. (2) State: alice holds 1000e18. alice.transfer(bob, 1000e18): tribute 5e18, burned 10e18, bob 985e18 (confirmed by the existing suite). Under the literal 'burn 1% of the fee' reading: tribute 5e18, burned 0.05e18, bob 994.95e18.","severity":"info","snippet":"2. **Swaps through the Uniswap v4 PoolManager are untaxed**, in both directions, because the launch requires exact settlement there (see above). The launch pool is a v4 pool, so trades in the launch pool itself are not taxed. Trades on any other venue are. If the requester wants pool trades taxed, that needs a v4 hook, which this launch does not deploy.","title":"Brief interpretation to confirm with the requester: 'from every trade' ships as 'every non-launch transfer' with launch-pool swaps untaxed, and '1% burn of supply from every fee' ships as 1% of the tr"},{"citation":"resolved","description":"From audit_economics. UniswapV3Pool.swap requires inside the callback that the pool's balance of the input token grew by at least the computed input (the 'IIA' check); a taxed ADVN transfer delivers 98.5%, so every swap paying ADVN into a v3 pool reverts, and v3 has no fee-on-transfer router variant. Buys from a v3 pool succeed with the trader receiving 98.5%. A v3 ADVN pool would be buy-only. Inherent to the requested design, not a code defect; the README sentence is correct for v2 and wrong for v3.","line":92,"path":"README.md","reproduction":"State: a v3 ADVN/WETH pool with liquidity; alice holds 1000e18 ADVN approved to the v3 SwapRouter. Call exactInputSingle(tokenIn = ADVN, tokenOut = WETH, amountIn = 1000e18). Trace: the pool computes 1000e18 owed, calls uniswapV3SwapCallback, the router calls ADVN.transferFrom(alice, pool, 1000e18); neither side is exempt so _update credits the pool 985e18, TRIBUTE_RECIPIENT 5e18 and burns 10e18 (the split confirmed by the existing suite). The pool's require(balance0Before + 1000e18 <= balance0()) sees 985e18 and reverts 'IIA'. Expected per the README: a fee-on-transfer swap function completes the sell. Actual: no such function exists in v3 and every v3 sell reverts. Not executed here (v3 is not vendored); traced from v3 core's swap.","severity":"info","snippet":"- **Integrators.** Exchanges, bridges, routers and vaults that assume `balanceOf(to)` increases by exactly `amount` will see 98.5% arrive. Deposit flows should read the balance delta. Uniswap v2/v3 style venues need their \"supporting fee on transfer tokens\" swap functions. Trades in the launch's v4 pool are exact.","title":"README tells integrators that v2/v3 venues work with 'supporting fee on transfer' swap functions, but Uniswap v3 has none: selling ADVN into a v3 pool reverts"},{"citation":"resolved","description":"From audit_economics. The constant matches the brief character for character (checksum of 0xc59b0c072f73ceea3dc354031165501c0ff25023), so the code is correct. Confirmed on Ethereum mainnet from this worker on 2026-11-12 (eth_getCode 0x, eth_getBalance 0, eth_getTransactionCount 0): the address has no contract, holds no ETH and has never sent a transaction, so there is no on-chain evidence that anyone controls its key. Because there is no setter, owner or sweep (by design, per the no-admin brief), a wrong or uncontrolled address strands 0.5% of every taxed transfer forever. Not a code defect: a trust assumption the README already flags at line 91. Before admission the requester should provide proof of control (a signed message or a transaction from the key).","line":40,"path":"src/NvidiaToken.sol","reproduction":"State: alice holds 1000e18 ADVN. Call alice.transfer(bob, 1000e18). Actual: 5e18 ADVN credited to 0xc59b0c072f73ceEA3Dc354031165501c0Ff25023 (confirmed by the existing suite). There is no call on the token that can redirect past or future tribute; if the key is not held by the intended recipient, the balance at that address only grows. Mainnet state at 'latest' on 2026-11-12: code 0x, balance 0 wei, nonce 0.","severity":"info","snippet":"    address public constant TRIBUTE_RECIPIENT = 0xc59b0c072f73ceEA3Dc354031165501c0Ff25023;","title":"Tribute recipient is a hard-coded constant with no recovery path; control of the address is unverified"}],"hash":"1daac6117a84aef2b4fcdab18a2ab6e73a06b5de1d0f8d44fc3fc899184a7a2b","nodeId":"83b71514-f5b3-4c1d-9540-490322be8e9d","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds the result. No repository file was changed; the scratch tests are removed.\n\n**Outcome.** The twelve specialist findings collapse to seven, all reproduced against the code. The existing suite of 78 tests passes, and all four attached proofs fail on this tree for the stated reasons.\n\n**Findings kept**\n\n1. **Medium, PoolManager two-way exemption** at `src/NvidiaToken.sol:133`. Four specialists reported the same root cause, merged into one. Anyone can route a wallet-to-wallet transfer through the v4 PoolManager's sync, settle and take, paying no tribute and no burn. The attached proof fails here with \"tribute skipped\". I also verified the minimal fix in a scratch copy of the token: dropping the outbound exemption makes the proof pass and still satisfies the launch floor, since only tokens entering the PoolManager need to arrive whole. The economics specialist's claim that nothing can be done at the token level was wrong for the outbound leg. This is a requester decision, because it would also tax pool buys.\n2. **Low, distributor lookup hardening** at line 148. Merged from the math specialist and the tester. A 32-byte non-address answer from the factory reverts every transfer and isExempt. I also confirmed the gas-burning and oversized-return variants: a 1e18 transfer needs about 6M gas against an INVALID-returning factory. Needs a misbehaving factory, so low.\n3. **Low, splitTransfer overflow** at line 94. Merged. The quote helper panics above type(uint256).max / 100 although the README promises any amount. Boundary confirmed.\n4. **Info, script truncates the launch number** to 64 bits. Verified with vm.setEnv: 2^64 + 5 deploys with launchNumber 5.\n5. **Info, brief interpretation** to confirm in writing: pool swaps untaxed and the 1% burn read as 1% of the amount.\n6. **Info, README v3 guidance** is wrong: v3 has no fee-on-transfer swap, so sells into a v3 pool revert on the IIA check.\n7. **Info, tribute recipient** is an unverified constant. Confirmed on mainnet today: no code, zero balance, nonce 0.\n\n**Coverage.** All three entry points are answered, approve holds and transfer and transferFrom carry finding 1, plus four invariant rows including the manifest shape. My own pass found nothing beyond the specialists' leads: supply, exempt flows, rounding, self-transfer, allowance and reentrancy all hold.","treeHash":null,"usage":{"cachedInputTokens":547564,"cost":{"source":"runtime","usdMicros":2537743},"inputTokens":258,"model":"claude-fable-5-1","outputTokens":18154,"runtime":"claude","turns":9,"wallClockMs":336569}},{"artifacts":[],"attempt":1,"bundleHash":"5fcf55ed14474a1f08aae1d882ed4bbfc1f954cb82b69c149d628d4119f7222b","device":"fa4b91aed45c94fa","findings":[],"hash":"5f404680082cfdfda47f4889a772ab8712ae7b2301f9ed545a574fce7f88ede1","nodeId":"15ffb0c2-80f7-40c9-bf3d-7b9dbaf17043","outcome":"completed","summary":"I fixed the notes in `launch.json`. They described an older version of the token, where transfers both into and out of the Uniswap v4 PoolManager were tax-free and pool trades were untaxed. The accepted `src/NvidiaToken.sol` only exempts transfers *into* the PoolManager (the pool seed and sells). Transfers *out* of it (buys, liquidity withdrawals, `take`) pay the full 1.5%, which also stops people routing wallet-to-wallet payments through the PoolManager to dodge the tax.\n\nThe notes now say this, and also mention the gas-capped lookup of the token's distributor, the constructor's zero-address check, and the two readings the README leaves for the requester to confirm. They're 1,910 characters, under the 4,000 limit. This is the only change in the diff; no other file was touched.\n\nThe rest of the manifest already matched the source, so I left it as it was:\n- **Token:** contract `NvidiaToken`, name Nvidia, symbol ADVN, 18 decimals.\n- **Constructor arguments:** `[$factory, $poolManager, $launchNumber]`, which matches the constructor `(address, address, uint64)`.\n- **Supply:** `totalSupply` is `\"1000000000000000000000000000\"`, which equals `INITIAL_SUPPLY`, minted once to `msg.sender`.\n- **Contracts:** none, since the token is the only contract in the accepted tree.\n- **Pool:** ETH as the paired currency, fee 12500, tick spacing 60, initial price at one to one.\n- **Economics:** the requester's object, copied exactly.\n\n`forge build` succeeds, and `forge test` with the verifier's fuzz seed passes all 43 tests. I couldn't run the protected launch-floor test (`Token.protected.t.sol`) here: it imports contracts and v4-core sources this repository doesn't have and needs the verifier's environment variables.","treeHash":"a04fbdcb03a231bef8717bae4648e1c7a16091a1","usage":{"cachedInputTokens":131242,"cost":{"source":"runtime","usdMicros":240044},"inputTokens":12,"model":"claude-opus-5-5","outputTokens":2708,"runtime":"claude","turns":6,"wallClockMs":38833}},{"artifacts":[],"attempt":1,"bundleHash":"56f6ded8d6358d6ba74ca831af48d789da5a53e026cdb5a43f9e8572245bcd46","device":"234a4a00ca903cb9","findings":[],"hash":"821543a16fbfd78b2e3e3a157f8791ee9877be9419543ebe59c77974e6975af3","nodeId":"f81e67d6-97b5-488c-addb-7e9d7449f97d","outcome":"completed","summary":"I fixed the main finding (the PoolManager tax bypass) and the two low ones. The reviewer's proof now passes, and `forge build`, `forge test` (45 tests, run with the verifier's fuzz seed) and `forge fmt --check` all pass. Nothing is committed.\n\n**The bypass (medium).** I reproduced it first: on the starting code the reviewer's proof failed with \"tribute skipped\". Anyone could send ADVN to the PoolManager and have it paid out to another wallet in one call, untaxed. The fix in `src/NvidiaToken.sol`:\n- **Into the PoolManager: still untaxed.** This covers the launch seed and sells, which must arrive exact or they revert.\n- **Out of the PoolManager: now taxed.** This covers buys, liquidity withdrawals and any payout. The tax comes out of the PoolManager's own balance, so its accounting still balances, and the receiver gets 98.5%.\n- **`isExempt(poolManager)` now returns false**, because the PoolManager is only exempt as a receiver. I updated the tests that assumed the old two-way exemption and added a test of the pass-through route.\n\n**The two low findings:**\n- **Factory lookup:** it now runs on a 50,000-gas budget and treats any answer that isn't a valid address as \"not known yet\". New tests with a factory that returns a non-address value, burns all its gas, or returns a huge answer show transfers still go through, correctly taxed and cheaply.\n- **`splitTransfer`:** it now divides by 200 and 100 directly. That gives the same results as before and can't overflow, even at the largest possible amount.\n\n**The info findings:**\n- **Deploy script:** it now rejects a launch number too big to fit.\n- **Uniswap v3:** the README now says ADVN can't be sold into a v3 pool, because v3 has no fee-on-transfer swap functions. A v3 pool would be buy-only.\n- **Tribute address:** I disputed this as a code defect. The address matches the brief and the brief asked for no admin, so there is deliberately no way to change it. The README records that the address showed no on-chain activity as of 2026-11-12 and asks the requester for proof they control it.\n\n**For the requester to confirm before launch** (marked in the README):\n- **\"From every trade\":** in the launch pool, buys now pay the 1.5% tax and sells don't. Taxing sells as well would need a Uniswap v4 hook, which this launch doesn't deploy.\n- **The burn:** it is implemented as 1% of each transfer amount, not 1% of the 0.5% fee.\n\nMy answers to each finding are in `.imd-responses.json`.\n\nSeveral files I didn't create appeared untracked in the repo root (`.bashrc`, `.gitmodules`, `.claude/`, `.vscode` and others). I left them alone, but they shouldn't be submitted, so check them before upload.","treeHash":"b2de9420bf967254f93f40dd9cefdb63e4fe6f50","usage":{"cachedInputTokens":496349,"cost":{"source":"runtime","usdMicros":787273},"inputTokens":21,"model":"claude-opus-5-5","outputTokens":14520,"runtime":"claude","turns":11,"wallClockMs":153872}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"c4617da5f1fd5ce8","findings":[],"hash":"8e416852c59b5fe53e4e667b7d747aae68bbd077d898d409295740a871650c47","nodeId":"83b71514-f5b3-4c1d-9540-490322be8e9d","outcome":"completed","summary":"All prior findings are settled as fixed, and I found no new reproducible defect. The findings file is written with an empty findings list and nine coverage rows.\n\n**What I verified on the revised tree**\n\n- **Medium, PoolManager two-way exemption (e644f2a3):** fixed. `_isLaunchFlow` at src/NvidiaToken.sol:144 now exempts only transfers into the PoolManager. Both attached bypass proofs pass on this tree, the escrow-route test and the invariant model agree, and a scratch v4-style manager ends with zero balance and zero delta after a taxed take, so flash accounting stays consistent. The launch floor's flows (seed from the factory, sells into the manager, sell-back of the trader's whole balance) are unaffected by tracing. The floor file itself cannot compile here because v4-core is not vendored.\n- **Low, lookup not failure-tolerant (4b5ec26b):** fixed. The call is capped at 50,000 gas, decodes as uint256 and rejects words above uint160. The attached proof passes. For the slither return-bomb lead I measured the largest answer a 50k-gas callee can produce: the transfer still succeeds and costs under 200k gas, so the lead is bounded, not a defect.\n- **Low, splitTransfer overflow (891acc0d):** fixed by dividing by the reduced denominators. Max-amount test and full-range fuzz pass.\n- **Info, deploy script truncation (9568c57a):** fixed. A scratch run with 2^64+5 reverts with LaunchNumberTooLarge.\n- **Info, documentation items (db100ab3, 1bba8dd9):** README assumptions 2 and 3 are rewritten and marked for requester confirmation. The v3 note is corrected.\n- **Info, tribute recipient control (1d2fed14, disputed):** not a code defect, and I did not restate it. The README now records the mainnet observation and asks for proof of control. This remains an open operational item for admission, not a finding.\n\n**Suite status:** 96 tests across six suites pass with the verifier's fuzz seed, including the invariant suite. Aderyn's two lines (large literal, unused public `isExempt`) are style noise, not defects.\n\n**Open for the requester before admission:** written confirmation of the two brief readings (tax on every non-launch transfer with pool buys taxed and sells exact, and a 1%-of-amount burn), and proof of control of the tribute address.","treeHash":null,"usage":{"cachedInputTokens":441355,"cost":{"source":"runtime","usdMicros":1987080},"inputTokens":194,"model":"claude-fable-5-1","outputTokens":10038,"runtime":"claude","turns":7,"wallClockMs":242884}},{"artifacts":[],"attempt":1,"bundleHash":"8cda8b685bcfcaa106fb27ac2978b7d756c9a769cb7f37a5982ab7cf4c758de6","device":"4576f670afa0131d","findings":[],"hash":"a45b9e97ef67f49efb5cf3fc90ec7958502719a43aa2923b559776868116699f","nodeId":"7b097c4c-70a9-4b6a-87c9-0f35011150e9","outcome":"completed","summary":"I've updated my tests for the revised token. All 98 tests now pass with the verifier's fuzz seed and with a second seed, and they also pass on a fresh copy of the tree with `test/scratch` left out. I found no new defects, so I didn't write `.imd-findings.json`.\n\n**Why my tests were failing:** after my last round, the token was changed so that only transfers *into* the Uniswap v4 PoolManager are free. Transfers *out* of it (buys, liquidity withdrawals, `take`) now pay the 1.5% fee. My earlier tests still treated the pool as free both ways, so three of them failed on the new code: the stateful invariant suite, its scripted sequence, and one fuzz test.\n\n**What I changed:**\n- **The stateful model** (`test/handlers/NvidiaTokenStateHandler.sol`): it now uses the new rule. Transfers to the pool are untaxed, transfers out of it are taxed, and the pool no longer counts as exempt. It also tracks the extra factory lookup that a transfer out of the pool now makes, and counts taxed payouts from the pool so the run can't pass without any happening.\n- **`test/NvidiaToken.stateful.t.sol`**: the scripted sequence now does a sell into the pool (arrives whole), then pays out the pool's whole balance (taxed). It checks the pool ends at zero, so the pool loses exactly the amount sent.\n- **`test/NvidiaToken.discovery.t.sol`**: the allowance fuzz test only treats the pool as exempt when it is receiving.\n- **New `test/NvidiaToken.pool.t.sol` (15 tests):**\n  - Fee amounts are checked against an independent calculation of 0.5% and 1% of the full amount, not against the token's own function.\n  - Payouts from the pool are taxed, both directly and via `transferFrom` (which spends the full allowance).\n  - A sell followed by a buy-back loses exactly the fee.\n  - Pool to factory is exact; pool to distributor is taxed until the factory names the distributor, then exact.\n  - Overspending and too-small allowances revert with nothing changed, and the right events are emitted.\n- **The two defects I reported last round are fixed** and now have regression tests:\n  - A malformed factory answer is ignored rather than breaking transfers, and a later valid answer is still accepted.\n  - `splitTransfer` gives the right split for every possible amount, including the maximum.\n- **A griefing check:** someone submits a distributor's first payout with a deliberately low gas limit, hoping the distributor lookup fails and the payout gets taxed. A fuzz test checks the payout either arrives in full or reverts. A full sweep of gas limits from 5,000 to 120,000 (in steps of 7) gave 8,605 full payouts, 7,824 reverts and none that arrived short.\n- **`test/TESTING.md`**: rewritten to describe the new pool rule and to say both earlier findings are fixed.\n\nThe new rule also means buyers in the launch pool receive 98.5% of the quoted amount. The token's README already says this, and the supplied protected launch test (which buys and then sells back what was bought) still allows it.\n\nThere are some untracked files at the repo root that were there before I started (`.bashrc`, `.gitconfig`, `.idea`, `.claude/` and similar). I didn't touch them.","treeHash":"6a4d3f99f5c3e0b2f514c9b621b22ab5f26c55ca","usage":{"cachedInputTokens":1269465,"cost":{"source":"runtime","usdMicros":1303968},"inputTokens":36,"model":"claude-opus-5-5","outputTokens":19657,"runtime":"claude","turns":22,"wallClockMs":328727}},{"artifacts":[],"attempt":1,"bundleHash":"5409513bcd724f5e72593c3967e3186fa7af60e461dd3ddd6d2681c895af4011","device":"d4b53d656a3fbe07","findings":[],"hash":"b57112109911acbbef9caf5f3d962ed48a5187bad31dec5c2913c3a4f28358e7","nodeId":"15ffb0c2-80f7-40c9-bf3d-7b9dbaf17043","outcome":"completed","summary":"Done. `launch.json` is written and is the only changed file.\n\n**What the manifest says**\n- Kind `custom_token`, token contract `NvidiaToken`, name Nvidia, symbol ADVN, 18 decimals.\n- Constructor args `$factory`, `$poolManager`, `$launchNumber`, matching the accepted constructor `(address, address, uint64)` in declaration order.\n- totalSupply is the constructor's single mint to msg.sender, 1,000,000,000 tokens in minor units.\n- contracts is empty: the accepted tree deploys only the token, with no application contracts.\n- pool and economics are copied exactly from the launch reference: native ETH, fee 12500, tick spacing 60, the one-to-one provenance price, and the requester's economics object verbatim.\n- notes describe the 0.5% tribute to Jensen Huang's wallet, the 1% burn, the untaxed launch flows via factory, PoolManager and the distributor lookup, and the absence of any admin path. They run to about 1,500 characters.\n\n**Verification**\n- A local schema check passed: only the allowed top-level keys, strings for uint256 and address values, numbers for fee, tickSpacing and decimals, lowercase addresses, economics equal to the job's copy.\n- `forge build` compiled cleanly.\n- `forge test` with the verifier's fuzz seed passed all 38 tests across both suites.\n- `git status` shows only the new `launch.json`; nothing else was touched.","treeHash":"f7108e0b92948dfc4c633b89121c261a7c10b602","usage":{"cachedInputTokens":144372,"cost":{"source":"runtime","usdMicros":815569},"inputTokens":130,"model":"claude-fable-5-1","outputTokens":3249,"runtime":"claude","turns":8,"wallClockMs":48613}},{"artifacts":[],"attempt":1,"bundleHash":"5c169823aff9eb9f8f94c5dd8d282714c455f867f392f555cd9cb08a9d09c465","device":"d0653dc91b6e2259","findings":[],"hash":"c15685aee8f9cb978cf8460cd242cbe9bf13b19e518ca8b9486bd124187fce3a","nodeId":"f81e67d6-97b5-488c-addb-7e9d7449f97d","outcome":"completed","summary":"The deliverable is complete and verified. Nothing further depends on another result, so there is nothing more to request.\n\n**Outcome.** The Nvidia (ADVN) custom token is implemented in `src/NvidiaToken.sol` as `contract NvidiaToken`, with a Foundry project at the repository root. `forge build`, `forge test` (38 tests, including fuzz and invariant suites run with the verifier's seed) and `forge fmt --check` all pass with solc 0.8.26 pinned and `bytecode_hash = \"none\"`.\n\n**What the token does**\n- Mints 1,000,000,000 ADVN (18 decimals) once to `msg.sender` in the constructor. No mint, owner, pause, blacklist, fee setter or upgrade path exists.\n- Every ordinary transfer sends 0.5% to Jensen Huang's wallet (a constant) and burns 1%, so the receiver gets 98.5%. Cuts round down; the sender pays the full amount and `transferFrom` spends the full allowance.\n- Transfers from or to the factory, the PoolManager, and the launch's MerkleDistributor (looked up via `distributorOf(launchNumber)` on the factory, then cached) move exactly, so the swarm share, pool seed, claims and v4 swaps all settle whole. The lookup tolerates a factory with no code, a revert or a malformed answer.\n- Constructor arguments are the three static launch values: `$factory`, `$poolManager`, `$launchNumber`. The constructor makes no external call.\n\n**Files**\n- `foundry.toml`, `remappings.txt`, `.gitignore`\n- `src/NvidiaToken.sol`\n- `script/DeployNvidiaToken.s.sol` (local-only helper; its `deploy(Config)` is tested directly)\n- `test/NvidiaToken.t.sol`, `test/NvidiaToken.invariant.t.sol`, `test/mocks/MockLaunchFactory.sol`\n- `README.md` with assumptions, deployment parameters, \"After launch\" (nothing to set), operational responsibilities, and security notes\n- `lib/forge-std` (v1.9.7) and `lib/openzeppelin-contracts` (v5.7.0) vendored as plain files with no nested `.git`\n\n**Assumptions flagged for the requester** (all documented in the README)\n- \"Trade\" is read as any transfer, since an ERC-20 cannot distinguish trades. Swaps through the Uniswap v4 PoolManager are untaxed in both directions because the launch floor requires exact settlement there; trades on other venues are taxed.\n- \"1% burn of supply from every fee\" is read as 1% of the transferred amount burned per taxed transfer, for a 1.5% total tax. If the requester meant 1% of the 0.5% tribute, `BURN_BPS` is the single constant to change.\n- The tribute recipient address is fixed as a constant exactly as given, with no setter.\n\n**Not run.** Slither is not available on this machine. I did not vendor v4-core to run a scratch swap against a real PoolManager; the PoolManager exemption makes those flows plain OpenZeppelin transfers, which the unit and fuzz tests cover.","treeHash":"4a43a0aa9e2ff91b647021e82391fb6e5adf9244","usage":{"cachedInputTokens":1346004,"cost":{"source":"runtime","usdMicros":3936939},"inputTokens":738,"model":"claude-fable-5-1","outputTokens":42643,"runtime":"claude","turns":24,"wallClockMs":652210}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"87804e27e9c9f85a","findings":[{"citation":"resolved","description":"Outside the math area (flow/economics), reported because it removes the token's only feature. _isLaunchFlow exempts a transfer when EITHER side is the PoolManager, by address alone. The v4 PoolManager is a permissionless singleton: anyone can unlock it, credit themselves with tokens sent in (sync + transfer + settle) and pay the same amount out to any address (take), with no pool, no swap and no pool fee involved. Both legs (holder -> PoolManager, PoolManager -> recipient) hit this line and skip splitTransfer, so a wallet-to-wallet payment moves 100% with tribute = 0 and burned = 0. The same exemption makes the PoolManager's ERC-6909 claim on the token (mint after settle, burn before take) a freely transferable, untaxed wrapper of ADVN. The README states that wallet-to-wallet transfers and transfers to other venues are taxed and only swaps in the launch pool are exact; with one helper contract deployed by anyone, every holder can skip the tax on every transfer, for about the gas of an ordinary taxed transfer (measured 102,599 gas for the relay against the real mainnet PoolManager runtime bytecode, versus 60,309-97,765 gas for a direct taxed transfer). Loser: the tribute recipient 0xc59b0c072f73ceEA3Dc354031165501c0Ff25023 (0.5% of the amount) and the burn (1%). No holder loses funds, hence medium. This cannot be closed inside the token while the launch floor requires transfers into and out of the PoolManager to be exact: it is a scope decision for the requester (tax in a v4 hook, or accept and state plainly in the README/notes that the tax is avoidable for any transfer, not only for pool swaps).","line":133,"path":"src/NvidiaToken.sol","reproduction":"State: token deployed with poolManager = the chain's v4 PoolManager (mainnet 0x000000000004444c5dc75cB358380D2e3dE08A90); Alice holds 1,000e18 ADVN; totalSupply S; tribute recipient balance J. Helper contract R (deployable by anyone): send(to, amount) calls poolManager.unlock(abi.encode(msg.sender, to, amount)); its unlockCallback does: poolManager.sync(token); token.transferFrom(from, poolManager, amount); poolManager.settle(); poolManager.take(token, to, amount). Calls: Alice: token.approve(R, 1000e18); Alice: R.send(Bob, 1000e18). Expected (README: wallet-to-wallet transfers are taxed): Bob +985e18, tribute recipient +5e18, totalSupply S - 10e18. Actual (run locally with the mainnet PoolManager runtime code etched at its own address): Bob balance = 1000e18, tribute recipient balance = J (delta 0), totalSupply = S (burned 0), no TransferTaxed event; relay gas 102,599. Compare the direct call Alice: token.transfer(Bob, 1000e18): Bob 985e18, tribute 5e18, burned 10e18.","severity":"medium","snippet":"        if (from == factory || to == factory || from == poolManager || to == poolManager) return true;","title":"The tax is optional: any transfer routed through the PoolManager (sync/settle/take, or ERC-6909 claims) pays no tribute and no burn"},{"citation":"resolved","description":"Boundary: the only external call in the token, the staticcall to factory.distributorOf(launchNumber), made on every non-launch transfer (and by isExempt) until a non-zero distributor is cached. Assumption (NatSpec lines 145-146, README 'treats any failure (no code, a revert, a malformed answer) as not known yet, so ordinary transfers never depend on the factory being reachable'). Actual: three answers are not tolerated. (a) Exactly 32 bytes whose top 96 bits are not zero pass the length check at line 149 and then abi.decode(data,(address)) at line 150 reverts (ABI coder v2 validates address words), so transfer, transferFrom and isExempt all revert. (b) The staticcall forwards all remaining gas (63/64). A factory that burns it (INVALID, an infinite loop) leaves 1/64 for the three balance writes: the same 1e18 transfer fails with 300,000, 1,000,000, 3,000,000 and 4,000,000 gas and only succeeds at 6,000,000 gas, consuming 5,995,399. (c) Return data is copied in full into memory before its length is checked; a 600,000-byte answer makes the transfer fail at 300,000, 500,000 and 1,000,000 gas and cost 1,637,938 gas when given 3,000,000. Reachability, stated honestly: the factory the launch floor models returns a clean address from a mapping getter, so none of these occur with it, and once a distributor is cached the factory is never called again. The exposure is a factory that misbehaves (or is replaced behind a proxy) while distributorOf(launchNumber) is still zero, and any deployment where it stays zero. The existing MalformedFactory test only covers a 16-byte answer. Minimal fix preserving behaviour: cap the call (for example factory.staticcall{gas: 50_000}(...)), keep the length check, decode as uint256 and return address(0) when the word exceeds type(uint160).max, otherwise address(uint160(word)).","line":148,"path":"src/NvidiaToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {NvidiaToken} from \"src/NvidiaToken.sol\";\n\n/// @notice A factory whose `distributorOf` answers with exactly 32 bytes that are not an address:\n/// the right length, the wrong shape (high 96 bits set).\ncontract NonAddressWordFactory {\n    fallback() external {\n        assembly (\"memory-safe\") {\n            mstore(0, not(0))\n            return(0, 32)\n        }\n    }\n}\n\n/// @notice The token says a malformed answer from the factory reads as \"distributor not known yet\",\n/// so ordinary transfers never depend on the factory. A 32-byte answer that is not an address must\n/// therefore leave ordinary transfers working and taxed, and `isExempt` answering false.\ncontract FactoryLookupProofTest is Test {\n    address constant POOL_MANAGER = address(0x4444);\n    address constant ALICE = address(0xA11CE);\n    address constant BOB = address(0xB0B);\n\n    NvidiaToken token;\n\n    function setUp() public {\n        address factory = address(new NonAddressWordFactory());\n        vm.prank(factory);\n        token = new NvidiaToken(factory, POOL_MANAGER, 7);\n        // from == factory: a launch flow, moves exactly and never asks the factory anything.\n        vm.prank(factory);\n        token.transfer(ALICE, 1_000e18);\n        assertEq(token.balanceOf(ALICE), 1_000e18);\n    }\n\n    function test_nonAddressWordFromFactoryReadsAsNotKnownYet_transfer() public {\n        vm.prank(ALICE);\n        token.transfer(BOB, 100e18);\n        assertEq(token.balanceOf(BOB), 98.5e18, \"the ordinary transfer did not deliver 98.5%\");\n        assertEq(token.balanceOf(token.TRIBUTE_RECIPIENT()), 0.5e18, \"the tribute was not paid\");\n        assertEq(token.totalSupply(), token.INITIAL_SUPPLY() - 1e18, \"the burn did not happen\");\n        assertEq(token.distributor(), address(0), \"a non-address word was cached as the distributor\");\n    }\n\n    function test_nonAddressWordFromFactoryReadsAsNotKnownYet_isExempt() public view {\n        assertFalse(token.isExempt(BOB));\n    }\n}","reproduction":"Deploy NvidiaToken(factory_ = F, poolManager_ = 0x4444, launchNumber_ = 7) with msg.sender = F, then F transfers 1,000e18 to Alice (launch flow, no lookup). (a) F = a contract whose fallback returns the 32-byte word 0xffff...ff: Alice calls transfer(Bob, 100e18). Expected: treated as 'not known yet', Bob receives 98.5e18, tribute 0.5e18, burned 1e18. Actual: the call reverts with empty revert data; isExempt(Bob) reverts as well instead of returning false. The attached proof shows both. (b) F = a contract whose fallback executes INVALID: Alice's transfer(Bob, 1e18) with a 300,000 / 1,000,000 / 3,000,000 / 4,000,000 gas limit reverts; with 6,000,000 it succeeds using 5,995,399 gas. Expected: about 98,000 gas. (c) F = a contract whose fallback returns 600,000 zero bytes: the transfer reverts with 300,000 / 500,000 / 1,000,000 gas and uses 1,637,938 gas at a 3,000,000 limit.","severity":"low","snippet":"        (bool ok, bytes memory data) = factory.staticcall(abi.encodeCall(ILaunchFactory.distributorOf, (launchNumber)));\n        if (!ok || data.length != 32) return address(0);\n        return abi.decode(data, (address));","title":"Distributor lookup is not failure-tolerant as documented: a 32-byte non-address answer, a gas-exhausting answer or a large answer from the factory reverts every ordinary transfer"},{"citation":"resolved","description":"Math precision, overflow of the intermediate product. splitTransfer is public pure and the README says it 'returns the three parts for any amount'. amount * BURN_BPS overflows uint256 once amount > type(uint256).max / 100 (about 1.157e75) and the call reverts with Panic(0x11) before the division. No transfer can reach this: _update checks balanceOf(from) >= value before calling splitTransfer and balances are bounded by the 1e27 supply, where amount * 100 <= 1e29. The effect is limited to an off-chain or on-chain integrator probing the quote with a sentinel such as type(uint256).max. Fix if wanted: Math.mulDiv(amount, BPS, 10_000) from the vendored OpenZeppelin, or narrow the README sentence to amounts up to the supply.","line":94,"path":"src/NvidiaToken.sol","reproduction":"Call token.splitTransfer(type(uint256).max). Expected per README: (net, tribute, burned) = (98.5%, 0.5%, 1%) of the amount. Actual: revert Panic(0x11). Boundary: splitTransfer(type(uint256).max / 100) returns; splitTransfer(type(uint256).max / 100 + 1) reverts.","severity":"info","snippet":"        tribute = (amount * TRIBUTE_BPS) / BPS_DENOMINATOR;\n        burned = (amount * BURN_BPS) / BPS_DENOMINATOR;","title":"splitTransfer panics for amounts above type(uint256).max / 100 although it is documented to answer for any amount"},{"citation":"resolved","description":"Math precision, unchecked narrowing cast. vm.envUint returns a uint256 and the explicit uint64(...) cast drops the high bits silently, so a launch number of 2^64 or more deploys a token bound to a different launch number, and _lookupDistributor then asks the factory for that other launch's distributor and exempts it. The script is documented as local-only and the production launch passes $launchNumber through the ABI decoder, which rejects an out-of-range word, so this is informational. Fix: require(value <= type(uint64).max) before the cast, or SafeCast.toUint64.","line":30,"path":"script/DeployNvidiaToken.s.sol","reproduction":"Set ADVN_FACTORY and ADVN_POOL_MANAGER to any non-zero addresses and ADVN_LAUNCH_NUMBER=18446744073709551621 (2^64 + 5), run DeployNvidiaToken.run(). Expected: revert, since the value does not fit a uint64. Actual: the token deploys and token.launchNumber() == 5.","severity":"info","snippet":"            launchNumber: uint64(vm.envUint(\"ADVN_LAUNCH_NUMBER\"))","title":"Local deploy script truncates ADVN_LAUNCH_NUMBER to 64 bits without a bounds check"}],"hash":"c6d7daa68dcaba0214310833365c11b0888e439cbb98255467fca63db7330771","nodeId":"823f15ea-6c09-43b3-8702-b31ce5899c7c","outcome":"completed","summary":"The review is written to `.imd-findings.json`: four findings and fourteen coverage rows, with no tracked file changed. The split arithmetic itself holds; the one finding that matters is outside the math area.\n\n## Findings\n\n1. **Medium — the tax can be skipped on any transfer** (`src/NvidiaToken.sol:133`). The exemption applies when either side is the PoolManager, and anyone can pay tokens into the PoolManager and take them out to another address without swapping. Against the real mainnet PoolManager bytecode, 1,000 ADVN moved from Alice to Bob with tribute 0 and burn 0, for about the gas of a normal transfer. This is outside my area, and it cannot be closed in the token while the launch floor requires exact PoolManager flows, so it is a decision for the requester.\n\n2. **Low — the factory lookup is not as failure-tolerant as documented** (`src/NvidiaToken.sol:148`). Three factory answers break ordinary transfers until a distributor is cached:\n   - a 32-byte answer that is not an address reverts `transfer`, `transferFrom` and `isExempt`;\n   - a factory that burns its gas makes a transfer fail at up to 4,000,000 gas;\n   - a 600,000-byte answer makes a transfer fail at up to 1,000,000 gas.\n\n   None of these happens with a factory that returns a clean address, as the floor's stand-in does. The finding carries a proof test that fails on the current code and passes on a patched copy (gas-capped call, decode as `uint256`, reject words above 160 bits).\n\n3. **Info — `splitTransfer` panics above `type(uint256).max / 100`** (`src/NvidiaToken.sol:94`). The README says it answers for any amount; no transfer can reach this, because the balance check comes first.\n\n4. **Info — the local deploy script truncates the launch number** (`script/DeployNvidiaToken.s.sol:30`). `ADVN_LAUNCH_NUMBER = 2^64 + 5` deploys with launch number 5. The script is local-only.\n\n## Coverage\n\n- **Entry points:** `approve` holds. `transfer` and `transferFrom` are marked as findings (reference 1, with finding 2 noted in the reason), though their arithmetic is exact.\n- **Math Precision:** net + tribute + burned equals the value on every taxed transfer, and nothing overflows below the supply. Amounts of 99 wei or less pay nothing and 100–199 wei pay 1 wei of burn only; this is documented and worth under 2 wei per transfer, so I recorded it as a coverage row rather than a finding.\n- **Boundary:** the only external call is the factory lookup (finding 2). Zero-value, self and tribute-recipient transfers conserve balances.\n- **Numerical Gap:** supply only ever falls by the burned amount, and the views match what the write path does.\n- **Not run:** the protected floor suite, because its v4-core harness is not vendored here. I traced the launch flows against it by reading only.\n\nThe repository's own 38 tests pass. My scratch tests under `test/scratch/` are deleted.","treeHash":null,"usage":{"cachedInputTokens":874438,"chain":[{"calls":2,"chainId":1,"failed":0,"own":2,"public":0,"refused":0}],"cost":{"source":"runtime","usdMicros":3093347},"inputTokens":26,"model":"claude-fable-5-2","outputTokens":35818,"runtime":"claude","turns":14,"wallClockMs":392958}},{"artifacts":[],"attempt":1,"bundleHash":"bb31f83cc3e4e8533e29e2568b114269a0487aa4c70cbfa846e6b2752a420004","device":"a7313281793d3077","findings":[{"description":"The factory lookup checks only call success and returndata length before abi.decode(data, (address)). A 32-byte word with any nonzero upper 96 bits passes those checks but makes the ABI decoder revert. Before a distributor has been cached, this blocks otherwise valid ordinary transfers, transferFrom calls and isExempt queries, contrary to the documented fallback for malformed or failed factory answers. This is a dependency-hardening issue: it requires a faulty/noncanonical response from the trusted factory, not an arbitrary token holder. A canonical production factory is unaffected; a cached distributor avoids the lookup. Validate the address encoding and treat invalid padding as an unknown distributor.","line":150,"path":"src/NvidiaToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {NvidiaToken} from \"src/NvidiaToken.sol\";\n\ncontract NonCanonicalDistributorFactory {\n    function deploy(address pool) external returns (NvidiaToken token) {\n        token = new NvidiaToken(address(this), pool, 1);\n        token.transfer(msg.sender, token.totalSupply());\n    }\n\n    fallback() external {\n        // Exactly 32 bytes, but bit 160 is not valid ABI padding for an address.\n        assembly (\"memory-safe\") {\n            mstore(0, shl(160, 1))\n            return(0, 32)\n        }\n    }\n}\n\ncontract NonCanonicalDistributorProofTest is Test {\n    function test_malformedAddressResponseMustNotBlockHolderTransfer() public {\n        NonCanonicalDistributorFactory factory = new NonCanonicalDistributorFactory();\n        NvidiaToken token = factory.deploy(makeAddr(\"pool\"));\n        address recipient = makeAddr(\"recipient\");\n        // Lookup failures are documented as \"not known yet\"; ordinary holders must still transfer.\n        (bool ok,) = address(token).call(abi.encodeCall(token.transfer, (recipient, 1_000)));\n        assertTrue(ok, \"32-byte malformed distributor response blocks a funded holder\");\n        assertEq(token.balanceOf(recipient), 985);\n        assertEq(token.balanceOf(0xc59b0c072f73ceEA3Dc354031165501c0Ff25023), 5);\n        assertEq(token.totalSupply(), 1_000_000_000e18 - 10);\n        assertEq(token.distributor(), address(0));\n    }\n}","reproduction":"Deploy NonCanonicalDistributorFactory from the attached proof. Its deploy(pool) creates NvidiaToken and forwards the constructor supply to the test holder; its lookup fallback returns exactly abi.encode(uint256(1) << 160). From that funded nonexempt holder call transfer(recipient, 1000). Expected: success, recipient +985, Jensen +5, totalSupply -10 and distributor still zero. Actual: the low-level transfer returns false because abi.decode reverts. Ran forge test --match-path test/scratch/NonCanonicalDistributor.proof.t.sol (also in the combined proof run); the test fails with \"32-byte malformed distributor response blocks a funded holder\".","severity":"low","title":"Noncanonical 32-byte distributor answers revert instead of falling back to unknown"},{"description":"The public splitTransfer helper accepts uint256 and is documented in README.md as returning the parts for any amount, but multiplication by 50 and 100 overflows before division. Inputs above type(uint256).max / 100 cannot be quoted even though amount / 200, amount / 100 and their net remainder all fit in uint256. This affects the view helper only: actual holder balances are bounded by the 1e27 initial supply, and oversized transfers correctly fail their balance check first. Division by the reduced constant denominators, or overflow-safe mulDiv, would implement the full-domain quote without changing rounding.","line":94,"path":"src/NvidiaToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {NvidiaToken} from \"src/NvidiaToken.sol\";\n\ncontract SplitOverflowProofTest is Test {\n    function test_previewAcceptsMaximumUint256WithoutIntermediateOverflow() public {\n        NvidiaToken token = new NvidiaToken(address(this), makeAddr(\"pool\"), 1);\n        uint256 amount = type(uint256).max;\n        // All three mathematically correct outputs fit, although amount * 50 does not.\n        (uint256 net, uint256 tribute, uint256 burned) = token.splitTransfer(amount);\n        assertEq(tribute, amount / 200);\n        assertEq(burned, amount / 100);\n        assertEq(net, amount - amount / 200 - amount / 100);\n        assertEq(net + tribute + burned, amount);\n    }\n}","reproduction":"Deploy NvidiaToken with nonzero factory and pool addresses and call splitTransfer(type(uint256).max). Expected: tribute = amount / 200, burned = amount / 100, net = amount - tribute - burned, with net + tribute + burned == amount. Actual: panic 0x11 at the multiplication. Ran forge test --match-path test/scratch/SplitOverflow.proof.t.sol (also in the combined proof run); the attached test fails with arithmetic underflow or overflow.","severity":"low","title":"splitTransfer overflows on large uint256 preview inputs although the split fits"}],"hash":"d3eae206a3d40cf86eb9d57cdab1c23b6c51409881a210591d25cdcb36154c51","nodeId":"7b097c4c-70a9-4b6a-87c9-0f35011150e9","outcome":"completed","summary":"Added failure-path, fuzz, and stateful invariant tests.\n\n`forge build` and `forge test` pass with the required seed: **78 passed, 0 failed**. The new invariant campaign exercised 16,384 calls.\n\nReported two low-severity defects with failing proofs in `.imd-findings.json`: malformed distributor responses blocking transfers, and overflow on large `splitTransfer` inputs.","treeHash":"1e8f4fd1d254a4bf24a2f0d3102a4b40c5fec27b","usage":{"cachedInputTokens":1771392,"cost":{"source":"estimated","usdMicros":3864062},"inputTokens":83022,"model":"gpt-6-astra","outputTokens":25249,"runtime":"codex","turns":7,"wallClockMs":714946}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"cc86b49d3c401897","findings":[{"citation":"resolved","description":"_isLaunchFlow exempts every transfer where either side is the Uniswap v4 PoolManager. The PoolManager is a general escrow anyone can use through unlock(): sync(ADVN), transfer ADVN into it, settle() for a credit, then take(ADVN, anyRecipient, amount). Both legs touch the PoolManager, so both are untaxed. This costs no swap fee and needs no pool or liquidity. Any holder or router can therefore move ADVN to any address with no tribute and no burn. The README and NatSpec say wallet-to-wallet transfers, exchange deposits and other venues are taxed, and the brief asks for 0.5% to 0xc59b...5023 plus a 1% burn on every trade. Both become optional: one helper contract (or any v4 router's settle/take actions) gets around them. The same clause (`from == poolManager`) also makes every buy from the launch pool untaxed. The README says buys must be exempt, but neither v4 settlement nor the launch floor needs that. PoolManager.take() never checks its own balance afterwards, and the floor's swap test only checks that something was bought and that the full balance can be sold back. Only tokens going into the PoolManager (sells, seeds, settles) must move exactly. The factory exemption already covers the seed (factory -> PoolManager). Impact: lost tribute to the named beneficiary and a burn that does not happen, under one condition: the sender routes through the PoolManager. Holders' funds are not at risk. Minimal fix: drop `from == poolManager` and keep `to == poolManager`. This keeps sells and the seed exact and taxes payouts from the PoolManager (buys, takes, LP withdrawals). This changes the README's assumption 2, so the requester has to decide whether pool buys should be taxed. The existing tests that encode the current exemption (test_poolManagerBothWaysIsUntaxed, testFuzz_launchFlowsAreExact for the PoolManager-outbound case, and the invariant handler's model) need updating to match.","line":133,"path":"src/NvidiaToken.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {NvidiaToken} from \"src/NvidiaToken.sol\";\n\ninterface IERC20Min {\n    function balanceOf(address) external view returns (uint256);\n    function transfer(address, uint256) external returns (bool);\n}\n\ninterface IUnlockCallbackMin {\n    function unlockCallback(bytes calldata) external returns (bytes memory);\n}\n\n/// @dev The part of Uniswap v4's PoolManager flash accounting the route uses, with v4's semantics:\n/// sync() snapshots the reserve, settle() credits the caller with balance - snapshot, take() pays out\n/// and debits the caller, and unlock() requires every delta to net to zero.\ncontract MiniPoolManager {\n    address syncedCurrency;\n    uint256 syncedReserve;\n    mapping(address => mapping(address => int256)) public delta;\n    address locker;\n\n    function unlock(bytes calldata data) external returns (bytes memory r) {\n        locker = msg.sender;\n        r = IUnlockCallbackMin(msg.sender).unlockCallback(data);\n        locker = address(0);\n    }\n\n    function sync(address currency) external {\n        syncedCurrency = currency;\n        syncedReserve = IERC20Min(currency).balanceOf(address(this));\n    }\n\n    function settle() external returns (uint256 paid) {\n        paid = IERC20Min(syncedCurrency).balanceOf(address(this)) - syncedReserve;\n        delta[msg.sender][syncedCurrency] += int256(paid);\n        syncedCurrency = address(0);\n    }\n\n    function take(address currency, address to, uint256 amount) external {\n        delta[msg.sender][currency] -= int256(amount);\n        require(IERC20Min(currency).transfer(to, amount), \"transfer failed\");\n    }\n}\n\n/// @dev Any holder's helper: moves tokens to a recipient through the PoolManager's escrow.\ncontract EscrowRoute is IUnlockCallbackMin {\n    MiniPoolManager immutable pm;\n    NvidiaToken immutable token;\n\n    constructor(MiniPoolManager pm_, NvidiaToken token_) {\n        pm = pm_;\n        token = token_;\n    }\n\n    function send(address to, uint256 amount) external {\n        pm.unlock(abi.encode(to, amount));\n    }\n\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        (address to, uint256 amount) = abi.decode(data, (address, uint256));\n        pm.sync(address(token));\n        token.transfer(address(pm), amount); // to == poolManager: untaxed\n        pm.settle();\n        pm.take(address(token), to, amount); // from == poolManager: untaxed\n        require(pm.delta(address(this), address(token)) == 0, \"unsettled\");\n        return \"\";\n    }\n}\n\ncontract PmBypassTest is Test {\n    NvidiaToken token;\n    MiniPoolManager pm;\n    address constant BOB = address(0xB0B);\n\n    function setUp() public {\n        pm = new MiniPoolManager();\n        token = new NvidiaToken(address(this), address(pm), 1);\n    }\n\n    /// A wallet-to-wallet transfer of 1,000,000 ADVN routed through the PoolManager must still pay\n    /// the 0.5% tribute and the 1% burn; today Bob receives the full amount and Jensen receives 0.\n    function test_walletToWalletViaPoolManagerStillPaysTax() public {\n        uint256 amount = 1_000_000e18;\n        EscrowRoute route = new EscrowRoute(pm, token);\n        token.transfer(address(route), amount); // from the factory: untaxed seed of the holder\n\n        uint256 supplyBefore = token.totalSupply();\n        route.send(BOB, amount);\n\n        (uint256 net, uint256 tribute, uint256 burned) = token.splitTransfer(amount);\n        assertEq(token.balanceOf(token.TRIBUTE_RECIPIENT()), tribute, \"tribute skipped\");\n        assertEq(supplyBefore - token.totalSupply(), burned, \"burn skipped\");\n        assertEq(token.balanceOf(BOB), net, \"receiver got the untaxed amount\");\n    }\n}","reproduction":"State: the token is deployed with factory_=F and poolManager_=PM (v4 flash accounting). F sends Alice's helper contract H 1,000,000e18 ADVN (untaxed, from F). Call H.send(Bob, 1_000_000e18). Inside PM.unlock -> H.unlockCallback: PM.sync(ADVN); ADVN.transfer(PM, 1e24) (to==PM, untaxed); PM.settle() credits +1e24; PM.take(ADVN, Bob, 1e24) (from==PM, untaxed); the delta nets to 0. Expected (taxed transfer): Bob 985,000e18, TRIBUTE_RECIPIENT +5,000e18, totalSupply -10,000e18. Actual: Bob 1,000,000e18, TRIBUTE_RECIPIENT 0, totalSupply unchanged. The attached test fails with 'tribute skipped: 0 != 5000000000000000000000' and passes once `from == poolManager` is removed from line 133 (checked in a copy of the tree).","severity":"medium","snippet":"        if (from == factory || to == factory || from == poolManager || to == poolManager) return true;","title":"Exempting transfers *from* the PoolManager lets any holder skip the 0.5% tribute and 1% burn on wallet-to-wallet transfers, and leaves every pool buy untaxed"}],"hash":"dd596b07fe573ac5dde504503d1262dfac23ad31e815b35c2d9c32b68917981c","nodeId":"2f060a1e-95ff-418a-9999-734a99e39aec","outcome":"completed","summary":"I found one defect, rated medium: any holder can skip the 0.5% tribute and the 1% burn by routing a transfer through the PoolManager. I wrote it to `.imd-findings.json` with a coverage row for each of the three entry points. The project's own suite passes (38 tests), and no tracked files were changed.\n\n**Finding 1 (medium): transfers out of the PoolManager are untaxed** (`src/NvidiaToken.sol:133`)\n\n```solidity\nif (from == factory || to == factory || from == poolManager || to == poolManager) return true;\n```\n\n- **Bypass:** any holder can send ADVN to any address tax-free by passing it through the PoolManager's escrow in one transaction: deposit the tokens, record the credit, then withdraw them to the recipient. Both legs touch the PoolManager, so neither is taxed. No pool, liquidity or swap fee is needed.\n- **Example:** sending 1,000,000 ADVN this way, Bob receives the full 1,000,000 instead of 985,000. Jensen's wallet gets 0 instead of 5,000, and nothing is burned instead of 10,000.\n- **Buys:** the same clause also makes every buy from the launch pool untaxed. The README says this is needed for exact settlement, but only tokens going *into* the PoolManager (sells and the seed) must arrive exact. The PoolManager never checks its own balance when paying out, and the launch floor only requires that a buy delivers something and that the full balance can be sold back.\n- **Fix:** remove `from == poolManager` and keep `to == poolManager`. The seed is still exempt because it comes from the factory, and sells still settle exactly.\n- **Decision for the requester:** this reverses the README's assumption that pool trades are untaxed, so pool buys would start paying the tax. Three of the project's own tests assume PoolManager payouts are untaxed and would need updating: `test_poolManagerBothWaysIsUntaxed`, the PoolManager-payout case of `testFuzz_launchFlowsAreExact`, and the invariant model.\n- **Proof:** the attached Foundry test fails on the current code with `tribute skipped: 0 != 5000000000000000000000`. It uses a minimal stand-in for the PoolManager, because v4-core isn't in `lib/`. In a copy of the tree outside the repo, it passes with the fix applied.\n\n**Coverage**\n- `transfer` and `transferFrom`: finding 1. The rest of the path holds: the balance check, the three-way split, rounding, the distributor cache and the handling of a factory that can't be reached. `transferFrom` spends the full allowance before the same path runs.\n- `approve`: holds. It is the standard OpenZeppelin version with no tax logic.\n- I also checked and recorded these invariants: supply never grows, the launch transfers (factory, distributor, seed, sells) move exact amounts, and a failed factory lookup never blocks transfers.\n\n**Not reported**\n- Amounts under 200 wei pay no tribute. The README already discloses this and splitting transfers that small costs more in gas than it saves.\n- I could not run the protected floor tests here, because they depend on harness files that aren't in this tree.\n- I deleted the scratch test and the temporary copy afterwards.","treeHash":null,"usage":{"cachedInputTokens":465744,"cost":{"source":"runtime","usdMicros":778374},"inputTokens":21,"model":"claude-opus-5-5","outputTokens":12630,"runtime":"claude","turns":11,"wallClockMs":148570}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"827152cce766ca0d","findings":[{"citation":"resolved","description":"_isLaunchFlow exempts every transfer whose from or to is the PoolManager, whoever starts it and for whatever reason. Uniswap v4's PoolManager lets any caller inside unlock() call sync(currency), send tokens, settle() to get credit for the balance change, and take(currency, to, amount) to pay that credit to any address, with no swap involved. Both legs touch the PoolManager, so both are exempt. Any holder can therefore send any amount to any wallet without paying the 0.5% tribute to TRIBUTE_RECIPIENT or the 1% burn. That breaks the documented guarantee (natspec lines 19-21 and README Assumption 1) that wallet-to-wallet transfers, exchange deposits and other-venue transfers are taxed. Every trade in the launch pool is already untaxed, a disclosed tradeoff, so in practice the fee is optional for anyone who uses a small relay contract. The same exemption also covers any other pool on the same PoolManager, for example an ADVN/USDC v4 pool anyone creates, so trades on it are untaxed too. In a permissions review this is an asymmetry: the exemption is granted by address, not by launch role, so it reaches every user of a shared singleton.","line":133,"path":"src/NvidiaToken.sol","reproduction":"State: the token is deployed with poolManager = the v4 PoolManager, and alice holds 1000e18 ADVN. (1) alice calls transfer(bob, 100e18): bob receives 98.5e18, the tribute recipient +0.5e18, totalSupply -1e18 (taxed, as documented). (2) alice approves a 20-line router for 100e18. Inside PoolManager.unlock the router calls sync(ADVN); ADVN.transferFrom(alice, PoolManager, 100e18) (exempt because to == poolManager); settle() (credit 100e18); take(ADVN, bob, 100e18) (exempt because from == poolManager). Expected under the spec: bob +98.5e18, tribute +0.5e18, burn 1e18. Actual: bob +100e18, tribute +0, totalSupply unchanged. I checked this locally with a scratch Foundry test, using a minimal contract with v4's balance-delta sync/settle/take semantics as the poolManager. v4-core is not vendored in this repo. The test passed: bob ended at 198.5e18, and the tribute balance and totalSupply were unchanged across the relay.","severity":"medium","snippet":"        if (from == factory || to == factory || from == poolManager || to == poolManager) return true;","title":"Blanket PoolManager exemption lets any holder move ADVN wallet-to-wallet with no tribute or burn (sync/transfer/settle/take relay)"}],"hash":"ee2314143010d170c7b4c7a9644c4ecd8b60e51ecb77db8fa20bd6904f16a0d4","nodeId":"a535dc0b-a2e1-4dcd-9bb3-99113b740f25","outcome":"completed","summary":"I found one medium-severity problem with access control and wrote it to `.imd-findings.json`. No source files were changed. I deleted my scratch test afterwards.\n\n**Finding 1 (medium): any holder can skip the tax by routing transfers through the Uniswap v4 PoolManager.** At `src/NvidiaToken.sol:133`, every transfer to or from the PoolManager is fee-free, whoever starts it and for whatever reason. That address is shared, and v4 lets anyone send it tokens and have them paid out to another address without making a trade. Both steps touch the PoolManager, so neither is taxed.\n- **What happens:** alice sends 100e18 to bob through a small relay contract. Bob receives the full 100e18, Jensen's wallet gets nothing and nothing is burned. The tax should have given bob 98.5e18, Jensen 0.5e18 and burned 1e18.\n- **Why it matters:** the code comments and README promise that wallet-to-wallet transfers are taxed. Any other pool on the same PoolManager, such as an ADVN/USDC pool anyone creates, is untaxed too.\n- **How I checked it:** a scratch Foundry test passed, but against a minimal stand-in for the PoolManager, not the real one. The repo doesn't include Uniswap v4, so I couldn't test against it, and there is no proof test in the finding.\n- **Fix:** the launch rules require the PoolManager exemption, so it can't simply be removed. Either the README and launch notes should say the tax is optional for anyone who routes through the PoolManager, or you decide whether to add a v4 hook. The launch doesn't deploy one at the moment.\n\n**Disclosed tradeoff, not reported as a defect:** trades in the launch pool itself are untaxed. Your brief says the fee comes \"from every trade\", but the README states this limit openly.\n\n**Coverage of the three entry points:**\n\n| Entry point | Verdict | Why |\n|---|---|---|\n| `NvidiaToken.transfer(address,uint256)` | finding 1 | Otherwise splits and burns as specified |\n| `NvidiaToken.transferFrom(address,address,uint256)` | finding 1 | Spends the full allowance, then follows the same path as `transfer` |\n| `NvidiaToken.approve(address,uint256)` | holds | Unchanged OpenZeppelin approve |\n\nI also checked that the token has no owner, setter, pause, blacklist, extra minting or `burnFrom`. The factory, PoolManager and launch number can't be changed after deployment, and only the factory's answer can set the cached distributor address. The supply never grows after the constructor.\n\nThe two static-analysis leads were low-severity style notes with no security impact, so I didn't report them.","treeHash":null,"usage":{"cachedInputTokens":185216,"cost":{"source":"runtime","usdMicros":361287},"inputTokens":12,"model":"claude-opus-5-5","outputTokens":7481,"runtime":"claude","turns":6,"wallClockMs":97682}}],"verification":[{"checks":[{"durationMs":1825,"exitCode":0,"name":"build","output":"Compiling 30 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.73s\nCompiler run successful!\n","passed":true},{"durationMs":1350,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 42 tests for test/NvidiaToken.t.sol:NvidiaTokenTest\n[PASS] testFuzz_cannotSpendMoreThanBalance(uint256,uint256) (runs: 512, μ: 108769, ~: 109149)\nLogs:\n  Bound result 3219196199\n  Bound result 21600\n\n[PASS] testFuzz_launchFlowsAreExact(uint256,uint8) (runs: 512, μ: 259570, ~: 213208)\nLogs:\n  Bound result 3219196199\n\n[PASS] testFuzz_splitTransferIsExactAndMonotone(uint256) (runs: 512, μ: 14453, ~: 14179)\nLogs:\n  Bound result 102821338452883068690537138\n\n[PASS] testFuzz_supplyNeverGrows(address,address,uint256) (runs: 512, μ: 159076, ~: 166051)\nLogs:\n  Bound result 531644620278218304063112020\n\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 512, μ: 214195, ~: 225166)\nLogs:\n  Bound result 352867614600379570164460930\n  Bound result 91137067559901050423743138\n\n[PASS] test_constantsAndLaunchAddresses() (gas: 72490)\n[PASS] test_constructorDoesNotCallTheFactory() (gas: 994615)\n[PASS] test_constructorRejectsZeroFactory() (gas: 227039)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 227074)\n[PASS] test_deployScriptFunctionDeploysWithConfig() (gas: 2526615)\n[PASS] test_dirtyWordFactoryAnswerDoesNotBlockTransfers() (gas: 1280310)\n[PASS] test_distributorFlowsAreUntaxedAndCached() (gas: 329179)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 222861)\n[PASS] test_exemptSenderStillNeedsBalance() (gas: 46132)\n[PASS] test_factoryCannotPullFromAHolderWithoutAllowance() (gas: 98715)\n[PASS] test_factoryCannotSendMoreThanSupply() (gas: 38431)\n[PASS] test_factoryInboundIsUntaxed() (gas: 112078)\n[PASS] test_factoryOutboundIsUntaxed() (gas: 107083)\n[PASS] test_factoryWithoutCodeDoesNotBlockTransfers() (gas: 1163280)\n[PASS] test_gasBurningFactoryDoesNotBlockTransfers() (gas: 1378155)\n[PASS] test_hugeFactoryAnswerDoesNotBlockTransfers() (gas: 1379043)\n[PASS] test_isExemptReflectsLaunchAddresses() (gas: 149116)\n[PASS] test_malformedFactoryAnswerDoesNotBlockTransfers() (gas: 1232801)\n[PASS] test_metadata() (gas: 40022)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 23150)\n[PASS] test_noMintOwnerOrAdminEntrypoints() (gas: 422917)\n[PASS] test_ordinaryTransferSplitsThreeWays() (gas: 215702)\n[PASS] test_poolManagerInboundIsUntaxedOutboundIsTaxed() (gas: 282120)\n[PASS] test_revertingFactoryDoesNotBlockTransfers() (gas: 1269464)\n[PASS] test_routingThroughPoolManagerEscrowIsTaxed() (gas: 2129903)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 4537686)\n[PASS] test_selfTransferIsTaxed() (gas: 156268)\n[PASS] test_splitTransferHandlesMaxAmount() (gas: 10237)\n[PASS] test_splitTransferMatchesReference() (gas: 9951)\n[PASS] test_tinyAmountsRoundCutsDown() (gas: 254373)\n[PASS] test_transferFromAboveAllowanceReverts() (gas: 143244)\n[PASS] test_transferFromIsTaxedAndSpendsFullAllowance() (gas: 269648)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 95688)\n[PASS] test_transferMoreThanBalanceRevertsWithFullAmount() (gas: 101368)\n[PASS] test_transferToZeroReverts() (gas: 88139)\n[PASS] test_tributeRecipientPaysTaxLikeAnyHolder() (gas: 166555)\n[PASS] test_zeroAmountTransferIsAllowedAndFree() (gas: 47564)\nSuite result: ok. 42 passed; 0 failed; 0 skipped; finished in 31.61ms (172.56ms CPU time)\n\nRan 1 test for test/NvidiaToken.invariant.t.sol:NvidiaTokenInvariantTest\n[PASS]\nNvidiaTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_distributorCachedOnceKnown\n[PASS] invariant_supplyIsInitialMinusBurned\n[PASS] invariant_tributeRecipientBalanceMatchesModel\n NvidiaTokenInvariantTest invariants (runs: 128, calls: 6144, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 3015  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 3129  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 4113447894\n  Bound result 1826855018762846987767911\n  Bound result 300000\n  Bound result 86\n  Bound result 49999999999999999999999999\n  Bound result 300000\n  Bound result 50000\n  Bound result 10000000000000000000000\n  Bound result 52\n  Bound result 2602331755307021975566\n  Bound result 255\n  Bound result 3219196199\n  Bound result 253\n  Bound result 15103537223316390\n  Bound result 6513\n  Bound result 1000000000000000000000000\n  Bound result 41458179178986234353817239\n  Bound result 9651053854512673221445647\n  Bound result 7\n  Bound result 19906553087768550739823020\n  Bound result 5000000000000000000\n  Bound result 100759194685374623261568331\n  Bound result 13324649208\n  Bound result 6342\n  Bound result 3\n  Bound result 101\n  Bound result 10000000000000000000000\n  Bound result 1\n  Bound result 300000\n  Bound result 29771849204772584630366866\n  Bound result 10001\n  Bound result 254\n  Bound result 709165530877685539593260\n  Bound result 32533442696478442666314213\n  Bound result 9000000000000000000000\n  Bound result 50\n  Bound result 5000000000000000000\n  Bound result 24576\n  Bound result 253\n  Bound result 2\n  Bound result 23723998304810604247710259\n  Bound result 2000000000000000000\n  Bound result 6511\n  Bound result 9000000000000000000000\n  Bound result 4528\n  Bound result 199\n  Bound result 14\n  Bound result 1\n  Bound result 32\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.23s (1.23s CPU time)\n\nRan 2 test suites in 1.23s (1.26s CPU time): 43 tests passed, 0 failed, 0 skipped (43 total tests)\n","passed":true},{"durationMs":54,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"NvidiaToken.approve(address,uint256)\",\"NvidiaToken.transfer(address,uint256)\",\"NvidiaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"README.md\":129,\"foundry.toml\":32,\"launch.json\":28,\"remappings.txt\":2,\"script/DeployNvidiaToken.s.sol\":42,\"src/NvidiaToken.sol\":170,\"test/NvidiaToken.invariant.t.sol\":148,\"test/NvidiaToken.t.sol\":558,\"test/mocks/MockLaunchFactory.sol\":117},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"5f404680082cfdfda47f4889a772ab8712ae7b2301f9ed545a574fce7f88ede1","verifiedTreeHash":"a04fbdcb03a231bef8717bae4648e1c7a16091a1","verifierVersion":"0.1.0+435fe828"},{"checks":[{"durationMs":1429,"exitCode":0,"name":"build","output":"Compiling 30 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.34s\nCompiler run successful!\n","passed":true},{"durationMs":1241,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 42 tests for test/NvidiaToken.t.sol:NvidiaTokenTest\n[PASS] testFuzz_cannotSpendMoreThanBalance(uint256,uint256) (runs: 512, μ: 108769, ~: 109149)\nLogs:\n  Bound result 3219196199\n  Bound result 21600\n\n[PASS] testFuzz_launchFlowsAreExact(uint256,uint8) (runs: 512, μ: 259570, ~: 213208)\nLogs:\n  Bound result 3592135236154813363335516\n\n[PASS] testFuzz_splitTransferIsExactAndMonotone(uint256) (runs: 512, μ: 14453, ~: 14179)\nLogs:\n  Bound result 20\n\n[PASS] testFuzz_supplyNeverGrows(address,address,uint256) (runs: 512, μ: 159076, ~: 166051)\nLogs:\n  Bound result 30704\n\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 512, μ: 214195, ~: 225166)\nLogs:\n  Bound result 3592135236154813363335516\n  Bound result 50550827\n\n[PASS] test_constantsAndLaunchAddresses() (gas: 72490)\n[PASS] test_constructorDoesNotCallTheFactory() (gas: 994615)\n[PASS] test_constructorRejectsZeroFactory() (gas: 227039)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 227074)\n[PASS] test_deployScriptFunctionDeploysWithConfig() (gas: 2526615)\n[PASS] test_dirtyWordFactoryAnswerDoesNotBlockTransfers() (gas: 1280310)\n[PASS] test_distributorFlowsAreUntaxedAndCached() (gas: 329179)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 222861)\n[PASS] test_exemptSenderStillNeedsBalance() (gas: 46132)\n[PASS] test_factoryCannotPullFromAHolderWithoutAllowance() (gas: 98715)\n[PASS] test_factoryCannotSendMoreThanSupply() (gas: 38431)\n[PASS] test_factoryInboundIsUntaxed() (gas: 112078)\n[PASS] test_factoryOutboundIsUntaxed() (gas: 107083)\n[PASS] test_factoryWithoutCodeDoesNotBlockTransfers() (gas: 1163280)\n[PASS] test_gasBurningFactoryDoesNotBlockTransfers() (gas: 1378155)\n[PASS] test_hugeFactoryAnswerDoesNotBlockTransfers() (gas: 1379043)\n[PASS] test_isExemptReflectsLaunchAddresses() (gas: 149116)\n[PASS] test_malformedFactoryAnswerDoesNotBlockTransfers() (gas: 1232801)\n[PASS] test_metadata() (gas: 40022)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 23150)\n[PASS] test_noMintOwnerOrAdminEntrypoints() (gas: 422917)\n[PASS] test_ordinaryTransferSplitsThreeWays() (gas: 215702)\n[PASS] test_poolManagerInboundIsUntaxedOutboundIsTaxed() (gas: 282120)\n[PASS] test_revertingFactoryDoesNotBlockTransfers() (gas: 1269464)\n[PASS] test_routingThroughPoolManagerEscrowIsTaxed() (gas: 2129903)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 4537686)\n[PASS] test_selfTransferIsTaxed() (gas: 156268)\n[PASS] test_splitTransferHandlesMaxAmount() (gas: 10237)\n[PASS] test_splitTransferMatchesReference() (gas: 9951)\n[PASS] test_tinyAmountsRoundCutsDown() (gas: 254373)\n[PASS] test_transferFromAboveAllowanceReverts() (gas: 143244)\n[PASS] test_transferFromIsTaxedAndSpendsFullAllowance() (gas: 269648)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 95688)\n[PASS] test_transferMoreThanBalanceRevertsWithFullAmount() (gas: 101368)\n[PASS] test_transferToZeroReverts() (gas: 88139)\n[PASS] test_tributeRecipientPaysTaxLikeAnyHolder() (gas: 166555)\n[PASS] test_zeroAmountTransferIsAllowedAndFree() (gas: 47564)\nSuite result: ok. 42 passed; 0 failed; 0 skipped; finished in 33.69ms (172.18ms CPU time)\n\nRan 1 test for test/NvidiaToken.invariant.t.sol:NvidiaTokenInvariantTest\n[PASS]\nNvidiaTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_distributorCachedOnceKnown\n[PASS] invariant_supplyIsInitialMinusBurned\n[PASS] invariant_tributeRecipientBalanceMatchesModel\n NvidiaTokenInvariantTest invariants (runs: 128, calls: 6144, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 3015  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 3129  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 4113447894\n  Bound result 1826855018762846987767911\n  Bound result 300000\n  Bound result 86\n  Bound result 49999999999999999999999999\n  Bound result 300000\n  Bound result 50000\n  Bound result 10000000000000000000000\n  Bound result 52\n  Bound result 2602331755307021975566\n  Bound result 255\n  Bound result 3219196199\n  Bound result 253\n  Bound result 15103537223316390\n  Bound result 6513\n  Bound result 1000000000000000000000000\n  Bound result 41458179178986234353817239\n  Bound result 9651053854512673221445647\n  Bound result 7\n  Bound result 19906553087768550739823020\n  Bound result 5000000000000000000\n  Bound result 100759194685374623261568331\n  Bound result 13324649208\n  Bound result 6342\n  Bound result 3\n  Bound result 101\n  Bound result 10000000000000000000000\n  Bound result 1\n  Bound result 300000\n  Bound result 29771849204772584630366866\n  Bound result 10001\n  Bound result 254\n  Bound result 709165530877685539593260\n  Bound result 32533442696478442666314213\n  Bound result 9000000000000000000000\n  Bound result 50\n  Bound result 5000000000000000000\n  Bound result 24576\n  Bound result 253\n  Bound result 2\n  Bound result 23723998304810604247710259\n  Bound result 2000000000000000000\n  Bound result 6511\n  Bound result 9000000000000000000000\n  Bound result 4528\n  Bound result 199\n  Bound result 14\n  Bound result 1\n  Bound result 32\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.13s (1.13s CPU time)\n\nRan 2 test suites in 1.13s (1.16s CPU time): 43 tests passed, 0 failed, 0 skipped (43 total tests)\n","passed":true},{"durationMs":43,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"NvidiaToken.approve(address,uint256)\",\"NvidiaToken.transfer(address,uint256)\",\"NvidiaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"README.md\":129,\"foundry.toml\":32,\"remappings.txt\":2,\"script/DeployNvidiaToken.s.sol\":42,\"src/NvidiaToken.sol\":170,\"test/NvidiaToken.invariant.t.sol\":148,\"test/NvidiaToken.t.sol\":558,\"test/mocks/MockLaunchFactory.sol\":117},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":504,"exitCode":0,"name":"slither","output":"[low/medium] return-bomb at src/NvidiaToken.sol:159: NvidiaToken._lookupDistributor() (src/NvidiaToken.sol#159-169) tries to limit the gas of an external call that controls implicit decoding","passed":true},{"durationMs":221,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/NvidiaToken.sol:33: Large Numeric Literal (2 places)\n[low] unused-public-function at src/NvidiaToken.sol:111: Public Function Not Used Internally","passed":true},{"durationMs":1269,"exitCode":0,"name":"proof e644f2a3d203","output":"Compiling 27 files with Solc 0.8.26\nSolc 0.8.26 finished in 721.60ms\nCompiler run successful!\n\nRan 1 test for test/imd-proof-17c9c0ac/Proof_e644f2a3d203.t.sol:PmBypassTest\n[PASS] test_walletToWalletViaPoolManagerStillPaysTax() (gas: 725935)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 594.70µs (172.91µs CPU time)\n\nRan 1 test suite in 3.06ms (594.70µs CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"821543a16fbfd78b2e3e3a157f8791ee9877be9419543ebe59c77974e6975af3","verifiedTreeHash":"b2de9420bf967254f93f40dd9cefdb63e4fe6f50","verifierVersion":"0.1.0+435fe828"},{"checks":[{"durationMs":3517,"exitCode":0,"name":"build","output":"Compiling 39 files with Solc 0.8.26\nSolc 0.8.26 finished in 3.41s\nCompiler run successful!\n","passed":true},{"durationMs":15608,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 10 tests for test/NvidiaToken.discovery.t.sol:NvidiaTokenDiscoveryTest\n[PASS] testFuzz_exemptEndpointsStillRequireGrossAllowance(uint8,bool,uint256) (runs: 1000, μ: 1578998, ~: 1583573)\nLogs:\n  Bound result 104572022243089716640998108\n\n[PASS] testFuzz_launchNumberSelectsOnlyItsOwnDistributor(uint64) (runs: 1000, μ: 1283623, ~: 1283571)\n[PASS] testFuzz_wrongLengthFactoryResponseIsIgnored(uint256) (runs: 1000, μ: 294212, ~: 294049)\nLogs:\n  Bound result 7\n\n[PASS] test_cachedDistributorCannotBeReplacedByAnotherFactoryAnswer() (gas: 444709)\n[PASS] test_cachedDistributorSurvivesFactoryFailureAndEmitsOnlyOnce() (gas: 315060)\n[PASS] test_distributorCanBeDiscoveredAfterAnEarlierUnknownLookup() (gas: 391337)\n[PASS] test_exemptionQueriesDoNotCacheOrFreezeAnUnknownDistributor() (gas: 350193)\n[PASS] test_failedFirstDistributorClaimDoesNotCache() (gas: 1459354)\n[PASS] test_revertingLookupCanRecoverLater() (gas: 355460)\n[PASS] test_validDistributorWordIsUsedBeforeAnyTaxIsCharged() (gas: 249704)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 354.31ms (903.81ms CPU time)\n\nRan 42 tests for test/NvidiaToken.t.sol:NvidiaTokenTest\n[PASS] testFuzz_cannotSpendMoreThanBalance(uint256,uint256) (runs: 512, μ: 108759, ~: 109149)\nLogs:\n  Bound result 1348\n  Bound result 10919\n\n[PASS] testFuzz_launchFlowsAreExact(uint256,uint8) (runs: 512, μ: 259739, ~: 213208)\nLogs:\n  Bound result 1348\n\n[PASS] testFuzz_splitTransferIsExactAndMonotone(uint256) (runs: 512, μ: 14452, ~: 14179)\nLogs:\n  Bound result 306721909457504203338028079\n\n[PASS] testFuzz_supplyNeverGrows(address,address,uint256) (runs: 512, μ: 159338, ~: 166063)\nLogs:\n  Bound result 13067950859\n\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 512, μ: 215250, ~: 225166)\nLogs:\n  Bound result 1348\n  Bound result 127\n\n[PASS] test_constantsAndLaunchAddresses() (gas: 72490)\n[PASS] test_constructorDoesNotCallTheFactory() (gas: 994615)\n[PASS] test_constructorRejectsZeroFactory() (gas: 227039)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 227074)\n[PASS] test_deployScriptFunctionDeploysWithConfig() (gas: 2526615)\n[PASS] test_dirtyWordFactoryAnswerDoesNotBlockTransfers() (gas: 1280310)\n[PASS] test_distributorFlowsAreUntaxedAndCached() (gas: 329179)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 222861)\n[PASS] test_exemptSenderStillNeedsBalance() (gas: 46132)\n[PASS] test_factoryCannotPullFromAHolderWithoutAllowance() (gas: 98715)\n[PASS] test_factoryCannotSendMoreThanSupply() (gas: 38431)\n[PASS] test_factoryInboundIsUntaxed() (gas: 112078)\n[PASS] test_factoryOutboundIsUntaxed() (gas: 107083)\n[PASS] test_factoryWithoutCodeDoesNotBlockTransfers() (gas: 1163280)\n[PASS] test_gasBurningFactoryDoesNotBlockTransfers() (gas: 1378155)\n[PASS] test_hugeFactoryAnswerDoesNotBlockTransfers() (gas: 1379043)\n[PASS] test_isExemptReflectsLaunchAddresses() (gas: 149116)\n[PASS] test_malformedFactoryAnswerDoesNotBlockTransfers() (gas: 1232801)\n[PASS] test_metadata() (gas: 40022)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 23150)\n[PASS] test_noMintOwnerOrAdminEntrypoints() (gas: 422917)\n[PASS] test_ordinaryTransferSplitsThreeWays() (gas: 215702)\n[PASS] test_poolManagerInboundIsUntaxedOutboundIsTaxed() (gas: 282120)\n[PASS] test_revertingFactoryDoesNotBlockTransfers() (gas: 1269464)\n[PASS] test_routingThroughPoolManagerEscrowIsTaxed() (gas: 2129903)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 4537686)\n[PASS] test_selfTransferIsTaxed() (gas: 156268)\n[PASS] test_splitTransferHandlesMaxAmount() (gas: 10237)\n[PASS] test_splitTransferMatchesReference() (gas: 9951)\n[PASS] test_tinyAmountsRoundCutsDown() (gas: 254373)\n[PASS] test_transferFromAboveAllowanceReverts() (gas: 143244)\n[PASS] test_transferFromIsTaxedAndSpendsFullAllowance() (gas: 269648)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 95688)\n[PASS] test_transferMoreThanBalanceRevertsWithFullAmount() (gas: 101368)\n[PASS] test_transferToZeroReverts() (gas: 88139)\n[PASS] test_tributeRecipientPaysTaxLikeAnyHolder() (gas: 166555)\n[PASS] test_zeroAmountTransferIsAllowedAndFree() (gas: 47564)\nSuite result: ok. 42 passed; 0 failed; 0 skipped; finished in 376.17ms (304.53ms CPU time)\n\nRan 15 tests for test/NvidiaToken.pool.t.sol:NvidiaTokenPoolTest\n[PASS] testFuzz_gasLimitedFirstClaimIsExactOrReverts(uint256) (runs: 1000, μ: 203229, ~: 222936)\nLogs:\n  Bound result 30911\n\n[PASS] testFuzz_nonAddressFactoryWordIsIgnoredAndLaterAnswerStillCaches(uint256) (runs: 1000, μ: 1513081, ~: 1513200)\nLogs:\n  Bound result 115792089237316195423570985007226406215939082667117842797817001878166390096565\n\n[PASS] testFuzz_poolOutboundIsTaxedFromTheGrossAmount(uint256,uint8,bool) (runs: 1000, μ: 323664, ~: 301377)\nLogs:\n  Bound result 500000000000000000000000000\n\n[PASS] testFuzz_poolOverspendRevertsWithGrossAmountAndChangesNothing(uint256,uint256) (runs: 1000, μ: 1343791, ~: 1344285)\nLogs:\n  Bound result 87871347300752315733235759\n  Bound result 115792089237316195423570985008687907853269984665640476168110283255597396404242\n\n[PASS] testFuzz_sellThenBuyBackNeverGainsAndLosesExactlyTheTax(uint256) (runs: 1000, μ: 255964, ~: 260924)\nLogs:\n  Bound result 17684671601\n\n[PASS] testFuzz_splitTransferMatchesTheSpecOverTheWholeRange(uint256) (runs: 1000, μ: 10793, ~: 10758)\n[PASS] test_allOnesFactoryWordDoesNotRevertTransfers() (gas: 1233078)\n[PASS] test_poolDelegatedPayoutNeedsTheGrossAllowance() (gas: 1376793)\n[PASS] test_poolIsNotExemptInIsExempt() (gas: 29360)\n[PASS] test_poolOutboundCachesTheDistributor() (gas: 237411)\n[PASS] test_poolOutboundEmitsTheThreeLegsAndTheTaxEvent() (gas: 171896)\n[PASS] test_poolSelfTransferIsExact() (gas: 109767)\n[PASS] test_poolToDistributorIsExactOnlyOnceTheFactoryNamesIt() (gas: 328185)\n[PASS] test_poolToFactoryIsExact() (gas: 137363)\n[PASS] test_splitTransferEdges() (gas: 64435)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 376.33ms (2.03s CPU time)\n\nRan 28 tests for test/NvidiaToken.adversarial.t.sol:NvidiaTokenAdversarialTest\n[PASS] testFuzz_addingOneRatePeriodAddsExactlyThreeWeiOfTax(uint256) (runs: 1000, μ: 19955, ~: 19675)\nLogs:\n  Bound result 17684671601\n\n[PASS] testFuzz_insufficientAllowancePreservesAllState(uint256,uint256) (runs: 1000, μ: 1385230, ~: 1386523)\nLogs:\n  Bound result 3\n  Bound result 2\n\n[PASS] testFuzz_previewMatchesActualAndCutsRoundDown(uint256) (runs: 1000, μ: 193325, ~: 197978)\nLogs:\n  Bound result 8173\n\n[PASS] testFuzz_rejectedTransferFromPreservesAllState(uint256,uint256) (runs: 1000, μ: 1466558, ~: 1467133)\nLogs:\n  Bound result 0\n  Bound result 36289872561614655774834148528087062063882282330245\n\n[PASS] testFuzz_roundTripCannotCreateValue(uint256) (runs: 1000, μ: 301997, ~: 310586)\nLogs:\n  Bound result 17684671601\n\n[PASS] testFuzz_selfTransferChargesOnlyTheTwoCuts(uint256) (runs: 1000, μ: 246888, ~: 251836)\nLogs:\n  Bound result 17684671601\n\n[PASS] test_approvalIsIsolatedByOwnerAndSpender() (gas: 245037)\n[PASS] test_approvalOverwritesAndRevocationTakesEffectImmediately() (gas: 1621392)\n[PASS] test_approveZeroSpenderRejectsZeroAndMaximum() (gas: 1310084)\n[PASS] test_constructorMintsOnceToActualDeployer() (gas: 1039282)\n[PASS] test_failedTransferFromRollsBackAllowanceAndNewCache() (gas: 1661280)\n[PASS] test_finiteAllowancePersistsAcrossSeveralSpends() (gas: 1621144)\n[PASS] test_fullSupplyTransferBurnsExactlyOnePercent() (gas: 204496)\n[PASS] test_grossAmountMustFitEvenWhenNetFits() (gas: 1338616)\n[PASS] test_infiniteAllowanceIsNotSpentButCanBeRevoked() (gas: 371328)\n[PASS] test_jensenSelfTransferOnlyLosesBurnButSpendsGrossAllowance() (gas: 196124)\n[PASS] test_maximumMinusOneAllowanceIsFinite() (gas: 268104)\n[PASS] test_maximumTransferRevertsForBalanceBeforeTaxArithmetic() (gas: 1427101)\n[PASS] test_netOnlyAllowanceCannotAuthorizeGrossTransfer() (gas: 1378895)\n[PASS] test_oneWeiMovesEvenWhenSenderIsEmptied() (gas: 166277)\n[PASS] test_roundingBoundaryTable() (gas: 90516)\n[PASS] test_selfTransferCannotSpendMoreThanBalance() (gas: 1338650)\n[PASS] test_taxedTransferToTokenContractStillConservesSupply() (gas: 183544)\n[PASS] test_transferFromDoesNotGiveOwnerImplicitAllowance() (gas: 1330944)\n[PASS] test_transferToJensenCreditsNetAndTributeExactlyOnce() (gas: 161767)\n[PASS] test_zeroAmountStillRejectsZeroEndpoints() (gas: 1328885)\n[PASS] test_zeroRecipientRollsBackFiniteAllowanceAndBalances() (gas: 1381661)\n[PASS] test_zeroTransferFromWithoutApprovalOnlyEmitsTransfer() (gas: 1334013)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 376.44ms (1.92s CPU time)\n\nRan 1 test for test/NvidiaToken.invariant.t.sol:NvidiaTokenInvariantTest\n[PASS]\nNvidiaTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_distributorCachedOnceKnown\n[PASS] invariant_supplyIsInitialMinusBurned\n[PASS] invariant_tributeRecipientBalanceMatchesModel\n NvidiaTokenInvariantTest invariants (runs: 128, calls: 6144, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 3015  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 3129  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 4113447894\n  Bound result 1826855018762846987767911\n  Bound result 242\n  Bound result 91\n  Bound result 5000000000000000000000000\n  Bound result 255\n  Bound result 80389977832443448857974839\n  Bound result 198\n  Bound result 20\n  Bound result 2602331755307021975566\n  Bound result 38435468697153663822184755\n  Bound result 3219196200\n  Bound result 95\n  Bound result 15103537223316390\n  Bound result 5798\n  Bound result 9\n  Bound result 85634900817075815932756591\n  Bound result 1000000000\n  Bound result 199\n  Bound result 2913\n  Bound result 990\n  Bound result 9934967143542358613624404\n  Bound result 13324649208\n  Bound result 415955172\n  Bound result 400\n  Bound result 18446744073709551616\n  Bound result 101\n  Bound result 1\n  Bound result 255\n  Bound result 8502475828917985478957314\n  Bound result 3336\n  Bound result 242\n  Bound result 36497524171082017324291848\n  Bound result 33055002416018707696469820\n  Bound result 2000000000000000000000\n  Bound result 50000\n  Bound result 990\n  Bound result 9291144608689328105452216\n  Bound result 95\n  Bound result 2\n  Bound result 44894044954427373864090503\n  Bound result 200000\n  Bound result 5688\n  Bound result 2000000000000000000000\n  Bound result 3948\n  Bound result 3\n  Bound result 18\n  Bound result 20716308757508865698504470\n  Bound result 18446744073709551615\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.25s (1.25s CPU time)\n\nRan 2 tests for test/NvidiaToken.stateful.t.sol:NvidiaTokenStatefulTest\n[PASS]\nNvidiaTokenStatefulTest invariants:\n[PASS] invariant_allowancesMatchPersistentAuthorizations\n[PASS] invariant_discoveryMatchesPublicationAndSuccessfulCalls\n[PASS] invariant_everyHolderMatchesIndependentLedger\n[PASS] invariant_supplyEqualsAllBalancesAndInitialLessBurns\n NvidiaTokenStatefulTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------------------+---------------------+-------+---------+----------╮\n| Contract                | Selector            | Calls | Reverts | Discards |\n+============================================================================+\n| NvidiaTokenStateHandler | approve             | 2054  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | attemptTransferFrom | 2095  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | publishDistributor  | 2003  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | rejectTransfer      | 2072  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | selfTransfer        | 2009  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | setFactoryAvailable | 2025  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | transfer            | 2065  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | transferFrom        | 2061  | 0       | 0        |\n╰-------------------------+---------------------+-------+---------+----------╯\n\n[PASS] test_handlerExercisesMeaningfulSuccessAndFailureSequences() (gas: 30315860)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 15.48s (15.49s CPU time)\n\nRan 6 test suites in 15.49s (18.22s CPU time): 98 tests passed, 0 failed, 0 skipped (98 total tests)\n","passed":true},{"durationMs":55,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"NvidiaToken.approve(address,uint256)\",\"NvidiaToken.transfer(address,uint256)\",\"NvidiaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"README.md\":129,\"foundry.toml\":32,\"remappings.txt\":2,\"script/DeployNvidiaToken.s.sol\":42,\"src/NvidiaToken.sol\":170,\"test/NvidiaToken.adversarial.t.sol\":374,\"test/NvidiaToken.discovery.t.sol\":207,\"test/NvidiaToken.invariant.t.sol\":148,\"test/NvidiaToken.pool.t.sol\":259,\"test/NvidiaToken.stateful.t.sol\":119,\"test/NvidiaToken.t.sol\":558,\"test/TESTING.md\":104,\"test/handlers/NvidiaTokenStateHandler.sol\":189,\"test/helpers/NvidiaTokenFixture.sol\":48,\"test/mocks/MockLaunchFactory.sol\":117},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"a45b9e97ef67f49efb5cf3fc90ec7958502719a43aa2923b559776868116699f","verifiedTreeHash":"6a4d3f99f5c3e0b2f514c9b621b22ab5f26c55ca","verifierVersion":"0.1.0+435fe828"},{"checks":[{"durationMs":1195,"exitCode":0,"name":"build","output":"Compiling 30 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.12s\nCompiler run successful!\n","passed":true},{"durationMs":1179,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 37 tests for test/NvidiaToken.t.sol:NvidiaTokenTest\n[PASS] testFuzz_cannotSpendMoreThanBalance(uint256,uint256) (runs: 512, μ: 108723, ~: 109172)\nLogs:\n  Bound result 289145417192798105164383452\n  Bound result 3055103255011771178\n\n[PASS] testFuzz_launchFlowsAreExact(uint256,uint8) (runs: 512, μ: 261284, ~: 279722)\nLogs:\n  Bound result 1521\n\n[PASS] testFuzz_splitTransferIsExactAndMonotone(uint256) (runs: 512, μ: 14427, ~: 14161)\nLogs:\n  Bound result 4353219903593487742761081\n\n[PASS] testFuzz_supplyNeverGrows(address,address,uint256) (runs: 512, μ: 159006, ~: 166167)\nLogs:\n  Bound result 20418\n\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 512, μ: 213082, ~: 225198)\nLogs:\n  Bound result 8647\n  Bound result 2178\n\n[PASS] test_constantsAndLaunchAddresses() (gas: 72402)\n[PASS] test_constructorDoesNotCallTheFactory() (gas: 1019591)\n[PASS] test_constructorRejectsZeroFactory() (gas: 229037)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 228985)\n[PASS] test_deployScriptFunctionDeploysWithConfig() (gas: 2573701)\n[PASS] test_distributorFlowsAreUntaxedAndCached() (gas: 329127)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 222904)\n[PASS] test_exemptSenderStillNeedsBalance() (gas: 38158)\n[PASS] test_factoryCannotPullFromAHolderWithoutAllowance() (gas: 98642)\n[PASS] test_factoryCannotSendMoreThanSupply() (gas: 38442)\n[PASS] test_factoryInboundIsUntaxed() (gas: 112028)\n[PASS] test_factoryOutboundIsUntaxed() (gas: 106988)\n[PASS] test_factoryWithoutCodeDoesNotBlockTransfers() (gas: 1188328)\n[PASS] test_isExemptReflectsLaunchAddresses() (gas: 141164)\n[PASS] test_malformedFactoryAnswerDoesNotBlockTransfers() (gas: 1257869)\n[PASS] test_metadata() (gas: 40132)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 23122)\n[PASS] test_noMintOwnerOrAdminEntrypoints() (gas: 422834)\n[PASS] test_ordinaryTransferSplitsThreeWays() (gas: 215778)\n[PASS] test_poolManagerBothWaysIsUntaxed() (gas: 204789)\n[PASS] test_revertingFactoryDoesNotBlockTransfers() (gas: 1294400)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 4627164)\n[PASS] test_selfTransferIsTaxed() (gas: 156328)\n[PASS] test_splitTransferMatchesReference() (gas: 9999)\n[PASS] test_tinyAmountsRoundCutsDown() (gas: 254543)\n[PASS] test_transferFromAboveAllowanceReverts() (gas: 143237)\n[PASS] test_transferFromIsTaxedAndSpendsFullAllowance() (gas: 269616)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 95643)\n[PASS] test_transferMoreThanBalanceRevertsWithFullAmount() (gas: 101414)\n[PASS] test_transferToZeroReverts() (gas: 88100)\n[PASS] test_tributeRecipientPaysTaxLikeAnyHolder() (gas: 166614)\n[PASS] test_zeroAmountTransferIsAllowedAndFree() (gas: 47558)\nSuite result: ok. 37 passed; 0 failed; 0 skipped; finished in 26.08ms (138.19ms CPU time)\n\nRan 1 test for test/NvidiaToken.invariant.t.sol:NvidiaTokenInvariantTest\n[PASS]\nNvidiaTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_distributorCachedOnceKnown\n[PASS] invariant_supplyIsInitialMinusBurned\n[PASS] invariant_tributeRecipientBalanceMatchesModel\n NvidiaTokenInvariantTest invariants (runs: 128, calls: 6144, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 3015  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 3129  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 4113447896\n  Bound result 1826855018762846987767911\n  Bound result 253\n  Bound result 255\n  Bound result 49999999999999999999999999\n  Bound result 253\n  Bound result 0\n  Bound result 985000000000000000000\n  Bound result 21\n  Bound result 2602331755307021975566\n  Bound result 242\n  Bound result 826074471\n  Bound result 243\n  Bound result 15103537223316390\n  Bound result 6212\n  Bound result 10000000000000000000000\n  Bound result 67388043669472633825196795\n  Bound result 356670107144588994935535503\n  Bound result 7\n  Bound result 3079\n  Bound result 10000000000000000000\n  Bound result 318736498867641276161142579\n  Bound result 13324649208\n  Bound result 8002\n  Bound result 10\n  Bound result 1080\n  Bound result 985000000000000000000\n  Bound result 1\n  Bound result 253\n  Bound result 6180237330998081580367266\n  Bound result 30\n  Bound result 253\n  Bound result 10549235288704808062185959\n  Bound result 43349339428945479326512254\n  Bound result 9000000000000000000000\n  Bound result 50\n  Bound result 10000000000000000000\n  Bound result 24576\n  Bound result 243\n  Bound result 2\n  Bound result 44295044954428196553577703\n  Bound result 101000000000000000000\n  Bound result 5849\n  Bound result 9000000000000000000000\n  Bound result 6863\n  Bound result 199\n  Bound result 14\n  Bound result 2\n  Bound result 32\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.08s (1.08s CPU time)\n\nRan 2 test suites in 1.08s (1.11s CPU time): 38 tests passed, 0 failed, 0 skipped (38 total tests)\n","passed":true},{"durationMs":40,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"NvidiaToken.approve(address,uint256)\",\"NvidiaToken.transfer(address,uint256)\",\"NvidiaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"README.md\":128,\"foundry.toml\":32,\"launch.json\":28,\"remappings.txt\":2,\"script/DeployNvidiaToken.s.sol\":36,\"src/NvidiaToken.sol\":152,\"test/NvidiaToken.invariant.t.sol\":149,\"test/NvidiaToken.t.sol\":494,\"test/mocks/MockLaunchFactory.sol\":28},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"b57112109911acbbef9caf5f3d962ed48a5187bad31dec5c2913c3a4f28358e7","verifiedTreeHash":"f7108e0b92948dfc4c633b89121c261a7c10b602","verifierVersion":"0.1.0+435fe828"},{"checks":[{"durationMs":1431,"exitCode":0,"name":"build","output":"Compiling 30 files with Solc 0.8.26\nSolc 0.8.26 finished in 1.34s\nCompiler run successful!\n","passed":true},{"durationMs":1200,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 37 tests for test/NvidiaToken.t.sol:NvidiaTokenTest\n[PASS] testFuzz_cannotSpendMoreThanBalance(uint256,uint256) (runs: 512, μ: 108723, ~: 109172)\nLogs:\n  Bound result 826074472\n  Bound result 22628\n\n[PASS] testFuzz_launchFlowsAreExact(uint256,uint8) (runs: 512, μ: 261284, ~: 279722)\nLogs:\n  Bound result 999999999999999999999999998\n\n[PASS] testFuzz_splitTransferIsExactAndMonotone(uint256) (runs: 512, μ: 14427, ~: 14161)\nLogs:\n  Bound result 306721909457504203338028079\n\n[PASS] testFuzz_supplyNeverGrows(address,address,uint256) (runs: 512, μ: 159006, ~: 166167)\nLogs:\n  Bound result 3\n\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 512, μ: 213082, ~: 225198)\nLogs:\n  Bound result 352867614600379570164460930\n  Bound result 91137067559901050423743138\n\n[PASS] test_constantsAndLaunchAddresses() (gas: 72402)\n[PASS] test_constructorDoesNotCallTheFactory() (gas: 1019591)\n[PASS] test_constructorRejectsZeroFactory() (gas: 229037)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 228985)\n[PASS] test_deployScriptFunctionDeploysWithConfig() (gas: 2573701)\n[PASS] test_distributorFlowsAreUntaxedAndCached() (gas: 329127)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 222904)\n[PASS] test_exemptSenderStillNeedsBalance() (gas: 38158)\n[PASS] test_factoryCannotPullFromAHolderWithoutAllowance() (gas: 98642)\n[PASS] test_factoryCannotSendMoreThanSupply() (gas: 38442)\n[PASS] test_factoryInboundIsUntaxed() (gas: 112028)\n[PASS] test_factoryOutboundIsUntaxed() (gas: 106988)\n[PASS] test_factoryWithoutCodeDoesNotBlockTransfers() (gas: 1188328)\n[PASS] test_isExemptReflectsLaunchAddresses() (gas: 141164)\n[PASS] test_malformedFactoryAnswerDoesNotBlockTransfers() (gas: 1257869)\n[PASS] test_metadata() (gas: 40132)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 23122)\n[PASS] test_noMintOwnerOrAdminEntrypoints() (gas: 422834)\n[PASS] test_ordinaryTransferSplitsThreeWays() (gas: 215778)\n[PASS] test_poolManagerBothWaysIsUntaxed() (gas: 204789)\n[PASS] test_revertingFactoryDoesNotBlockTransfers() (gas: 1294400)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 4627164)\n[PASS] test_selfTransferIsTaxed() (gas: 156328)\n[PASS] test_splitTransferMatchesReference() (gas: 9999)\n[PASS] test_tinyAmountsRoundCutsDown() (gas: 254543)\n[PASS] test_transferFromAboveAllowanceReverts() (gas: 143237)\n[PASS] test_transferFromIsTaxedAndSpendsFullAllowance() (gas: 269616)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 95643)\n[PASS] test_transferMoreThanBalanceRevertsWithFullAmount() (gas: 101414)\n[PASS] test_transferToZeroReverts() (gas: 88100)\n[PASS] test_tributeRecipientPaysTaxLikeAnyHolder() (gas: 166614)\n[PASS] test_zeroAmountTransferIsAllowedAndFree() (gas: 47558)\nSuite result: ok. 37 passed; 0 failed; 0 skipped; finished in 28.00ms (151.81ms CPU time)\n\nRan 1 test for test/NvidiaToken.invariant.t.sol:NvidiaTokenInvariantTest\n[PASS]\nNvidiaTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_distributorCachedOnceKnown\n[PASS] invariant_supplyIsInitialMinusBurned\n[PASS] invariant_tributeRecipientBalanceMatchesModel\n NvidiaTokenInvariantTest invariants (runs: 128, calls: 6144, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 3015  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 3129  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 4113447896\n  Bound result 1826855018762846987767911\n  Bound result 253\n  Bound result 255\n  Bound result 49999999999999999999999999\n  Bound result 253\n  Bound result 0\n  Bound result 985000000000000000000\n  Bound result 21\n  Bound result 2602331755307021975566\n  Bound result 242\n  Bound result 826074471\n  Bound result 243\n  Bound result 15103537223316390\n  Bound result 6212\n  Bound result 10000000000000000000000\n  Bound result 67388043669472633825196795\n  Bound result 356670107144588994935535503\n  Bound result 7\n  Bound result 3079\n  Bound result 10000000000000000000\n  Bound result 318736498867641276161142579\n  Bound result 13324649208\n  Bound result 8002\n  Bound result 10\n  Bound result 1080\n  Bound result 985000000000000000000\n  Bound result 1\n  Bound result 253\n  Bound result 6180237330998081580367266\n  Bound result 30\n  Bound result 253\n  Bound result 10549235288704808062185959\n  Bound result 43349339428945479326512254\n  Bound result 9000000000000000000000\n  Bound result 50\n  Bound result 10000000000000000000\n  Bound result 24576\n  Bound result 243\n  Bound result 2\n  Bound result 44295044954428196553577703\n  Bound result 101000000000000000000\n  Bound result 5849\n  Bound result 9000000000000000000000\n  Bound result 6863\n  Bound result 199\n  Bound result 14\n  Bound result 2\n  Bound result 32\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.09s (1.09s CPU time)\n\nRan 2 test suites in 1.10s (1.12s CPU time): 38 tests passed, 0 failed, 0 skipped (38 total tests)\n","passed":true},{"durationMs":39,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"NvidiaToken.approve(address,uint256)\",\"NvidiaToken.transfer(address,uint256)\",\"NvidiaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"README.md\":128,\"foundry.toml\":32,\"remappings.txt\":2,\"script/DeployNvidiaToken.s.sol\":36,\"src/NvidiaToken.sol\":152,\"test/NvidiaToken.invariant.t.sol\":149,\"test/NvidiaToken.t.sol\":494,\"test/mocks/MockLaunchFactory.sol\":28},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":506,"exitCode":0,"name":"slither","output":"slither: no results at low impact or above","passed":true},{"durationMs":238,"exitCode":0,"name":"aderyn","output":"[low] large-numeric-literal at src/NvidiaToken.sol:31: Large Numeric Literal\n[low] unused-public-function at src/NvidiaToken.sol:101: Public Function Not Used Internally","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c15685aee8f9cb978cf8460cd242cbe9bf13b19e518ca8b9486bd124187fce3a","verifiedTreeHash":"4a43a0aa9e2ff91b647021e82391fb6e5adf9244","verifierVersion":"0.1.0+435fe828"},{"checks":[{"durationMs":2424,"exitCode":0,"name":"build","output":"Compiling 35 files with Solc 0.8.26\nSolc 0.8.26 finished in 2.33s\nCompiler run successful!\n","passed":true},{"durationMs":14615,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 10 tests for test/NvidiaToken.discovery.t.sol:NvidiaTokenDiscoveryTest\n[PASS] testFuzz_exemptEndpointsStillRequireGrossAllowance(uint8,bool,uint256) (runs: 1000, μ: 1573941, ~: 1578926)\nLogs:\n  Bound result 173973566721250918144194601\n\n[PASS] testFuzz_launchNumberSelectsOnlyItsOwnDistributor(uint64) (runs: 1000, μ: 1308677, ~: 1308625)\n[PASS] testFuzz_wrongLengthFactoryResponseIsIgnored(uint256) (runs: 1000, μ: 294115, ~: 294046)\nLogs:\n  Bound result 87\n\n[PASS] test_cachedDistributorCannotBeReplacedByAnotherFactoryAnswer() (gas: 444869)\n[PASS] test_cachedDistributorSurvivesFactoryFailureAndEmitsOnlyOnce() (gas: 315170)\n[PASS] test_distributorCanBeDiscoveredAfterAnEarlierUnknownLookup() (gas: 391326)\n[PASS] test_exemptionQueriesDoNotCacheOrFreezeAnUnknownDistributor() (gas: 350385)\n[PASS] test_failedFirstDistributorClaimDoesNotCache() (gas: 1455128)\n[PASS] test_revertingLookupCanRecoverLater() (gas: 355475)\n[PASS] test_validDistributorWordIsUsedBeforeAnyTaxIsCharged() (gas: 249631)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 376.50ms (1.02s CPU time)\n\nRan 37 tests for test/NvidiaToken.t.sol:NvidiaTokenTest\n[PASS] testFuzz_cannotSpendMoreThanBalance(uint256,uint256) (runs: 512, μ: 108731, ~: 109172)\nLogs:\n  Bound result 999999999999999999999999997\n  Bound result 3\n\n[PASS] testFuzz_launchFlowsAreExact(uint256,uint8) (runs: 512, μ: 261535, ~: 279722)\nLogs:\n  Bound result 1521\n\n[PASS] testFuzz_splitTransferIsExactAndMonotone(uint256) (runs: 512, μ: 14426, ~: 14161)\nLogs:\n  Bound result 306721909457504203338028079\n\n[PASS] testFuzz_supplyNeverGrows(address,address,uint256) (runs: 512, μ: 159479, ~: 166179)\nLogs:\n  Bound result 7396\n\n[PASS] testFuzz_taxedTransferConservesValue(uint256,uint256) (runs: 512, μ: 214205, ~: 225198)\nLogs:\n  Bound result 1521\n  Bound result 822\n\n[PASS] test_constantsAndLaunchAddresses() (gas: 72402)\n[PASS] test_constructorDoesNotCallTheFactory() (gas: 1019591)\n[PASS] test_constructorRejectsZeroFactory() (gas: 229037)\n[PASS] test_constructorRejectsZeroPoolManager() (gas: 228985)\n[PASS] test_deployScriptFunctionDeploysWithConfig() (gas: 2573701)\n[PASS] test_distributorFlowsAreUntaxedAndCached() (gas: 329127)\n[PASS] test_distributorOfAnotherLaunchIsNotExempt() (gas: 222904)\n[PASS] test_exemptSenderStillNeedsBalance() (gas: 38158)\n[PASS] test_factoryCannotPullFromAHolderWithoutAllowance() (gas: 98642)\n[PASS] test_factoryCannotSendMoreThanSupply() (gas: 38442)\n[PASS] test_factoryInboundIsUntaxed() (gas: 112028)\n[PASS] test_factoryOutboundIsUntaxed() (gas: 106988)\n[PASS] test_factoryWithoutCodeDoesNotBlockTransfers() (gas: 1188328)\n[PASS] test_isExemptReflectsLaunchAddresses() (gas: 141164)\n[PASS] test_malformedFactoryAnswerDoesNotBlockTransfers() (gas: 1257869)\n[PASS] test_metadata() (gas: 40132)\n[PASS] test_mintsWholeSupplyToDeployerOnce() (gas: 23122)\n[PASS] test_noMintOwnerOrAdminEntrypoints() (gas: 422834)\n[PASS] test_ordinaryTransferSplitsThreeWays() (gas: 215778)\n[PASS] test_poolManagerBothWaysIsUntaxed() (gas: 204789)\n[PASS] test_revertingFactoryDoesNotBlockTransfers() (gas: 1294400)\n[PASS] test_runtimeHasNoDelegatecallCallcodeOrSelfdestruct() (gas: 4627164)\n[PASS] test_selfTransferIsTaxed() (gas: 156328)\n[PASS] test_splitTransferMatchesReference() (gas: 9999)\n[PASS] test_tinyAmountsRoundCutsDown() (gas: 254543)\n[PASS] test_transferFromAboveAllowanceReverts() (gas: 143237)\n[PASS] test_transferFromIsTaxedAndSpendsFullAllowance() (gas: 269616)\n[PASS] test_transferFromWithoutAllowanceReverts() (gas: 95643)\n[PASS] test_transferMoreThanBalanceRevertsWithFullAmount() (gas: 101414)\n[PASS] test_transferToZeroReverts() (gas: 88100)\n[PASS] test_tributeRecipientPaysTaxLikeAnyHolder() (gas: 166614)\n[PASS] test_zeroAmountTransferIsAllowedAndFree() (gas: 47558)\nSuite result: ok. 37 passed; 0 failed; 0 skipped; finished in 376.57ms (1.87s CPU time)\n\nRan 28 tests for test/NvidiaToken.adversarial.t.sol:NvidiaTokenAdversarialTest\n[PASS] testFuzz_addingOneRatePeriodAddsExactlyThreeWeiOfTax(uint256) (runs: 1000, μ: 20045, ~: 19771)\nLogs:\n  Bound result 8338\n\n[PASS] testFuzz_insufficientAllowancePreservesAllState(uint256,uint256) (runs: 1000, μ: 1381113, ~: 1382212)\nLogs:\n  Bound result 1\n  Bound result 0\n\n[PASS] testFuzz_previewMatchesActualAndCutsRoundDown(uint256) (runs: 1000, μ: 193419, ~: 198086)\nLogs:\n  Bound result 17684671601\n\n[PASS] testFuzz_rejectedTransferFromPreservesAllState(uint256,uint256) (runs: 1000, μ: 1462323, ~: 1462871)\nLogs:\n  Bound result 3\n  Bound result 41785721441670582149245894567915179652535804124703229\n\n[PASS] testFuzz_roundTripCannotCreateValue(uint256) (runs: 1000, μ: 302005, ~: 310655)\nLogs:\n  Bound result 856514290210573543867985400\n\n[PASS] testFuzz_selfTransferChargesOnlyTheTwoCuts(uint256) (runs: 1000, μ: 246847, ~: 251827)\nLogs:\n  Bound result 17684671601\n\n[PASS] test_approvalIsIsolatedByOwnerAndSpender() (gas: 244897)\n[PASS] test_approvalOverwritesAndRevocationTakesEffectImmediately() (gas: 1617126)\n[PASS] test_approveZeroSpenderRejectsZeroAndMaximum() (gas: 1305783)\n[PASS] test_constructorMintsOnceToActualDeployer() (gas: 1064130)\n[PASS] test_failedTransferFromRollsBackAllowanceAndNewCache() (gas: 1657085)\n[PASS] test_finiteAllowancePersistsAcrossSeveralSpends() (gas: 1616933)\n[PASS] test_fullSupplyTransferBurnsExactlyOnePercent() (gas: 204500)\n[PASS] test_grossAmountMustFitEvenWhenNetFits() (gas: 1334402)\n[PASS] test_infiniteAllowanceIsNotSpentButCanBeRevoked() (gas: 371405)\n[PASS] test_jensenSelfTransferOnlyLosesBurnButSpendsGrossAllowance() (gas: 196171)\n[PASS] test_maximumMinusOneAllowanceIsFinite() (gas: 268095)\n[PASS] test_maximumTransferRevertsForBalanceBeforeTaxArithmetic() (gas: 1422932)\n[PASS] test_netOnlyAllowanceCannotAuthorizeGrossTransfer() (gas: 1374584)\n[PASS] test_oneWeiMovesEvenWhenSenderIsEmptied() (gas: 166309)\n[PASS] test_roundingBoundaryTable() (gas: 90948)\n[PASS] test_selfTransferCannotSpendMoreThanBalance() (gas: 1334436)\n[PASS] test_taxedTransferToTokenContractStillConservesSupply() (gas: 183604)\n[PASS] test_transferFromDoesNotGiveOwnerImplicitAllowance() (gas: 1326639)\n[PASS] test_transferToJensenCreditsNetAndTributeExactlyOnce() (gas: 161827)\n[PASS] test_zeroAmountStillRejectsZeroEndpoints() (gas: 1324529)\n[PASS] test_zeroRecipientRollsBackFiniteAllowanceAndBalances() (gas: 1377350)\n[PASS] test_zeroTransferFromWithoutApprovalOnlyEmitsTransfer() (gas: 1329719)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 376.61ms (1.95s CPU time)\n\nRan 1 test for test/NvidiaToken.invariant.t.sol:NvidiaTokenInvariantTest\n[PASS]\nNvidiaTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToSupply\n[PASS] invariant_distributorCachedOnceKnown\n[PASS] invariant_supplyIsInitialMinusBurned\n[PASS] invariant_tributeRecipientBalanceMatchesModel\n NvidiaTokenInvariantTest invariants (runs: 128, calls: 6144, reverts: 0)\n\n╭-----------------+--------------+-------+---------+----------╮\n| Contract        | Selector     | Calls | Reverts | Discards |\n+=============================================================+\n| TransferHandler | transfer     | 3015  | 0       | 0        |\n|-----------------+--------------+-------+---------+----------|\n| TransferHandler | transferFrom | 3129  | 0       | 0        |\n╰-----------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 4113447896\n  Bound result 1826855018762846987767911\n  Bound result 242\n  Bound result 91\n  Bound result 199\n  Bound result 255\n  Bound result 71\n  Bound result 9\n  Bound result 58\n  Bound result 2602331755307021975566\n  Bound result 45273809422671963212623825\n  Bound result 826074470\n  Bound result 95\n  Bound result 15103537223316390\n  Bound result 6163\n  Bound result 5000000000000000000000000\n  Bound result 65664749514020932582746419\n  Bound result 1652137092\n  Bound result 24223716171029613714375830\n  Bound result 3078\n  Bound result 198\n  Bound result 119824798788248618249534247\n  Bound result 13324649208\n  Bound result 7902\n  Bound result 400\n  Bound result 596\n  Bound result 9\n  Bound result 1\n  Bound result 255\n  Bound result 12331979801045371991030714\n  Bound result 3445\n  Bound result 242\n  Bound result 48173144981237154639577664\n  Bound result 28464015435199542147117630\n  Bound result 4\n  Bound result 100\n  Bound result 198\n  Bound result 1000000000000000000000\n  Bound result 95\n  Bound result 2\n  Bound result 1624968515742488227331191\n  Bound result 42\n  Bound result 5737\n  Bound result 3\n  Bound result 6737\n  Bound result 2000\n  Bound result 1000000000000000000\n  Bound result 89594703296435420987758153\n  Bound result 0\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.28s (1.27s CPU time)\n\nRan 2 tests for test/NvidiaToken.stateful.t.sol:NvidiaTokenStatefulTest\n[PASS]\nNvidiaTokenStatefulTest invariants:\n[PASS] invariant_allowancesMatchPersistentAuthorizations\n[PASS] invariant_discoveryMatchesPublicationAndSuccessfulCalls\n[PASS] invariant_everyHolderMatchesIndependentLedger\n[PASS] invariant_supplyEqualsAllBalancesAndInitialLessBurns\n NvidiaTokenStatefulTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------------------+---------------------+-------+---------+----------╮\n| Contract                | Selector            | Calls | Reverts | Discards |\n+============================================================================+\n| NvidiaTokenStateHandler | approve             | 2054  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | attemptTransferFrom | 2095  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | publishDistributor  | 2003  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | rejectTransfer      | 2072  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | selfTransfer        | 2009  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | setFactoryAvailable | 2025  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | transfer            | 2065  | 0       | 0        |\n|-------------------------+---------------------+-------+---------+----------|\n| NvidiaTokenStateHandler | transferFrom        | 2061  | 0       | 0        |\n╰-------------------------+---------------------+-------+---------+----------╯\n\n[PASS] test_handlerExercisesMeaningfulSuccessAndFailureSequences() (gas: 25632685)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 14.50s (14.51s CPU time)\n\nRan 5 test suites in 14.51s (16.91s CPU time): 78 tests passed, 0 failed, 0 skipped (78 total tests)\n","passed":true},{"durationMs":47,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"NvidiaToken.approve(address,uint256)\",\"NvidiaToken.transfer(address,uint256)\",\"NvidiaToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":3,\"README.md\":128,\"foundry.toml\":32,\"remappings.txt\":2,\"script/DeployNvidiaToken.s.sol\":36,\"src/NvidiaToken.sol\":152,\"test/NvidiaToken.adversarial.t.sol\":374,\"test/NvidiaToken.discovery.t.sol\":205,\"test/NvidiaToken.invariant.t.sol\":149,\"test/NvidiaToken.stateful.t.sol\":113,\"test/NvidiaToken.t.sol\":494,\"test/TESTING.md\":90,\"test/handlers/NvidiaTokenStateHandler.sol\":182,\"test/helpers/NvidiaTokenFixture.sol\":48,\"test/mocks/MockLaunchFactory.sol\":28},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"d3eae206a3d40cf86eb9d57cdab1c23b6c51409881a210591d25cdcb36154c51","verifiedTreeHash":"1e8f4fd1d254a4bf24a2f0d3102a4b40c5fec27b","verifierVersion":"0.1.0+435fe828"}]}