{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"14b042ca-c83f-4ba6-b2a5-12141deeb5d3","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"35d908cec6cd54c327f29fed9fdf73fbba7ef55c1cecc18df1ddc8d9061f29b7","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"b640e6f029195ea9823eafed8f62932a9065523729d647b6cd07c7bef3ff4744","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"7d94aebf0cb0a1fd06322e31485f5ed33768c50a30c6943f014048c34bc138ff","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"4eec95bf719efa56b6abb3f10521bccaa35bd5edc4668a7b012922a7bc5c73c2","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"6cf3fb979a6ec88675cf4e2aeeb6f7c98c1aeb317edbe71b39028e3710d0265c","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"eaa5334de601e98357b3d1dae9a2e7fb36f8b991f221bb0c0f042af9fb02e35d","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"e924fdb2beefcf8082b879a5bb0adf742637fae4def427b19615cf857efd100f","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"c7a9b4baaade37ff971a7edb06d40b707f1e6405904300a8261137ce8aa35868","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Deploy a new IMDeezNutz ($DEEZ) launch on Ethereum mainnet as a univ4_hook custom token paired with $IMD.\n\nUse the existing source from this repository as the base:\nhttps://github.com/identity-md-launches/launch-2225-imdeeznutz\n\nPrevious related job: bf4f5d7a-dffa-470e-a307-591e2bdf8955\n\nRequirements:\n- Keep the existing token, hook, rewards, and liquidity lock logic.\n- Modify the launch so that at least 10,000,000 $DEEZ of the requester’s 2% is sent directly to DeezLiquidityLock and locked in the same transaction as deployment. The remaining portion of the 2% should still go to the requester wallet.\n- Deploy everything on mainnet.\n- Publish all addresses clearly: token, hook, rewards, liquidity lock, pool details, launch tx hashes, and website URL (with real addresses filled into the site config).\n\nToken name: IMDeezNutz\nToken symbol: DEEZ\n\nTotal supply: 1,000,000,000","parentJobId":null,"planHash":"f8aca22c2e449238a372b1e4b68d9cb54e230e1faa7cd4b3fbe604067a39356a","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"14b042ca-c83f-4ba6-b2a5-12141deeb5d3","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2230-imdeeznutz"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"53938","feedbackHash":"0edff2c9644b636319128c257b04acad0752ba4ddbadc54f350b16206542ec29","nodeKey":"audit_economics","submissionHash":"35d908cec6cd54c327f29fed9fdf73fbba7ef55c1cecc18df1ddc8d9061f29b7","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51145","feedbackHash":"43b102a67b5454ae617b5a80dbb58e4c4418fef96c3c1023b630575e178ae6e7","nodeKey":"audit_flow","submissionHash":"b640e6f029195ea9823eafed8f62932a9065523729d647b6cd07c7bef3ff4744","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52191","feedbackHash":"9ae06b9b952c0f5982bd62d3aed30ab2f117d37e9fb912325e24ae35a73022fa","nodeKey":"audit_judge","submissionHash":"e81c81ca35ed57c1d56099268cac5995dff0a2016ca6d6ea32ee46f3b5ec4c24","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52131","feedbackHash":"fdaaed8208ff0e0009e6c7042bee5f953c661ef92ce8dae1ab21e3c014a0c59c","nodeKey":"audit_judge","submissionHash":"7d94aebf0cb0a1fd06322e31485f5ed33768c50a30c6943f014048c34bc138ff","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52139","feedbackHash":"7ae6d6664b4cd1a97da71280fcf6cd47035d71d121b0ebd10edc3cadd7804990","nodeKey":"audit_math","submissionHash":"4eec95bf719efa56b6abb3f10521bccaa35bd5edc4668a7b012922a7bc5c73c2","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52337","feedbackHash":"955e81a1799b9f759b942ed42dc8001d097090b8eb9e308e58a0651d012ae6b4","nodeKey":"audit_permissions","submissionHash":"6cf3fb979a6ec88675cf4e2aeeb6f7c98c1aeb317edbe71b39028e3710d0265c","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"54149","feedbackHash":"791cb98cb4c7ee01496fa0a1bb836e6e0a18854379e5e418acaf1b5f2413f753","nodeKey":"build_contract_project","submissionHash":"ad4550f9662ca62cd426579edca932126bae1790ba8a490b6bd7811faefa7758","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51502","feedbackHash":"643cb63c37532d4c66a7f0613046124b508b232ed12410cda99c1364440b1020","nodeKey":"build_contract_project","submissionHash":"06220ce0b6010e7f03bb2f2d2cdc32b2c2f4c8567c750cf0b3b01839b8748a7c","tag1":"verification:checks","tag2":"acceptance-v2","value":0},{"agentId":"51163","feedbackHash":"8cd6127b926520f3fd2bdb0f85cb90c98ff2b1f4ed7899a8a61bb97223bfe5d4","nodeKey":"build_contract_project","submissionHash":"eaa5334de601e98357b3d1dae9a2e7fb36f8b991f221bb0c0f042af9fb02e35d","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51020","feedbackHash":"6354d3bb4cfef96cc00a15e9b151a7ed2df3b81e40a091dd2403551fb5bdd53b","nodeKey":"manifest","submissionHash":"114059a82a38996b57ce2f9e900052438984c47f24601271f3bc8052ba7bcc94","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51104","feedbackHash":"964ec8988785d1f5d6e32771938789c33952d55246eea469b065835da50cf3fe","nodeKey":"manifest","submissionHash":"e924fdb2beefcf8082b879a5bb0adf742637fae4def427b19615cf857efd100f","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51073","feedbackHash":"ca41af4c3db5b9c7a9de95c5b7d55db0f93ee413eb2e21ad6ec1c53296005636","nodeKey":"write_foundry_tests","submissionHash":"76dbe4f61cff98a9e5036bc0621929a6ded7ae5974b2979f63bcf838a8141642","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52289","feedbackHash":"8b7bb8d6bd17b05d70942052a84dd6cb921d841f19e860fe8317b42415631188","nodeKey":"write_foundry_tests","submissionHash":"c7a9b4baaade37ff971a7edb06d40b707f1e6405904300a8261137ce8aa35868","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"400601e870a0b38ff2834b1efbdf735301d07f358de2feebd2bdf8feb0e46f75","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"9fa2b3951c8b85693dc2dbeed851c7ceddeaecbe61795d892754f244f859b8ae","device":"68fd8dd6450ac70c","findings":[],"hash":"06220ce0b6010e7f03bb2f2d2cdc32b2c2f4c8567c750cf0b3b01839b8748a7c","nodeId":"f5877fbb-c74e-4c24-8293-a23aa08855a6","outcome":"completed","summary":"Repaired the fuzz test’s incorrect assumption about unharvested fee dust. Added regression coverage for zero-share claims, harvest rollback, and recycling. Contract logic is unchanged.\n\nValidation passed:\n\n- `forge build`\n- All 200 Foundry tests with the supplied seed\n- `forge fmt --check`\n- All 13 Python tests\n\nMainnet deployment and address publication remain pending with IMD’s deployment service; no transactions were broadcast.","treeHash":"f9e65ca71cbcef2e9f94e6a9710440db7bf2c666","usage":{"cachedInputTokens":3241856,"inputTokens":201342,"model":"gpt-6-astra","outputTokens":57154,"runtime":"codex","turns":11,"wallClockMs":1775049}},{"artifacts":[],"attempt":1,"bundleHash":"97007e6658db34bcaedca0b943596fdde82ec0ff0aaaceea24f16395f8ff2a90","device":"a31e321b410aaa02","findings":[],"hash":"114059a82a38996b57ce2f9e900052438984c47f24601271f3bc8052ba7bcc94","nodeId":"cb6914e0-1847-484d-9132-0c8914c6f10f","outcome":"completed","summary":"Done. launch.json is written and verified. Only that file changed in the working tree.\n\n**The manifest** lists the four contracts the factory deploys, in constructor dependency order, exactly as the accepted source and README define them:\n\n- `DeezLaunch` takes the requester as `$owner`, the mainnet Uniswap v4 PoolManager, and the $IMD token address.\n- `DeezToken` takes the launcher reference and mints the full supply to it.\n- `DeezRewards` takes the token reference, $IMD, the PoolManager, and the launcher reference.\n- `DeezLiquidityLock` takes the PoolManager and the rewards reference.\n\nDeezHook is deliberately absent. The launcher deploys it with CREATE2 in the requester's launch transaction, which also opens the pool, locks 980,000,000 plus 10,000,000 $DEEZ in the lock, and pays the remaining 10,000,000 to the requester wallet. The notes explain this and stay under the 4,000 character limit.\n\n**Verification performed:**\n\n- Confirmed on Ethereum mainnet through a public RPC that the $IMD address reports symbol IMD with 18 decimals and that the PoolManager address has code.\n- `forge build` succeeds with only lint warnings.\n- `forge test` with the verifier's fuzz seed: 187 passed, 0 failed.\n- A scratch test rehearsed the protected probe: all four contracts deploy in one call from a factory on an empty chain with the manifest's arguments, predictions match, every runtime is under EIP-170, and no DELEGATECALL, CALLCODE or SELFDESTRUCT opcode appears. It also checked the resulting wiring, token name and symbol, and the supply sitting in the launcher.\n- The manifest validated as JSON with only the kind, contracts and notes keys, unique identifiers, string arguments, and backward-only contract references.\n\n**What remains after deployment** is outside this task: the requester mines the hook salt, sends the launch transaction, and fills the site config from the factory record and launch results.","treeHash":"b8b801955ee0e2b1b2ec5585e33b18168798fcda","usage":{"cachedInputTokens":366646,"inputTokens":226,"model":"claude-fable-5-1","outputTokens":7961,"runtime":"claude","turns":16,"wallClockMs":334778}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"01695e9524859621","findings":[{"citation":"resolved","description":"DeezToken mints the whole 1,000,000,000 $DEEZ to DeezLaunch in the factory transaction (src/DeezToken.sol:47 `_mint(launcher_, TOTAL_SUPPLY)`), and the launcher holds it until the requester sends `launch` (a separate, later transaction: the salt is mined off chain after the factory record is known). DeezRewards weights every holder by its average balance over the UTC day (`weightOf`) and divides each day's pot by `eligibleSupplyAt`, which subtracts only the PoolManager, 0x..dEaD, the hook and the distributor itself (src/DeezRewards.sol:167-173); `isExcluded` lists the same four. The launcher is not among them. On the launch day the launcher's weight is TOTAL_SUPPLY * (secondsHeldBeforeLaunch / 1 day), which dwarfs the weight of everyone who actually holds after launch (the requester's 10,000,000 plus whatever buyers bought). The launch day is credited with all fees of the first trading hours (the hook records fees by epoch), so `pot.total * weight / eligibleSupply` leaves most of that pot owed to DeezLaunch. DeezLaunch has no call into `claim` and `claim` requires `msg.sender == account`, so that share is unclaimable; it sits until `recycle` folds it into the pot of epoch launch+91, paying holders of a day three months later. The requester chooses the launch time but cannot avoid this: even a launch at 00:00:00 UTC of a later day leaves the whole first-day pot subject to whatever hours the launcher held that day, and any hour of holding is counted. Economics: launch at 12:00 UTC (factory at 01:00) gives the launcher 458,333,333 token-days of weight against 23.5 million for the requester and a 100 $IMD buyer: live holders can claim 4.9% of the launch-day pot (0.0976 of 2 $IMD in the proof); 95.1% is owed to the launcher. Launch day is normally the highest-fee day of a launch, so the loss to the holders the README promises rewards to is material. Fix (preserves the design): treat the launcher as an excluded address in both places: add `account == launcher` to `isExcluded` and `+ weightOf(launcher, epoch)` to `eligibleSupplyAt` (the `launcher` immutable already exists). Verified: the proof passes with exactly those two changes and fails with only one of them.","line":155,"path":"src/DeezRewards.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test, console} from \"forge-std/Test.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {IUnlockCallback} from \"v4-core/src/interfaces/callback/IUnlockCallback.sol\";\nimport {IHooks} from \"v4-core/src/interfaces/IHooks.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {BalanceDelta} from \"v4-core/src/types/BalanceDelta.sol\";\nimport {SwapParams} from \"v4-core/src/types/PoolOperation.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {DeezLaunch} from \"src/DeezLaunch.sol\";\nimport {DeezToken} from \"src/DeezToken.sol\";\nimport {DeezHook} from \"src/DeezHook.sol\";\nimport {DeezRewards} from \"src/DeezRewards.sol\";\nimport {DeezLiquidityLock} from \"src/DeezLiquidityLock.sol\";\n\ncontract Imd is ERC20 {\n    constructor() ERC20(\"IMD\", \"IMD\") {}\n\n    function mint(address to, uint256 amount) external {\n        _mint(to, amount);\n    }\n}\n\n/// @dev Stands in for the factory: deploys the four application contracts in one call, manifest order.\ncontract Factory {\n    function deployAll(address requester, IPoolManager pm, address imd)\n        external\n        returns (DeezLaunch launcher, DeezToken token, DeezRewards rewards, DeezLiquidityLock lock)\n    {\n        launcher = new DeezLaunch(requester, pm, imd);\n        token = new DeezToken(address(launcher));\n        rewards = new DeezRewards(address(token), imd, address(pm), address(launcher));\n        lock = new DeezLiquidityLock(pm, address(rewards));\n    }\n}\n\n/// @dev Minimal router: exact-input swap paid from its own balance.\ncontract Buyer is IUnlockCallback {\n    IPoolManager public immutable pm;\n\n    constructor(IPoolManager pm_) {\n        pm = pm_;\n    }\n\n    function swap(PoolKey memory key, bool zeroForOne, int256 amountSpecified) external returns (BalanceDelta) {\n        uint160 limit = zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1;\n        return abi.decode(pm.unlock(abi.encode(key, SwapParams(zeroForOne, amountSpecified, limit))), (BalanceDelta));\n    }\n\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        require(msg.sender == address(pm));\n        (PoolKey memory key, SwapParams memory params) = abi.decode(data, (PoolKey, SwapParams));\n        BalanceDelta delta = pm.swap(key, params, \"\");\n        _settle(key.currency0, delta.amount0());\n        _settle(key.currency1, delta.amount1());\n        return abi.encode(delta);\n    }\n\n    function _settle(Currency c, int128 amount) private {\n        if (amount < 0) {\n            pm.sync(c);\n            IERC20(Currency.unwrap(c)).transfer(address(pm), uint256(uint128(-amount)));\n            pm.settle();\n        } else if (amount > 0) {\n            pm.take(c, address(this), uint256(uint128(amount)));\n        }\n    }\n}\n\n/// @notice The launcher holds the whole supply from the factory transaction until `launch`, and `DeezRewards`\n/// does not exclude it. Its average balance over the launch day therefore dominates `eligibleSupplyAt(launchDay)`,\n/// so the holders who actually traded and held on launch day can claim only a small slice of that day's fees;\n/// the rest is owed to a contract that cannot claim and is only recycled 91 days later.\n/// Fails on the current code (holders can claim ~4% of the launch-day pot); passes once the launcher's\n/// pre-launch holding no longer counts as eligible supply (e.g. `isExcluded(launcher)`).\ncontract LauncherWeightTest is Test {\n    address constant REQUESTER = address(0xB045);\n    uint256 constant DAY = 1 days;\n\n    PoolManager pm;\n    Imd imd;\n    DeezLaunch launcher;\n    DeezToken token;\n    DeezRewards rewards;\n    DeezLiquidityLock lock;\n    DeezHook hook;\n    PoolKey key;\n    bool tokenIsCurrency0;\n\n    function setUp() public {\n        // Factory transaction at 01:00 UTC of day E: the supply is minted to the launcher now.\n        uint256 dayStart = (1_700_000_000 / DAY) * DAY;\n        vm.warp(dayStart + 1 hours);\n        pm = new PoolManager(address(this));\n        imd = new Imd();\n        Factory factory = new Factory();\n        (launcher, token, rewards, lock) = factory.deployAll(REQUESTER, IPoolManager(address(pm)), address(imd));\n        tokenIsCurrency0 = address(token) < address(imd);\n    }\n\n    function mineSalt() internal view returns (bytes32) {\n        for (uint256 i = 0; i < 300_000; i++) {\n            address predicted = launcher.hookAddress(bytes32(i), address(token), address(rewards), address(lock));\n            if (uint160(predicted) & ((1 << 14) - 1) == 0x20CC) return bytes32(i);\n        }\n        revert(\"no salt\");\n    }\n\n    function test_launchDayFeesAreMostlyOwedToTheLauncher() public {\n        uint256 epoch = block.timestamp / DAY;\n        // The requester launches at 12:00 UTC of the same day: the launcher held 1,000,000,000 $DEEZ for 11 hours.\n        vm.warp(epoch * DAY + 12 hours);\n        bytes32 salt = mineSalt();\n        vm.prank(REQUESTER);\n        hook = launcher.launch(address(token), address(rewards), address(lock), salt);\n        key = hook.poolKey();\n\n        // A buyer pays 100 $IMD for $DEEZ right after launch: 2 $IMD of fees are recorded against the launch day.\n        Buyer buyer = new Buyer(IPoolManager(address(pm)));\n        imd.mint(address(buyer), 100 ether);\n        buyer.swap(key, !tokenIsCurrency0, -100 ether);\n        assertEq(hook.pendingFeesOf(epoch), 2 ether);\n\n        // The day ends; anyone harvests. The launch-day pot is 2 $IMD.\n        vm.warp((epoch + 1) * DAY + 1);\n        hook.harvest();\n        (uint128 pot,,,) = rewards.pots(epoch);\n        assertEq(pot, 2 ether);\n\n        // Everyone who is not excluded and holds $DEEZ after launch: the requester (10,000,000), the buyer and the\n        // lock's 1 ppm dust. Together they should be able to claim (almost) the whole pot of the day they traded.\n        uint256 claimableByHolders = rewards.claimable(REQUESTER, epoch) + rewards.claimable(address(buyer), epoch)\n            + rewards.claimable(address(lock), epoch);\n        uint256 launcherWeight = rewards.weightOf(address(launcher), epoch);\n        console.log(\"eligible supply (wei-days):\", rewards.eligibleSupplyAt(epoch));\n        console.log(\"launcher weight  (wei-days):\", launcherWeight);\n        console.log(\"pot (wei):\", pot);\n        console.log(\"claimable by live holders (wei):\", claimableByHolders);\n        assertEq(token.balanceOf(address(launcher)), 0, \"the launcher holds nothing after launch\");\n        // The launcher cannot claim: `claim` requires msg.sender == account and the launcher has no such call.\n        assertGe(claimableByHolders, uint256(pot) * 99 / 100, \"launch-day holders can claim the launch-day fees\");\n    }\n}","reproduction":"1. Factory transaction at 01:00 UTC of day E deploys DeezLaunch, DeezToken (mints 1e9 DEEZ to DeezLaunch), DeezRewards, DeezLiquidityLock. 2. At 12:00 UTC of day E the requester calls DeezLaunch.launch(token, rewards, lock, salt): 990,000,000 DEEZ go to the PoolManager via the lock, 10,000,000 to the requester, launcher balance becomes 0. 3. A buyer swaps exact-input 100 IMD for DEEZ: hook.pendingFeesOf(E) == 2e18. 4. At 00:00:01 of day E+1 anyone calls hook.harvest(): pots[E].total == 2e18. 5. Expected: claimable(requester,E) + claimable(buyer,E) + claimable(lock,E) ~= 2e18 (everyone who held after launch). Actual: 97,630,340,007,265,301 wei (0.0976 IMD, 4.9%); rewards.weightOf(DeezLaunch, E) == 458,333,333,333,333,333,333,333,333 of eligibleSupplyAt(E) == 481,855,175,649,809,033,788,714,805. DeezLaunch cannot call claim (NotAccount), so 1.90 IMD of the 2 IMD stays in pot E until recycle(E) at epoch E+91 moves it into pots[E+91].","severity":"high","snippet":"        return account == poolManager || account == BURN_ADDRESS || account == hook || account == address(this)\n            || account == address(0);","title":"Launcher's pre-launch holding of the whole supply counts as eligible supply, so launch-day fees are mostly owed to DeezLaunch (which can never claim) instead of launch-day holders"}],"hash":"35d908cec6cd54c327f29fed9fdf73fbba7ef55c1cecc18df1ddc8d9061f29b7","nodeId":"d224923d-314e-4dbc-aa50-656461f35276","outcome":"completed","summary":"Review complete. The findings file is written and validated, and the source tree is unchanged.\n\n**Result: one substantiated finding (high), with a Foundry proof.**\n\n- **Launch-day fees are mostly owed to DeezLaunch, which can never claim.** The token mints the whole supply to the launcher in the factory transaction, and the launcher holds it until the requester's later `launch` call. DeezRewards weights holders by average balance over the UTC day and subtracts only the PoolManager, the burn address, the hook and itself from the eligible supply, so the launcher's pre-launch hours count as eligible weight. In the proof (factory at 01:00, launch at 12:00, one 100 IMD buy), the launcher carries 458M of 482M token-days and the live holders can claim 0.098 of the 2 IMD launch-day pot. The remainder sits unclaimable until `recycle` hands it to whoever holds 91 days later. The fix that preserves the design is to add the launcher to both `isExcluded` and `eligibleSupplyAt`. I verified the proof passes with exactly those two lines and still fails with only one of them, then restored the source.\n\n**Coverage.** All 18 listed entry points have a row, plus four invariant and periphery rows. Three entry points and one invariant point to finding 1; the rest hold. Specific checks that held in my area: the hook's 2% fee traced through v4 delta accounting on all four swap shapes, the `PartialFill` guard, the `reserved` conservation invariant, the pending-fee claim invariant, the lock's single-sided range placement on both currency orders, the fee-return accounting on top-ups, and the recycle and repeat-claim capping math. I fork-checked the real $IMD token on mainnet: transfers move exact amounts and no pause, blocklist, fee or mint selectors are present, so the harvest-to-credit path cannot be bricked by the pair token. It does have an owner, which I noted as a trust assumption rather than a finding.\n\n**Not reported.** Dust-level effects (per-checkpoint truncation of a wei-day, the lock's 1 ppm residue counting as eligible weight, the second lock event reporting 10M while locking 10M plus the first lock's residue) and design choices that are not defects (fee avoidable via an unhooked pool, sells reverting before any buy, recycle timing being open to anyone).\n\n**Artifacts.** `.imd-findings.json` at the repository root holds the finding, the proof source and the coverage record. The proof is at `test/scratch/LauncherWeight.t.sol` and can be run with `forge test --match-path test/scratch/LauncherWeight.t.sol`. No file outside `test/scratch/` and the findings file was changed.","treeHash":null,"usage":{"cachedInputTokens":1603721,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":50018,"runtime":"claude","turns":39,"wallClockMs":907536}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"079b3bf4557d8811","findings":[{"citation":"resolved","description":"eligibleSupplyAt() subtracts only the PoolManager, burn address, hook and the distributor. DeezToken mints all 1,000,000,000 $DEEZ to DeezLaunch in the factory transaction, and DeezLaunch keeps it until the requester calls launch() in a later transaction. That call needs a hook salt mined against the already-deployed addresses, so a gap is unavoidable. For the launch epoch, DeezLaunch's time-weighted balance (1e9 * gap / 86400 $DEEZ) goes into the eligible supply. DeezLaunch has no claim path, so its share of the pot can never be claimed by anyone. It sits unclaimed until recycle() is allowed 91 epochs later, then goes to an unrelated epoch's holders. Launch day is when trading volume, and so fee income, is highest, and the real holders that day get only a small fraction of it. A 1-hour gap gives DeezLaunch about 41.7M average $DEEZ of weight, against about 10M for the requester, so about 80% of launch-day fees are stranded. With a 12-hour gap about 99% are stranded. The fee-weighting invariant (each holder's share of the pot equals its weight / sum of claimable weights) fails under integer-exact math. Fix: exclude `launcher` (already immutable in DeezRewards) in isExcluded() and in eligibleSupplyAt(). Optionally exclude the liquidity lock as well: it keeps the 1-ppm dust (about 10 $DEEZ) and also cannot claim.","line":170,"path":"src/DeezRewards.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {DeezLaunch} from \"src/DeezLaunch.sol\";\nimport {DeezToken} from \"src/DeezToken.sol\";\nimport {DeezRewards} from \"src/DeezRewards.sol\";\nimport {DeezLiquidityLock} from \"src/DeezLiquidityLock.sol\";\n\ncontract PairToken is ERC20 {\n    constructor() ERC20(\"IMD\", \"IMD\") {}\n    function mint(address to, uint256 amount) external { _mint(to, amount); }\n}\n\ncontract LaunchEpochDilutionTest is Test {\n    address constant REQUESTER = address(0xB0B);\n\n    function _salt(DeezLaunch l, address t, address r, address k) internal view returns (bytes32) {\n        bytes32 h = keccak256(l.hookInitCode(t, r, k));\n        for (uint256 i = 0; i < 400_000; i++) {\n            address p = address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), address(l), bytes32(i), h)))));\n            if (uint160(p) & 0x3FFF == 0x20CC) return bytes32(i);\n        }\n        revert(\"no salt\");\n    }\n\n    /// The factory deploys at the start of a UTC day; the requester calls `launch` 12 hours later. The\n    /// launcher held the whole supply for those 12 hours, is not excluded, and has no claim path, so the\n    /// launch day's pot is split as if 500,000,000 average $DEEZ were eligible holders.\n    function test_launcherBalanceBeforeLaunchDilutesLaunchEpoch() public {\n        vm.warp(20_000 days); // start of epoch 20000\n        PoolManager manager = new PoolManager(address(this));\n        PairToken imd = new PairToken();\n        DeezLaunch launcher = new DeezLaunch(REQUESTER, IPoolManager(address(manager)), address(imd));\n        DeezToken token = new DeezToken(address(launcher));\n        DeezRewards rewards = new DeezRewards(address(token), address(imd), address(manager), address(launcher));\n        DeezLiquidityLock lock = new DeezLiquidityLock(IPoolManager(address(manager)), address(rewards));\n        bytes32 salt = _salt(launcher, address(token), address(rewards), address(lock));\n\n        vm.warp(20_000 days + 12 hours);\n        vm.prank(REQUESTER);\n        launcher.launch(address(token), address(rewards), address(lock), salt);\n\n        // 1,000 $IMD of fees reach the launch-day pot (donation + accrue stands in for harvested swap fees).\n        imd.mint(address(rewards), 1_000 ether);\n        rewards.accrue();\n\n        vm.warp(20_001 days);\n        uint256[] memory epochs = new uint256[](1);\n        epochs[0] = 20_000;\n        // The requester is the only claimable holder of the epoch; it should receive (almost) the whole pot.\n        uint256 paid = rewards.claimable(REQUESTER, 20_000);\n        emit log_named_uint(\"requester claimable (wei)\", paid);\n        emit log_named_uint(\"launcher weight (wei)\", rewards.weightOf(address(launcher), 20_000));\n        emit log_named_uint(\"eligible supply (wei)\", rewards.eligibleSupplyAt(20_000));\n        assertGt(paid, 990 ether, \"launch-day pot diluted by the launcher's pre-launch balance\");\n    }\n}","reproduction":"Warp to 20_000 days (start of epoch 20000). Deploy PoolManager, a pair ERC20, then DeezLaunch(REQUESTER, pm, imd), DeezToken(launcher), DeezRewards(token, imd, pm, launcher) and DeezLiquidityLock(pm, rewards). Warp +12h, and REQUESTER calls launch(token, rewards, lock, minedSalt). Mint 1,000 IMD to rewards and call accrue() (this stands in for harvested launch-day fees). Warp to 20_001 days. rewards.weightOf(launcher, 20000) = 5e26 and eligibleSupplyAt(20000) = 5.05e26. claimable(REQUESTER, 20000) = 9.90 IMD, but REQUESTER is the only claimable holder and should get about 1,000 IMD. The other ~990 IMD stays locked until recycle(20000) at epoch 20091. With the launcher excluded, claimable comes out at about 999.999 IMD and the test passes.","severity":"medium","snippet":"        uint256 excluded = weightOf(poolManager, epoch) + weightOf(BURN_ADDRESS, epoch) + weightOf(hook, epoch)\n            + weightOf(address(this), epoch);","title":"DeezLaunch's pre-launch balance of the whole supply is counted as an eligible holder, stranding most of the launch-day reward pot"}],"hash":"4eec95bf719efa56b6abb3f10521bccaa35bd5edc4668a7b012922a7bc5c73c2","nodeId":"693d323d-93f0-4d68-a631-6e0e7bf25a3f","outcome":"completed","summary":"I found one defect in the math area, a medium. It's written to `.imd-findings.json` with a Foundry proof that I ran and that fails on the current code. The file also has coverage rows for all 18 entry points plus two invariants. I changed no project files and deleted the scratch test after running it.\n\n**Finding 1 (medium): the launcher's pre-launch balance dilutes the launch-day reward pot.** `src/DeezRewards.sol:170`\n- **Cause:** `eligibleSupplyAt()` leaves out only the PoolManager, the burn address, the hook and the rewards contract. `DeezLaunch` holds all 1,000,000,000 $DEEZ from the factory deployment until the requester calls `launch()`. That call is a separate transaction, because it needs a hook salt mined against the addresses already deployed, so there is always a gap.\n- **Effect:** for that gap, `DeezLaunch` counts as a holder in the launch epoch. It has no way to claim, so its share sits unclaimed until `recycle()` is allowed 91 epochs later, and then it goes to an unrelated epoch's holders.\n- **Reproduction:** deploy at the start of a UTC day, call `launch` 12 hours later, then put 1,000 $IMD into that day's pot. The requester is the only holder who can claim, but `claimable` returns 9.90 $IMD. The launcher's weight is 5e26 out of an eligible supply of 5.05e26.\n- **Scale:** a 1-hour gap strands about 80% of launch-day fees; a 12-hour gap strands about 99%.\n- **Fix:** exclude `launcher`, which `DeezRewards` already stores as an immutable, in `isExcluded()` and `eligibleSupplyAt()`. Optionally exclude the liquidity lock too: it keeps about 10 $DEEZ of rounding dust and can't claim either.\n\n**What I checked and found sound:**\n- **Hook fee math:** all four fee cases (exact-in and exact-out buys and sells) against Uniswap v4's delta conventions, plus the `PartialFill` check and the amount minted as fees. Rounding is down and only wei-sized, in the trader's favour.\n- **Liquidity lock:** tick rounding for negative ticks, the single-sided ranges, liquidity size against `uint128` at 980M, the 1-ppm shave, and the principal/fees accounting in `unlockCallback`.\n- **Token history:** the `uint96` and `uint120` casts have wide headroom. Rounding error per balance change is under 1 wei and is absorbed by the cap in `_owed`.\n- **Rewards accounting:** `reserved` never exceeds the contract's balance. `accrue`, `credit`, `recycle` and repeat claims conserve funds. The epoch end boundary is consistent between `hasEnded` and the cumulative lookups.\n- **Launch amounts:** 980M + 10M + 10M equals the total supply, and at least 10M is locked in the launch transaction.\n\n**Leads I dropped:**\n- The `uint128` casts flagged by aderyn only overflow if the $IMD balance exceeds 3.4e38.\n- Fees that round to zero only occur on swaps under 50 wei, where gas costs far more than the fee avoided.\n\n**Outside my area, not filed:** the 10M is locked in the `launch` transaction, which also deploys the hook, not in the factory's deployment transaction. The README explains why this is unavoidable. Whether that meets \"locked in the same transaction as deployment\" is a requirements question for the judge.","treeHash":null,"usage":{"cachedInputTokens":838081,"inputTokens":3262,"model":"claude-opus-5-5","outputTokens":24420,"runtime":"claude","turns":14,"wallClockMs":366704}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"da7ed792c3bf5b80","findings":[{"citation":"resolved","description":"isExcluded enumerates the four addresses that hold $DEEZ but can never earn: the PoolManager, the burn address, the hook and the rewards contract itself. The launcher (DeezLaunch) is a fifth such address and is omitted. DeezToken mints the entire 1,000,000,000 $DEEZ to the launcher in its constructor (DeezToken.sol:406) at factory-deployment time, and the launcher keeps the whole supply until the requester calls launch(). So over the launch epoch the launcher's average balance (weightOf) is enormous (the whole supply for the fraction of the epoch before launch). Because the launcher is not excluded, weightOf(launcher, e) is counted inside eligibleSupplyAt(e) = avgTotalSupply - avg(pool+burn+hook+rewards) (src/DeezRewards.sol:167-173): the launcher's weight sits in the denominator but belongs to no claimable account. DeezLaunch has no claim path (claim requires msg.sender == account, and the launcher is a contract with no forwarding function), so the launcher's pro-rata share of every launch-epoch pot is unclaimable. It is not burned or redistributed to the real holders of that epoch; it only becomes recoverable 90 epochs later via recycle(e), which folds it into the *current* epoch's pot (src/DeezRewards.sol:269-279), paying it to whoever holds $DEEZ ~90 days later rather than to the launch-epoch holders. The launch day is typically the highest-volume day, so this misallocates the bulk of the first epoch's fees. (DeezLiquidityLock, which holds the ~ppm shave, is a lesser instance of the same omission.)","line":155,"path":"src/DeezRewards.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {IHooks} from \"v4-core/src/interfaces/IHooks.sol\";\nimport {IUnlockCallback} from \"v4-core/src/interfaces/callback/IUnlockCallback.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {BalanceDelta} from \"v4-core/src/types/BalanceDelta.sol\";\nimport {SwapParams} from \"v4-core/src/types/PoolOperation.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {DeezLaunch} from \"src/DeezLaunch.sol\";\nimport {DeezToken} from \"src/DeezToken.sol\";\nimport {DeezHook} from \"src/DeezHook.sol\";\nimport {DeezRewards} from \"src/DeezRewards.sol\";\nimport {DeezLiquidityLock} from \"src/DeezLiquidityLock.sol\";\nimport {HookFlags} from \"src/HookFlags.sol\";\n\ncontract PairToken is ERC20 {\n    constructor() ERC20(\"IMD\", \"IMD\") {}\n    function mint(address to, uint256 a) external { _mint(to, a); }\n}\n\ncontract Buyer is IUnlockCallback {\n    IPoolManager immutable m;\n    constructor(IPoolManager m_) { m = m_; }\n    function swap(PoolKey memory key, bool zeroForOne, int256 amt) external {\n        m.unlock(abi.encode(key, zeroForOne, amt));\n    }\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        (PoolKey memory key, bool z, int256 amt) = abi.decode(data, (PoolKey, bool, int256));\n        uint160 limit = z ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1;\n        BalanceDelta d = m.swap(key, SwapParams(z, amt, limit), \"\");\n        _s(key.currency0, d.amount0());\n        _s(key.currency1, d.amount1());\n        return \"\";\n    }\n    function _s(Currency c, int128 a) private {\n        if (a < 0) { m.sync(c); IERC20(Currency.unwrap(c)).transfer(address(m), uint256(uint128(-a))); m.settle(); }\n        else if (a > 0) m.take(c, address(this), uint256(uint128(a)));\n    }\n}\n\ncontract Factory {\n    function deployAll(address req, IPoolManager pm, address imd)\n        external returns (DeezLaunch l, DeezToken t, DeezRewards r, DeezLiquidityLock k)\n    {\n        l = new DeezLaunch(req, pm, imd);\n        t = new DeezToken(address(l));\n        r = new DeezRewards(address(t), imd, address(pm), address(l));\n        k = new DeezLiquidityLock(pm, address(r));\n    }\n}\n\n/// The launcher holds the whole supply from factory deployment until `launch`, is not excluded from rewards and\n/// cannot claim, so it takes most of the launch epoch's fees away from the real holders of that epoch.\ncontract LauncherWeightTest is Test {\n    uint160 constant FLAGS = HookFlags.BEFORE_INITIALIZE | HookFlags.BEFORE_SWAP | HookFlags.AFTER_SWAP\n        | HookFlags.BEFORE_SWAP_RETURN_DELTA | HookFlags.AFTER_SWAP_RETURN_DELTA;\n    address constant REQ = address(0xB045);\n\n    function test_launchEpochFeesReachTheHoldersOfTheLaunchEpoch() public {\n        uint256 E = 20_000;\n        vm.warp(E * 1 days); // factory deploys at the start of epoch E\n        PoolManager manager = new PoolManager(address(this));\n        PairToken imd = new PairToken();\n        (DeezLaunch launcher, DeezToken token, DeezRewards rewards, DeezLiquidityLock lock) =\n            new Factory().deployAll(REQ, IPoolManager(address(manager)), address(imd));\n\n        vm.warp(E * 1 days + 6 hours); // the requester launches six hours later\n        bytes32 salt;\n        for (uint256 i = 0; i < 300_000; i++) {\n            if (HookFlags.matches(launcher.hookAddress(bytes32(i), address(token), address(rewards), address(lock)), FLAGS)) {\n                salt = bytes32(i);\n                break;\n            }\n        }\n        vm.prank(REQ);\n        DeezHook hook = launcher.launch(address(token), address(rewards), address(lock), salt);\n\n        bool t0 = address(token) < address(imd);\n        PoolKey memory key = PoolKey(\n            t0 ? Currency.wrap(address(token)) : Currency.wrap(address(imd)),\n            t0 ? Currency.wrap(address(imd)) : Currency.wrap(address(token)),\n            12_500, 60, IHooks(address(hook))\n        );\n        Buyer buyer = new Buyer(IPoolManager(address(manager)));\n        imd.mint(address(buyer), 1_000 ether);\n        buyer.swap(key, !t0, -1_000 ether); // a buy: 20 $IMD fee in epoch E\n\n        vm.warp((E + 1) * 1 days);\n        uint256 potTotal = hook.pendingFeesOf(E);\n        assertEq(potTotal, 20 ether);\n        uint256 toHolders = rewards.claimable(REQ, E) + rewards.claimable(address(buyer), E);\n        uint256 toLauncher = rewards.claimable(address(launcher), E);\n        emit log_named_uint(\"to holders\", toHolders);\n        emit log_named_uint(\"to launcher (unclaimable)\", toLauncher);\n        // Every wei of the launch epoch's fee should be claimable by the accounts that can claim it.\n        assertGe(toHolders, potTotal * 99 / 100, \"launch-epoch fees diverted to the launcher's weight\");\n    }\n}","reproduction":"Factory deploys the four contracts at the start of epoch E; the whole 1e9 $DEEZ sits in the launcher. The requester calls launch() 6 hours into epoch E (launcher balance goes to 0, requester gets 10,000,000 $DEEZ, PoolManager gets ~990,000,000 $DEEZ as locked liquidity). A buyer swaps 1,000 $IMD into the pool, generating a 20 $IMD fee recorded against epoch E. After epoch E ends: pendingFeesOf(E) = 20 $IMD. claimable(launcher, E) ~= 10.74 $IMD (unclaimable, no claim path), while the sum of claimable(requester,E)+claimable(buyer,E) ~= 9.26 $IMD. Expected: essentially the whole 20 $IMD is claimable by the real holders of epoch E, because the launcher is a transient holder that can never earn. Actual: >50% of the launch-epoch fees are credited to the launcher's weight and are permanently unclaimable by the intended recipients.","severity":"high","snippet":"        return account == poolManager || account == BURN_ADDRESS || account == hook || account == address(this)\n            || account == address(0);","title":"DeezLaunch is not in the rewards exclusion set, so a large share of the launch-epoch fees is diverted to the launcher's weight and stranded"}],"hash":"6cf3fb979a6ec88675cf4e2aeeb6f7c98c1aeb317edbe71b39028e3710d0265c","nodeId":"7380628f-7017-4814-ad4d-be497ac6b784","outcome":"completed","summary":"I wrote `.imd-findings.json`. It has **one high-severity finding**, backed by a Foundry test that fails on the current code, and a coverage row for **all 18** listed entry points. I changed no other files apart from scratch tests under `test/scratch/`, which are allowed.\n\n## Finding 1 (high): launch-day fees go to `DeezLaunch`, which can never claim them\n\n- **Where:** `src/DeezRewards.sol:155`, `isExcluded`.\n- **Cause:** The rewards contract excludes the addresses that hold $DEEZ but can never earn: the PoolManager, the burn address, the hook and the rewards contract itself. `DeezLaunch` is missing from that list, but it is the same kind of holder. `DeezToken` mints the whole 1,000,000,000 supply to it when the factory deploys, and it keeps all of it until the requester calls `launch()`.\n- **Effect:** For the launch day, the launcher's average balance is counted in the total that fees are split across. The launcher has no way to claim: `claim` requires `msg.sender == account`, and the launcher has no function that could make that call. So its share of the launch-day fees sits unpaid. After 90 days, `recycle` adds it to whatever day is current then, so it goes to whoever holds $DEEZ at that point, not to the holders of launch day. Launch day is usually the busiest trading day.\n- **How to reproduce:**\n  1. The factory deploys at the start of day E.\n  2. The requester calls `launch` 6 hours later.\n  3. Someone buys with 1,000 $IMD, which creates a 20 $IMD fee.\n  4. After day E ends, the requester and buyer together can claim **about 9.26 $IMD**. **About 10.74 $IMD** is credited to the launcher and nobody can claim it. Expected: the holders who can claim get at least 99% of the fee.\n- **Proof:** `test/scratch/LauncherWeight.t.sol`, embedded in the JSON. Running `forge test --match-path` on it fails for exactly this reason.\n- **Suggested fix:** Add `launcher` to `isExcluded` and to the excluded total in `eligibleSupplyAt`. `DeezLiquidityLock`, which holds the small leftover from the liquidity add, should arguably be excluded too.\n\n## Coverage\n- **Finding:** `DeezRewards.claim` and `DeezRewards.finalize`. `finalize` stores the eligible total that still includes the launcher's balance.\n- **Holds:** everything else.\n  - `setHook` can only be called by the launcher, only once, and only with a hook that points back to this rewards contract.\n  - `credit` can only be called by the hook.\n  - The hook's and the lock's callbacks only accept calls from the PoolManager, and the hook serves exactly one pool.\n  - `launch` can only be called by the requester, only once, and it checks the three contracts it is given.\n  - The functions anyone can call (`lock`, `lockAs`, `harvest`, `harvestEpochs`, `accrue`, `recycle`) are meant to be open. I traced them and found no access gap.\n  - The token functions are standard OpenZeppelin ERC-20 with no admin powers added.\n\n## Leads I checked and ruled out\n- Someone sending tokens to the lock before launch can't change how launch locks the liquidity, because it sets the position type explicitly and ignores the other token.\n- Nobody can front-run the hook deployment, because only the launcher can deploy to that address.\n- Several static-analysis warnings (reentrancy, unsafe casting) didn't lead to a reproducible problem in permissions.","treeHash":null,"usage":{"cachedInputTokens":1085058,"inputTokens":36,"model":"claude-opus-5-5","outputTokens":24994,"runtime":"claude","turns":20,"wallClockMs":1091327}},{"artifacts":[],"attempt":1,"bundleHash":"c965d655e9caa2c64d06f5c45b7f40b52aef299f34f0df29ce5a7f2fdadb385b","device":"43eaeedfc1287bf1","findings":[{"description":"The brief requires at least 10,000,000 DEEZ of the requester allocation to reach DeezLiquidityLock and be locked in the same transaction as deployment. The application constructors only record dependencies and mint the entire supply to DeezLaunch. Hook deployment, pool initialization, liquidity locking and the requester payout occur exclusively in the later launch() call (lines 109-146), which accepts only msg.sender == requester. A factory deployment cannot complete this through the current constructor sequence, and an ordinary factory follow-up call is rejected by NotRequester. Thus deployment leaves 1,000,000,000 DEEZ in DeezLaunch, zero DEEZ or liquidity in the lock, no hook, and no requester payout. Successful tests of a subsequent launch() do not establish the required deployment atomicity. Complete deployment and the required allocation atomically, preserving the authorized requester and pool parameters.","line":94,"path":"src/DeezLaunch.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {DeezLaunch} from \"src/DeezLaunch.sol\";\nimport {DeezToken} from \"src/DeezToken.sol\";\nimport {DeezRewards} from \"src/DeezRewards.sol\";\nimport {DeezLiquidityLock} from \"src/DeezLiquidityLock.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract AtomicityPair is ERC20 {\n    constructor() ERC20(\"Test IMD\", \"IMD\") {}\n}\n\ncontract AtomicityDeploymentFactory {\n    function deployAll(address requester, IPoolManager manager, address pair)\n        external returns (DeezLaunch launch, DeezToken token, DeezRewards rewards, DeezLiquidityLock liquidityLock)\n    {\n        launch = new DeezLaunch(requester, manager, pair);\n        token = new DeezToken(address(launch));\n        rewards = new DeezRewards(address(token), pair, address(manager), address(launch));\n        liquidityLock = new DeezLiquidityLock(manager, address(rewards));\n    }\n}\n\ncontract DeploymentAtomicityProof is Test {\n    function test_deploymentMustAlreadyCustodyTheRequesterAllocationInTheLock() public {\n        address requester = makeAddr(\"requester\");\n        PoolManager manager = new PoolManager(address(this));\n        AtomicityPair pair = new AtomicityPair();\n        AtomicityDeploymentFactory factory = new AtomicityDeploymentFactory();\n        // Exactly one call for the full application-deployment transaction. No transient-state assumptions\n        // and no later call impersonating the requester to complete deployment.\n        (DeezLaunch launch, DeezToken token,, DeezLiquidityLock liquidityLock) =\n            factory.deployAll(requester, IPoolManager(address(manager)), address(pair));\n        uint256 lockedPrincipal = address(token) < address(pair)\n            ? liquidityLock.totalLocked0() : liquidityLock.totalLocked1();\n        // Includes rounding dust still held by the lock: the requirement fails even under this weaker bound.\n        assertGe(\n            lockedPrincipal + token.balanceOf(address(liquidityLock)),\n            launch.LOCKED_REQUESTER_SHARE(),\n            \"deployment left the requester's locked allocation outside DeezLiquidityLock\"\n        );\n        assertEq(token.balanceOf(requester), launch.PAID_REQUESTER_SHARE());\n        assertTrue(launch.launched());\n    }\n}","reproduction":"Run the self-contained proof under test/scratch/DeploymentAtomicityProof.t.sol with forge test --match-path test/scratch/DeploymentAtomicityProof.t.sol -vvv. A helper deploys DeezLaunch, DeezToken, DeezRewards and DeezLiquidityLock in one external call, with a real local PoolManager and a test pair ERC20. Immediately after that deployment call the test expects locked principal plus lock-held rounding dust to be at least 10,000,000e18. Actual result is 0, failing assertGe with 0 < 10000000000000000000000000. No fork, ffi, environment values, or out-of-band requester launch call are used. The failure was reproduced locally. The subsequent assertions also require the remainder paid to the requester and launched == true.","severity":"high","title":"Application deployment does not lock the requester allocation; a separate requester transaction is required"}],"hash":"76dbe4f61cff98a9e5036bc0621929a6ded7ae5974b2979f63bcf838a8141642","nodeId":"7936ebc9-2549-42de-800b-5c2cfecafdea","outcome":"completed","summary":"Added failure-path tests and stateful invariants. `forge build` and all **212 tests pass** with the required seed.\n\nReported a **high-severity defect** in `.imd-findings.json`, with a reproduced failing proof: locking requires a separate requester transaction after deployment. Production contracts and configuration remain unchanged.","treeHash":"6769f7c99599f15d0de419951b275c1377a74607","usage":{"cachedInputTokens":2656000,"inputTokens":121904,"model":"gpt-6-astra","outputTokens":31231,"runtime":"codex","turns":8,"wallClockMs":955646}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"de319b702da6aa2e","findings":[],"hash":"7d94aebf0cb0a1fd06322e31485f5ed33768c50a30c6943f014048c34bc138ff","nodeId":"24cb6421-5f97-420a-a245-11635a71fbca","outcome":"completed","summary":"The fix for my high finding works. The other two items from last round are resolved as documented trust assumptions, and I found no new defect I could reproduce. `.imd-findings.json` has an empty findings list and a coverage row for each of the 18 entry points, all `holds`, plus one invariant row.\n\n**What I raised last round:**\n- **[high] DeezLaunch's pre-launch holding diluted the launch-day rewards: fixed.** `src/DeezRewards.sol` now excludes the `launcher` from rewards (`isExcluded`, lines 158–161) and subtracts its holding from the eligible supply (`eligibleSupplyAt`, lines 171–177). I copied all four proofs that reported this into `test/scratch/` and ran them; all four pass now. I confirmed in the code that the launcher's `claim` reverts with `Excluded` and that `claimable` returns 0 for it.\n- **[low] `launch()` accepts a complete look-alike token set: settled as a trust assumption.** The author is right that pinning DeezToken's code hash can't work, because its immutables (`mintedAt`, `launcher`) make the deployed code differ per deployment. The comments in `DeezLaunch.sol` now accurately say the check is consistency only. The README makes checking `token()`, `rewards()` and `liquidityLock()` against the factory's record a required step before anything is published. Only the requester can trigger this, and it only hurts their own launch. I dropped the matching info item from the test writer as part of this.\n- **[info] The 10,000,000 $DEEZ is locked in the launch transaction, not the factory's deployment transaction: acknowledged.** The test writer's proof still fails (`0 < 10000000000000000000000000`), as expected. The factory only runs constructors, and those can't open a v4 pool or deploy the hook at its required address. The reading is now written down in the README and `launch.json`. Inside `launch()` the 10,000,000 is locked (`DeezLaunch.sol:146-147`) before the other 10,000,000 is paid (line 149). No code change can meet the literal wording in this launch mode, so the requester has to decide whether the launch transaction is acceptable.\n- **The test writer's lock-dust item: dropped.** The lock holds about 10 $DEEZ of leftover dust, about 2e-7 of a day's rewards; that share is recycled after 90 days and the README documents it.\n\n**Tests:** the full suite ran 223 passing and 1 failing, the deployment-transaction proof above.\n\n**Repo state:** I deleted `test/scratch/` after use. The repo root has untracked files I didn't create: `.bashrc`, `.profile`, `.gitconfig`, `.claude/`, `.vscode`, `.idea` and others. I left them alone, but they shouldn't go into a submission.","treeHash":null,"usage":{"cachedInputTokens":667607,"inputTokens":18,"model":"claude-opus-5-5","outputTokens":8344,"runtime":"claude","turns":14,"wallClockMs":304705}},{"artifacts":[],"attempt":2,"bundleHash":"f9393ad0f6e6491e2f2c071a203255368966be8103ec52b994dcac541f63f81d","device":"06d00e98fbdd1ee9","findings":[],"hash":"ad4550f9662ca62cd426579edca932126bae1790ba8a490b6bd7811faefa7758","nodeId":"f5877fbb-c74e-4c24-8293-a23aa08855a6","outcome":"completed","summary":"Work is complete and verified locally. Here is the recap.\n\n**What was built**\n\nThe repository now holds a Foundry project at the root with the IMDeezNutz launch rebuilt for the `evm_contracts` launch mode. The token, hook, rewards and liquidity lock keep the previous launch's logic. A new `DeezLaunch` contract finishes the launch in one transaction.\n\n- **Factory deploys four contracts** in order: `DeezLaunch` (requester `$owner`, mainnet PoolManager, $IMD), `DeezToken` (mints the full supply to the launcher), `DeezRewards` and `DeezLiquidityLock`. All constructors are static, call nothing, and fit EIP-170.\n- **`DeezLaunch.launch`** is requester-only and runs once. It deploys the hook with a mined CREATE2 salt, records it in the distributor, opens the pool at 2,500 $IMD for the whole supply, locks 980,000,000 $DEEZ plus 10,000,000 $DEEZ of the requester's 2% in `DeezLiquidityLock`, and sends the other 10,000,000 $DEEZ to the requester wallet. A wrong salt or impostor address reverts the whole transaction.\n- **Why requester-gated:** the launcher must be deployed before the contracts that name it, so it cannot learn their addresses authentically on chain. The requester reads them from the launch record. This is documented as a trust assumption in the README.\n- **Static analysis faults removed:** `bytes.concat` replaces `abi.encodePacked` for the init code, the token history is written directly, floor-to-spacing uses a remainder, no strict equalities on balances or timestamps, and every external return value is consumed and checked.\n\n**Verification**\n\n| Check | Result |\n|---|---|\n| `forge build` | passes, no compiler warnings |\n| `forge test` with the verifier's fuzz seed | 187 passed, 0 failed |\n| `forge fmt --check` | passes |\n\nOne upstream fuzz test needed a fix: with a 1 wei late fee nobody can claim, so nothing harvested it. The test now harvests explicitly, as anyone may.\n\n**Deliverables for publishing**\n\nThe README lists manifest arguments per contract, the launch steps, the salt-mining command in `script/MineHookSalt.s.sol`, after-launch responsibilities, and all chosen constants. The site config in `site/deez.config.js` has the real $IMD and PoolManager addresses filled and blank fields for everything the factory and launch transactions will produce, so no address is invented.\n\n**Left out, and why**\n\n- Slither is not installed on this machine, so the findings were addressed by design rather than re-run. The README records each pattern and its fix.\n- No deployment, broadcast or `launch.json` was done. IMD's deployer launches the contracts, and the manifest step writes the manifest.\n- The nested `.gitmodules` files inside `lib/v4-core` and `lib/openzeppelin-contracts` could not be deleted because the sandbox mounts them read-only. They are ordinary files with no `.git` directories, so no submodule exists.","treeHash":"973f7c2efd89ec396ec95130ba797c635bc191e6","usage":{"cachedInputTokens":3481068,"inputTokens":834,"model":"claude-fable-5-1","outputTokens":101516,"runtime":"claude","turns":45,"wallClockMs":1739870}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"3b9f88f55251764d","findings":[{"citation":"resolved","description":"The factory deploys DeezToken in one transaction, minting 1,000,000,000 $DEEZ to DeezLaunch, and the requester calls DeezLaunch.launch in a later transaction (the hook salt is mined off chain between the two). For every second between the mint and the launch the launcher holds 100% of the supply, and DeezToken's checkpoints integrate that holding into weightOf(launcher, epoch). eligibleSupplyAt (src/DeezRewards.sol:167-173) subtracts only the PoolManager, the burn address, the hook and the distributor itself, and isExcluded (src/DeezRewards.sol:154-157) lists the same four, so the launcher's token-days stay in the denominator of every launch-day share. DeezLaunch has no code path that calls claim and claim requires msg.sender == account, so the launcher's share of the launch-day pot is unclaimable; it sits in pots[launchEpoch] until recycle folds it into the pot of launchEpoch + 91, where it is paid to whoever holds $DEEZ on that later day. The fraction misdirected equals the launcher's token-days over the eligible token-days of the epoch: with a launch twelve hours after the factory transaction it is ~97% of the launch day's fees (launcher 500M token-days versus ~14M for the requester and buyers); with a launch one hour after it on a day with 10 hours of trading left, still ~70%. The launch day is the heaviest fee day of a launch and the only day affected, since the launcher holds nothing afterwards. The previous launch had no such window because the factory minted and seeded in one transaction; the DeezLaunch two-transaction design introduced it. The test suite does not catch it because every rewards test uses the test contract as the launcher and treats it as an ordinary claiming holder (test/DeezRewards.t.sol test_deployerShareIsProportionalToo), and DeezLaunch.t.sol never claims. DeezLiquidityLock is in the same position (it holds the ~990 $DEEZ shave dust and anything sent to it, and can never claim), but its weight is dust. Minimal fix preserving the design: DeezRewards already stores `launcher`; add `account == launcher` to isExcluded and `+ weightOf(launcher, epoch)` to eligibleSupplyAt (the attached test passes with exactly that change). Alternatively exclude the lock as well.","line":170,"path":"src/DeezRewards.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {IUnlockCallback} from \"v4-core/src/interfaces/callback/IUnlockCallback.sol\";\nimport {IHooks} from \"v4-core/src/interfaces/IHooks.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {BalanceDelta} from \"v4-core/src/types/BalanceDelta.sol\";\nimport {SwapParams} from \"v4-core/src/types/PoolOperation.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {DeezLaunch} from \"src/DeezLaunch.sol\";\nimport {DeezToken} from \"src/DeezToken.sol\";\nimport {DeezHook} from \"src/DeezHook.sol\";\nimport {DeezRewards} from \"src/DeezRewards.sol\";\nimport {DeezLiquidityLock} from \"src/DeezLiquidityLock.sol\";\n\ncontract ImdMock is ERC20 {\n    constructor() ERC20(\"IMD\", \"IMD\") {}\n\n    function mint(address to, uint256 amount) external {\n        _mint(to, amount);\n    }\n}\n\n/// @dev Stands in for the factory: deploys the four manifest contracts in one call, in manifest order.\ncontract FactoryStandIn {\n    function deployAll(address requester, IPoolManager poolManager, address imd)\n        external\n        returns (DeezLaunch launcher, DeezToken token, DeezRewards rewards, DeezLiquidityLock lock)\n    {\n        launcher = new DeezLaunch(requester, poolManager, imd);\n        token = new DeezToken(address(launcher));\n        rewards = new DeezRewards(address(token), imd, address(poolManager), address(launcher));\n        lock = new DeezLiquidityLock(poolManager, address(rewards));\n    }\n}\n\n/// @dev Minimal router: exact-input swap paid from its own balances.\ncontract Router is IUnlockCallback {\n    IPoolManager public immutable manager;\n\n    constructor(IPoolManager manager_) {\n        manager = manager_;\n    }\n\n    function swap(PoolKey memory key, bool zeroForOne, int256 amountSpecified) external returns (BalanceDelta) {\n        uint160 limit = zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1;\n        bytes memory out = manager.unlock(abi.encode(key, SwapParams(zeroForOne, amountSpecified, limit)));\n        return abi.decode(out, (BalanceDelta));\n    }\n\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        require(msg.sender == address(manager), \"not manager\");\n        (PoolKey memory key, SwapParams memory params) = abi.decode(data, (PoolKey, SwapParams));\n        BalanceDelta delta = manager.swap(key, params, \"\");\n        _settle(key.currency0, delta.amount0());\n        _settle(key.currency1, delta.amount1());\n        return abi.encode(delta);\n    }\n\n    function _settle(Currency currency, int128 amount) private {\n        if (amount < 0) {\n            uint256 owed = uint256(uint128(-amount));\n            manager.sync(currency);\n            IERC20(Currency.unwrap(currency)).transfer(address(manager), owed);\n            manager.settle();\n        } else if (amount > 0) {\n            manager.take(currency, address(this), uint256(uint128(amount)));\n        }\n    }\n}\n\n/// @notice The factory deploys the four contracts at the start of a UTC day; the requester mines the salt and\n/// launches twelve hours later, in the same epoch. All trading of the launch day happens after the launch.\n/// `DeezLaunch` held the whole supply for the first half of the day and is not excluded from `eligibleSupplyAt`,\n/// so it carries ~99% of the day's weight, can never claim, and the launch-day holders get ~1% of the pot.\ncontract LauncherWeightTest is Test {\n    uint160 internal constant FLAGS = (1 << 13) | (1 << 7) | (1 << 6) | (1 << 3) | (1 << 2);\n    address internal constant REQUESTER = address(0xB045);\n    uint256 internal constant EPOCH = 1 days;\n\n    PoolManager internal manager;\n    ImdMock internal imd;\n    DeezLaunch internal launcher;\n    DeezToken internal token;\n    DeezRewards internal rewards;\n    DeezLiquidityLock internal lock;\n    DeezHook internal hook;\n    PoolKey internal key;\n    bool internal tokenIsCurrency0;\n\n    function setUp() public {\n        uint256 epochStart = 20_000 * EPOCH; // first second of epoch 20,000\n        vm.warp(epochStart);\n        manager = new PoolManager(address(this));\n        imd = new ImdMock();\n        FactoryStandIn factory = new FactoryStandIn();\n        (launcher, token, rewards, lock) = factory.deployAll(REQUESTER, IPoolManager(address(manager)), address(imd));\n        tokenIsCurrency0 = address(token) < address(imd);\n\n        // The requester launches twelve hours later, in the same epoch.\n        vm.warp(epochStart + 12 hours);\n        bytes32 salt;\n        for (uint256 i = 0; i < 300_000; i++) {\n            address predicted = launcher.hookAddress(bytes32(i), address(token), address(rewards), address(lock));\n            if (uint160(predicted) & ((1 << 14) - 1) == FLAGS) {\n                salt = bytes32(i);\n                break;\n            }\n        }\n        vm.prank(REQUESTER);\n        hook = launcher.launch(address(token), address(rewards), address(lock), salt);\n        key = hook.poolKey();\n    }\n\n    function test_launchDayHoldersGetTheLaunchDayFees() public {\n        uint256 epoch = rewards.currentEpoch();\n        assertEq(epoch, 20_000);\n        assertEq(token.balanceOf(address(launcher)), 0, \"the launcher holds nothing after the launch\");\n\n        // The launch day's trading: a buyer pays 50 $IMD for $DEEZ; the hook keeps 2% = 1 $IMD for the epoch.\n        Router buyer = new Router(IPoolManager(address(manager)));\n        imd.mint(address(buyer), 50 ether);\n        buyer.swap(key, !tokenIsCurrency0, -50 ether);\n        uint256 pot = hook.pendingFeesOf(epoch);\n        assertEq(pot, 1 ether);\n\n        // The day ends. The only non-excluded $DEEZ holders of the day are the requester (10,000,000 $DEEZ for\n        // the last twelve hours), the buyer (a few thousand $DEEZ for seconds) and the lock's shave dust.\n        vm.warp((epoch + 1) * EPOCH);\n        uint256 requesterWeight = rewards.weightOf(REQUESTER, epoch);\n        uint256 buyerWeight = rewards.weightOf(address(buyer), epoch);\n        uint256 lockWeight = rewards.weightOf(address(lock), epoch);\n        uint256 launcherWeight = rewards.weightOf(address(launcher), epoch);\n        assertEq(requesterWeight, 10_000_000 ether / 2, \"ten million for half a day\");\n        assertEq(launcherWeight, 1_000_000_000 ether / 2, \"the launcher held the whole supply for half a day\");\n\n        uint256[] memory epochs = new uint256[](1);\n        epochs[0] = epoch;\n        vm.prank(REQUESTER);\n        uint256 paid = rewards.claim(REQUESTER, epochs);\n        vm.prank(address(buyer));\n        paid += rewards.claim(address(buyer), epochs);\n\n        // Expected: the launch day's holders together receive the launch day's fees (minus the lock's dust share,\n        // well under 0.1%). Actual: ~1%, the rest is attributed to the launcher, which can never claim, and is\n        // only recycled into the pot of epoch 20,091 for whoever holds $DEEZ then.\n        uint256 expectedFloor = pot * (requesterWeight + buyerWeight) / (requesterWeight + buyerWeight + lockWeight);\n        assertGe(paid, expectedFloor - 1, \"launch-day holders are paid the launch-day pot\");\n    }\n}","reproduction":"1. At t0 = 20000 days (the first second of epoch 20000) deploy PoolManager, a mock $IMD, then as the factory: DeezLaunch(requester, pm, imd), DeezToken(launcher), DeezRewards(token, imd, pm, launcher), DeezLiquidityLock(pm, rewards). The token mints 1e27 to the launcher at t0.\n2. At t0 + 12h the requester mines the salt and calls launcher.launch(token, rewards, lock, salt). 990M $DEEZ go to the PoolManager via the lock, 10M to the requester.\n3. A buyer swaps 50 $IMD exact-input for $DEEZ in the same second: hook.pendingFeesOf(20000) == 1e18.\n4. Warp to (20001) * 1 days. weightOf(requester, 20000) == 5e24 (10M for half a day), weightOf(launcher, 20000) == 5e26 (the whole supply for half a day); eligibleSupplyAt(20000) = 1e27 - weightOf(pm) = ~5.15e26.\n5. The requester and the buyer each call rewards.claim(self, [20000]).\nExpected: together they receive the whole 1e18 pot minus the lock's dust share (>= 0.9999e18), since they are the only holders of the day who can claim.\nActual: they receive 28064602920915183 wei (2.8% of the pot); 971935397079084817 wei is attributed to DeezLaunch, is unclaimable, and can only be recycled into epoch 20091 by anyone calling recycle(20000) after day 20091 starts. The test test/scratch/LauncherWeight.t.sol fails with `28064602920915183 < 999999653645446863` on this code and passes once `launcher` is added to isExcluded and eligibleSupplyAt.","severity":"high","snippet":"        uint256 excluded = weightOf(poolManager, epoch) + weightOf(BURN_ADDRESS, epoch) + weightOf(hook, epoch)\n            + weightOf(address(this), epoch);","title":"DeezLaunch holds the whole supply before launch but is not excluded from reward weights: most of the launch day's fees are attributed to an address that can never claim"},{"citation":"resolved","description":"The README and the launch natspec state that the requester \"chooses nothing but the moment and the mined salt\" and that the three addresses \"are checked to be the ones deployed for this launcher\". _check (src/DeezLaunch.sol:181-198) only reads values the passed contracts report about themselves: token.launcher(), token.balanceOf(launcher), rewards.launcher()/token()/rewardToken()/poolManager()/hook(), lock.poolManager()/rewards(). A token, a DeezRewards and a DeezLiquidityLock that the requester deploys with the launcher's address as `launcher_` satisfy every check, and the existing test (test/DeezLaunch.t.sol test_launchRefusesContractsThatAreNotItsOwn) only shows that a fake token is refused when paired with the real DeezRewards. This is a requester-privileged action, so it is reported as a trust assumption with a concrete mechanism rather than an exploit: the requester is the beneficiary of the launch and would mainly be hurting their own launch. The consequences for others are that the factory-recorded DeezToken (the address the launch record and site publish) can never trade, since its entire supply sits in DeezLaunch with launched == true and no other transfer path, and that the reviewed launcher's `Launched` event and `token()` getter name an unreviewed token (in the repro, one with a mint function). The deployment handoff mitigates this if the publisher cross-checks DeezLaunch.token() against the factory record before publishing. A contract-level fix would need the launcher to know the factory's addresses, which the manifest order (DeezLaunch first) does not allow; the cheapest guard is to verify in `launch` that `DeezToken(token_)` has the expected creation-code hash via `extcodehash` against a constant, or to document the publisher cross-check as a required step.","line":184,"path":"src/DeezLaunch.sol","reproduction":"1. Factory deploys DeezLaunch(requester, pm, imd), DeezToken(launcher), DeezRewards(realToken, imd, pm, launcher), DeezLiquidityLock(pm, realRewards).\n2. The requester deploys FakeToken(launcher) (an ERC-20 with launcher() == DeezLaunch, 1e27 minted to DeezLaunch and an owner-only mint), DeezRewards(fake, imd, pm, launcher) and DeezLiquidityLock(pm, fakeRewards), mines a salt for launcher.hookAddress(salt, fake, fakeRewards, fakeLock) and calls launcher.launch(fake, fakeRewards, fakeLock, salt).\nExpected (per the natspec): revert with WrongToken / WrongRewards / WrongLiquidityLock.\nActual: the call succeeds; launcher.token() == fake, launcher.launched() == true, the real DeezToken still reports balanceOf(launcher) == 1e27 with no path out, and the pool, hook and 10M payout are all on the fake token. Verified with a scratch test (test/scratch/Impostor.t.sol, not attached as proof because the finding is low).","severity":"low","snippet":"        if (DeezToken(token_).launcher() != address(this)) revert WrongToken(token_);\n        uint256 held = IERC20(token_).balanceOf(address(this));\n        if (held < TOTAL_SUPPLY) revert SupplyNotHere(held);","title":"DeezLaunch._check verifies self-consistency of the passed contracts, not identity: the requester can launch a substitute token/rewards/lock set and strand the real supply in the launcher"}],"hash":"b640e6f029195ea9823eafed8f62932a9065523729d647b6cd07c7bef3ff4744","nodeId":"9db1270c-488d-46e2-b792-82147aab507d","outcome":"completed","summary":"The review is complete and the findings file is written and validated.\n\n**Outcome.** One high finding with a failing Foundry proof, one low trust-assumption finding, and a coverage record for all 18 entry points plus two invariants, in `.imd-findings.json`. The working tree is clean. Only `test/scratch/` holds my two scratch tests, which is gitignored and reserved for this purpose.\n\n**Finding 1 (high, with proof).** The factory mints the whole supply to `DeezLaunch` in one transaction, and the requester launches in a later one after mining the hook salt. For that gap the launcher holds 100% of `$DEEZ`, its token-days are integrated by the token's checkpoints, and `DeezRewards` excludes only the PoolManager, burn address, hook and itself. The launcher can never call `claim`, so its share of the launch-day pot is stranded until `recycle` hands it to whoever holds on day 91. The proof test deploys at the start of a day, launches twelve hours later, trades once, and shows the day's only claimable holders receive 2.8% of the pot instead of essentially all of it. The test passes with the minimal fix of adding the already-stored `launcher` to `isExcluded` and `eligibleSupplyAt`. The existing suite misses this because every rewards test uses the test contract as the launcher and treats it as an ordinary claimant.\n\n**Finding 2 (low).** The launcher's checks read only what the passed contracts say about themselves. A requester-deployed fake token, a `DeezRewards` built on it, and a lock built on that pass every check, launching an unreviewed token and stranding the real supply in the launcher forever. This is requester-privileged, so it is reported as a trust assumption with a verified mechanism, not an exploit.\n\n**What held.** The hook's fee math on all four swap shapes against the v4 delta flow, claim minting and burning, harvest ordering and `reserved` accounting, the lock's tick rounding, single-sided ranges, 1 ppm shave and fee-credit netting, the token's checkpoint arithmetic and bounds, and the opening-price computation on both currency orders. The full existing suite passes.\n\n**Open item, not a finding.** I confirmed the mainnet `$IMD` address has code, symbol `IMD` and a supply far below the `uint128` truncation threshold, but I could not verify its transfer semantics. A fee-on-transfer or blocklisting behavior would make `credit` revert with `Unfunded` and the lock's `_settle` revert with `SettleMismatch`.","treeHash":null,"usage":{"cachedInputTokens":2471073,"inputTokens":610,"model":"claude-fable-5-1","outputTokens":48515,"runtime":"claude","turns":39,"wallClockMs":797202}},{"artifacts":[],"attempt":1,"bundleHash":"3f9e466fce8b411a27594940fb1f6c4fc63b6a1495ca3b32597f98f9e8e4598f","device":"ee9fbaf2480d1034","findings":[{"description":"The brief requires at least 10,000,000 $DEEZ of the requester's 2% to be sent to DeezLiquidityLock and locked in the same transaction as deployment. The constructors (DeezLaunch, DeezToken, DeezRewards, DeezLiquidityLock) only mint the full supply into DeezLaunch. The lock happens only in DeezLaunch.launch(), which is a separate transaction that only the requester can send. Until the requester sends it, the whole supply, including the 2%, sits unlocked in DeezLaunch, and nobody else can complete the launch. The revision only changed comments and the rewards exclusion, so the earlier report still holds. The passing suite tests that launch() is safe and atomic once it is called (DeezLaunchRollback, DeezLaunchLifecycleInvariant). It does not assert that deployment meets the requirement.","line":113,"path":"src/DeezLaunch.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {DeezLaunch} from \"src/DeezLaunch.sol\";\nimport {DeezToken} from \"src/DeezToken.sol\";\nimport {DeezRewards} from \"src/DeezRewards.sol\";\nimport {DeezLiquidityLock} from \"src/DeezLiquidityLock.sol\";\n\ncontract PairToken is ERC20 {\n    constructor() ERC20(\"IMD\", \"IMD\") {}\n}\n\n/// @notice The launch factory deploys the manifest's contracts in one transaction: one call here.\ncontract OneTransactionDeployment {\n    function deploy(address requester, IPoolManager manager, address imd)\n        external\n        returns (DeezLaunch launcher, DeezToken token, DeezRewards rewards, DeezLiquidityLock lock)\n    {\n        launcher = new DeezLaunch(requester, manager, imd);\n        token = new DeezToken(address(launcher));\n        rewards = new DeezRewards(address(token), imd, address(manager), address(launcher));\n        lock = new DeezLiquidityLock(manager, address(rewards));\n    }\n}\n\n/// The brief: at least 10,000,000 $DEEZ of the requester's 2% is sent to DeezLiquidityLock and locked in the\n/// same transaction as deployment. After the deployment transaction nothing is locked: the allocation is still\n/// in DeezLaunch and only a later, requester-only `launch` call (which the requester may never send) locks it.\ncontract DeploymentLocksRequesterShareProof is Test {\n    function test_deploymentTransactionLocksAtLeastTenMillionOfTheRequesterShare() public {\n        PoolManager manager = new PoolManager(address(this));\n        PairToken imd = new PairToken();\n        OneTransactionDeployment factory = new OneTransactionDeployment();\n        (DeezLaunch launcher, DeezToken token,, DeezLiquidityLock lock) =\n            factory.deploy(makeAddr(\"requester\"), IPoolManager(address(manager)), address(imd));\n\n        // Locked = moved into the PoolManager as the lock's permanent position (the lock only ever adds).\n        uint256 lockedDeez = token.balanceOf(address(manager));\n        assertGe(lockedDeez, 10_000_000 ether, \"requester share locked in the deployment transaction\");\n        assertGe(lock.totalLocked0() + lock.totalLocked1(), 10_000_000 ether, \"lock recorded the locked share\");\n        assertTrue(launcher.launched(), \"deployment left the launch unfinished\");\n    }\n}","reproduction":"Deploy the four manifest contracts in one call, as the factory does (OneTransactionDeployment.deploy in the proof). Read the state right after that call. Expected: PoolManager holds >= 10,000,000e18 $DEEZ from the lock's position, the lock's totalLocked >= 10,000,000e18, and launched() == true. Actual: 0 $DEEZ is locked, totalLocked0 + totalLocked1 == 0, launched() == false, and DeezLaunch holds 1,000,000,000e18 $DEEZ.","severity":"medium","title":"Requester's 10,000,000 $DEEZ is not locked in the deployment transaction; it needs a later requester-only launch() call"},{"description":"_check only checks that the contracts are consistent with each other. Anyone can deploy a new DeezToken(launcher), which mints another 1,000,000,000 to the launcher, along with a matching DeezRewards and DeezLiquidityLock. The requester can then launch with that set. launched becomes true, so the factory's DeezToken supply stays in DeezLaunch forever. The contract notice documents this and leaves it to the publisher to cross-check token()/rewards()/liquidityLock() against the factory's record. test/DeezLauncherExclusion.t.sol pins that cross-check. It does not treat the stranded supply as intended. The risk is limited to the requester, because only the requester can call launch().","line":186,"path":"src/DeezLaunch.sol","reproduction":"LookAlikeBuilder.build(launcher, manager, imd), mine a salt for that set, then call launch(fakeToken, fakeRewards, fakeLock, salt) as the requester. Expected (if provenance were enforced): revert. Actual: success; launcher.token() != factory token, and token.balanceOf(launcher) == 1e27 permanently. A mixed set is refused with WrongRewards / WrongLiquidityLock.","severity":"info","title":"launch() accepts any complete look-alike contract set; the factory's token can then be stranded in DeezLaunch"},{"description":"After launch, DeezLiquidityLock still holds 10.000979999999999859 $DEEZ that the two single-sided locks did not use. It also holds any $DEEZ that someone sends to it or that a top-up returns as LP fees, until the next lock(). The lock is not in isExcluded and has no claim path, so its weight counts as eligible supply. Its share of each pot cannot be claimed until recycle() folds it into a later epoch, 90 epochs on. With the launch dust this is about 2e-7 of a pot, which is negligible unless large unlocked balances sit in the lock.","line":158,"path":"src/DeezRewards.sol","reproduction":"Launch at the start of an epoch, buy with 100 $IMD (fee pot 2e18), then harvest after the epoch. token.balanceOf(lock) == 10000979999999999859 and rewards.claimable(lock, epoch) == 425178430560 wei. That amount is unclaimable until recycle.","severity":"info","title":"DeezLiquidityLock is not excluded from rewards and keeps ~10 $DEEZ of rounding dust after launch"}],"hash":"c7a9b4baaade37ff971a7edb06d40b707f1e6405904300a8261137ce8aa35868","nodeId":"7936ebc9-2549-42de-800b-5c2cfecafdea","outcome":"completed","summary":"I've updated the tests for the revised launch, and `forge build` and `forge test` pass with the verifier's seed: 219 tests, none failing. The main deployment requirement is still not met, so I've reported it again in `.imd-findings.json` with a failing test as proof.\n\n**What I added:**\n- **`test/DeezLauncherExclusion.t.sol` (new)** covers the revision that stops the launcher earning rewards:\n  - A fuzzed test launches at any second of the launch day, with a random buy and a random amount sent back to the launcher. It checks that the launcher's holding is never counted when splitting rewards and that it can never claim. The day's pot goes only to holders who can claim, a launcher claim reverts with `Excluded`, and the $IMD the rewards contract holds equals what it owes.\n  - A launch in the last second of the day still pays out the whole pot.\n  - Before launch there is no pot, no claim and no credit.\n  - Anyone can deploy a full look-alike set of contracts that name the launcher. A stranger can't launch with it, and mixing real and fake contracts reverts with `WrongRewards` / `WrongLiquidityLock`. A complete fake set still launches, and the only way to catch it is for the publisher to compare the launcher's `token()`, `rewards()` and `liquidityLock()` with the factory's record.\n- **`DeezLaunchLifecycleInvariant.t.sol`** now also checks, after every random call sequence, that the launcher is excluded from rewards.\n- **`test/ADVERSARIAL_TESTS.md`** is updated to match.\n\n**Findings in `.imd-findings.json`:**\n1. **Medium: the requester's 10,000,000 $DEEZ is not locked when the contracts are deployed.** The brief requires it to be locked in the same transaction as deployment. In fact it is locked only by a later `DeezLaunch.launch()` call that only the requester can send. The revision didn't change this. The proof test deploys all four contracts in one call and fails with \"requester share locked in the deployment transaction: 0 < 10000000000000000000000000\". It will pass once deployment does the lock.\n2. **Info: a look-alike contract set is accepted.** If the requester launches with it, the factory's 1,000,000,000 $DEEZ stays in the launcher for good. The code documents this, only the requester can trigger it, and the publisher's cross-check catches it.\n3. **Info: the liquidity lock is not excluded from rewards.** It keeps 10.00098 $DEEZ of rounding dust after launch. On a 2 $IMD pot that earns about 4.25e11 wei, which nobody can claim until `recycle` moves it to a later day, at least 90 days on. It's negligible unless someone leaves a large balance in the lock.\n\nThese tests run on a local chain only. The mainnet deployment, the published addresses and transaction hashes, and the website config still need to be checked separately.","treeHash":"72b50e49586347af510cf4932194b8ab326cf901","usage":{"cachedInputTokens":1230350,"inputTokens":38,"model":"claude-opus-5-5","outputTokens":20759,"runtime":"claude","turns":21,"wallClockMs":851457}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"1f9cb1750ebf47ed","findings":[{"citation":"resolved","description":"Merged from audit_flow, audit_permissions, audit_math and audit_economics (same root cause, one fix). DeezToken mints all 1,000,000,000 $DEEZ to DeezLaunch in the factory transaction (src/DeezToken.sol:47 `_mint(launcher_, TOTAL_SUPPLY)`), and the launcher holds it until the requester sends launch() in a later transaction (the hook salt is mined against the deployed addresses first, so a gap of minutes to hours is the normal case). DeezRewards weights every holder by its average balance over the UTC day (weightOf) and divides each day's pot by eligibleSupplyAt, which subtracts only the PoolManager, 0x..dEaD, the hook and the distributor itself (src/DeezRewards.sol:170-171); isExcluded (line 155) lists the same four. The launcher is not among them, although DeezRewards already stores it as the immutable `launcher`. On the launch day the launcher's weight is TOTAL_SUPPLY * secondsHeldBeforeLaunch / 1 day, which dwarfs the weight of everyone who holds after launch (the requester's 10,000,000 plus buyers). DeezLaunch has no call into claim, and claim requires msg.sender == account, so that share is unclaimable; it sits in pots[E] until anyone calls recycle(E) after epoch E+91, which folds it into the pot of that later day and pays it to whoever holds $DEEZ then. Launch day carries the first trading hours and is normally the heaviest fee day, so the holders the launch promises rewards to lose most of it to a different set of holders three months later. Reproduced: with the factory at 01:00 UTC and launch at 12:00 UTC, live holders can claim 4.9% of the launch-day pot; at 12 hours' gap on a 24-hour day ~97%; even a 1-minute slip past 00:00 UTC strands ~6.5%. The fix preserves the design: add `account == launcher` to isExcluded and `+ weightOf(launcher, epoch)` to eligibleSupplyAt. Verified: a scratch copy of DeezRewards with exactly those two changes makes the attached proof pass (test/scratch/FixedCheck.t.sol in this review); with the current code it fails. Optionally exclude DeezLiquidityLock the same way: it keeps the 1-ppm shave (about 1,000 $DEEZ) and also cannot claim, but its weight is dust. DeezLiquidityLock.sol is otherwise unaffected. The existing suite misses this because every rewards test uses the test contract as the launcher and treats it as an ordinary claiming holder (test/DeezRewards.t.sol), and test/DeezLaunch.t.sol never claims.","line":155,"path":"src/DeezRewards.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test, console} from \"forge-std/Test.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {IUnlockCallback} from \"v4-core/src/interfaces/callback/IUnlockCallback.sol\";\nimport {IHooks} from \"v4-core/src/interfaces/IHooks.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {BalanceDelta} from \"v4-core/src/types/BalanceDelta.sol\";\nimport {SwapParams} from \"v4-core/src/types/PoolOperation.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {DeezLaunch} from \"src/DeezLaunch.sol\";\nimport {DeezToken} from \"src/DeezToken.sol\";\nimport {DeezHook} from \"src/DeezHook.sol\";\nimport {DeezRewards} from \"src/DeezRewards.sol\";\nimport {DeezLiquidityLock} from \"src/DeezLiquidityLock.sol\";\n\ncontract Imd is ERC20 {\n    constructor() ERC20(\"IMD\", \"IMD\") {}\n\n    function mint(address to, uint256 amount) external {\n        _mint(to, amount);\n    }\n}\n\n/// @dev Stands in for the factory: deploys the four application contracts in one call, manifest order.\ncontract Factory {\n    function deployAll(address requester, IPoolManager pm, address imd)\n        external\n        returns (DeezLaunch launcher, DeezToken token, DeezRewards rewards, DeezLiquidityLock lock)\n    {\n        launcher = new DeezLaunch(requester, pm, imd);\n        token = new DeezToken(address(launcher));\n        rewards = new DeezRewards(address(token), imd, address(pm), address(launcher));\n        lock = new DeezLiquidityLock(pm, address(rewards));\n    }\n}\n\n/// @dev Minimal router: exact-input swap paid from its own balance.\ncontract Buyer is IUnlockCallback {\n    IPoolManager public immutable pm;\n\n    constructor(IPoolManager pm_) {\n        pm = pm_;\n    }\n\n    function swap(PoolKey memory key, bool zeroForOne, int256 amountSpecified) external returns (BalanceDelta) {\n        uint160 limit = zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1;\n        return abi.decode(pm.unlock(abi.encode(key, SwapParams(zeroForOne, amountSpecified, limit))), (BalanceDelta));\n    }\n\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        require(msg.sender == address(pm));\n        (PoolKey memory key, SwapParams memory params) = abi.decode(data, (PoolKey, SwapParams));\n        BalanceDelta delta = pm.swap(key, params, \"\");\n        _settle(key.currency0, delta.amount0());\n        _settle(key.currency1, delta.amount1());\n        return abi.encode(delta);\n    }\n\n    function _settle(Currency c, int128 amount) private {\n        if (amount < 0) {\n            pm.sync(c);\n            IERC20(Currency.unwrap(c)).transfer(address(pm), uint256(uint128(-amount)));\n            pm.settle();\n        } else if (amount > 0) {\n            pm.take(c, address(this), uint256(uint128(amount)));\n        }\n    }\n}\n\n/// @notice The launcher holds the whole supply from the factory transaction until `launch`, and `DeezRewards`\n/// does not exclude it. Its average balance over the launch day therefore dominates `eligibleSupplyAt(launchDay)`,\n/// so the holders who actually traded and held on launch day can claim only a small slice of that day's fees;\n/// the rest is owed to a contract that cannot claim and is only recycled 91 days later.\n/// Fails on the current code (holders can claim ~4% of the launch-day pot); passes once the launcher's\n/// pre-launch holding no longer counts as eligible supply (e.g. `isExcluded(launcher)`).\ncontract LauncherWeightTest is Test {\n    address constant REQUESTER = address(0xB045);\n    uint256 constant DAY = 1 days;\n\n    PoolManager pm;\n    Imd imd;\n    DeezLaunch launcher;\n    DeezToken token;\n    DeezRewards rewards;\n    DeezLiquidityLock lock;\n    DeezHook hook;\n    PoolKey key;\n    bool tokenIsCurrency0;\n\n    function setUp() public {\n        // Factory transaction at 01:00 UTC of day E: the supply is minted to the launcher now.\n        uint256 dayStart = (1_700_000_000 / DAY) * DAY;\n        vm.warp(dayStart + 1 hours);\n        pm = new PoolManager(address(this));\n        imd = new Imd();\n        Factory factory = new Factory();\n        (launcher, token, rewards, lock) = factory.deployAll(REQUESTER, IPoolManager(address(pm)), address(imd));\n        tokenIsCurrency0 = address(token) < address(imd);\n    }\n\n    function mineSalt() internal view returns (bytes32) {\n        for (uint256 i = 0; i < 300_000; i++) {\n            address predicted = launcher.hookAddress(bytes32(i), address(token), address(rewards), address(lock));\n            if (uint160(predicted) & ((1 << 14) - 1) == 0x20CC) return bytes32(i);\n        }\n        revert(\"no salt\");\n    }\n\n    function test_launchDayFeesAreMostlyOwedToTheLauncher() public {\n        uint256 epoch = block.timestamp / DAY;\n        // The requester launches at 12:00 UTC of the same day: the launcher held 1,000,000,000 $DEEZ for 11 hours.\n        vm.warp(epoch * DAY + 12 hours);\n        bytes32 salt = mineSalt();\n        vm.prank(REQUESTER);\n        hook = launcher.launch(address(token), address(rewards), address(lock), salt);\n        key = hook.poolKey();\n\n        // A buyer pays 100 $IMD for $DEEZ right after launch: 2 $IMD of fees are recorded against the launch day.\n        Buyer buyer = new Buyer(IPoolManager(address(pm)));\n        imd.mint(address(buyer), 100 ether);\n        buyer.swap(key, !tokenIsCurrency0, -100 ether);\n        assertEq(hook.pendingFeesOf(epoch), 2 ether);\n\n        // The day ends; anyone harvests. The launch-day pot is 2 $IMD.\n        vm.warp((epoch + 1) * DAY + 1);\n        hook.harvest();\n        (uint128 pot,,,) = rewards.pots(epoch);\n        assertEq(pot, 2 ether);\n\n        // Everyone who is not excluded and holds $DEEZ after launch: the requester (10,000,000), the buyer and the\n        // lock's 1 ppm dust. Together they should be able to claim (almost) the whole pot of the day they traded.\n        uint256 claimableByHolders = rewards.claimable(REQUESTER, epoch) + rewards.claimable(address(buyer), epoch)\n            + rewards.claimable(address(lock), epoch);\n        uint256 launcherWeight = rewards.weightOf(address(launcher), epoch);\n        console.log(\"eligible supply (wei-days):\", rewards.eligibleSupplyAt(epoch));\n        console.log(\"launcher weight  (wei-days):\", launcherWeight);\n        console.log(\"pot (wei):\", pot);\n        console.log(\"claimable by live holders (wei):\", claimableByHolders);\n        assertEq(token.balanceOf(address(launcher)), 0, \"the launcher holds nothing after launch\");\n        // The launcher cannot claim: `claim` requires msg.sender == account and the launcher has no such call.\n        assertGe(claimableByHolders, uint256(pot) * 99 / 100, \"launch-day holders can claim the launch-day fees\");\n    }\n}","reproduction":"1. At 01:00 UTC of day E deploy PoolManager, a mock $IMD, then as the factory in one call: DeezLaunch(requester, pm, imd), DeezToken(launcher), DeezRewards(token, imd, pm, launcher), DeezLiquidityLock(pm, rewards). The token mints 1e27 $DEEZ to the launcher now. 2. At 12:00 UTC of day E the requester calls launcher.launch(token, rewards, lock, minedSalt): 980,000,000 + 10,000,000 $DEEZ go to the PoolManager via the lock, 10,000,000 to the requester, launcher balance becomes 0. 3. A buyer swaps exact-input 100 $IMD for $DEEZ: hook.pendingFeesOf(E) == 2e18. 4. At 00:00:01 of day E+1 anyone calls hook.harvest(): pots[E].total == 2e18. 5. Expected: claimable(requester,E) + claimable(buyer,E) + claimable(lock,E) >= 0.99 * 2e18, since they are the only holders of the day who can claim. Actual: 97,630,340,007,265,301 wei (0.0976 $IMD, 4.9%); rewards.weightOf(DeezLaunch, E) == 458,333,333,333,333,333,333,333,333 of eligibleSupplyAt(E) == 481,855,175,649,809,033,788,714,805. rewards.claim(launcher, [E]) is impossible (NotAccount: the launcher never calls it), so 1.90 $IMD stays in pot E until recycle(E) at epoch E+91 moves it into pots[E+91]. Attached proof (test/scratch/Proof_963231dd6fcd.t.sol) fails on this code with `launch-day holders can claim the launch-day fees: 97630340007265301 < 1980000000000000000` and passes with `launcher` excluded in isExcluded and eligibleSupplyAt.","severity":"high","snippet":"        return account == poolManager || account == BURN_ADDRESS || account == hook || account == address(this)\n            || account == address(0);","title":"DeezLaunch holds the whole supply between the factory transaction and launch() but is not excluded from reward weights, so most of the launch-day fee pot is owed to a contract that can never claim and"},{"citation":"resolved","description":"The natspec (src/DeezLaunch.sol:31-32) and the README say the three addresses are \"checked to be the ones deployed for this launcher\". _check (lines 181-198) only reads values the passed contracts report about themselves: token.launcher(), token.balanceOf(launcher), rewards.launcher()/token()/rewardToken()/poolManager()/hook(), lock.poolManager()/rewards(). An ERC-20 the requester deploys that returns the launcher from launcher() and mints 1e27 to it, plus a DeezRewards built on that token and a DeezLiquidityLock built on that DeezRewards, satisfy every check. The existing test (test/DeezLaunch.t.sol test_launchRefusesContractsThatAreNotItsOwn) only shows a fake token being refused when paired with the real DeezRewards. This is a requester-privileged action and the requester is the launch's beneficiary, so it is a trust assumption with a concrete mechanism rather than an exploit: the requester would mostly hurt their own launch. The consequences for others are that the factory-recorded DeezToken (the address the launch record and the site publish from the factory record) can never trade, since its entire supply sits in DeezLaunch with launched == true and no other transfer path (AlreadyLaunched on retry), and that the reviewed launcher's Launched event, token() and hook() name an unreviewed token (in the reproduction, one with an owner-only mint) under the launcher's reviewed address. The publisher cross-checking DeezLaunch.token() against the factory record before filling site/deez.config.js mitigates it. A contract-level guard that keeps the design: in launch, require `extcodehash(token_)` to equal the known DeezToken runtime hash (a constant, since bytecode_hash = none makes it deterministic), or document the publisher cross-check as a required step of the handoff.","line":184,"path":"src/DeezLaunch.sol","reproduction":"1. Factory deploys DeezLaunch(requester, pm, imd), DeezToken(launcher), DeezRewards(realToken, imd, pm, launcher), DeezLiquidityLock(pm, realRewards). 2. The requester deploys FakeToken(launcher) (an ERC-20 whose launcher() returns DeezLaunch, with 1e27 minted to DeezLaunch and an owner-only mint), DeezRewards(fake, imd, pm, launcher) and DeezLiquidityLock(pm, fakeRewards), mines a salt for launcher.hookAddress(salt, fake, fakeRewards, fakeLock) and calls launcher.launch(fake, fakeRewards, fakeLock, salt). Expected per the natspec: revert with WrongToken / WrongRewards / WrongLiquidityLock. Actual: the call succeeds; launcher.launched() == true, launcher.token() == fake, hook.rewards() == fakeRewards, fake.balanceOf(requester) == 10,000,000e18, the factory's DeezToken still reports balanceOf(launcher) == 1e27 with no path out, and launcher.launch(realToken, ...) now reverts AlreadyLaunched. Verified with test/scratch/Impostor.t.sol in this review (passes, i.e. the substitute launch goes through).","severity":"low","snippet":"        if (DeezToken(token_).launcher() != address(this)) revert WrongToken(token_);","title":"DeezLaunch._check verifies that the passed token, rewards and lock are self-consistent, not that they are the factory's: the requester can launch a substitute token set and strand the factory-recorded"},{"citation":"resolved","description":"write_foundry_tests reported this as high: the brief says at least 10,000,000 $DEEZ of the requester's 2% must be sent to DeezLiquidityLock \"and locked in the same transaction as deployment\", and its proof (test/scratch/Proof_8eb6b83070b2.t.sol) deploys the four manifest contracts in one call and finds 0 locked (reproduced: `0 < 10000000000000000000000000`). That reproduction is correct, but the expectation it encodes cannot be satisfied by any constructor: this launch mode's factory only runs constructors, with CREATE2 and no follow-up call, and its rehearsal (Contracts.protected.t.sol) runs them on an empty chain where a constructor that calls another contract reverts and parks the launch. Opening the pool and locking liquidity require calls into the PoolManager, and the hook needs a salt mined against the deployed addresses, so the hook deployment, pool initialization, both lock positions and the requester payout are done in one later transaction, DeezLaunch.launch, callable by the requester only (line 113), once. In that transaction the 10,000,000 $DEEZ is sent to the lock and locked before the other 10,000,000 is paid (lines 142-146), so there is no window in which the requester holds an unlocked 20,000,000. The deviation from the literal wording is therefore a documented design constraint (README, launch.json notes), not a code defect, and no code change is proposed: the author's answer can be an acknowledgement that \"deployment\" in the brief means the launch transaction. It is reported so the requester, who wrote the brief, decides rather than the reviewer. Until launch() is sent nothing trades and the whole supply sits in DeezLaunch; only the requester can release it.","line":113,"path":"src/DeezLaunch.sol","reproduction":"Deploy DeezLaunch(requester, pm, imd), DeezToken(launcher), DeezRewards(token, imd, pm, launcher), DeezLiquidityLock(pm, rewards) in one call (the factory transaction). Expected by the brief's literal wording: lock.totalLocked0/1 + token.balanceOf(lock) >= 10,000,000e18 and token.balanceOf(requester) == 10,000,000e18. Actual: both are 0 and token.balanceOf(launcher) == 1,000,000,000e18; after the requester's launch(token, rewards, lock, minedSalt) the lock holds the 980,000,000 + 10,000,000 positions and the requester 10,000,000e18 (test/DeezLaunch.t.sol test_launchDeploysWiresOpensLocksAndPays).","severity":"info","snippet":"        if (msg.sender != requester) revert NotRequester();","title":"The requester's 10,000,000 $DEEZ is locked in the requester's launch() transaction, not in the factory's deployment transaction: the brief's literal wording cannot be met under the evm_contracts facto"}],"hash":"e81c81ca35ed57c1d56099268cac5995dff0a2016ca6d6ea32ee46f3b5ec4c24","nodeId":"24cb6421-5f97-420a-a245-11635a71fbca","outcome":"completed","summary":"The review is complete and written to `.imd-findings.json`. No source files were changed. Scratch tests live only under test/scratch, which is ignored and not submitted.\n\n**What I kept**\n\n- **High, merged from four specialists.** DeezLaunch holds the entire 1,000,000,000 $DEEZ between the factory transaction and the requester's launch call, and DeezRewards does not exclude it from reward weights. Its pre-launch token-days sit in the launch day's eligible supply, so most of that day's fee pot is owed to a contract that can never claim and is only recycled to holders 91 days later. All four attached proofs fail on this code for that reason. I attached the economics specialist's proof. I also copied DeezRewards into scratch with the two-line fix the specialists propose, excluding the launcher in both places, and the proof passes against it, so the fix is sound.\n- **Low.** The launcher's identity check only reads what the passed contracts say about themselves. A requester-deployed substitute token, rewards and lock set passes every check. I confirmed this with a scratch test. It is requester-privileged and mostly self-harm, so low, with the publisher cross-check named as the mitigation.\n- **Info.** The tester's \"not locked in the deployment transaction\" finding reproduces, but its expectation cannot be met under this launch mode. Constructors are rehearsed on an empty chain and may not call the PoolManager, so the lock has to happen in the launch transaction. I reported it as a design-interpretation note for the requester to acknowledge, not as a code defect, and downgraded it from the tester's high.\n\n**What I checked independently.** All 18 entry points have a coverage row, plus rows for the manifest and the deployment model. The mainnet PoolManager has code and the $IMD address returns symbol IMD with 18 decimals via a public RPC. Contract sizes, opcodes, constructor argument order, hook flag bits and the v4 delta sign conventions in the hook all hold. The static-analysis lines were all benign or already covered by the above.","treeHash":null,"usage":{"cachedInputTokens":1117743,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":30784,"runtime":"claude","turns":28,"wallClockMs":838424}},{"artifacts":[],"attempt":1,"bundleHash":"172b02d6a09c0f82e9d22eb424a0b143ab02a5a691cc4770d71333c27aecb9ef","device":"e67cc6ec4009b226","findings":[],"hash":"e924fdb2beefcf8082b879a5bb0adf742637fae4def427b19615cf857efd100f","nodeId":"cb6914e0-1847-484d-9132-0c8914c6f10f","outcome":"completed","summary":"The revised launch.json is done and verified. Only that file changed.\n\n**What I checked.** The builder's latest accepted revision left every constructor signature unchanged, so the four manifest entries and their arguments still match the source exactly: DeezLaunch takes the owner, the mainnet Uniswap v4 PoolManager and the $IMD token; DeezToken takes the launcher; DeezRewards takes the token, $IMD, the PoolManager and the launcher; DeezLiquidityLock takes the PoolManager and the distributor. No findings were listed in the brief, so the contract entries were left as accepted.\n\n**What I changed.** Only the notes, to describe the implementation as it now stands:\n\n- The rewards distributor now excludes the launcher from reward weights and eligible supply, so the pre-launch holding of the full supply cannot strand the launch day's pot.\n- The brief's \"same transaction as deployment\" is read as the launch transaction, since the factory transaction runs constructors only and nothing trades or leaves the launcher before then.\n- Publishing the site config requires first confirming the launcher's recorded token, rewards and lock addresses equal the factory's record.\n\n**Verification.**\n\n| Check | Result |\n|---|---|\n| Schema and ABI validation (scratch script against built artifacts) | passed, notes 2,717 characters |\n| forge build | ok |\n| forge test with the verifier's fuzz seed | 190 passed, 0 failed |\n\nThe scratch validator lives in test/scratch and is not part of the submission.","treeHash":"75173f712ccd3ffdda44f6c4930dcf446b37e990","usage":{"cachedInputTokens":292511,"inputTokens":194,"model":"claude-fable-5-1","outputTokens":5216,"runtime":"claude","turns":7,"wallClockMs":165739}},{"artifacts":[],"attempt":1,"bundleHash":"11ea58f0eb1254d1595134876e456fff858c4bcbb9877f39ec9861eed68e545b","device":"8af9903f4ad1eed0","findings":[],"hash":"eaa5334de601e98357b3d1dae9a2e7fb36f8b991f221bb0c0f042af9fb02e35d","nodeId":"f5877fbb-c74e-4c24-8293-a23aa08855a6","outcome":"completed","summary":"The revision is complete. Build, all 191 tests with the verifier's fuzz seed, and `forge fmt --check` pass. The reviewer's proof fails on the starting tree and passes now.\n\n**What I found and changed**\n\n- **Launcher dilution (high, fixed).** Reproduced: the proof failed with holders able to claim only about 5% of the launch-day pot. The fix is in `src/DeezRewards.sol` and is exactly the two lines the finding proposed. The launcher is now in `isExcluded`, and its weight is subtracted in `eligibleSupplyAt`. Its claim reverts `Excluded`, its claimable is zero, and its weight stays readable for reporting. The liquidity lock stays unexcluded on purpose, since it holds only the 1 ppm shave, and the README says so.\n- **Look-alike token set (low, fixed by documentation).** The mechanism is real, but the proposed code guard cannot work. `DeezToken` has immutables, so its runtime hash differs per deployment and cannot be pinned as a constant. The natspec in `src/DeezLaunch.sol` no longer claims provenance, and the README now makes reading `token()`, `rewards()` and `liquidityLock()` from the launcher and comparing them with the factory record a required step before publishing.\n- **\"Same transaction as deployment\" (info, disputed).** The reproduction is right, but no constructor can open a pool or lock liquidity in this launch mode. The README now has an explicit assumption section stating that \"deployment\" means the launch transaction, and what would have to change if the requester meant otherwise.\n\n**Tests added or adapted**\n\n- Launch suite, both currency orders: factory transaction one day, launch at noon the next, one buy, harvest after midnight. Launch-day holders can claim at least 99% of the pot, the requester actually claims, and the launcher's claim reverts.\n- Distributor unit suite: two new tests cover the launcher holding all epoch and holding for half of it. Four existing tests that used the test contract as an earning holder now use a plain holder, and the excluded-address checks include the launcher.\n\n**Answers** are in `.imd-responses.json` at the repository root with verdicts fixed, fixed, disputed. That file is listed in the repository's own git exclude list, which is the harness's setup, so it sits in the working tree rather than in a commit. Nothing was committed, since the task did not ask for it.","treeHash":"5c9870e7d97b02005b43416c00b277c1a69213fe","usage":{"cachedInputTokens":1578788,"inputTokens":450,"model":"claude-fable-5-1","outputTokens":27159,"runtime":"claude","turns":49,"wallClockMs":841349}}],"verification":[{"checks":[{"durationMs":75594,"exitCode":0,"name":"build","output":"Compiling 97 files with Solc 0.8.26\nSolc 0.8.26 finished in 75.48s\nCompiler run successful!\n","passed":true},{"durationMs":4244,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/DeezFlywheel.t.sol:DeezFlywheelTest\n[PASS] test_earlyClaimerGetsItsShareOfFeesHarvestedLater() (gas: 2161108)\n[PASS] test_feesBelongToTheEpochTheyWereTradedInWheneverHarvested() (gas: 1164796)\n[PASS] test_lastSecondBuyerCannotSnipeTheEpochsPot() (gas: 1651147)\n[PASS] test_tradesBecomeHolderRewards() (gas: 1947513)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 12.57ms (4.00ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken0Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1905565)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 840546)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 963997)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 20284510)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 960567)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61951)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71556)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 50.89ms (25.02ms CPU time)\n\nRan 24 tests for test/DeezRewards.t.sol:DeezRewardsTest\n[PASS] testFuzz_claimsNeverExceedThePotAndSplitByBalance(uint96,uint96,uint96) (runs: 256, μ: 838101, ~: 838076)\n[PASS] testFuzz_claimsNeverExceedThePotWithMidEpochMoves(uint96,uint32,uint32,uint96) (runs: 256, μ: 1195719, ~: 1195796)\n[PASS] test_accrueCreditsTheCurrentEpochOnce() (gas: 195007)\n[PASS] test_balanceMovedAfterTheEpochDoesNotChangeIt() (gas: 746713)\n[PASS] test_claimBeforeTheEpochEndsReverts() (gas: 336533)\n[PASS] test_claimHarvestsOnlyTheEpochsItPays() (gas: 617087)\n[PASS] test_claimHarvestsThePendingFeesOfTheEpochFirst() (gas: 972560)\n[PASS] test_claimManyEpochsAtOnce() (gas: 1055389)\n[PASS] test_claimsAreProportionalToTheAverageBalance() (gas: 1288158)\n[PASS] test_constructorRefusesZeroAddresses() (gas: 10913)\n[PASS] test_creditGoesToTheEpochTheHookNames() (gas: 431309)\n[PASS] test_creditRefusesOthersAndUnfundedAmounts() (gas: 221353)\n[PASS] test_creditToAClosedOrFutureEpochGoesToTheCurrentOne() (gas: 406015)\n[PASS] test_deployerShareIsProportionalToo() (gas: 674502)\n[PASS] test_doubleClaimPaysNothingMore() (gas: 820604)\n[PASS] test_emptyClaimReverts() (gas: 381656)\n[PASS] test_epochArithmetic() (gas: 31377)\n[PASS] test_excludedAddresses() (gas: 33214)\n[PASS] test_excludedAddressesCannotClaim() (gas: 249694)\n[PASS] test_finalizeRequiresAnEndedEpoch() (gas: 195790)\n[PASS] test_lateCreditIsPaidOnASecondClaim() (gas: 1056780)\n[PASS] test_onlyTheAccountItselfCanClaim() (gas: 840182)\n[PASS] test_recycleFoldsUnclaimedIntoTheCurrentEpoch() (gas: 934426)\n[PASS] test_rewardsAreWeightedByHoldingTime() (gas: 1035184)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 107.90ms (205.05ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken1Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1195357)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 926515)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 628626)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 958405)\n[PASS] test_lockBothBecomesFullRange() (gas: 1249163)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1183014)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 819228)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 192355329)\n[PASS] test_lockRefusesNothing() (gas: 53515)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1044726)\n[PASS] test_wiring() (gas: 37454)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 109.51ms (65.11ms CPU time)\n\nRan 21 tests for test/DeezLaunch.t.sol:DeezLaunchToken0Test\n[PASS] testFuzz_minimumAndConservationAcrossOpeningPrices(int24) (runs: 256, μ: 7776114, ~: 7776359)\n[PASS] test_badHookSaltRollsBackTokenCreation() (gas: 5265077)\n[PASS] test_cannotLaunchInsideManagerUnlock() (gas: 6700740)\n[PASS] test_cannotWithdrawLockedPositionOrBalances() (gas: 7765013)\n[PASS] test_constructorNeedsNoLiveDependencies() (gas: 561066)\n[PASS] test_constructorRejectsInvalidRecipientsAndDependencies() (gas: 8932)\n[PASS] test_invalidOpeningPriceRollsBackAllContracts() (gas: 7047369)\n[PASS] test_laterFactoryFailureRollsBackTheEntireLaunch() (gas: 7241279)\n[PASS] test_launchDeploysFundsAndLocksInOneCall() (gas: 7824490)\n[PASS] test_launcherHasNoOngoingAdminAndFitsDeploymentLimits() (gas: 102588)\n[PASS] test_minimumCheckFailureRollsBackThePositionAndEveryContract() (gas: 15213917)\n[PASS] test_missingLiveDependencyFailsBeforeCreatingAnything() (gas: 597647)\n[PASS] test_onlyConfiguredFactoryCanLaunch() (gas: 588562)\n[PASS] test_ordinaryTransfersAndRewardsStillWork() (gas: 9576565)\n[PASS] test_pairedTokenDustCannotChangeLockMode() (gas: 7856843)\n[PASS] test_pinnedCodeHashesMatchReviewedArtifacts() (gas: 43076)\n[PASS] test_rejectsAlteredHookCodeBeforeCreatingAnything() (gas: 627502)\n[PASS] test_rejectsAlteredTokenCodeBeforeCreatingAnything() (gas: 597997)\n[PASS] test_rejectsSecondLaunch() (gas: 8207060)\n[PASS] test_rejectsWrongChain() (gas: 588693)\n[PASS] test_unfundableSingleSidedRangeRollsBackAllContracts() (gas: 7162475)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 109.51ms (115.21ms CPU time)\n\nRan 24 tests for test/DeezFailurePaths.t.sol:DeezRewardsFailurePathsTest\n[PASS] testFuzz_allHoldersTogetherNeverDrainMoreThanThePot(uint96,uint96,uint128,uint32,uint32) (runs: 512, μ: 925363, ~: 990988)\n[PASS] testFuzz_claimOrderAndLateFeesDoNotChangeFinalShares(uint96,uint128,uint128,uint8,uint32) (runs: 512, μ: 1303611, ~: 1267862)\n[PASS] test_accrueWithNothingNewCreditsNothing() (gas: 222234)\n[PASS] test_balanceMovedInTheFirstSecondOfTheNextEpochDoesNotCount() (gas: 567559)\n[PASS] test_batchWithAnUnendedEpochPaysNothing() (gas: 424964)\n[PASS] test_closedEpochRefusesClaimsAndASecondRecycle() (gas: 328984)\n[PASS] test_creditCannotBeForgedOrOverdrawn() (gas: 209801)\n[PASS] test_duplicateEpochInOneBatchPaysItOnce() (gas: 479590)\n[PASS] test_emptyBatchReverts() (gas: 224027)\n[PASS] test_epochWithNoEligibleSupplyPaysNobodyAndIsRecycled() (gas: 632803)\n[PASS] test_excludedAddressesCannotClaimEvenForThemselves() (gas: 323579)\n[PASS] test_finalizeIsIdempotentAndIgnoresLaterTransfers() (gas: 392374)\n[PASS] test_holderWithNoBalanceInTheEpochHasNothingToClaim() (gas: 342163)\n[PASS] test_lastSecondBuyerWeighsOneSecond() (gas: 763055)\n[PASS] test_lateFeeAfterSomeClaimedStillSplitsExactlyByBalance() (gas: 715812)\n[PASS] test_lateFeeDustCanBeHarvestedAndRecycledWhenEveryShareRoundsToZero() (gas: 1646598)\n[PASS] test_nobodyCanClaimForSomeoneElse() (gas: 441749)\n[PASS] test_pendingFeesOfAClosedEpochGoToTheCurrentPot() (gas: 510528)\n[PASS] test_recycleOfAnEpochThatNeverHadAPotClosesItForNothing() (gas: 99956)\n[PASS] test_recycleOpensExactlyAfterTheClaimWindow() (gas: 447710)\n[PASS] test_recycledRewardsArePaidByTheNewEpochsBalances() (gas: 551269)\n[PASS] test_shareThatRoundsToZeroIsRefusedNotPaid() (gas: 472404)\n[PASS] test_unaccruedDonationGoesToTheCurrentEpochNotAnEndedOne() (gas: 430201)\n[PASS] test_weightReadsRevertUntilTheEpochHasEnded() (gas: 222989)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 118.66ms (224.15ms CPU time)\n\nRan 11 tests for test/DeezToken.t.sol:DeezTokenTest\n[PASS] testFuzz_cumulativeBalanceMatchesHoldingTime(uint96,uint32,uint32) (runs: 256, μ: 283608, ~: 283574)\n[PASS] testFuzz_pastBalanceMatchesBalanceAtThatTime(uint96,uint96,uint32) (runs: 256, μ: 264892, ~: 265162)\n[PASS] test_cumulativeBalanceAllowsTheCurrentSecondButNotTheFuture() (gas: 11964)\n[PASS] test_cumulativeBalanceIntegratesHoldingTime() (gas: 510668)\n[PASS] test_cumulativeBalanceRefusesTheFuture() (gas: 20155)\n[PASS] test_metadataAndSupply() (gas: 51264)\n[PASS] test_noMintOwnerOrPause() (gas: 147107)\n[PASS] test_pastBalanceRefusesTheCurrentSecondAndTheFuture() (gas: 22620)\n[PASS] test_pastBalancesFollowTransfers() (gas: 458770)\n[PASS] test_transferFromRespectsAllowance() (gas: 309071)\n[PASS] test_transferMovesExactlyWhatItWasAsked() (gas: 125405)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 125.60ms (223.88ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken0Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1191703)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 931915)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 628629)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 954747)\n[PASS] test_lockBothBecomesFullRange() (gas: 1249175)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1161767)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 822866)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 20366189)\n[PASS] test_lockRefusesNothing() (gas: 53515)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1044738)\n[PASS] test_wiring() (gas: 37454)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 125.66ms (29.28ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken0Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 770275, ~: 770523)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 782426, ~: 782554)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 804028)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 773000)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 807312)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 953247)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122950)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 9036)\n[PASS] test_constructorWiresTheDistributor() (gas: 54167)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 782231)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 915662)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 870500)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 628934)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 955419)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1403852)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 962171)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1283991)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1128998)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43121)\n[PASS] test_hookHasNoOwner() (gas: 54392)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 20405597)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1060042)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 21015718)\n[PASS] test_refusesASecondPool() (gas: 46701)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 808824)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 796847)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1115173)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 125.67ms (214.64ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken1Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 775790, ~: 775912)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 776866, ~: 777105)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 809451)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 782766)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 811421)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 964326)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122926)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 9036)\n[PASS] test_constructorWiresTheDistributor() (gas: 54167)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 777292)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 931494)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 886466)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 624203)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 976743)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1409258)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 967463)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1289283)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1134290)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43121)\n[PASS] test_hookHasNoOwner() (gas: 54392)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 192396393)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1065465)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 193096784)\n[PASS] test_refusesASecondPool() (gas: 46689)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 803381)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 792718)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1114818)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 125.62ms (261.23ms CPU time)\n\nRan 21 tests for test/DeezLaunch.t.sol:DeezLaunchToken1Test\n[PASS] testFuzz_minimumAndConservationAcrossOpeningPrices(int24) (runs: 256, μ: 7780783, ~: 7781085)\n[PASS] test_badHookSaltRollsBackTokenCreation() (gas: 5265152)\n[PASS] test_cannotLaunchInsideManagerUnlock() (gas: 6700326)\n[PASS] test_cannotWithdrawLockedPositionOrBalances() (gas: 7769384)\n[PASS] test_constructorNeedsNoLiveDependencies() (gas: 561072)\n[PASS] test_constructorRejectsInvalidRecipientsAndDependencies() (gas: 8937)\n[PASS] test_invalidOpeningPriceRollsBackAllContracts() (gas: 7047417)\n[PASS] test_laterFactoryFailureRollsBackTheEntireLaunch() (gas: 7245657)\n[PASS] test_launchDeploysFundsAndLocksInOneCall() (gas: 7828711)\n[PASS] test_launcherHasNoOngoingAdminAndFitsDeploymentLimits() (gas: 102575)\n[PASS] test_minimumCheckFailureRollsBackThePositionAndEveryContract() (gas: 15222809)\n[PASS] test_missingLiveDependencyFailsBeforeCreatingAnything() (gas: 597643)\n[PASS] test_onlyConfiguredFactoryCanLaunch() (gas: 588558)\n[PASS] test_ordinaryTransfersAndRewardsStillWork() (gas: 9582843)\n[PASS] test_pairedTokenDustCannotChangeLockMode() (gas: 7861165)\n[PASS] test_pinnedCodeHashesMatchReviewedArtifacts() (gas: 43076)\n[PASS] test_rejectsAlteredHookCodeBeforeCreatingAnything() (gas: 627495)\n[PASS] test_rejectsAlteredTokenCodeBeforeCreatingAnything() (gas: 597990)\n[PASS] test_rejectsSecondLaunch() (gas: 8211419)\n[PASS] test_rejectsWrongChain() (gas: 588689)\n[PASS] test_unfundableSingleSidedRangeRollsBackAllContracts() (gas: 7162412)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 127.42ms (76.65ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken1Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1911241)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 846759)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 969420)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 192282674)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 960555)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61939)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71544)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 138.52ms (78.54ms CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken0Test\n[PASS]\nDeezHookInvariantToken0Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken0Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 460.65ms (450.79ms CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken1Test\n[PASS]\nDeezHookInvariantToken1Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken1Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 519.90ms (488.37ms CPU time)\n\nRan 1 test for test/DeezRewardsInvariant.t.sol:DeezRewardsInvariantTest\n[PASS]\nDeezRewardsInvariantTest invariants:\n[PASS] invariant_claimsNeverExceedTheBalanceShare\n[PASS] invariant_closedEpochsNeverReopen\n[PASS] invariant_holdsAtLeastWhatItReserved\n[PASS] invariant_imdIsConserved\n[PASS] invariant_noHolderIsPaidMoreThanItsShareOfAnyPot\n[PASS] invariant_noPotPaysMoreThanItHolds\n[PASS] invariant_onlyTheAccountClaimsItsShare\n[PASS] invariant_pendingFeesAreTrackedExactly\n[PASS] invariant_reservedEqualsWhatOpenPotsOwe\n[PASS] invariant_supplyNeverChanges\n DeezRewardsInvariantTest invariants (runs: 256, calls: 15360, reverts: 0)\n\n╭----------------+---------------------+-------+---------+----------╮\n| Contract       | Selector            | Calls | Reverts | Discards |\n+===================================================================+\n| RewardsHandler | claim               | 1520  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | claimFor            | 1582  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | finalize            | 1497  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | fund                | 1506  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | harvest             | 1554  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | lateFee             | 1503  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | recycle             | 1561  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | transfer            | 1508  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warp                | 1557  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warpPastClaimWindow | 1572  | 0       | 0        |\n╰----------------+---------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.11s (4.11s CPU time)\n\nRan 15 test suites in 4.12s (6.37s CPU time): 200 tests passed, 0 failed, 0 skipped (200 total tests)\n","passed":true},{"durationMs":89,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"DeezHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"DeezHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"DeezHook.harvest()\",\"DeezHook.harvestEpochs(uint256[])\",\"DeezHook.unlockCallback(bytes)\",\"DeezLaunch.launch((bytes32,bytes32,uint160),bytes,bytes)\",\"DeezLiquidityLock.lock()\",\"DeezLiquidityLock.lockAs(uint8,int24,int24)\",\"DeezLiquidityLock.unlockCallback(bytes)\",\"DeezRewards.accrue()\",\"DeezRewards.claim(address,uint256[])\",\"DeezRewards.credit(uint256,uint256)\",\"DeezRewards.finalize(uint256)\",\"DeezRewards.recycle(uint256)\",\"DeezToken.approve(address,uint256)\",\"DeezToken.transfer(address,uint256)\",\"DeezToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":6,\"README.md\":359,\"docs/MAINNET.md\":155,\"docs/SECURITY_REVIEW.md\":63,\"docs/deployment.md\":24,\"foundry.toml\":20,\"remappings.txt\":5,\"site/deez.config.js\":33,\"site/index.html\":328,\"site/logo.svg\":10,\"src/DeezHook.sol\":341,\"src/DeezLaunch.sol\":191,\"src/DeezLiquidityLock.sol\":193,\"src/DeezRewards.sol\":262,\"src/DeezToken.sol\":144,\"src/HookFlags.sol\":34,\"test/DeezBase.t.sol\":123,\"test/DeezFailurePaths.t.sol\":593,\"test/DeezFlywheel.t.sol\":150,\"test/DeezHook.t.sol\":387,\"test/DeezHookInvariant.t.sol\":153,\"test/DeezLaunch.t.sol\":368,\"test/DeezLiquidityLock.t.sol\":175,\"test/DeezRewards.t.sol\":448,\"test/DeezRewardsInvariant.t.sol\":304,\"test/DeezToken.t.sol\":174,\"test/mocks/MockERC20.sol\":15,\"test/mocks/MockHook.sol\":36,\"test/mocks/Swapper.sol\":85,\"test/test_launch_tools.py\":199,\"tools/launch_common.py\":95,\"tools/prepare_launch.py\":81,\"tools/publish_deployment.py\":210},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":4976,"exitCode":0,"name":"slither","output":"[high/high] encode-packed-collision at src/DeezLaunch.sol:108: DeezLaunch.launch(DeezLaunch.Parameters,bytes,bytes) (src/DeezLaunch.sol#108-174) calls abi.encodePacked() with multiple dynamic arguments:\n[high/high] uninitialized-state at src/DeezToken.sol:86: DeezToken._history (src/DeezToken.sol#36) is never initialized. It is used in:\n[medium/medium] divide-before-multiply at src/DeezLiquidityLock.sol:183: DeezLiquidityLock._floorToSpacing(int24,int24) (src/DeezLiquidityLock.sol#183-187) performs a multiplication on the result of a division:\n[medium/high] incorrect-equality at src/DeezLiquidityLock.sol:92: DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#92-124) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/DeezLiquidityLock.sol:92: DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#92-124) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/DeezToken.sol:109: DeezToken._checkpoint(address) (src/DeezToken.sol#109-126) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/DeezLiquidityLock.sol:92: DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#92-124) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/DeezLiquidityLock.sol:92: DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#92-124) uses a dangerous strict equality:\n[medium/medium] unused-return at src/DeezLiquidityLock.sol:142: DeezLiquidityLock._settle(Currency,int128) (src/DeezLiquidityLock.sol#142-148) ignores return value by poolManager.settle() (src/DeezLiquidityLock.sol#147)\n[medium/medium] unused-return at src/DeezHook.sol:212: DeezHook._harvest(uint256[]) (src/DeezHook.sol#212-228) ignores return value by poolManager.unlock(abi.encode(amount)) (src/DeezHook.sol#223)\n[medium/medium] unused-return at src/DeezRewards.sol:212: DeezRewards.claim(address,uint256[]) (src/DeezRewards.sol#212-233) ignores return value by IDeezHarvester(hook).harvestEpochs(epochs) (src/DeezRewards.sol#215)\n[medium/medium] unused-return at src/DeezHook.sol:212: DeezHook._harvest(uint256[]) (src/DeezHook.sol#212-228) ignores return value by rewards.accrue() (src/DeezHook.sol#222)\n[medium/medium] unused-return at src/DeezLaunch.sol:108: DeezLaunch.launch(DeezLaunch.Parameters,bytes,bytes) (src/DeezLaunch.sol#108-174) ignores return value by liquidityLock.lockAs(DeezLiquidityLock.Mode.Token1Only,openingTick,openingTick) (src/DeezLaunch.sol#151-153)\n[medium/medium] unused-return at src/DeezLiquidityLock.sol:127: DeezLiquidityLock.unlockCallback(bytes) (src/DeezLiquidityLock.sol#127-140) ignores return value by (delta,None) = poolManager.modifyLiquidity(key,ModifyLiquidityParams({tickLower:tickLower,tickUpper:tickUpper,liquidityDelta:int256(uint256(liquidity)),salt:bytes32(0)}),) (src/DeezLiquidityLock.sol#130-136)\n[medium/medium] unused-return at src/DeezLaunch.sol:108: DeezLaunch.launch(DeezLaunch.Parameters,bytes,bytes) (src/DeezLaunch.sol#108-174) ignores return value by liquidityLock.lockAs(DeezLiquidityLock.Mode.Token0Only,openingTick,openingTick) (src/DeezLaunch.sol#151-153)\n[medium/medium] unused-return at src/DeezLiquidityLock.sol:92: DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#92-124) ignores return value by (sqrtPriceX96,tick,None,None) = poolManager.getSlot0(key.toId()) (src/DeezLiquidityLock.sol#101)\n[low/medium] calls-loop at src/DeezHook.sol:212: DeezHook._harvest(uint256[]) (src/DeezHook.sol#212-228) has external calls inside a loop: rewards.credit(epochs[i_scope_0],amounts[i_scope_0]) (src/DeezHook.sol#225)\n[low/medium] calls-loop at src/DeezHook.sol:212: DeezHook._harvest(uint256[]) (src/DeezHook.sol#212-228) has external calls inside a loop: rewards.credit(epochs[i_scope_0],amounts[i_scope_0]) (src/DeezHook.sol#225)\n[low/medium] calls-loop at src/DeezRewards.sol:137: DeezRewards.eligibleSupplyAt(uint256) (src/DeezRewards.sol#137-143) has external calls inside a loop: total = token.getCumulativeTotalSupply(start + EPOCH_LENGTH) - token.getCumulativeTotalSupply(start) (src/DeezRewards.sol#139)\n[low/medium] calls-loop at src/DeezRewards.sol:148: DeezRewards.claimable(address,uint256) (src/DeezRewards.sol#148-157) has external calls inside a loop: total = pot.total + IDeezHarvester(hook).pendingFeesOf(epoch) (src/DeezRewards.sol#152)\n[low/medium] calls-loop at src/DeezRewards.sol:130: DeezRewards.weightOf(address,uint256) (src/DeezRewards.sol#130-134) has external calls inside a loop: token.getCumulativeBalanceOf(account,start + EPOCH_LENGTH) - token.getCumulativeBalanceOf(account,start) (src/DeezRewards.sol#132-133)\n[low/medium] calls-loop at src/DeezRewards.sol:130: DeezRewards.weightOf(address,uint256) (src/DeezRewards.sol#130-134) has external calls inside a loop: token.getCumulativeBalanceOf(account,start + EPOCH_LENGTH) - token.getCumulativeBalanceOf(account,start) (src/DeezRewards.sol#132-133)\n[low/medium] calls-loop at src/DeezRewards.sol:137: DeezRewards.eligibleSupplyAt(uint256) (src/DeezRewards.sol#137-143) has external calls inside a loop: total = token.getCumulativeTotalSupply(start + EPOCH_LENGTH) - token.getCumulativeTotalSupply(start) (src/DeezRewards.sol#139)\n[low/medium] reentrancy-benign at src/DeezRewards.sol:212: Reentrancy in DeezRewards.claim(address,uint256[]) (src/DeezRewards.sol#212-233):\n[low/medium] reentrancy-benign at src/DeezLaunch.sol:108: Reentrancy in DeezLaunch.launch(DeezLaunch.Parameters,bytes,bytes) (src/DeezLaunch.sol#108-174):\n[low/medium] reentrancy-benign at src/DeezLiquidityLock.sol:92: Reentrancy in DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#92-124):\n[low/medium] reentrancy-benign at src/DeezHook.sol:174: Reentrancy in DeezHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/DeezHook.sol#174-192):\n[low/medium] reentrancy-events at src/DeezLiquidityLock.sol:92: Reentrancy in DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#92-124):\n[low/medium] reentrancy-events at src/DeezHook.sol:174: Reentrancy in DeezHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/DeezHook.sol#174-192):\n[low/medium] reentrancy-events at src/DeezHook.sol:212: Reentrancy in DeezHook._harvest(uint256[]) (src/DeezHook.sol#212-228):\n[low/medium] reentrancy-events at src/DeezLaunch.sol:108: Reentrancy in DeezLaunch.launch(DeezLaunch.Parameters,bytes,bytes) (src/DeezLaunch.sol#108-174):\n[low/medium] timestamp at src/DeezRewards.sol:185: DeezRewards.credit(uint256,uint256) (src/DeezRewards.sol#185-193) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:56: DeezToken.getPastBalanceOf(address,uint256) (src/DeezToken.sol#56-61) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezRewards.sol:148: DeezRewards.claimable(address,uint256) (src/DeezRewards.sol#148-157) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezRewards.sol:119: DeezRewards.hasEnded(uint256) (src/DeezRewards.sol#119-121) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:78: DeezToken.getCumulativeTotalSupply(uint256) (src/DeezToken.sol#78-83) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:68: DeezToken.getCumulativeBalanceOf(address,uint256) (src/DeezToken.sol#68-74) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezRewards.sol:236: DeezRewards.recycle(uint256) (src/DeezRewards.sol#236-246) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:109: DeezToken._checkpoint(address) (src/DeezToken.sol#109-126) uses timestamp for comparisons","passed":false}],"detail":"static analysis found encode-packed-collision at src/DeezLaunch.sol:108: DeezLaunch.launch(DeezLaunch.Parameters,bytes,bytes) (src/DeezLaunch.sol#108-174) calls abi.encodePacked() with multiple dynamic arguments:","evaluation":"checks","profile":"foundry","status":"rejected","submissionHash":"06220ce0b6010e7f03bb2f2d2cdc32b2c2f4c8567c750cf0b3b01839b8748a7c","verifiedTreeHash":"f9e65ca71cbcef2e9f94e6a9710440db7bf2c666","verifierVersion":"0.1.0+a6ee6548"},{"checks":[{"durationMs":75791,"exitCode":0,"name":"build","output":"Compiling 102 files with Solc 0.8.26\nSolc 0.8.26 finished in 75.69s\nCompiler run successful!\n","passed":true},{"durationMs":4173,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/DeezFlywheel.t.sol:DeezFlywheelTest\n[PASS] test_earlyClaimerGetsItsShareOfFeesHarvestedLater() (gas: 2188569)\n[PASS] test_feesBelongToTheEpochTheyWereTradedInWheneverHarvested() (gas: 1178253)\n[PASS] test_lastSecondBuyerCannotSnipeTheEpochsPot() (gas: 1664409)\n[PASS] test_tradesBecomeHolderRewards() (gas: 1965479)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 17.81ms (3.00ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken0Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1208385)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 940446)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 964014)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266888)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1172198)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 830366)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 12216088)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054091)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 30.99ms (15.28ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken0Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1924388)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 844044)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 969168)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 12132258)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969833)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61951)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71556)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 45.49ms (25.07ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken1Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1930064)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 850257)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 974591)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 1213224)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969821)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61939)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71544)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 49.52ms (4.44ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken1Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1212044)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 935043)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 967677)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266876)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1193447)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 826726)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 1298755)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054079)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 51.15ms (5.30ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken1Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 778178, ~: 778326)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 779306, ~: 779547)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 811875)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 785146)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 813845)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 969453)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122947)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 779716)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 933874)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 887772)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 625465)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 978005)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1417783)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 971005)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1294664)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1140667)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 1331484)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1070022)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 1910765)\n[PASS] test_refusesASecondPool() (gas: 46689)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 805849)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 795142)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119478)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 125.79ms (114.88ms CPU time)\n\nRan 23 tests for test/DeezFailurePaths.t.sol:DeezRewardsFailurePathsTest\n[PASS] testFuzz_allHoldersTogetherNeverDrainMoreThanThePot(uint96,uint96,uint128,uint32,uint32) (runs: 512, μ: 942665, ~: 1014207)\n[PASS] testFuzz_claimOrderAndLateFeesDoNotChangeFinalShares(uint96,uint128,uint128,uint8,uint32) (runs: 512, μ: 1201935, ~: 1162326)\n[PASS] test_accrueWithNothingNewCreditsNothing() (gas: 222432)\n[PASS] test_balanceMovedInTheFirstSecondOfTheNextEpochDoesNotCount() (gas: 574119)\n[PASS] test_batchWithAnUnendedEpochPaysNothing() (gas: 430676)\n[PASS] test_closedEpochRefusesClaimsAndASecondRecycle() (gas: 333820)\n[PASS] test_creditCannotBeForgedOrOverdrawn() (gas: 214111)\n[PASS] test_duplicateEpochInOneBatchPaysItOnce() (gas: 488462)\n[PASS] test_emptyBatchReverts() (gas: 226474)\n[PASS] test_epochWithNoEligibleSupplyPaysNobodyAndIsRecycled() (gas: 643921)\n[PASS] test_excludedAddressesCannotClaimEvenForThemselves() (gas: 339255)\n[PASS] test_finalizeIsIdempotentAndIgnoresLaterTransfers() (gas: 398192)\n[PASS] test_holderWithNoBalanceInTheEpochHasNothingToClaim() (gas: 348086)\n[PASS] test_lastSecondBuyerWeighsOneSecond() (gas: 772291)\n[PASS] test_lateFeeAfterSomeClaimedStillSplitsExactlyByBalance() (gas: 731534)\n[PASS] test_nobodyCanClaimForSomeoneElse() (gas: 445168)\n[PASS] test_pendingFeesOfAClosedEpochGoToTheCurrentPot() (gas: 519437)\n[PASS] test_recycleOfAnEpochThatNeverHadAPotClosesItForNothing() (gas: 100110)\n[PASS] test_recycleOpensExactlyAfterTheClaimWindow() (gas: 451085)\n[PASS] test_recycledRewardsArePaidByTheNewEpochsBalances() (gas: 557732)\n[PASS] test_shareThatRoundsToZeroIsRefusedNotPaid() (gas: 479436)\n[PASS] test_unaccruedDonationGoesToTheCurrentEpochNotAnEndedOne() (gas: 435339)\n[PASS] test_weightReadsRevertUntilTheEpochHasEnded() (gas: 225629)\nSuite result: ok. 23 passed; 0 failed; 0 skipped; finished in 125.95ms (242.76ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken0Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 772646, ~: 772873)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 784844, ~: 784962)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 806452)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 775380)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 809736)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 958374)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122971)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 784655)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 918042)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 871806)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 630196)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 956681)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1412377)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 965713)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1289372)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1135375)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 12248802)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1064599)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 12848869)\n[PASS] test_refusesASecondPool() (gas: 46701)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 811292)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 799271)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119833)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 273.00ms (340.72ms CPU time)\n\nRan 15 tests for test/DeezLaunch.t.sol:DeezLaunchToken1Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8603)\n[PASS] test_factoryDeploymentLeavesEverythingUnlaunched() (gas: 56007)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 87747180)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 87557225)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 85083744)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 86034517)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 84946784)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926385)\n[PASS] test_launchRunsOnce() (gas: 172667574)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 88717621)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74088)\n[PASS] test_nothingIsOwned() (gas: 107289)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 13976)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 89343226)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 3059366)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 339.74ms (1.75s CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken0Test\n[PASS]\nDeezHookInvariantToken0Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken0Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 470.77ms (454.06ms CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken1Test\n[PASS]\nDeezHookInvariantToken1Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken1Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 524.79ms (480.16ms CPU time)\n\nRan 15 tests for test/DeezLaunch.t.sol:DeezLaunchToken0Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8603)\n[PASS] test_factoryDeploymentLeavesEverythingUnlaunched() (gas: 56007)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 34392656)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 34203997)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 31734402)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 32683030)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 31597519)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926385)\n[PASS] test_launchRunsOnce() (gas: 65760112)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 35357205)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74088)\n[PASS] test_nothingIsOwned() (gas: 107289)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 13976)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 35987237)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 181482498)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 1.21s (1.94s CPU time)\n\nRan 24 tests for test/DeezRewards.t.sol:DeezRewardsTest\n[PASS] testFuzz_claimsNeverExceedThePotAndSplitByBalance(uint96,uint96,uint96) (runs: 256, μ: 848437, ~: 848411)\n[PASS] testFuzz_claimsNeverExceedThePotWithMidEpochMoves(uint96,uint32,uint32,uint96) (runs: 256, μ: 1208858, ~: 1208934)\n[PASS] test_accrueCreditsTheCurrentEpochOnce() (gas: 195183)\n[PASS] test_balanceMovedAfterTheEpochDoesNotChangeIt() (gas: 759363)\n[PASS] test_claimBeforeTheEpochEndsReverts() (gas: 341765)\n[PASS] test_claimHarvestsOnlyTheEpochsItPays() (gas: 626503)\n[PASS] test_claimHarvestsThePendingFeesOfTheEpochFirst() (gas: 990070)\n[PASS] test_claimManyEpochsAtOnce() (gas: 1066960)\n[PASS] test_claimsAreProportionalToTheAverageBalance() (gas: 1310733)\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8803)\n[PASS] test_creditGoesToTheEpochTheHookNames() (gas: 436426)\n[PASS] test_creditRefusesOthersAndUnfundedAmounts() (gas: 227829)\n[PASS] test_creditToAClosedOrFutureEpochGoesToTheCurrentOne() (gas: 411044)\n[PASS] test_deployerShareIsProportionalToo() (gas: 681654)\n[PASS] test_doubleClaimPaysNothingMore() (gas: 833135)\n[PASS] test_emptyClaimReverts() (gas: 387104)\n[PASS] test_epochArithmetic() (gas: 31685)\n[PASS] test_excludedAddresses() (gas: 41878)\n[PASS] test_excludedAddressesCannotClaim() (gas: 251970)\n[PASS] test_finalizeRequiresAnEndedEpoch() (gas: 198268)\n[PASS] test_lateCreditIsPaidOnASecondClaim() (gas: 1076754)\n[PASS] test_onlyTheAccountItselfCanClaim() (gas: 847409)\n[PASS] test_recycleFoldsUnclaimedIntoTheCurrentEpoch() (gas: 946576)\n[PASS] test_rewardsAreWeightedByHoldingTime() (gas: 1046850)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 1.21s (265.07ms CPU time)\n\nRan 11 tests for test/DeezToken.t.sol:DeezTokenTest\n[PASS] testFuzz_cumulativeBalanceMatchesHoldingTime(uint96,uint32,uint32) (runs: 256, μ: 284536, ~: 284486)\n[PASS] testFuzz_pastBalanceMatchesBalanceAtThatTime(uint96,uint96,uint32) (runs: 256, μ: 266271, ~: 266538)\n[PASS] test_cumulativeBalanceAllowsTheCurrentSecondButNotTheFuture() (gas: 12108)\n[PASS] test_cumulativeBalanceIntegratesHoldingTime() (gas: 514182)\n[PASS] test_cumulativeBalanceRefusesTheFuture() (gas: 20199)\n[PASS] test_metadataAndSupply() (gas: 51418)\n[PASS] test_noMintOwnerOrPause() (gas: 147261)\n[PASS] test_pastBalanceRefusesTheCurrentSecondAndTheFuture() (gas: 22664)\n[PASS] test_pastBalancesFollowTransfers() (gas: 461865)\n[PASS] test_transferFromRespectsAllowance() (gas: 310333)\n[PASS] test_transferMovesExactlyWhatItWasAsked() (gas: 126080)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 1.21s (340.41ms CPU time)\n\nRan 1 test for test/DeezRewardsInvariant.t.sol:DeezRewardsInvariantTest\n[PASS]\nDeezRewardsInvariantTest invariants:\n[PASS] invariant_claimsNeverExceedTheBalanceShare\n[PASS] invariant_closedEpochsNeverReopen\n[PASS] invariant_holdsAtLeastWhatItReserved\n[PASS] invariant_imdIsConserved\n[PASS] invariant_noHolderIsPaidMoreThanItsShareOfAnyPot\n[PASS] invariant_noPotPaysMoreThanItHolds\n[PASS] invariant_onlyTheAccountClaimsItsShare\n[PASS] invariant_pendingFeesAreTrackedExactly\n[PASS] invariant_reservedEqualsWhatOpenPotsOwe\n[PASS] invariant_supplyNeverChanges\n DeezRewardsInvariantTest invariants (runs: 256, calls: 15360, reverts: 0)\n\n╭----------------+---------------------+-------+---------+----------╮\n| Contract       | Selector            | Calls | Reverts | Discards |\n+===================================================================+\n| RewardsHandler | claim               | 1520  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | claimFor            | 1582  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | finalize            | 1497  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | fund                | 1506  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | harvest             | 1554  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | lateFee             | 1503  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | recycle             | 1561  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | transfer            | 1508  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warp                | 1557  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warpPastClaimWindow | 1572  | 0       | 0        |\n╰----------------+---------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.05s (4.04s CPU time)\n\nRan 15 test suites in 4.05s (9.73s CPU time): 187 tests passed, 0 failed, 0 skipped (187 total tests)\n","passed":true},{"durationMs":76,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"DeezHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"DeezHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"DeezHook.harvest()\",\"DeezHook.harvestEpochs(uint256[])\",\"DeezHook.unlockCallback(bytes)\",\"DeezLaunch.launch(address,address,address,bytes32)\",\"DeezLiquidityLock.lock()\",\"DeezLiquidityLock.lockAs(uint8,int24,int24)\",\"DeezLiquidityLock.unlockCallback(bytes)\",\"DeezRewards.accrue()\",\"DeezRewards.claim(address,uint256[])\",\"DeezRewards.credit(uint256,uint256)\",\"DeezRewards.finalize(uint256)\",\"DeezRewards.recycle(uint256)\",\"DeezRewards.setHook(address)\",\"DeezToken.approve(address,uint256)\",\"DeezToken.transfer(address,uint256)\",\"DeezToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":217,\"foundry.toml\":20,\"launch.json\":36,\"remappings.txt\":5,\"script/MineHookSalt.s.sol\":42,\"site/deez.config.js\":27,\"site/index.html\":319,\"site/logo.svg\":10,\"src/DeezHook.sol\":359,\"src/DeezLaunch.sol\":199,\"src/DeezLiquidityLock.sol\":237,\"src/DeezRewards.sol\":295,\"src/DeezToken.sol\":150,\"src/HookFlags.sol\":34,\"test/DeezBase.t.sol\":140,\"test/DeezFailurePaths.t.sol\":530,\"test/DeezFlywheel.t.sol\":150,\"test/DeezHook.t.sol\":396,\"test/DeezHookInvariant.t.sol\":153,\"test/DeezLaunch.t.sol\":410,\"test/DeezLiquidityLock.t.sol\":175,\"test/DeezRewards.t.sol\":451,\"test/DeezRewardsInvariant.t.sol\":305,\"test/DeezToken.t.sol\":174,\"test/mocks/MockERC20.sol\":15,\"test/mocks/MockHook.sol\":36,\"test/mocks/Swapper.sol\":85},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"114059a82a38996b57ce2f9e900052438984c47f24601271f3bc8052ba7bcc94","verifiedTreeHash":"b8b801955ee0e2b1b2ec5585e33b18168798fcda","verifierVersion":"0.1.0+a6ee6548"},{"checks":[{"durationMs":111434,"exitCode":0,"name":"build","output":"Compiling 108 files with Solc 0.8.26\nSolc 0.8.26 finished in 111.32s\nCompiler run successful!\n","passed":true},{"durationMs":9071,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 3 tests for test/DeezRewardsTransferFailures.t.sol:DeezRewardsTransferFailuresTest\n[PASS] test_falseReturningPayoutRollsBackHarvestAccrualAndClaim() (gas: 724499)\n[PASS] test_payoutCallbackCannotReenterClaimAndOuterClaimCompletesOnce() (gas: 537418)\n[PASS] test_revertingPayoutRollsBackHarvestAccrualAndClaim() (gas: 724360)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.90ms (1.11ms CPU time)\n\nRan 4 tests for test/DeezLaunchRollback.t.sol:DeezLaunchRollbackToken0Test\n[PASS] test_finalPayoutFailureRollsBackBothLiquidityAddsAndAllowsRetry() (gas: 5424012)\n[PASS] test_poolInitializationFailureRollsBackHookDeploymentAndWiring() (gas: 4838949)\n[PASS] test_requesterLockTransferFailureRollsBackThePoolSeed() (gas: 5369691)\n[PASS] test_requesterTransfersDirectlyToLockBeforeWalletPayoutWithinLaunchCall() (gas: 2691848)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 8.16ms (3.09ms CPU time)\n\nRan 4 tests for test/DeezLaunchRollback.t.sol:DeezLaunchRollbackToken1Test\n[PASS] test_finalPayoutFailureRollsBackBothLiquidityAddsAndAllowsRetry() (gas: 5431898)\n[PASS] test_poolInitializationFailureRollsBackHookDeploymentAndWiring() (gas: 4842885)\n[PASS] test_requesterLockTransferFailureRollsBackThePoolSeed() (gas: 5378285)\n[PASS] test_requesterTransfersDirectlyToLockBeforeWalletPayoutWithinLaunchCall() (gas: 2695791)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 17.23ms (3.74ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken0Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1924388)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 844044)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 969168)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 12132258)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969833)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61951)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71556)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 23.42ms (13.56ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken1Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1930064)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 850257)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 974591)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 1213224)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969821)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61939)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71544)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 38.38ms (4.44ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken0Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1208385)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 940446)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 964014)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266888)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1172198)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 830366)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 12216088)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054091)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 40.89ms (24.91ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken1Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1212044)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 935043)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 967677)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266876)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1193447)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 826726)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 1298755)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054079)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 55.43ms (5.31ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken1Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 778178, ~: 778326)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 779306, ~: 779547)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 811875)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 785146)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 813845)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 969453)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122947)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 779716)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 933874)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 887772)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 625465)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 978005)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1417783)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 971005)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1294664)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1140667)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 1331484)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1070022)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 1910765)\n[PASS] test_refusesASecondPool() (gas: 46689)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 805849)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 795142)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119478)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 178.00ms (185.49ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken0Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 772646, ~: 772873)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 784844, ~: 784962)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 806452)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 775380)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 809736)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 958374)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122971)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 784655)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 918042)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 871806)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 630196)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 956681)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1412377)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 965713)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1289372)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1135375)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 12248802)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1064599)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 12848869)\n[PASS] test_refusesASecondPool() (gas: 46701)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 811292)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 799271)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119833)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 178.00ms (201.59ms CPU time)\n\nRan 11 tests for test/DeezToken.t.sol:DeezTokenTest\n[PASS] testFuzz_cumulativeBalanceMatchesHoldingTime(uint96,uint32,uint32) (runs: 256, μ: 284541, ~: 284487)\n[PASS] testFuzz_pastBalanceMatchesBalanceAtThatTime(uint96,uint96,uint32) (runs: 256, μ: 266273, ~: 266544)\n[PASS] test_cumulativeBalanceAllowsTheCurrentSecondButNotTheFuture() (gas: 12108)\n[PASS] test_cumulativeBalanceIntegratesHoldingTime() (gas: 514182)\n[PASS] test_cumulativeBalanceRefusesTheFuture() (gas: 20199)\n[PASS] test_metadataAndSupply() (gas: 51418)\n[PASS] test_noMintOwnerOrPause() (gas: 147261)\n[PASS] test_pastBalanceRefusesTheCurrentSecondAndTheFuture() (gas: 22664)\n[PASS] test_pastBalancesFollowTransfers() (gas: 461865)\n[PASS] test_transferFromRespectsAllowance() (gas: 310333)\n[PASS] test_transferMovesExactlyWhatItWasAsked() (gas: 126080)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 181.83ms (363.82ms CPU time)\n\nRan 4 tests for test/DeezFlywheel.t.sol:DeezFlywheelTest\n[PASS] test_earlyClaimerGetsItsShareOfFeesHarvestedLater() (gas: 2188569)\n[PASS] test_feesBelongToTheEpochTheyWereTradedInWheneverHarvested() (gas: 1178253)\n[PASS] test_lastSecondBuyerCannotSnipeTheEpochsPot() (gas: 1664409)\n[PASS] test_tradesBecomeHolderRewards() (gas: 1965479)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 215.13ms (3.30ms CPU time)\n\nRan 23 tests for test/DeezFailurePaths.t.sol:DeezRewardsFailurePathsTest\n[PASS] testFuzz_allHoldersTogetherNeverDrainMoreThanThePot(uint96,uint96,uint128,uint32,uint32) (runs: 512, μ: 941221, ~: 1006195)\n[PASS] testFuzz_claimOrderAndLateFeesDoNotChangeFinalShares(uint96,uint128,uint128,uint8,uint32) (runs: 512, μ: 1196440, ~: 1162052)\n[PASS] test_accrueWithNothingNewCreditsNothing() (gas: 222432)\n[PASS] test_balanceMovedInTheFirstSecondOfTheNextEpochDoesNotCount() (gas: 574119)\n[PASS] test_batchWithAnUnendedEpochPaysNothing() (gas: 430676)\n[PASS] test_closedEpochRefusesClaimsAndASecondRecycle() (gas: 333820)\n[PASS] test_creditCannotBeForgedOrOverdrawn() (gas: 214111)\n[PASS] test_duplicateEpochInOneBatchPaysItOnce() (gas: 488462)\n[PASS] test_emptyBatchReverts() (gas: 226474)\n[PASS] test_epochWithNoEligibleSupplyPaysNobodyAndIsRecycled() (gas: 643921)\n[PASS] test_excludedAddressesCannotClaimEvenForThemselves() (gas: 339255)\n[PASS] test_finalizeIsIdempotentAndIgnoresLaterTransfers() (gas: 398192)\n[PASS] test_holderWithNoBalanceInTheEpochHasNothingToClaim() (gas: 348086)\n[PASS] test_lastSecondBuyerWeighsOneSecond() (gas: 772291)\n[PASS] test_lateFeeAfterSomeClaimedStillSplitsExactlyByBalance() (gas: 731534)\n[PASS] test_nobodyCanClaimForSomeoneElse() (gas: 445168)\n[PASS] test_pendingFeesOfAClosedEpochGoToTheCurrentPot() (gas: 519437)\n[PASS] test_recycleOfAnEpochThatNeverHadAPotClosesItForNothing() (gas: 100110)\n[PASS] test_recycleOpensExactlyAfterTheClaimWindow() (gas: 451085)\n[PASS] test_recycledRewardsArePaidByTheNewEpochsBalances() (gas: 557732)\n[PASS] test_shareThatRoundsToZeroIsRefusedNotPaid() (gas: 479436)\n[PASS] test_unaccruedDonationGoesToTheCurrentEpochNotAnEndedOne() (gas: 435339)\n[PASS] test_weightReadsRevertUntilTheEpochHasEnded() (gas: 225629)\nSuite result: ok. 23 passed; 0 failed; 0 skipped; finished in 330.74ms (546.43ms CPU time)\n\nRan 24 tests for test/DeezRewards.t.sol:DeezRewardsTest\n[PASS] testFuzz_claimsNeverExceedThePotAndSplitByBalance(uint96,uint96,uint96) (runs: 256, μ: 848437, ~: 848411)\n[PASS] testFuzz_claimsNeverExceedThePotWithMidEpochMoves(uint96,uint32,uint32,uint96) (runs: 256, μ: 1208854, ~: 1208931)\n[PASS] test_accrueCreditsTheCurrentEpochOnce() (gas: 195183)\n[PASS] test_balanceMovedAfterTheEpochDoesNotChangeIt() (gas: 759363)\n[PASS] test_claimBeforeTheEpochEndsReverts() (gas: 341765)\n[PASS] test_claimHarvestsOnlyTheEpochsItPays() (gas: 626503)\n[PASS] test_claimHarvestsThePendingFeesOfTheEpochFirst() (gas: 990070)\n[PASS] test_claimManyEpochsAtOnce() (gas: 1066960)\n[PASS] test_claimsAreProportionalToTheAverageBalance() (gas: 1310733)\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8803)\n[PASS] test_creditGoesToTheEpochTheHookNames() (gas: 436426)\n[PASS] test_creditRefusesOthersAndUnfundedAmounts() (gas: 227829)\n[PASS] test_creditToAClosedOrFutureEpochGoesToTheCurrentOne() (gas: 411044)\n[PASS] test_deployerShareIsProportionalToo() (gas: 681654)\n[PASS] test_doubleClaimPaysNothingMore() (gas: 833135)\n[PASS] test_emptyClaimReverts() (gas: 387104)\n[PASS] test_epochArithmetic() (gas: 31685)\n[PASS] test_excludedAddresses() (gas: 41878)\n[PASS] test_excludedAddressesCannotClaim() (gas: 251970)\n[PASS] test_finalizeRequiresAnEndedEpoch() (gas: 198268)\n[PASS] test_lateCreditIsPaidOnASecondClaim() (gas: 1076754)\n[PASS] test_onlyTheAccountItselfCanClaim() (gas: 847409)\n[PASS] test_recycleFoldsUnclaimedIntoTheCurrentEpoch() (gas: 946576)\n[PASS] test_rewardsAreWeightedByHoldingTime() (gas: 1046850)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 344.70ms (429.00ms CPU time)\n\nRan 6 tests for test/DeezTokenHistoryEdges.t.sol:DeezTokenHistoryEdgesTest\n[PASS] testFuzz_binarySearchFindsEveryIntervalOfLongHistory(uint256,uint256,uint256) (runs: 1000, μ: 3475922, ~: 3476305)\n[PASS] test_allowanceFailureLeavesHistoriesUntouched() (gas: 100312)\n[PASS] test_failedTransferFromRestoresSpentAllowanceAndBothHistories() (gas: 148071)\n[PASS] test_fullSupplyRoundTripInOneSecondHasNoRewardWeight() (gas: 242347)\n[PASS] test_zeroAndSelfTransfersPreserveExactWholeDayTokenTime() (gas: 194136)\n[PASS] test_zeroReceiverCannotBurnSupplyOrCreateCheckpoints() (gas: 75878)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 344.87ms (344.49ms CPU time)\n\nRan 15 tests for test/DeezLaunch.t.sol:DeezLaunchToken1Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8607)\n[PASS] test_constructorWiringNamesRequesterAndDependencies() (gas: 27036)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 87747178)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 87557223)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 85083742)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 86034526)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 84946805)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926367)\n[PASS] test_launchRunsOnce() (gas: 172667596)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 88717621)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74110)\n[PASS] test_nothingIsOwned() (gas: 107311)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 13998)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 89343248)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 3059388)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 369.49ms (1.64s CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken0Test\n[PASS]\nDeezHookInvariantToken0Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken0Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 572.53ms (560.11ms CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken1Test\n[PASS]\nDeezHookInvariantToken1Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken1Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 597.80ms (538.82ms CPU time)\n\nRan 2 tests for test/DeezLaunchLifecycleInvariant.t.sol:DeezLaunchLifecycleInvariantTest\n[PASS] invariant_custodyIsConservedAndOnlyOneRequesterLaunchCanSucceed() (runs: 256, calls: 15360, reverts: 0)\n\n╭----------------------------+-------------------+-------+---------+----------╮\n| Contract                   | Selector          | Calls | Reverts | Discards |\n+=============================================================================+\n| DeezLaunchLifecycleHandler | attempt           | 5095  | 0       | 0        |\n|----------------------------+-------------------+-------+---------+----------|\n| DeezLaunchLifecycleHandler | launchAsRequester | 5103  | 0       | 0        |\n|----------------------------+-------------------+-------+---------+----------|\n| DeezLaunchLifecycleHandler | movePayout        | 5162  | 0       | 0        |\n╰----------------------------+-------------------+-------+---------+----------╯\n\n[PASS] test_failedAttemptsThenSuccessThenReplay() (gas: 3299863)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 1.36s (1.34s CPU time)\n\nRan 15 tests for test/DeezLaunch.t.sol:DeezLaunchToken0Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8607)\n[PASS] test_constructorWiringNamesRequesterAndDependencies() (gas: 27036)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 34392654)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 34203995)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 31734400)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 32683039)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 31597540)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926367)\n[PASS] test_launchRunsOnce() (gas: 65760134)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 35357205)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74110)\n[PASS] test_nothingIsOwned() (gas: 107311)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 13998)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 35987259)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 181482520)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 1.42s (2.00s CPU time)\n\nRan 2 tests for test/DeezLiquidityLockInvariant.t.sol:DeezLockInvariantToken1Test\n[PASS] invariant_positionsArePermanentAndPrincipalAndFeesAreConserved() (runs: 256, calls: 15360, reverts: 0)\n\n╭-----------------+-----------------------+-------+---------+----------╮\n| Contract        | Selector              | Calls | Reverts | Discards |\n+======================================================================+\n| DeezLockHandler | add                   | 2632  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | donate                | 2594  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectForeignCallback | 2541  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectForeignRemoval  | 2501  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectStaleTick       | 2537  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | swap                  | 2555  | 0       | 0        |\n╰-----------------+-----------------------+-------+---------+----------╯\n\n[PASS] test_feeCreditsCanExceedTopUpWithoutEscapingTheLock() (gas: 1090174)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.75s (2.71s CPU time)\n\nRan 2 tests for test/DeezLiquidityLockInvariant.t.sol:DeezLockInvariantToken0Test\n[PASS] invariant_positionsArePermanentAndPrincipalAndFeesAreConserved() (runs: 256, calls: 15360, reverts: 0)\n\n╭-----------------+-----------------------+-------+---------+----------╮\n| Contract        | Selector              | Calls | Reverts | Discards |\n+======================================================================+\n| DeezLockHandler | add                   | 2632  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | donate                | 2594  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectForeignCallback | 2541  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectForeignRemoval  | 2501  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectStaleTick       | 2537  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | swap                  | 2555  | 0       | 0        |\n╰-----------------+-----------------------+-------+---------+----------╯\n\n[PASS] test_feeCreditsCanExceedTopUpWithoutEscapingTheLock() (gas: 1036045)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.91s (2.89s CPU time)\n\nRan 1 test for test/DeezRewardsInvariant.t.sol:DeezRewardsInvariantTest\n[PASS]\nDeezRewardsInvariantTest invariants:\n[PASS] invariant_claimsNeverExceedTheBalanceShare\n[PASS] invariant_closedEpochsNeverReopen\n[PASS] invariant_holdsAtLeastWhatItReserved\n[PASS] invariant_imdIsConserved\n[PASS] invariant_noHolderIsPaidMoreThanItsShareOfAnyPot\n[PASS] invariant_noPotPaysMoreThanItHolds\n[PASS] invariant_onlyTheAccountClaimsItsShare\n[PASS] invariant_pendingFeesAreTrackedExactly\n[PASS] invariant_reservedEqualsWhatOpenPotsOwe\n[PASS] invariant_supplyNeverChanges\n DeezRewardsInvariantTest invariants (runs: 256, calls: 15360, reverts: 0)\n\n╭----------------+---------------------+-------+---------+----------╮\n| Contract       | Selector            | Calls | Reverts | Discards |\n+===================================================================+\n| RewardsHandler | claim               | 1520  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | claimFor            | 1582  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | finalize            | 1497  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | fund                | 1506  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | harvest             | 1554  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | lateFee             | 1503  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | recycle             | 1561  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | transfer            | 1508  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warp                | 1557  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warpPastClaimWindow | 1572  | 0       | 0        |\n╰----------------+---------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.32s (4.32s CPU time)\n\nRan 2 tests for test/DeezTokenHistoryInvariant.t.sol:DeezTokenHistoryInvariantTest\n[PASS]\nDeezTokenHistoryInvariantTest invariants:\n[PASS] invariant_balancesAllowancesAndTokenTimeMatchIndependentLedger\n[PASS] invariant_closedHistoryRemainsImmutable\n DeezTokenHistoryInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭--------------------+------------------+-------+---------+----------╮\n| Contract           | Selector         | Calls | Reverts | Discards |\n+====================================================================+\n| DeezHistoryHandler | approve          | 3538  | 0       | 0        |\n|--------------------+------------------+-------+---------+----------|\n| DeezHistoryHandler | checkObservation | 3497  | 0       | 0        |\n|--------------------+------------------+-------+---------+----------|\n| DeezHistoryHandler | elapse           | 3408  | 0       | 0        |\n|--------------------+------------------+-------+---------+----------|\n| DeezHistoryHandler | rejectOverdraft  | 3381  | 0       | 0        |\n|--------------------+------------------+-------+---------+----------|\n| DeezHistoryHandler | transfer         | 3387  | 0       | 0        |\n|--------------------+------------------+-------+---------+----------|\n| DeezHistoryHandler | transferFrom     | 3269  | 0       | 0        |\n╰--------------------+------------------+-------+---------+----------╯\n\n[PASS] test_handlerExercisesApprovalsFullTransfersAndHistory() (gas: 2010755)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 8.94s (8.94s CPU time)\n\nRan 23 test suites in 8.95s (25.19s CPU time): 212 tests passed, 0 failed, 0 skipped (212 total tests)\n","passed":true},{"durationMs":81,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"DeezHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"DeezHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"DeezHook.harvest()\",\"DeezHook.harvestEpochs(uint256[])\",\"DeezHook.unlockCallback(bytes)\",\"DeezLaunch.launch(address,address,address,bytes32)\",\"DeezLiquidityLock.lock()\",\"DeezLiquidityLock.lockAs(uint8,int24,int24)\",\"DeezLiquidityLock.unlockCallback(bytes)\",\"DeezRewards.accrue()\",\"DeezRewards.claim(address,uint256[])\",\"DeezRewards.credit(uint256,uint256)\",\"DeezRewards.finalize(uint256)\",\"DeezRewards.recycle(uint256)\",\"DeezRewards.setHook(address)\",\"DeezToken.approve(address,uint256)\",\"DeezToken.transfer(address,uint256)\",\"DeezToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":217,\"foundry.toml\":20,\"remappings.txt\":5,\"script/MineHookSalt.s.sol\":42,\"site/deez.config.js\":27,\"site/index.html\":319,\"site/logo.svg\":10,\"src/DeezHook.sol\":359,\"src/DeezLaunch.sol\":199,\"src/DeezLiquidityLock.sol\":237,\"src/DeezRewards.sol\":295,\"src/DeezToken.sol\":150,\"src/HookFlags.sol\":34,\"test/ADVERSARIAL_TESTS.md\":60,\"test/DeezBase.t.sol\":140,\"test/DeezFailurePaths.t.sol\":530,\"test/DeezFlywheel.t.sol\":150,\"test/DeezHook.t.sol\":396,\"test/DeezHookInvariant.t.sol\":153,\"test/DeezLaunch.t.sol\":408,\"test/DeezLaunchLifecycleInvariant.t.sol\":182,\"test/DeezLaunchRollback.t.sol\":196,\"test/DeezLiquidityLock.t.sol\":175,\"test/DeezLiquidityLockInvariant.t.sol\":268,\"test/DeezRewards.t.sol\":451,\"test/DeezRewardsInvariant.t.sol\":305,\"test/DeezRewardsTransferFailures.t.sol\":135,\"test/DeezToken.t.sol\":174,\"test/DeezTokenHistoryEdges.t.sol\":116,\"test/DeezTokenHistoryInvariant.t.sol\":217,\"test/mocks/MockERC20.sol\":15,\"test/mocks/MockHook.sol\":36,\"test/mocks/Swapper.sol\":85},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"76dbe4f61cff98a9e5036bc0621929a6ded7ae5974b2979f63bcf838a8141642","verifiedTreeHash":"6769f7c99599f15d0de419951b275c1377a74607","verifierVersion":"0.1.0+a6ee6548"},{"checks":[{"durationMs":84485,"exitCode":0,"name":"build","output":"Compiling 102 files with Solc 0.8.26\nSolc 0.8.26 finished in 84.36s\nCompiler run successful!\n","passed":true},{"durationMs":4379,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/DeezFlywheel.t.sol:DeezFlywheelTest\n[PASS] test_earlyClaimerGetsItsShareOfFeesHarvestedLater() (gas: 2188569)\n[PASS] test_feesBelongToTheEpochTheyWereTradedInWheneverHarvested() (gas: 1178253)\n[PASS] test_lastSecondBuyerCannotSnipeTheEpochsPot() (gas: 1664409)\n[PASS] test_tradesBecomeHolderRewards() (gas: 1965479)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 36.89ms (7.12ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken0Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1924388)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 844044)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 969168)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 12132258)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969833)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61951)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71556)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 40.73ms (22.16ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken0Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1208385)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 940446)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 964014)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266888)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1172198)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 830366)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 12216088)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054091)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 56.90ms (24.14ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken1Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1212044)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 935043)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 967677)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266876)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1193447)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 826726)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 1298755)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054079)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 65.38ms (7.40ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken1Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1930064)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 850257)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 974591)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 1213224)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969821)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61939)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71544)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 68.76ms (6.83ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken0Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 772646, ~: 772873)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 784844, ~: 784962)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 806452)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 775380)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 809736)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 958374)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122971)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 784655)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 918042)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 871806)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 630196)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 956681)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1412377)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 965713)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1289372)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1135375)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 12248802)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1064599)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 12848869)\n[PASS] test_refusesASecondPool() (gas: 46701)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 811292)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 799271)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119833)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 165.92ms (217.08ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken1Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 778178, ~: 778326)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 779306, ~: 779547)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 811875)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 785146)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 813845)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 969453)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122947)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 779716)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 933874)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 887772)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 625465)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 978005)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1417783)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 971005)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1294664)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1140667)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 1331484)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1070022)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 1910765)\n[PASS] test_refusesASecondPool() (gas: 46689)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 805849)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 795142)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119478)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 165.22ms (167.02ms CPU time)\n\nRan 15 tests for test/DeezLaunch.t.sol:DeezLaunchToken1Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8603)\n[PASS] test_factoryDeploymentLeavesEverythingUnlaunched() (gas: 56007)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 87747180)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 87557225)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 85083744)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 86034517)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 84946784)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926385)\n[PASS] test_launchRunsOnce() (gas: 172667574)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 88717621)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74088)\n[PASS] test_nothingIsOwned() (gas: 107289)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 13976)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 89343226)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 3059366)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 383.14ms (1.95s CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken0Test\n[PASS]\nDeezHookInvariantToken0Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken0Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 520.64ms (500.29ms CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken1Test\n[PASS]\nDeezHookInvariantToken1Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken1Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 561.10ms (511.19ms CPU time)\n\nRan 24 tests for test/DeezRewards.t.sol:DeezRewardsTest\n[PASS] testFuzz_claimsNeverExceedThePotAndSplitByBalance(uint96,uint96,uint96) (runs: 256, μ: 848437, ~: 848411)\n[PASS] testFuzz_claimsNeverExceedThePotWithMidEpochMoves(uint96,uint32,uint32,uint96) (runs: 256, μ: 1208858, ~: 1208934)\n[PASS] test_accrueCreditsTheCurrentEpochOnce() (gas: 195183)\n[PASS] test_balanceMovedAfterTheEpochDoesNotChangeIt() (gas: 759363)\n[PASS] test_claimBeforeTheEpochEndsReverts() (gas: 341765)\n[PASS] test_claimHarvestsOnlyTheEpochsItPays() (gas: 626503)\n[PASS] test_claimHarvestsThePendingFeesOfTheEpochFirst() (gas: 990070)\n[PASS] test_claimManyEpochsAtOnce() (gas: 1066960)\n[PASS] test_claimsAreProportionalToTheAverageBalance() (gas: 1310733)\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8803)\n[PASS] test_creditGoesToTheEpochTheHookNames() (gas: 436426)\n[PASS] test_creditRefusesOthersAndUnfundedAmounts() (gas: 227829)\n[PASS] test_creditToAClosedOrFutureEpochGoesToTheCurrentOne() (gas: 411044)\n[PASS] test_deployerShareIsProportionalToo() (gas: 681654)\n[PASS] test_doubleClaimPaysNothingMore() (gas: 833135)\n[PASS] test_emptyClaimReverts() (gas: 387104)\n[PASS] test_epochArithmetic() (gas: 31685)\n[PASS] test_excludedAddresses() (gas: 41878)\n[PASS] test_excludedAddressesCannotClaim() (gas: 251970)\n[PASS] test_finalizeRequiresAnEndedEpoch() (gas: 198268)\n[PASS] test_lateCreditIsPaidOnASecondClaim() (gas: 1076754)\n[PASS] test_onlyTheAccountItselfCanClaim() (gas: 847409)\n[PASS] test_recycleFoldsUnclaimedIntoTheCurrentEpoch() (gas: 946576)\n[PASS] test_rewardsAreWeightedByHoldingTime() (gas: 1046850)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 1.44s (1.59s CPU time)\n\nRan 23 tests for test/DeezFailurePaths.t.sol:DeezRewardsFailurePathsTest\n[PASS] testFuzz_allHoldersTogetherNeverDrainMoreThanThePot(uint96,uint96,uint128,uint32,uint32) (runs: 512, μ: 942665, ~: 1014207)\n[PASS] testFuzz_claimOrderAndLateFeesDoNotChangeFinalShares(uint96,uint128,uint128,uint8,uint32) (runs: 512, μ: 1201935, ~: 1162326)\n[PASS] test_accrueWithNothingNewCreditsNothing() (gas: 222432)\n[PASS] test_balanceMovedInTheFirstSecondOfTheNextEpochDoesNotCount() (gas: 574119)\n[PASS] test_batchWithAnUnendedEpochPaysNothing() (gas: 430676)\n[PASS] test_closedEpochRefusesClaimsAndASecondRecycle() (gas: 333820)\n[PASS] test_creditCannotBeForgedOrOverdrawn() (gas: 214111)\n[PASS] test_duplicateEpochInOneBatchPaysItOnce() (gas: 488462)\n[PASS] test_emptyBatchReverts() (gas: 226474)\n[PASS] test_epochWithNoEligibleSupplyPaysNobodyAndIsRecycled() (gas: 643921)\n[PASS] test_excludedAddressesCannotClaimEvenForThemselves() (gas: 339255)\n[PASS] test_finalizeIsIdempotentAndIgnoresLaterTransfers() (gas: 398192)\n[PASS] test_holderWithNoBalanceInTheEpochHasNothingToClaim() (gas: 348086)\n[PASS] test_lastSecondBuyerWeighsOneSecond() (gas: 772291)\n[PASS] test_lateFeeAfterSomeClaimedStillSplitsExactlyByBalance() (gas: 731534)\n[PASS] test_nobodyCanClaimForSomeoneElse() (gas: 445168)\n[PASS] test_pendingFeesOfAClosedEpochGoToTheCurrentPot() (gas: 519437)\n[PASS] test_recycleOfAnEpochThatNeverHadAPotClosesItForNothing() (gas: 100110)\n[PASS] test_recycleOpensExactlyAfterTheClaimWindow() (gas: 451085)\n[PASS] test_recycledRewardsArePaidByTheNewEpochsBalances() (gas: 557732)\n[PASS] test_shareThatRoundsToZeroIsRefusedNotPaid() (gas: 479436)\n[PASS] test_unaccruedDonationGoesToTheCurrentEpochNotAnEndedOne() (gas: 435339)\n[PASS] test_weightReadsRevertUntilTheEpochHasEnded() (gas: 225629)\nSuite result: ok. 23 passed; 0 failed; 0 skipped; finished in 1.44s (353.44ms CPU time)\n\nRan 11 tests for test/DeezToken.t.sol:DeezTokenTest\n[PASS] testFuzz_cumulativeBalanceMatchesHoldingTime(uint96,uint32,uint32) (runs: 256, μ: 284536, ~: 284486)\n[PASS] testFuzz_pastBalanceMatchesBalanceAtThatTime(uint96,uint96,uint32) (runs: 256, μ: 266271, ~: 266538)\n[PASS] test_cumulativeBalanceAllowsTheCurrentSecondButNotTheFuture() (gas: 12108)\n[PASS] test_cumulativeBalanceIntegratesHoldingTime() (gas: 514182)\n[PASS] test_cumulativeBalanceRefusesTheFuture() (gas: 20199)\n[PASS] test_metadataAndSupply() (gas: 51418)\n[PASS] test_noMintOwnerOrPause() (gas: 147261)\n[PASS] test_pastBalanceRefusesTheCurrentSecondAndTheFuture() (gas: 22664)\n[PASS] test_pastBalancesFollowTransfers() (gas: 461865)\n[PASS] test_transferFromRespectsAllowance() (gas: 310333)\n[PASS] test_transferMovesExactlyWhatItWasAsked() (gas: 126080)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 1.44s (178.28ms CPU time)\n\nRan 15 tests for test/DeezLaunch.t.sol:DeezLaunchToken0Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8603)\n[PASS] test_factoryDeploymentLeavesEverythingUnlaunched() (gas: 56007)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 34392656)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 34203997)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 31734402)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 32683030)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 31597519)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926385)\n[PASS] test_launchRunsOnce() (gas: 65760112)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 35357205)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74088)\n[PASS] test_nothingIsOwned() (gas: 107289)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 13976)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 35987237)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 181482498)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 1.44s (2.31s CPU time)\n\nRan 1 test for test/DeezRewardsInvariant.t.sol:DeezRewardsInvariantTest\n[PASS]\nDeezRewardsInvariantTest invariants:\n[PASS] invariant_claimsNeverExceedTheBalanceShare\n[PASS] invariant_closedEpochsNeverReopen\n[PASS] invariant_holdsAtLeastWhatItReserved\n[PASS] invariant_imdIsConserved\n[PASS] invariant_noHolderIsPaidMoreThanItsShareOfAnyPot\n[PASS] invariant_noPotPaysMoreThanItHolds\n[PASS] invariant_onlyTheAccountClaimsItsShare\n[PASS] invariant_pendingFeesAreTrackedExactly\n[PASS] invariant_reservedEqualsWhatOpenPotsOwe\n[PASS] invariant_supplyNeverChanges\n DeezRewardsInvariantTest invariants (runs: 256, calls: 15360, reverts: 0)\n\n╭----------------+---------------------+-------+---------+----------╮\n| Contract       | Selector            | Calls | Reverts | Discards |\n+===================================================================+\n| RewardsHandler | claim               | 1520  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | claimFor            | 1582  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | finalize            | 1497  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | fund                | 1506  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | harvest             | 1554  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | lateFee             | 1503  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | recycle             | 1561  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | transfer            | 1508  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warp                | 1557  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warpPastClaimWindow | 1572  | 0       | 0        |\n╰----------------+---------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.24s (4.24s CPU time)\n\nRan 15 test suites in 4.25s (12.06s CPU time): 187 tests passed, 0 failed, 0 skipped (187 total tests)\n","passed":true},{"durationMs":92,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"DeezHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"DeezHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"DeezHook.harvest()\",\"DeezHook.harvestEpochs(uint256[])\",\"DeezHook.unlockCallback(bytes)\",\"DeezLaunch.launch(address,address,address,bytes32)\",\"DeezLiquidityLock.lock()\",\"DeezLiquidityLock.lockAs(uint8,int24,int24)\",\"DeezLiquidityLock.unlockCallback(bytes)\",\"DeezRewards.accrue()\",\"DeezRewards.claim(address,uint256[])\",\"DeezRewards.credit(uint256,uint256)\",\"DeezRewards.finalize(uint256)\",\"DeezRewards.recycle(uint256)\",\"DeezRewards.setHook(address)\",\"DeezToken.approve(address,uint256)\",\"DeezToken.transfer(address,uint256)\",\"DeezToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":217,\"foundry.toml\":20,\"remappings.txt\":5,\"script/MineHookSalt.s.sol\":42,\"site/deez.config.js\":27,\"site/index.html\":319,\"site/logo.svg\":10,\"src/DeezHook.sol\":359,\"src/DeezLaunch.sol\":199,\"src/DeezLiquidityLock.sol\":237,\"src/DeezRewards.sol\":295,\"src/DeezToken.sol\":150,\"src/HookFlags.sol\":34,\"test/DeezBase.t.sol\":140,\"test/DeezFailurePaths.t.sol\":530,\"test/DeezFlywheel.t.sol\":150,\"test/DeezHook.t.sol\":396,\"test/DeezHookInvariant.t.sol\":153,\"test/DeezLaunch.t.sol\":410,\"test/DeezLiquidityLock.t.sol\":175,\"test/DeezRewards.t.sol\":451,\"test/DeezRewardsInvariant.t.sol\":305,\"test/DeezToken.t.sol\":174,\"test/mocks/MockERC20.sol\":15,\"test/mocks/MockHook.sol\":36,\"test/mocks/Swapper.sol\":85},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":6120,"exitCode":0,"name":"slither","output":"[low/medium] calls-loop at src/DeezRewards.sol:160: DeezRewards.weightOf(address,uint256) (src/DeezRewards.sol#160-164) has external calls inside a loop: token.getCumulativeBalanceOf(account,start + EPOCH_LENGTH) - token.getCumulativeBalanceOf(account,start) (src/DeezRewards.sol#162-163)\n[low/medium] calls-loop at src/DeezRewards.sol:167: DeezRewards.eligibleSupplyAt(uint256) (src/DeezRewards.sol#167-173) has external calls inside a loop: total = token.getCumulativeTotalSupply(start + EPOCH_LENGTH) - token.getCumulativeTotalSupply(start) (src/DeezRewards.sol#169)\n[low/medium] calls-loop at src/DeezHook.sol:228: DeezHook._harvest(uint256[]) (src/DeezHook.sol#228-246) has external calls inside a loop: rewards.credit(epochs[i_scope_0],amounts[i_scope_0]) (src/DeezHook.sol#243)\n[low/medium] calls-loop at src/DeezRewards.sol:160: DeezRewards.weightOf(address,uint256) (src/DeezRewards.sol#160-164) has external calls inside a loop: token.getCumulativeBalanceOf(account,start + EPOCH_LENGTH) - token.getCumulativeBalanceOf(account,start) (src/DeezRewards.sol#162-163)\n[low/medium] calls-loop at src/DeezHook.sol:228: DeezHook._harvest(uint256[]) (src/DeezHook.sol#228-246) has external calls inside a loop: rewards.credit(epochs[i_scope_0],amounts[i_scope_0]) (src/DeezHook.sol#243)\n[low/medium] calls-loop at src/DeezRewards.sol:167: DeezRewards.eligibleSupplyAt(uint256) (src/DeezRewards.sol#167-173) has external calls inside a loop: total = token.getCumulativeTotalSupply(start + EPOCH_LENGTH) - token.getCumulativeTotalSupply(start) (src/DeezRewards.sol#169)\n[low/medium] calls-loop at src/DeezRewards.sol:178: DeezRewards.claimable(address,uint256) (src/DeezRewards.sol#178-187) has external calls inside a loop: total = pot.total + IDeezHarvester(hook).pendingFeesOf(epoch) (src/DeezRewards.sol#182)\n[low/medium] reentrancy-benign at src/DeezHook.sol:190: Reentrancy in DeezHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/DeezHook.sol#190-208):\n[low/medium] reentrancy-benign at src/DeezLiquidityLock.sol:110: Reentrancy in DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#110-150):\n[low/medium] reentrancy-benign at src/DeezLaunch.sol:109: Reentrancy in DeezLaunch.launch(address,address,address,bytes32) (src/DeezLaunch.sol#109-147):\n[low/medium] reentrancy-benign at src/DeezRewards.sol:242: Reentrancy in DeezRewards.claim(address,uint256[]) (src/DeezRewards.sol#242-266):\n[low/medium] reentrancy-events at src/DeezLaunch.sol:109: Reentrancy in DeezLaunch.launch(address,address,address,bytes32) (src/DeezLaunch.sol#109-147):\n[low/medium] reentrancy-events at src/DeezLaunch.sol:109: Reentrancy in DeezLaunch.launch(address,address,address,bytes32) (src/DeezLaunch.sol#109-147):\n[low/medium] reentrancy-events at src/DeezLaunch.sol:109: Reentrancy in DeezLaunch.launch(address,address,address,bytes32) (src/DeezLaunch.sol#109-147):\n[low/medium] reentrancy-events at src/DeezHook.sol:228: Reentrancy in DeezHook._harvest(uint256[]) (src/DeezHook.sol#228-246):\n[low/medium] reentrancy-events at src/DeezHook.sol:190: Reentrancy in DeezHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/DeezHook.sol#190-208):\n[low/medium] reentrancy-events at src/DeezLiquidityLock.sol:110: Reentrancy in DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#110-150):\n[low/medium] timestamp at src/DeezToken.sol:75: DeezToken.getCumulativeBalanceOf(address,uint256) (src/DeezToken.sol#75-81) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezRewards.sol:149: DeezRewards.hasEnded(uint256) (src/DeezRewards.sol#149-151) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezRewards.sol:215: DeezRewards.credit(uint256,uint256) (src/DeezRewards.sol#215-223) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezRewards.sol:269: DeezRewards.recycle(uint256) (src/DeezRewards.sol#269-279) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezRewards.sol:178: DeezRewards.claimable(address,uint256) (src/DeezRewards.sol#178-187) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:63: DeezToken.getPastBalanceOf(address,uint256) (src/DeezToken.sol#63-68) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:116: DeezToken._checkpoint(address) (src/DeezToken.sol#116-133) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:85: DeezToken.getCumulativeTotalSupply(uint256) (src/DeezToken.sol#85-90) uses timestamp for comparisons","passed":true},{"durationMs":845,"exitCode":0,"name":"aderyn","output":"[high] reentrancy-state-change at src/DeezHook.sol:201: Reentrancy: State change after external call (14 places)\n[high] unsafe-casting at src/DeezRewards.sol:206: Unsafe Casting of integers (2 places)\n[low] costly-loop at src/DeezHook.sol:230: Costly operations inside loop (2 places)\n[low] internal-function-used-once at src/HookFlags.sol:26: Internal Function Used Only Once\n[low] large-numeric-literal at src/DeezHook.sol:48: Large Numeric Literal (6 places)\n[low] literal-instead-of-constant at src/DeezLaunch.sol:173: Literal Instead of Constant (2 places)\n[low] missing-inheritance at src/DeezLaunch.sol:34: Missing Inheritance\n[low] modifier-used-only-once at src/DeezLiquidityLock.sol:74: Modifier Invoked Only Once\n[low] require-revert-in-loop at src/DeezRewards.sol:250: Loop Contains `require`/`revert`\n[low] state-change-without-event at src/DeezHook.sol:149: State Change Without Event\n[low] state-no-address-check at src/DeezLaunch.sol:117: Address State Variable Set Without Checks (3 places)\n[low] unused-import at src/DeezLiquidityLock.sol:9: Unused Import","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"ad4550f9662ca62cd426579edca932126bae1790ba8a490b6bd7811faefa7758","verifiedTreeHash":"973f7c2efd89ec396ec95130ba797c635bc191e6","verifierVersion":"0.1.0+a6ee6548"},{"checks":[{"durationMs":266531,"exitCode":0,"name":"build","output":"Compiling 109 files with Solc 0.8.26\nSolc 0.8.26 finished in 266.20s\nCompiler run successful!\n","passed":true},{"durationMs":17529,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 3 tests for test/DeezRewardsTransferFailures.t.sol:DeezRewardsTransferFailuresTest\n[PASS] test_falseReturningPayoutRollsBackHarvestAccrualAndClaim() (gas: 735338)\n[PASS] test_payoutCallbackCannotReenterClaimAndOuterClaimCompletesOnce() (gas: 542837)\n[PASS] test_revertingPayoutRollsBackHarvestAccrualAndClaim() (gas: 735198)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.89ms (2.36ms CPU time)\n\nRan 4 tests for test/DeezLaunchRollback.t.sol:DeezLaunchRollbackToken0Test\n[PASS] test_finalPayoutFailureRollsBackBothLiquidityAddsAndAllowsRetry() (gas: 5424012)\n[PASS] test_poolInitializationFailureRollsBackHookDeploymentAndWiring() (gas: 4838949)\n[PASS] test_requesterLockTransferFailureRollsBackThePoolSeed() (gas: 5369691)\n[PASS] test_requesterTransfersDirectlyToLockBeforeWalletPayoutWithinLaunchCall() (gas: 2691848)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 33.96ms (15.94ms CPU time)\n\nRan 4 tests for test/DeezFlywheel.t.sol:DeezFlywheelTest\n[PASS] test_earlyClaimerGetsItsShareOfFeesHarvestedLater() (gas: 2219324)\n[PASS] test_feesBelongToTheEpochTheyWereTradedInWheneverHarvested() (gas: 1198687)\n[PASS] test_lastSecondBuyerCannotSnipeTheEpochsPot() (gas: 1679767)\n[PASS] test_tradesBecomeHolderRewards() (gas: 1985913)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 36.57ms (8.89ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken0Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1954987)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 844044)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 969168)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 12132258)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969833)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61951)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71556)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 63.41ms (42.22ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken1Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1960663)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 850257)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 974591)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 1213224)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969821)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61939)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71544)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 109.68ms (13.70ms CPU time)\n\nRan 11 tests for test/DeezToken.t.sol:DeezTokenTest\n[PASS] testFuzz_cumulativeBalanceMatchesHoldingTime(uint96,uint32,uint32) (runs: 256, μ: 284543, ~: 284499)\n[PASS] testFuzz_pastBalanceMatchesBalanceAtThatTime(uint96,uint96,uint32) (runs: 256, μ: 266273, ~: 266544)\n[PASS] test_cumulativeBalanceAllowsTheCurrentSecondButNotTheFuture() (gas: 12108)\n[PASS] test_cumulativeBalanceIntegratesHoldingTime() (gas: 514182)\n[PASS] test_cumulativeBalanceRefusesTheFuture() (gas: 20199)\n[PASS] test_metadataAndSupply() (gas: 51418)\n[PASS] test_noMintOwnerOrPause() (gas: 147261)\n[PASS] test_pastBalanceRefusesTheCurrentSecondAndTheFuture() (gas: 22664)\n[PASS] test_pastBalancesFollowTransfers() (gas: 461865)\n[PASS] test_transferFromRespectsAllowance() (gas: 310333)\n[PASS] test_transferMovesExactlyWhatItWasAsked() (gas: 126080)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 109.75ms (139.08ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken1Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1212044)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 935043)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 967677)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266876)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1193447)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 826726)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 1298755)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054079)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 136.27ms (14.67ms CPU time)\n\nRan 4 tests for test/DeezLaunchRollback.t.sol:DeezLaunchRollbackToken1Test\n[PASS] test_finalPayoutFailureRollsBackBothLiquidityAddsAndAllowsRetry() (gas: 5431898)\n[PASS] test_poolInitializationFailureRollsBackHookDeploymentAndWiring() (gas: 4842885)\n[PASS] test_requesterLockTransferFailureRollsBackThePoolSeed() (gas: 5378285)\n[PASS] test_requesterTransfersDirectlyToLockBeforeWalletPayoutWithinLaunchCall() (gas: 2695791)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 195.33ms (71.03ms CPU time)\n\nRan 4 tests for test/DeezLauncherExclusion.t.sol:DeezLauncherExclusionTest\n[PASS] testFuzz_launchDayPotIgnoresLauncherHolding(uint256,uint256,uint256) (runs: 64, μ: 5094473, ~: 5101173)\n[PASS] test_launchInTheLastSecondOfTheDayStillPaysTheWholePot() (gas: 4698287)\n[PASS] test_lookAlikeSetPassesTheConsistencyChecksSoPublishersMustCrossCheck() (gas: 12659089)\n[PASS] test_noLaunchMeansNoPotAndNoClaimForAnyone() (gas: 117668)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 234.16ms (292.50ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken0Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1208385)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 940446)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 964014)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266888)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1172198)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 830366)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 12216088)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054091)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 310.12ms (193.95ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken1Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 778168, ~: 778262)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 779290, ~: 779497)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 811875)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 785146)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 813845)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 969453)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122947)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 779716)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 933874)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 887772)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 625465)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 978005)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1417783)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 971005)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1294664)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1140667)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 1331484)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1070022)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 1910765)\n[PASS] test_refusesASecondPool() (gas: 46689)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 805849)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 795142)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119478)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 348.42ms (295.96ms CPU time)\n\nRan 25 tests for test/DeezRewards.t.sol:DeezRewardsTest\n[PASS] testFuzz_claimsNeverExceedThePotAndSplitByBalance(uint96,uint96,uint96) (runs: 256, μ: 868874, ~: 868845)\n[PASS] testFuzz_claimsNeverExceedThePotWithMidEpochMoves(uint96,uint32,uint32,uint96) (runs: 256, μ: 1166787, ~: 1166868)\n[PASS] test_accrueCreditsTheCurrentEpochOnce() (gas: 195183)\n[PASS] test_balanceMovedAfterTheEpochDoesNotChangeIt() (gas: 805779)\n[PASS] test_claimBeforeTheEpochEndsReverts() (gas: 341817)\n[PASS] test_claimHarvestsOnlyTheEpochsItPays() (gas: 646937)\n[PASS] test_claimHarvestsThePendingFeesOfTheEpochFirst() (gas: 1010608)\n[PASS] test_claimManyEpochsAtOnce() (gas: 1102561)\n[PASS] test_claimsAreProportionalToTheAverageBalance() (gas: 1347591)\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8825)\n[PASS] test_creditGoesToTheEpochTheHookNames() (gas: 436448)\n[PASS] test_creditRefusesOthersAndUnfundedAmounts() (gas: 227829)\n[PASS] test_creditToAClosedOrFutureEpochGoesToTheCurrentOne() (gas: 411066)\n[PASS] test_doubleClaimPaysNothingMore() (gas: 833886)\n[PASS] test_emptyClaimReverts() (gas: 379004)\n[PASS] test_epochArithmetic() (gas: 31685)\n[PASS] test_excludedAddresses() (gas: 51193)\n[PASS] test_excludedAddressesCannotClaim() (gas: 283481)\n[PASS] test_finalizeRequiresAnEndedEpoch() (gas: 239411)\n[PASS] test_lateCreditIsPaidOnASecondClaim() (gas: 1087201)\n[PASS] test_launcherHoldingBeforeALateLaunchDoesNotDiluteTheLaunchDay() (gas: 738637)\n[PASS] test_launcherHoldingNeitherEarnsNorDilutes() (gas: 750859)\n[PASS] test_onlyTheAccountItselfCanClaim() (gas: 867873)\n[PASS] test_recycleFoldsUnclaimedIntoTheCurrentEpoch() (gas: 967114)\n[PASS] test_rewardsAreWeightedByHoldingTime() (gas: 1172432)\nSuite result: ok. 25 passed; 0 failed; 0 skipped; finished in 538.66ms (631.01ms CPU time)\n\nRan 23 tests for test/DeezFailurePaths.t.sol:DeezRewardsFailurePathsTest\n[PASS] testFuzz_allHoldersTogetherNeverDrainMoreThanThePot(uint96,uint96,uint128,uint32,uint32) (runs: 512, μ: 974430, ~: 1039593)\n[PASS] testFuzz_claimOrderAndLateFeesDoNotChangeFinalShares(uint96,uint128,uint128,uint8,uint32) (runs: 512, μ: 1228805, ~: 1193103)\n[PASS] test_accrueWithNothingNewCreditsNothing() (gas: 222432)\n[PASS] test_balanceMovedInTheFirstSecondOfTheNextEpochDoesNotCount() (gas: 584388)\n[PASS] test_batchWithAnUnendedEpochPaysNothing() (gas: 440945)\n[PASS] test_closedEpochRefusesClaimsAndASecondRecycle() (gas: 333924)\n[PASS] test_creditCannotBeForgedOrOverdrawn() (gas: 214111)\n[PASS] test_duplicateEpochInOneBatchPaysItOnce() (gas: 498783)\n[PASS] test_emptyBatchReverts() (gas: 226526)\n[PASS] test_epochWithNoEligibleSupplyPaysNobodyAndIsRecycled() (gas: 674520)\n[PASS] test_excludedAddressesCannotClaimEvenForThemselves() (gas: 382307)\n[PASS] test_finalizeIsIdempotentAndIgnoresLaterTransfers() (gas: 418522)\n[PASS] test_holderWithNoBalanceInTheEpochHasNothingToClaim() (gas: 368520)\n[PASS] test_lastSecondBuyerWeighsOneSecond() (gas: 782612)\n[PASS] test_lateFeeAfterSomeClaimedStillSplitsExactlyByBalance() (gas: 741959)\n[PASS] test_nobodyCanClaimForSomeoneElse() (gas: 455385)\n[PASS] test_pendingFeesOfAClosedEpochGoToTheCurrentPot() (gas: 519541)\n[PASS] test_recycleOfAnEpochThatNeverHadAPotClosesItForNothing() (gas: 100110)\n[PASS] test_recycleOpensExactlyAfterTheClaimWindow() (gas: 461302)\n[PASS] test_recycledRewardsArePaidByTheNewEpochsBalances() (gas: 568001)\n[PASS] test_shareThatRoundsToZeroIsRefusedNotPaid() (gas: 499870)\n[PASS] test_unaccruedDonationGoesToTheCurrentEpochNotAnEndedOne() (gas: 445556)\n[PASS] test_weightReadsRevertUntilTheEpochHasEnded() (gas: 225629)\nSuite result: ok. 23 passed; 0 failed; 0 skipped; finished in 611.24ms (1.21s CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken0Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 772646, ~: 772889)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 784844, ~: 784976)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 806452)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 775380)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 809736)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 958374)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122971)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 784655)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 918042)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 871806)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 630196)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 956681)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1412377)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 965713)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1289372)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1135375)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 12248802)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1064599)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 12848869)\n[PASS] test_refusesASecondPool() (gas: 46701)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 811292)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 799271)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119833)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 666.78ms (677.31ms CPU time)\n\nRan 16 tests for test/DeezLaunch.t.sol:DeezLaunchToken1Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8629)\n[PASS] test_constructorWiringNamesRequesterAndDependencies() (gas: 27036)\n[PASS] test_launchDayFeesGoToTheHoldersOfTheLaunchDay() (gas: 89717520)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 87747222)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 87557245)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 85083760)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 86034544)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 84946823)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926389)\n[PASS] test_launchRunsOnce() (gas: 172667618)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 88717648)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74209)\n[PASS] test_nothingIsOwned() (gas: 107333)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 14020)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 89343294)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 3059410)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 1.06s (5.54s CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken1Test\n[PASS]\nDeezHookInvariantToken1Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken1Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.11s (1.01s CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken0Test\n[PASS]\nDeezHookInvariantToken0Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken0Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.15s (1.12s CPU time)\n\nRan 16 tests for test/DeezLaunch.t.sol:DeezLaunchToken0Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8629)\n[PASS] test_constructorWiringNamesRequesterAndDependencies() (gas: 27036)\n[PASS] test_launchDayFeesGoToTheHoldersOfTheLaunchDay() (gas: 36361056)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 34392698)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 34204017)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 31734418)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 32683057)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 31597558)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926389)\n[PASS] test_launchRunsOnce() (gas: 65760156)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 35357232)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74209)\n[PASS] test_nothingIsOwned() (gas: 107333)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 14020)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 35987305)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 181482542)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 2.77s (4.11s CPU time)\n\nRan 6 tests for test/DeezTokenHistoryEdges.t.sol:DeezTokenHistoryEdgesTest\n[PASS] testFuzz_binarySearchFindsEveryIntervalOfLongHistory(uint256,uint256,uint256) (runs: 1000, μ: 3475931, ~: 3476308)\n[PASS] test_allowanceFailureLeavesHistoriesUntouched() (gas: 100312)\n[PASS] test_failedTransferFromRestoresSpentAllowanceAndBothHistories() (gas: 148071)\n[PASS] test_fullSupplyRoundTripInOneSecondHasNoRewardWeight() (gas: 242347)\n[PASS] test_zeroAndSelfTransfersPreserveExactWholeDayTokenTime() (gas: 194136)\n[PASS] test_zeroReceiverCannotBurnSupplyOrCreateCheckpoints() (gas: 75878)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 2.77s (2.77s CPU time)\n\nRan 2 tests for test/DeezLaunchLifecycleInvariant.t.sol:DeezLaunchLifecycleInvariantTest\n[PASS] invariant_custodyIsConservedAndOnlyOneRequesterLaunchCanSucceed() (runs: 256, calls: 15360, reverts: 0)\n\n╭----------------------------+-------------------+-------+---------+----------╮\n| Contract                   | Selector          | Calls | Reverts | Discards |\n+=============================================================================+\n| DeezLaunchLifecycleHandler | attempt           | 5095  | 0       | 0        |\n|----------------------------+-------------------+-------+---------+----------|\n| DeezLaunchLifecycleHandler | launchAsRequester | 5103  | 0       | 0        |\n|----------------------------+-------------------+-------+---------+----------|\n| DeezLaunchLifecycleHandler | movePayout        | 5162  | 0       | 0        |\n╰----------------------------+-------------------+-------+---------+----------╯\n\n[PASS] test_failedAttemptsThenSuccessThenReplay() (gas: 3301442)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.79s (2.78s CPU time)\n\nRan 2 tests for test/DeezLiquidityLockInvariant.t.sol:DeezLockInvariantToken0Test\n[PASS] invariant_positionsArePermanentAndPrincipalAndFeesAreConserved() (runs: 256, calls: 15360, reverts: 0)\n\n╭-----------------+-----------------------+-------+---------+----------╮\n| Contract        | Selector              | Calls | Reverts | Discards |\n+======================================================================+\n| DeezLockHandler | add                   | 2632  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | donate                | 2594  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectForeignCallback | 2541  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectForeignRemoval  | 2501  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectStaleTick       | 2537  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | swap                  | 2555  | 0       | 0        |\n╰-----------------+-----------------------+-------+---------+----------╯\n\n[PASS] test_feeCreditsCanExceedTopUpWithoutEscapingTheLock() (gas: 1036045)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 5.47s (5.41s CPU time)\n\nRan 2 tests for test/DeezLiquidityLockInvariant.t.sol:DeezLockInvariantToken1Test\n[PASS] invariant_positionsArePermanentAndPrincipalAndFeesAreConserved() (runs: 256, calls: 15360, reverts: 0)\n\n╭-----------------+-----------------------+-------+---------+----------╮\n| Contract        | Selector              | Calls | Reverts | Discards |\n+======================================================================+\n| DeezLockHandler | add                   | 2632  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | donate                | 2594  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectForeignCallback | 2541  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectForeignRemoval  | 2501  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | rejectStaleTick       | 2537  | 0       | 0        |\n|-----------------+-----------------------+-------+---------+----------|\n| DeezLockHandler | swap                  | 2555  | 0       | 0        |\n╰-----------------+-----------------------+-------+---------+----------╯\n\n[PASS] test_feeCreditsCanExceedTopUpWithoutEscapingTheLock() (gas: 1090174)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 5.70s (5.59s CPU time)\n\nRan 1 test for test/DeezRewardsInvariant.t.sol:DeezRewardsInvariantTest\n[PASS]\nDeezRewardsInvariantTest invariants:\n[PASS] invariant_claimsNeverExceedTheBalanceShare\n[PASS] invariant_closedEpochsNeverReopen\n[PASS] invariant_holdsAtLeastWhatItReserved\n[PASS] invariant_imdIsConserved\n[PASS] invariant_noHolderIsPaidMoreThanItsShareOfAnyPot\n[PASS] invariant_noPotPaysMoreThanItHolds\n[PASS] invariant_onlyTheAccountClaimsItsShare\n[PASS] invariant_pendingFeesAreTrackedExactly\n[PASS] invariant_reservedEqualsWhatOpenPotsOwe\n[PASS] invariant_supplyNeverChanges\n DeezRewardsInvariantTest invariants (runs: 256, calls: 15360, reverts: 0)\n\n╭----------------+---------------------+-------+---------+----------╮\n| Contract       | Selector            | Calls | Reverts | Discards |\n+===================================================================+\n| RewardsHandler | claim               | 1520  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | claimFor            | 1582  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | finalize            | 1497  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | fund                | 1506  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | harvest             | 1554  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | lateFee             | 1503  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | recycle             | 1561  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | transfer            | 1508  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warp                | 1557  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warpPastClaimWindow | 1572  | 0       | 0        |\n╰----------------+---------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 9.23s (9.19s CPU time)\n\nRan 2 tests for test/DeezTokenHistoryInvariant.t.sol:DeezTokenHistoryInvariantTest\n[PASS]\nDeezTokenHistoryInvariantTest invariants:\n[PASS] invariant_balancesAllowancesAndTokenTimeMatchIndependentLedger\n[PASS] invariant_closedHistoryRemainsImmutable\n DeezTokenHistoryInvariantTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭--------------------+------------------+-------+---------+----------╮\n| Contract           | Selector         | Calls | Reverts | Discards |\n+====================================================================+\n| DeezHistoryHandler | approve          | 3538  | 0       | 0        |\n|--------------------+------------------+-------+---------+----------|\n| DeezHistoryHandler | checkObservation | 3497  | 0       | 0        |\n|--------------------+------------------+-------+---------+----------|\n| DeezHistoryHandler | elapse           | 3408  | 0       | 0        |\n|--------------------+------------------+-------+---------+----------|\n| DeezHistoryHandler | rejectOverdraft  | 3381  | 0       | 0        |\n|--------------------+------------------+-------+---------+----------|\n| DeezHistoryHandler | transfer         | 3387  | 0       | 0        |\n|--------------------+------------------+-------+---------+----------|\n| DeezHistoryHandler | transferFrom     | 3269  | 0       | 0        |\n╰--------------------+------------------+-------+---------+----------╯\n\n[PASS] test_handlerExercisesApprovalsFullTransfersAndHistory() (gas: 2010755)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 17.19s (17.19s CPU time)\n\nRan 24 test suites in 17.20s (52.64s CPU time): 219 tests passed, 0 failed, 0 skipped (219 total tests)\n","passed":true},{"durationMs":219,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"DeezHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"DeezHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"DeezHook.harvest()\",\"DeezHook.harvestEpochs(uint256[])\",\"DeezHook.unlockCallback(bytes)\",\"DeezLaunch.launch(address,address,address,bytes32)\",\"DeezLiquidityLock.lock()\",\"DeezLiquidityLock.lockAs(uint8,int24,int24)\",\"DeezLiquidityLock.unlockCallback(bytes)\",\"DeezRewards.accrue()\",\"DeezRewards.claim(address,uint256[])\",\"DeezRewards.credit(uint256,uint256)\",\"DeezRewards.finalize(uint256)\",\"DeezRewards.recycle(uint256)\",\"DeezRewards.setHook(address)\",\"DeezToken.approve(address,uint256)\",\"DeezToken.transfer(address,uint256)\",\"DeezToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":250,\"foundry.toml\":20,\"remappings.txt\":5,\"script/MineHookSalt.s.sol\":42,\"site/deez.config.js\":27,\"site/index.html\":319,\"site/logo.svg\":10,\"src/DeezHook.sol\":359,\"src/DeezLaunch.sol\":204,\"src/DeezLiquidityLock.sol\":237,\"src/DeezRewards.sol\":299,\"src/DeezToken.sol\":150,\"src/HookFlags.sol\":34,\"test/ADVERSARIAL_TESTS.md\":66,\"test/DeezBase.t.sol\":140,\"test/DeezFailurePaths.t.sol\":530,\"test/DeezFlywheel.t.sol\":150,\"test/DeezHook.t.sol\":396,\"test/DeezHookInvariant.t.sol\":153,\"test/DeezLaunch.t.sol\":447,\"test/DeezLaunchLifecycleInvariant.t.sol\":184,\"test/DeezLaunchRollback.t.sol\":196,\"test/DeezLauncherExclusion.t.sol\":209,\"test/DeezLiquidityLock.t.sol\":175,\"test/DeezLiquidityLockInvariant.t.sol\":268,\"test/DeezRewards.t.sol\":483,\"test/DeezRewardsInvariant.t.sol\":305,\"test/DeezRewardsTransferFailures.t.sol\":135,\"test/DeezToken.t.sol\":174,\"test/DeezTokenHistoryEdges.t.sol\":116,\"test/DeezTokenHistoryInvariant.t.sol\":217,\"test/mocks/MockERC20.sol\":15,\"test/mocks/MockHook.sol\":36,\"test/mocks/Swapper.sol\":85},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c7a9b4baaade37ff971a7edb06d40b707f1e6405904300a8261137ce8aa35868","verifiedTreeHash":"72b50e49586347af510cf4932194b8ab326cf901","verifierVersion":"0.1.0+a6ee6548"},{"checks":[{"durationMs":85236,"exitCode":0,"name":"build","output":"Compiling 102 files with Solc 0.8.26\nSolc 0.8.26 finished in 85.11s\nCompiler run successful!\n","passed":true},{"durationMs":4188,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken0Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1208385)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 940446)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 964014)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266888)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1172198)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 830366)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 12216088)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054091)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 25.94ms (16.39ms CPU time)\n\nRan 4 tests for test/DeezFlywheel.t.sol:DeezFlywheelTest\n[PASS] test_earlyClaimerGetsItsShareOfFeesHarvestedLater() (gas: 2219324)\n[PASS] test_feesBelongToTheEpochTheyWereTradedInWheneverHarvested() (gas: 1198687)\n[PASS] test_lastSecondBuyerCannotSnipeTheEpochsPot() (gas: 1679767)\n[PASS] test_tradesBecomeHolderRewards() (gas: 1985913)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 47.51ms (3.98ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken1Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1960663)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 850257)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 974591)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 1213224)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969821)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61939)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71544)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 51.17ms (4.89ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken0Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1954987)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 844044)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 969168)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 12132258)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969833)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61951)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71556)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 56.57ms (39.72ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken1Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1212044)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 935043)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 967677)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266876)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1193447)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 826726)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 1298755)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054079)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 63.81ms (8.00ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken1Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 778168, ~: 778262)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 779290, ~: 779497)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 811875)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 785146)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 813845)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 969453)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122947)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 779716)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 933874)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 887772)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 625465)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 978005)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1417783)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 971005)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1294664)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1140667)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 1331484)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1070022)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 1910765)\n[PASS] test_refusesASecondPool() (gas: 46689)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 805849)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 795142)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119478)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 147.45ms (138.21ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken0Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 772646, ~: 772889)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 784844, ~: 784976)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 806452)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 775380)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 809736)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 958374)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122971)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 784655)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 918042)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 871806)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 630196)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 956681)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1412377)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 965713)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1289372)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1135375)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 12248802)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1064599)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 12848869)\n[PASS] test_refusesASecondPool() (gas: 46701)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 811292)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 799271)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119833)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 147.53ms (185.11ms CPU time)\n\nRan 16 tests for test/DeezLaunch.t.sol:DeezLaunchToken1Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8625)\n[PASS] test_factoryDeploymentLeavesEverythingUnlaunched() (gas: 56024)\n[PASS] test_launchDayFeesGoToTheHoldersOfTheLaunchDay() (gas: 89717504)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 87747226)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 87557247)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 85083762)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 86034534)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 84946801)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926407)\n[PASS] test_launchRunsOnce() (gas: 172667596)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 88717648)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74187)\n[PASS] test_nothingIsOwned() (gas: 107311)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 13998)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 89343272)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 3059388)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 498.06ms (2.43s CPU time)\n\nRan 23 tests for test/DeezFailurePaths.t.sol:DeezRewardsFailurePathsTest\n[PASS] testFuzz_allHoldersTogetherNeverDrainMoreThanThePot(uint96,uint96,uint128,uint32,uint32) (runs: 512, μ: 976657, ~: 1045014)\n[PASS] testFuzz_claimOrderAndLateFeesDoNotChangeFinalShares(uint96,uint128,uint128,uint8,uint32) (runs: 512, μ: 1230559, ~: 1193023)\n[PASS] test_accrueWithNothingNewCreditsNothing() (gas: 222432)\n[PASS] test_balanceMovedInTheFirstSecondOfTheNextEpochDoesNotCount() (gas: 584388)\n[PASS] test_batchWithAnUnendedEpochPaysNothing() (gas: 440945)\n[PASS] test_closedEpochRefusesClaimsAndASecondRecycle() (gas: 333924)\n[PASS] test_creditCannotBeForgedOrOverdrawn() (gas: 214111)\n[PASS] test_duplicateEpochInOneBatchPaysItOnce() (gas: 498783)\n[PASS] test_emptyBatchReverts() (gas: 226526)\n[PASS] test_epochWithNoEligibleSupplyPaysNobodyAndIsRecycled() (gas: 674520)\n[PASS] test_excludedAddressesCannotClaimEvenForThemselves() (gas: 382307)\n[PASS] test_finalizeIsIdempotentAndIgnoresLaterTransfers() (gas: 418522)\n[PASS] test_holderWithNoBalanceInTheEpochHasNothingToClaim() (gas: 368520)\n[PASS] test_lastSecondBuyerWeighsOneSecond() (gas: 782612)\n[PASS] test_lateFeeAfterSomeClaimedStillSplitsExactlyByBalance() (gas: 741959)\n[PASS] test_nobodyCanClaimForSomeoneElse() (gas: 455385)\n[PASS] test_pendingFeesOfAClosedEpochGoToTheCurrentPot() (gas: 519541)\n[PASS] test_recycleOfAnEpochThatNeverHadAPotClosesItForNothing() (gas: 100110)\n[PASS] test_recycleOpensExactlyAfterTheClaimWindow() (gas: 461302)\n[PASS] test_recycledRewardsArePaidByTheNewEpochsBalances() (gas: 568001)\n[PASS] test_shareThatRoundsToZeroIsRefusedNotPaid() (gas: 499870)\n[PASS] test_unaccruedDonationGoesToTheCurrentEpochNotAnEndedOne() (gas: 445556)\n[PASS] test_weightReadsRevertUntilTheEpochHasEnded() (gas: 225629)\nSuite result: ok. 23 passed; 0 failed; 0 skipped; finished in 498.03ms (513.00ms CPU time)\n\nRan 11 tests for test/DeezToken.t.sol:DeezTokenTest\n[PASS] testFuzz_cumulativeBalanceMatchesHoldingTime(uint96,uint32,uint32) (runs: 256, μ: 284536, ~: 284486)\n[PASS] testFuzz_pastBalanceMatchesBalanceAtThatTime(uint96,uint96,uint32) (runs: 256, μ: 266271, ~: 266538)\n[PASS] test_cumulativeBalanceAllowsTheCurrentSecondButNotTheFuture() (gas: 12108)\n[PASS] test_cumulativeBalanceIntegratesHoldingTime() (gas: 514182)\n[PASS] test_cumulativeBalanceRefusesTheFuture() (gas: 20199)\n[PASS] test_metadataAndSupply() (gas: 51418)\n[PASS] test_noMintOwnerOrPause() (gas: 147261)\n[PASS] test_pastBalanceRefusesTheCurrentSecondAndTheFuture() (gas: 22664)\n[PASS] test_pastBalancesFollowTransfers() (gas: 461865)\n[PASS] test_transferFromRespectsAllowance() (gas: 310333)\n[PASS] test_transferMovesExactlyWhatItWasAsked() (gas: 126080)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 497.98ms (234.26ms CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken0Test\n[PASS]\nDeezHookInvariantToken0Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken0Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 607.02ms (578.55ms CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken1Test\n[PASS]\nDeezHookInvariantToken1Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken1Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 649.27ms (581.39ms CPU time)\n\nRan 16 tests for test/DeezLaunch.t.sol:DeezLaunchToken0Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8625)\n[PASS] test_factoryDeploymentLeavesEverythingUnlaunched() (gas: 56024)\n[PASS] test_launchDayFeesGoToTheHoldersOfTheLaunchDay() (gas: 36361040)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 34392702)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 34204019)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 31734420)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 32683047)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 31597536)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926407)\n[PASS] test_launchRunsOnce() (gas: 65760134)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 35357232)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74187)\n[PASS] test_nothingIsOwned() (gas: 107311)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 13998)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 35987283)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 181482520)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 1.32s (2.17s CPU time)\n\nRan 25 tests for test/DeezRewards.t.sol:DeezRewardsTest\n[PASS] testFuzz_claimsNeverExceedThePotAndSplitByBalance(uint96,uint96,uint96) (runs: 256, μ: 868874, ~: 868845)\n[PASS] testFuzz_claimsNeverExceedThePotWithMidEpochMoves(uint96,uint32,uint32,uint96) (runs: 256, μ: 1166802, ~: 1166876)\n[PASS] test_accrueCreditsTheCurrentEpochOnce() (gas: 195183)\n[PASS] test_balanceMovedAfterTheEpochDoesNotChangeIt() (gas: 805779)\n[PASS] test_claimBeforeTheEpochEndsReverts() (gas: 341817)\n[PASS] test_claimHarvestsOnlyTheEpochsItPays() (gas: 646937)\n[PASS] test_claimHarvestsThePendingFeesOfTheEpochFirst() (gas: 1010608)\n[PASS] test_claimManyEpochsAtOnce() (gas: 1102561)\n[PASS] test_claimsAreProportionalToTheAverageBalance() (gas: 1347591)\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8825)\n[PASS] test_creditGoesToTheEpochTheHookNames() (gas: 436448)\n[PASS] test_creditRefusesOthersAndUnfundedAmounts() (gas: 227829)\n[PASS] test_creditToAClosedOrFutureEpochGoesToTheCurrentOne() (gas: 411066)\n[PASS] test_doubleClaimPaysNothingMore() (gas: 833886)\n[PASS] test_emptyClaimReverts() (gas: 379004)\n[PASS] test_epochArithmetic() (gas: 31685)\n[PASS] test_excludedAddresses() (gas: 51193)\n[PASS] test_excludedAddressesCannotClaim() (gas: 283481)\n[PASS] test_finalizeRequiresAnEndedEpoch() (gas: 239411)\n[PASS] test_lateCreditIsPaidOnASecondClaim() (gas: 1087201)\n[PASS] test_launcherHoldingBeforeALateLaunchDoesNotDiluteTheLaunchDay() (gas: 738637)\n[PASS] test_launcherHoldingNeitherEarnsNorDilutes() (gas: 750859)\n[PASS] test_onlyTheAccountItselfCanClaim() (gas: 867873)\n[PASS] test_recycleFoldsUnclaimedIntoTheCurrentEpoch() (gas: 967114)\n[PASS] test_rewardsAreWeightedByHoldingTime() (gas: 1172432)\nSuite result: ok. 25 passed; 0 failed; 0 skipped; finished in 1.32s (233.85ms CPU time)\n\nRan 1 test for test/DeezRewardsInvariant.t.sol:DeezRewardsInvariantTest\n[PASS]\nDeezRewardsInvariantTest invariants:\n[PASS] invariant_claimsNeverExceedTheBalanceShare\n[PASS] invariant_closedEpochsNeverReopen\n[PASS] invariant_holdsAtLeastWhatItReserved\n[PASS] invariant_imdIsConserved\n[PASS] invariant_noHolderIsPaidMoreThanItsShareOfAnyPot\n[PASS] invariant_noPotPaysMoreThanItHolds\n[PASS] invariant_onlyTheAccountClaimsItsShare\n[PASS] invariant_pendingFeesAreTrackedExactly\n[PASS] invariant_reservedEqualsWhatOpenPotsOwe\n[PASS] invariant_supplyNeverChanges\n DeezRewardsInvariantTest invariants (runs: 256, calls: 15360, reverts: 0)\n\n╭----------------+---------------------+-------+---------+----------╮\n| Contract       | Selector            | Calls | Reverts | Discards |\n+===================================================================+\n| RewardsHandler | claim               | 1520  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | claimFor            | 1582  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | finalize            | 1497  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | fund                | 1506  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | harvest             | 1554  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | lateFee             | 1503  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | recycle             | 1561  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | transfer            | 1508  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warp                | 1557  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warpPastClaimWindow | 1572  | 0       | 0        |\n╰----------------+---------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.06s (4.05s CPU time)\n\nRan 15 test suites in 4.06s (9.99s CPU time): 190 tests passed, 0 failed, 0 skipped (190 total tests)\n","passed":true},{"durationMs":86,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"DeezHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"DeezHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"DeezHook.harvest()\",\"DeezHook.harvestEpochs(uint256[])\",\"DeezHook.unlockCallback(bytes)\",\"DeezLaunch.launch(address,address,address,bytes32)\",\"DeezLiquidityLock.lock()\",\"DeezLiquidityLock.lockAs(uint8,int24,int24)\",\"DeezLiquidityLock.unlockCallback(bytes)\",\"DeezRewards.accrue()\",\"DeezRewards.claim(address,uint256[])\",\"DeezRewards.credit(uint256,uint256)\",\"DeezRewards.finalize(uint256)\",\"DeezRewards.recycle(uint256)\",\"DeezRewards.setHook(address)\",\"DeezToken.approve(address,uint256)\",\"DeezToken.transfer(address,uint256)\",\"DeezToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":250,\"foundry.toml\":20,\"launch.json\":36,\"remappings.txt\":5,\"script/MineHookSalt.s.sol\":42,\"site/deez.config.js\":27,\"site/index.html\":319,\"site/logo.svg\":10,\"src/DeezHook.sol\":359,\"src/DeezLaunch.sol\":204,\"src/DeezLiquidityLock.sol\":237,\"src/DeezRewards.sol\":299,\"src/DeezToken.sol\":150,\"src/HookFlags.sol\":34,\"test/DeezBase.t.sol\":140,\"test/DeezFailurePaths.t.sol\":530,\"test/DeezFlywheel.t.sol\":150,\"test/DeezHook.t.sol\":396,\"test/DeezHookInvariant.t.sol\":153,\"test/DeezLaunch.t.sol\":449,\"test/DeezLiquidityLock.t.sol\":175,\"test/DeezRewards.t.sol\":483,\"test/DeezRewardsInvariant.t.sol\":305,\"test/DeezToken.t.sol\":174,\"test/mocks/MockERC20.sol\":15,\"test/mocks/MockHook.sol\":36,\"test/mocks/Swapper.sol\":85},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"e924fdb2beefcf8082b879a5bb0adf742637fae4def427b19615cf857efd100f","verifiedTreeHash":"75173f712ccd3ffdda44f6c4930dcf446b37e990","verifierVersion":"0.1.0+a6ee6548"},{"checks":[{"durationMs":81578,"exitCode":0,"name":"build","output":"Compiling 102 files with Solc 0.8.26\nSolc 0.8.26 finished in 81.47s\nCompiler run successful!\n","passed":true},{"durationMs":4093,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/DeezFlywheel.t.sol:DeezFlywheelTest\n[PASS] test_earlyClaimerGetsItsShareOfFeesHarvestedLater() (gas: 2219324)\n[PASS] test_feesBelongToTheEpochTheyWereTradedInWheneverHarvested() (gas: 1198687)\n[PASS] test_lastSecondBuyerCannotSnipeTheEpochsPot() (gas: 1679767)\n[PASS] test_tradesBecomeHolderRewards() (gas: 1985913)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 15.41ms (4.26ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken0Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1954987)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 844044)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 969168)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 12132258)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969833)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61951)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71556)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 43.72ms (23.39ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken0Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1208385)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 940446)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 964014)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266888)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1172198)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 830366)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 12216088)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054091)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 61.60ms (20.67ms CPU time)\n\nRan 11 tests for test/DeezLiquidityLock.t.sol:DeezLiquidityLockToken1Test\n[PASS] test_lockAsFullRangeAndTheLeftoverSingleSided() (gas: 1212044)\n[PASS] test_lockAsRefusesAPriceOutsideTheCallersBounds() (gas: 935043)\n[PASS] test_lockAsRefusesAnEmptySide() (gas: 635363)\n[PASS] test_lockAsSingleSidedIgnoresDustOnTheOtherSide() (gas: 967677)\n[PASS] test_lockBothBecomesFullRange() (gas: 1266876)\n[PASS] test_lockDeezOnlyBecomesLiquidityAboveThePrice() (gas: 1193447)\n[PASS] test_lockImdOnlyBecomesABuyWallBelowThePrice() (gas: 826726)\n[PASS] test_lockRefusesBeforeThePoolExists() (gas: 1298755)\n[PASS] test_lockRefusesNothing() (gas: 58965)\n[PASS] test_lockedLiquidityCannotBeRemoved() (gas: 1054079)\n[PASS] test_wiring() (gas: 42895)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 62.44ms (6.01ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken1Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 778168, ~: 778262)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 779290, ~: 779497)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 811875)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 785146)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 813845)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 969453)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122947)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 779716)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 933874)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 887772)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 625465)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 978005)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1417783)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 971005)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1294664)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1140667)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 1331484)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1070022)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 1910765)\n[PASS] test_refusesASecondPool() (gas: 46689)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 805849)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 795142)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119478)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 134.13ms (144.87ms CPU time)\n\nRan 28 tests for test/DeezHook.t.sol:DeezHookToken0Test\n[PASS] testFuzz_buyExactInputFeeIsExact(uint96) (runs: 256, μ: 772646, ~: 772889)\n[PASS] testFuzz_sellExactInputFeeIsExact(uint96) (runs: 256, μ: 784844, ~: 784976)\n[PASS] test_buyExactInputTakesTwoPercentOfTheImdPaid() (gas: 806452)\n[PASS] test_buyExactOutputOnAFreshManagerSeededWithTokensOnly() (gas: 775380)\n[PASS] test_buyExactOutputTakesTwoPercentOfTheImdPaid() (gas: 809736)\n[PASS] test_buyOnAFreshManagerSeededWithTokensOnly() (gas: 958374)\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 122971)\n[PASS] test_constructorRefusesZeroAndSameAddresses() (gas: 16441)\n[PASS] test_constructorWiresTheDistributor() (gas: 56446)\n[PASS] test_deezSpecifiedPartialFillsAreChargedOnWhatActuallyTraded() (gas: 784655)\n[PASS] test_exactInputBuyStoppedByThePriceLimitReverts() (gas: 918042)\n[PASS] test_exactOutputSellBeyondThePoolsImdReverts() (gas: 871806)\n[PASS] test_exactOutputSellStoppedByThePriceLimitReverts() (gas: 630196)\n[PASS] test_exactOutputSellThatFillsOnlyPartOfTheRequestReverts() (gas: 956681)\n[PASS] test_feeDeltasSumToZeroForTheHook() (gas: 1412377)\n[PASS] test_feesAccumulateAcrossSwaps() (gas: 965713)\n[PASS] test_feesAreRecordedAgainstTheEpochTheyWereTradedIn() (gas: 1289372)\n[PASS] test_harvestMovesFeesToTheDistributorAndCreditsTheEpoch() (gas: 1135375)\n[PASS] test_harvestWithNothingPendingIsANoop() (gas: 43165)\n[PASS] test_hookHasNoOwner() (gas: 54436)\n[PASS] test_initializesFromAnyCallerOnTheLaunchPoolOnce() (gas: 12248802)\n[PASS] test_oldEpochsAreHarvestedByNumber() (gas: 1064599)\n[PASS] test_permissionsMatchTheAddress() (gas: 9154)\n[PASS] test_refusesAPoolWithOtherCurrencies() (gas: 12848869)\n[PASS] test_refusesASecondPool() (gas: 46701)\n[PASS] test_sellExactInputTakesTwoPercentOfTheImdReceived() (gas: 811292)\n[PASS] test_sellExactOutputTakesTwoPercentOfTheImdReceived() (gas: 799271)\n[PASS] test_zeroLiquidityChangeCollectsWithoutHookInterference() (gas: 1119833)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 163.69ms (286.54ms CPU time)\n\nRan 7 tests for test/DeezFailurePaths.t.sol:DeezHookFailurePathsToken1Test\n[PASS] test_claimThatRevertsLeavesTheHooksFeesUntouched() (gas: 1960663)\n[PASS] test_dustSwapsTradeWithoutAFee() (gas: 850257)\n[PASS] test_harvestTwiceMovesTheFeesOnce() (gas: 974591)\n[PASS] test_hookCallbacksRefuseBeforeInitialization() (gas: 1213224)\n[PASS] test_lockSpendsAlmostEverythingAndKeepsItLocked() (gas: 969821)\n[PASS] test_swapCallbacksRefuseAnyOtherPoolKey() (gas: 61939)\n[PASS] test_unlockCallbacksRefuseEveryoneButThePoolManager() (gas: 71544)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 182.28ms (6.01ms CPU time)\n\nRan 23 tests for test/DeezFailurePaths.t.sol:DeezRewardsFailurePathsTest\n[PASS] testFuzz_allHoldersTogetherNeverDrainMoreThanThePot(uint96,uint96,uint128,uint32,uint32) (runs: 512, μ: 976657, ~: 1045014)\n[PASS] testFuzz_claimOrderAndLateFeesDoNotChangeFinalShares(uint96,uint128,uint128,uint8,uint32) (runs: 512, μ: 1230559, ~: 1193023)\n[PASS] test_accrueWithNothingNewCreditsNothing() (gas: 222432)\n[PASS] test_balanceMovedInTheFirstSecondOfTheNextEpochDoesNotCount() (gas: 584388)\n[PASS] test_batchWithAnUnendedEpochPaysNothing() (gas: 440945)\n[PASS] test_closedEpochRefusesClaimsAndASecondRecycle() (gas: 333924)\n[PASS] test_creditCannotBeForgedOrOverdrawn() (gas: 214111)\n[PASS] test_duplicateEpochInOneBatchPaysItOnce() (gas: 498783)\n[PASS] test_emptyBatchReverts() (gas: 226526)\n[PASS] test_epochWithNoEligibleSupplyPaysNobodyAndIsRecycled() (gas: 674520)\n[PASS] test_excludedAddressesCannotClaimEvenForThemselves() (gas: 382307)\n[PASS] test_finalizeIsIdempotentAndIgnoresLaterTransfers() (gas: 418522)\n[PASS] test_holderWithNoBalanceInTheEpochHasNothingToClaim() (gas: 368520)\n[PASS] test_lastSecondBuyerWeighsOneSecond() (gas: 782612)\n[PASS] test_lateFeeAfterSomeClaimedStillSplitsExactlyByBalance() (gas: 741959)\n[PASS] test_nobodyCanClaimForSomeoneElse() (gas: 455385)\n[PASS] test_pendingFeesOfAClosedEpochGoToTheCurrentPot() (gas: 519541)\n[PASS] test_recycleOfAnEpochThatNeverHadAPotClosesItForNothing() (gas: 100110)\n[PASS] test_recycleOpensExactlyAfterTheClaimWindow() (gas: 461302)\n[PASS] test_recycledRewardsArePaidByTheNewEpochsBalances() (gas: 568001)\n[PASS] test_shareThatRoundsToZeroIsRefusedNotPaid() (gas: 499870)\n[PASS] test_unaccruedDonationGoesToTheCurrentEpochNotAnEndedOne() (gas: 445556)\n[PASS] test_weightReadsRevertUntilTheEpochHasEnded() (gas: 225629)\nSuite result: ok. 23 passed; 0 failed; 0 skipped; finished in 230.68ms (315.27ms CPU time)\n\nRan 16 tests for test/DeezLaunch.t.sol:DeezLaunchToken1Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8625)\n[PASS] test_factoryDeploymentLeavesEverythingUnlaunched() (gas: 56024)\n[PASS] test_launchDayFeesGoToTheHoldersOfTheLaunchDay() (gas: 89717504)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 87747226)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 87557247)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 85083762)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 86034534)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 84946801)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926407)\n[PASS] test_launchRunsOnce() (gas: 172667596)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 88717648)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74187)\n[PASS] test_nothingIsOwned() (gas: 107311)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 13998)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 89343272)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 3059388)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 352.44ms (1.94s CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken0Test\n[PASS]\nDeezHookInvariantToken0Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken0Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 526.52ms (502.90ms CPU time)\n\nRan 1 test for test/DeezHookInvariant.t.sol:DeezHookInvariantToken1Test\n[PASS]\nDeezHookInvariantToken1Test invariants:\n[PASS] invariant_claimsAreBackedByTheManager\n[PASS] invariant_everyFeeIsPendingOrHarvested\n[PASS] invariant_everyFeeIsTwoPercentOfTheGrossImd\n[PASS] invariant_harvestedImdSitsInTheDistributor\n[PASS] invariant_hookAndDistributorHoldNoDeez\n[PASS] invariant_pendingFeesAreExactlyTheHookClaims\n DeezHookInvariantToken1Test invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭-------------+--------------+-------+---------+----------╮\n| Contract    | Selector     | Calls | Reverts | Discards |\n+=========================================================+\n| HookHandler | buyExactIn   | 369   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | buyExactOut  | 355   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | donate       | 362   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | harvest      | 371   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactIn  | 330   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | sellExactOut | 403   | 0       | 0        |\n|-------------+--------------+-------+---------+----------|\n| HookHandler | warp         | 370   | 0       | 0        |\n╰-------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 552.94ms (481.34ms CPU time)\n\nRan 25 tests for test/DeezRewards.t.sol:DeezRewardsTest\n[PASS] testFuzz_claimsNeverExceedThePotAndSplitByBalance(uint96,uint96,uint96) (runs: 256, μ: 868874, ~: 868845)\n[PASS] testFuzz_claimsNeverExceedThePotWithMidEpochMoves(uint96,uint32,uint32,uint96) (runs: 256, μ: 1166802, ~: 1166876)\n[PASS] test_accrueCreditsTheCurrentEpochOnce() (gas: 195183)\n[PASS] test_balanceMovedAfterTheEpochDoesNotChangeIt() (gas: 805779)\n[PASS] test_claimBeforeTheEpochEndsReverts() (gas: 341817)\n[PASS] test_claimHarvestsOnlyTheEpochsItPays() (gas: 646937)\n[PASS] test_claimHarvestsThePendingFeesOfTheEpochFirst() (gas: 1010608)\n[PASS] test_claimManyEpochsAtOnce() (gas: 1102561)\n[PASS] test_claimsAreProportionalToTheAverageBalance() (gas: 1347591)\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8825)\n[PASS] test_creditGoesToTheEpochTheHookNames() (gas: 436448)\n[PASS] test_creditRefusesOthersAndUnfundedAmounts() (gas: 227829)\n[PASS] test_creditToAClosedOrFutureEpochGoesToTheCurrentOne() (gas: 411066)\n[PASS] test_doubleClaimPaysNothingMore() (gas: 833886)\n[PASS] test_emptyClaimReverts() (gas: 379004)\n[PASS] test_epochArithmetic() (gas: 31685)\n[PASS] test_excludedAddresses() (gas: 51193)\n[PASS] test_excludedAddressesCannotClaim() (gas: 283481)\n[PASS] test_finalizeRequiresAnEndedEpoch() (gas: 239411)\n[PASS] test_lateCreditIsPaidOnASecondClaim() (gas: 1087201)\n[PASS] test_launcherHoldingBeforeALateLaunchDoesNotDiluteTheLaunchDay() (gas: 738637)\n[PASS] test_launcherHoldingNeitherEarnsNorDilutes() (gas: 750859)\n[PASS] test_onlyTheAccountItselfCanClaim() (gas: 867873)\n[PASS] test_recycleFoldsUnclaimedIntoTheCurrentEpoch() (gas: 967114)\n[PASS] test_rewardsAreWeightedByHoldingTime() (gas: 1172432)\nSuite result: ok. 25 passed; 0 failed; 0 skipped; finished in 1.27s (2.54s CPU time)\n\nRan 11 tests for test/DeezToken.t.sol:DeezTokenTest\n[PASS] testFuzz_cumulativeBalanceMatchesHoldingTime(uint96,uint32,uint32) (runs: 256, μ: 284536, ~: 284486)\n[PASS] testFuzz_pastBalanceMatchesBalanceAtThatTime(uint96,uint96,uint32) (runs: 256, μ: 266271, ~: 266538)\n[PASS] test_cumulativeBalanceAllowsTheCurrentSecondButNotTheFuture() (gas: 12108)\n[PASS] test_cumulativeBalanceIntegratesHoldingTime() (gas: 514182)\n[PASS] test_cumulativeBalanceRefusesTheFuture() (gas: 20199)\n[PASS] test_metadataAndSupply() (gas: 51418)\n[PASS] test_noMintOwnerOrPause() (gas: 147261)\n[PASS] test_pastBalanceRefusesTheCurrentSecondAndTheFuture() (gas: 22664)\n[PASS] test_pastBalancesFollowTransfers() (gas: 461865)\n[PASS] test_transferFromRespectsAllowance() (gas: 310333)\n[PASS] test_transferMovesExactlyWhatItWasAsked() (gas: 126080)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 1.27s (1.46s CPU time)\n\nRan 16 tests for test/DeezLaunch.t.sol:DeezLaunchToken0Test\n[PASS] test_constructorRefusesZeroAddresses() (gas: 8625)\n[PASS] test_factoryDeploymentLeavesEverythingUnlaunched() (gas: 56024)\n[PASS] test_launchDayFeesGoToTheHoldersOfTheLaunchDay() (gas: 36361040)\n[PASS] test_launchDeploysWiresOpensLocksAndPays() (gas: 34392702)\n[PASS] test_launchEmitsTheLaunchFacts() (gas: 34204019)\n[PASS] test_launchRefusesASaltWithoutTheFlags() (gas: 31734420)\n[PASS] test_launchRefusesContractsThatAreNotItsOwn() (gas: 32683047)\n[PASS] test_launchRefusesEveryoneButTheRequester() (gas: 31597536)\n[PASS] test_launchRefusesWhenTheSupplyIsNotHere() (gas: 926407)\n[PASS] test_launchRunsOnce() (gas: 65760134)\n[PASS] test_launchedLiquidityCannotBeRemovedByAnyone() (gas: 35357232)\n[PASS] test_lockAndClaimRefuseBeforeTheHookIsSet() (gas: 74187)\n[PASS] test_nothingIsOwned() (gas: 107311)\n[PASS] test_openingPriceIsTheSameValuationOnBothSides() (gas: 13998)\n[PASS] test_poolTradesAfterLaunchAndTheHookTakesItsFee() (gas: 35987283)\n[PASS] test_setHookIsTheLaunchersAlone() (gas: 181482520)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 1.27s (2.10s CPU time)\n\nRan 1 test for test/DeezRewardsInvariant.t.sol:DeezRewardsInvariantTest\n[PASS]\nDeezRewardsInvariantTest invariants:\n[PASS] invariant_claimsNeverExceedTheBalanceShare\n[PASS] invariant_closedEpochsNeverReopen\n[PASS] invariant_holdsAtLeastWhatItReserved\n[PASS] invariant_imdIsConserved\n[PASS] invariant_noHolderIsPaidMoreThanItsShareOfAnyPot\n[PASS] invariant_noPotPaysMoreThanItHolds\n[PASS] invariant_onlyTheAccountClaimsItsShare\n[PASS] invariant_pendingFeesAreTrackedExactly\n[PASS] invariant_reservedEqualsWhatOpenPotsOwe\n[PASS] invariant_supplyNeverChanges\n DeezRewardsInvariantTest invariants (runs: 256, calls: 15360, reverts: 0)\n\n╭----------------+---------------------+-------+---------+----------╮\n| Contract       | Selector            | Calls | Reverts | Discards |\n+===================================================================+\n| RewardsHandler | claim               | 1520  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | claimFor            | 1582  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | finalize            | 1497  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | fund                | 1506  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | harvest             | 1554  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | lateFee             | 1503  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | recycle             | 1561  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | transfer            | 1508  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warp                | 1557  | 0       | 0        |\n|----------------+---------------------+-------+---------+----------|\n| RewardsHandler | warpPastClaimWindow | 1572  | 0       | 0        |\n╰----------------+---------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.96s (3.96s CPU time)\n\nRan 15 test suites in 3.97s (10.10s CPU time): 190 tests passed, 0 failed, 0 skipped (190 total tests)\n","passed":true},{"durationMs":73,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"DeezHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"DeezHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"DeezHook.harvest()\",\"DeezHook.harvestEpochs(uint256[])\",\"DeezHook.unlockCallback(bytes)\",\"DeezLaunch.launch(address,address,address,bytes32)\",\"DeezLiquidityLock.lock()\",\"DeezLiquidityLock.lockAs(uint8,int24,int24)\",\"DeezLiquidityLock.unlockCallback(bytes)\",\"DeezRewards.accrue()\",\"DeezRewards.claim(address,uint256[])\",\"DeezRewards.credit(uint256,uint256)\",\"DeezRewards.finalize(uint256)\",\"DeezRewards.recycle(uint256)\",\"DeezRewards.setHook(address)\",\"DeezToken.approve(address,uint256)\",\"DeezToken.transfer(address,uint256)\",\"DeezToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":250,\"foundry.toml\":20,\"remappings.txt\":5,\"script/MineHookSalt.s.sol\":42,\"site/deez.config.js\":27,\"site/index.html\":319,\"site/logo.svg\":10,\"src/DeezHook.sol\":359,\"src/DeezLaunch.sol\":204,\"src/DeezLiquidityLock.sol\":237,\"src/DeezRewards.sol\":299,\"src/DeezToken.sol\":150,\"src/HookFlags.sol\":34,\"test/DeezBase.t.sol\":140,\"test/DeezFailurePaths.t.sol\":530,\"test/DeezFlywheel.t.sol\":150,\"test/DeezHook.t.sol\":396,\"test/DeezHookInvariant.t.sol\":153,\"test/DeezLaunch.t.sol\":449,\"test/DeezLiquidityLock.t.sol\":175,\"test/DeezRewards.t.sol\":483,\"test/DeezRewardsInvariant.t.sol\":305,\"test/DeezToken.t.sol\":174,\"test/mocks/MockERC20.sol\":15,\"test/mocks/MockHook.sol\":36,\"test/mocks/Swapper.sol\":85},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":5373,"exitCode":0,"name":"slither","output":"[low/medium] calls-loop at src/DeezHook.sol:228: DeezHook._harvest(uint256[]) (src/DeezHook.sol#228-246) has external calls inside a loop: rewards.credit(epochs[i_scope_0],amounts[i_scope_0]) (src/DeezHook.sol#243)\n[low/medium] calls-loop at src/DeezHook.sol:228: DeezHook._harvest(uint256[]) (src/DeezHook.sol#228-246) has external calls inside a loop: rewards.credit(epochs[i_scope_0],amounts[i_scope_0]) (src/DeezHook.sol#243)\n[low/medium] calls-loop at src/DeezRewards.sol:164: DeezRewards.weightOf(address,uint256) (src/DeezRewards.sol#164-168) has external calls inside a loop: token.getCumulativeBalanceOf(account,start + EPOCH_LENGTH) - token.getCumulativeBalanceOf(account,start) (src/DeezRewards.sol#166-167)\n[low/medium] calls-loop at src/DeezRewards.sol:164: DeezRewards.weightOf(address,uint256) (src/DeezRewards.sol#164-168) has external calls inside a loop: token.getCumulativeBalanceOf(account,start + EPOCH_LENGTH) - token.getCumulativeBalanceOf(account,start) (src/DeezRewards.sol#166-167)\n[low/medium] calls-loop at src/DeezRewards.sol:171: DeezRewards.eligibleSupplyAt(uint256) (src/DeezRewards.sol#171-177) has external calls inside a loop: total = token.getCumulativeTotalSupply(start + EPOCH_LENGTH) - token.getCumulativeTotalSupply(start) (src/DeezRewards.sol#173)\n[low/medium] calls-loop at src/DeezRewards.sol:171: DeezRewards.eligibleSupplyAt(uint256) (src/DeezRewards.sol#171-177) has external calls inside a loop: total = token.getCumulativeTotalSupply(start + EPOCH_LENGTH) - token.getCumulativeTotalSupply(start) (src/DeezRewards.sol#173)\n[low/medium] calls-loop at src/DeezRewards.sol:182: DeezRewards.claimable(address,uint256) (src/DeezRewards.sol#182-191) has external calls inside a loop: total = pot.total + IDeezHarvester(hook).pendingFeesOf(epoch) (src/DeezRewards.sol#186)\n[low/medium] reentrancy-benign at src/DeezRewards.sol:246: Reentrancy in DeezRewards.claim(address,uint256[]) (src/DeezRewards.sol#246-270):\n[low/medium] reentrancy-benign at src/DeezHook.sol:190: Reentrancy in DeezHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/DeezHook.sol#190-208):\n[low/medium] reentrancy-benign at src/DeezLiquidityLock.sol:110: Reentrancy in DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#110-150):\n[low/medium] reentrancy-benign at src/DeezLaunch.sol:113: Reentrancy in DeezLaunch.launch(address,address,address,bytes32) (src/DeezLaunch.sol#113-151):\n[low/medium] reentrancy-events at src/DeezLaunch.sol:113: Reentrancy in DeezLaunch.launch(address,address,address,bytes32) (src/DeezLaunch.sol#113-151):\n[low/medium] reentrancy-events at src/DeezHook.sol:228: Reentrancy in DeezHook._harvest(uint256[]) (src/DeezHook.sol#228-246):\n[low/medium] reentrancy-events at src/DeezLaunch.sol:113: Reentrancy in DeezLaunch.launch(address,address,address,bytes32) (src/DeezLaunch.sol#113-151):\n[low/medium] reentrancy-events at src/DeezHook.sol:190: Reentrancy in DeezHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/DeezHook.sol#190-208):\n[low/medium] reentrancy-events at src/DeezLaunch.sol:113: Reentrancy in DeezLaunch.launch(address,address,address,bytes32) (src/DeezLaunch.sol#113-151):\n[low/medium] reentrancy-events at src/DeezLiquidityLock.sol:110: Reentrancy in DeezLiquidityLock.lockAs(DeezLiquidityLock.Mode,int24,int24) (src/DeezLiquidityLock.sol#110-150):\n[low/medium] timestamp at src/DeezRewards.sol:273: DeezRewards.recycle(uint256) (src/DeezRewards.sol#273-283) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:75: DeezToken.getCumulativeBalanceOf(address,uint256) (src/DeezToken.sol#75-81) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezRewards.sol:219: DeezRewards.credit(uint256,uint256) (src/DeezRewards.sol#219-227) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:63: DeezToken.getPastBalanceOf(address,uint256) (src/DeezToken.sol#63-68) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezRewards.sol:151: DeezRewards.hasEnded(uint256) (src/DeezRewards.sol#151-153) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:116: DeezToken._checkpoint(address) (src/DeezToken.sol#116-133) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezRewards.sol:182: DeezRewards.claimable(address,uint256) (src/DeezRewards.sol#182-191) uses timestamp for comparisons\n[low/medium] timestamp at src/DeezToken.sol:85: DeezToken.getCumulativeTotalSupply(uint256) (src/DeezToken.sol#85-90) uses timestamp for comparisons","passed":true},{"durationMs":614,"exitCode":0,"name":"aderyn","output":"[high] reentrancy-state-change at src/DeezHook.sol:201: Reentrancy: State change after external call (14 places)\n[high] unsafe-casting at src/DeezRewards.sol:210: Unsafe Casting of integers (2 places)\n[low] costly-loop at src/DeezHook.sol:230: Costly operations inside loop (2 places)\n[low] internal-function-used-once at src/HookFlags.sol:26: Internal Function Used Only Once\n[low] large-numeric-literal at src/DeezHook.sol:48: Large Numeric Literal (6 places)\n[low] literal-instead-of-constant at src/DeezLaunch.sol:177: Literal Instead of Constant (2 places)\n[low] missing-inheritance at src/DeezLaunch.sol:38: Missing Inheritance\n[low] modifier-used-only-once at src/DeezLiquidityLock.sol:74: Modifier Invoked Only Once\n[low] require-revert-in-loop at src/DeezRewards.sol:254: Loop Contains `require`/`revert`\n[low] state-change-without-event at src/DeezHook.sol:149: State Change Without Event\n[low] state-no-address-check at src/DeezLaunch.sol:121: Address State Variable Set Without Checks (3 places)\n[low] unused-import at src/DeezLiquidityLock.sol:9: Unused Import","passed":true},{"durationMs":10502,"exitCode":0,"name":"proof 1d8f8490c6d0","output":"Compiling 91 files with Solc 0.8.26\nSolc 0.8.26 finished in 9.88s\nCompiler run successful!\n\nRan 1 test for test/imd-proof-82b224e7/Proof_1d8f8490c6d0.t.sol:LauncherWeightTest\n[PASS] test_launchDayFeesAreMostlyOwedToTheLauncher() (gas: 14619926)\nLogs:\n  eligible supply (wei-days): 23521842316475700455381472\n  launcher weight  (wei-days): 458333333333333333333333333\n  pot (wei): 2000000000000000000\n  claimable by live holders (wei): 1999999999999999999\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 20.71ms (19.86ms CPU time)\n\nRan 1 test suite in 21.50ms (20.71ms 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":"eaa5334de601e98357b3d1dae9a2e7fb36f8b991f221bb0c0f042af9fb02e35d","verifiedTreeHash":"5c9870e7d97b02005b43416c00b277c1a69213fe","verifierVersion":"0.1.0+a6ee6548"}]}