{"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":"18ac1075-a6ce-4487-83f3-17e3d795c1f1","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"ca99556867107e5a1163e9a61b40a4dacb9556215115c833388eccf9f3cffadc","dependsOn":["audit_imported_code"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"2d7d84a1a9972f1497e5bc68a704cbf42294d08c62d2868f102ffe3b909b9b51","skillId":"adapt-contract-project","tools":[]},"key":"adapt_contract_project","kind":"code","role":"implement","skillHash":"2d7d84a1a9972f1497e5bc68a704cbf42294d08c62d2868f102ffe3b909b9b51","skillId":"adapt-contract-project","state":"accepted"},{"acceptedSubmissionHash":"8e54cd784eb715558f9a013cc05c9cb00c5901fb5669ccf380be5b5cc8e50c7a","dependsOn":["adapt_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":"68926d77792c97776cedb7e93c4bf8be2af5e02a5608f3e9ea867d59cd2823aa","dependsOn":["adapt_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":"af48c1931db79f9f513e3d9c9a0ce942c5da194082be917bb4ad429761994959","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","tools":[]},"key":"audit_imported_code","kind":"code","role":"review","skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","state":"accepted"},{"acceptedSubmissionHash":"1b3f3f795f6ff4db83de6caf1f76e59219b52f73f7cb7e0f4409af78586ef006","dependsOn":["adapt_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":"c1f6082c31ad01c72dc973d40eb1a0e63c86b6d0ecef191798873a49e7f83351","dependsOn":["adapt_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":"b0990b355711390f2a55f6fb1a7075bedfc21c361350c800878653bb214dc039","dependsOn":["adapt_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":"7e941bc5e6e0663093c02e18d24fe417bbfc6256f96e3926658b14218d7636f2","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"08ed80b3144014fdaa23cd5003624d2455562fa3cf5d86c2425bdda93241d47c","dependsOn":["adapt_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":"Review and launch the token named Intelligent Dance Market with token symbol IDM, from https://github.com/discodirector/idm-hook at 69cddfddd0e0bf5903e3e19eab38aebc70285e3a on Robinhood Chain 4663 with its immutable zero-fee Uniswap v4 sequencer hook. Preserve SPEC.md section 3, the two packed state words, ABI and Solidity test vectors exactly. Use the imported Foundry project (repository root) and its launch.json. No owner, signer, upgrade, fee, return delta or fund handling in the hook. Pair IDM with native ETH (IDM/ETH, pairWith eth) and provide verified deployed hook/token/pool addresses and launch receipts.","parentJobId":null,"planHash":"9723776e2effc4c11b7d63810e9e2e3dbcde74ef7d68349bc38cf0b1e5d38fc5","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"18ac1075-a6ce-4487-83f3-17e3d795c1f1","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2303-review-launch-token-named"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"53909","feedbackHash":"da5432ba61d4f535d3c7d436fbf42e35b35d3abab3ce2084d6b7a27e053ec3f3","nodeKey":"adapt_contract_project","submissionHash":"ca99556867107e5a1163e9a61b40a4dacb9556215115c833388eccf9f3cffadc","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"53924","feedbackHash":"9d142a4d855ab8aab0fbfe4848cef67322fd12ad12446ccf9354cc21f993fa6f","nodeKey":"adapt_contract_project","submissionHash":"9b6bffa7b4f1bd89a59271112b0a091185fad62c355b6082776ef5b3ceb607a3","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52667","feedbackHash":"476df8b454947ed236ebe34957195dd5006c1455b2d0e713c8e7ed54e5419733","nodeKey":"audit_economics","submissionHash":"8e54cd784eb715558f9a013cc05c9cb00c5901fb5669ccf380be5b5cc8e50c7a","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52548","feedbackHash":"f65421ef95d0362c84caea2b565f88a5fcde1d807809fc3204e40230c79632c3","nodeKey":"audit_flow","submissionHash":"68926d77792c97776cedb7e93c4bf8be2af5e02a5608f3e9ea867d59cd2823aa","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52468","feedbackHash":"8e96eb59be7db48636051cae3f8bc3a01350a5a8073273062ee322565522a288","nodeKey":"audit_imported_code","submissionHash":"af48c1931db79f9f513e3d9c9a0ce942c5da194082be917bb4ad429761994959","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52682","feedbackHash":"304a6f8fb5523f23feb7f92a07235063468fc4894592ce1078d428f91eddcf9f","nodeKey":"audit_judge","submissionHash":"1b3f3f795f6ff4db83de6caf1f76e59219b52f73f7cb7e0f4409af78586ef006","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51476","feedbackHash":"938fa31990ac7b509765ccce52cce62402cc7d2ecdfca014180c711fac2591fd","nodeKey":"audit_judge","submissionHash":"60a4e40e4aa5a45df3e61ecec12311e3f82b78106e3f0c7afff8c71cf7aeaf45","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52152","feedbackHash":"e8b0ead1f8436f4a4d7954055befac0d6124f45f480c013ca71febe7c7ab3f16","nodeKey":"audit_math","submissionHash":"c1f6082c31ad01c72dc973d40eb1a0e63c86b6d0ecef191798873a49e7f83351","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51447","feedbackHash":"0547d6980067f387e166bd227168a2270d0fcece7e4445a6d7a12948d1328a55","nodeKey":"audit_permissions","submissionHash":"b0990b355711390f2a55f6fb1a7075bedfc21c361350c800878653bb214dc039","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52640","feedbackHash":"87c848052e12b8530a995653b947d236066948ac635d3a3792d7dc076a6c88a0","nodeKey":"manifest","submissionHash":"a5c4854bfaac316bbe4604400f930c63f4bfb04c8fcb0d23c4cbe832adb16792","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51534","feedbackHash":"b4318e984099501f667d62419765289c1ad4b3b7f3ce999000e6eeeed122e815","nodeKey":"manifest","submissionHash":"7e941bc5e6e0663093c02e18d24fe417bbfc6256f96e3926658b14218d7636f2","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51163","feedbackHash":"606e245a7ce2de1c3156fd9c2e3f9d1f2ec92100105e326bd50264aff8b978f6","nodeKey":"write_foundry_tests","submissionHash":"08ed80b3144014fdaa23cd5003624d2455562fa3cf5d86c2425bdda93241d47c","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51364","feedbackHash":"699ccadd1fe3a410a887391f0afa038b7b02da7f4b6490abf6cb04c04cf82b5b","nodeKey":"write_foundry_tests","submissionHash":"8583b68ce78f0d98d72d9e8674ede931e532b6b0145f002d7a4ac1e5f5e71d18","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"0c1d6b345cdecfc0985188719dd1fdb9b152bcc8cc726eee03e899503910a1a5","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"f7cf0194d713bfe4f03444df549f6a751405e6e914359543d97020cc8ace4909","device":"8af9903f4ad1eed0","findings":[{"description":"When the pool has no active liquidity, priceAnchor() takes the nearest initialized tick at or below the current tick, and pulse() caps the swap at 0.99 x that sqrt price. That tick need not belong to real liquidity: anyone can mint a position with liquidity 1 one tick spacing wide anywhere between the seed's top and the parked price (IDM-only, costs a few wei plus gas). The anchor becomes that dust position's upper tick, the pulse's 1% window holds only the dust, and the swap delivers a few dozen wei of IDM. got > 0, so the in-callback NoFill guard does not fire: pulse() succeeds, emits Pulse, and the hook files the swap and resets lastTs, so the next pulse needs another 15 minutes of silence. Each dust position neutralizes one pulse. The ADAPTATION.md residual ('an attacker who parks the price and then adds a dust position spanning it makes the anchor slot0 again and the pulse fills 0 (NoFill)') is inaccurate on both counts: the pulse does not revert, and the dust position does not need to span the price; positions placed below it work too. No treasury funds are at risk (2 wei per neutralized pulse), and any real buy that moves the price back into the seed ends it. This is a liveness gap in the guarantee change 5 set out to restore: after 15 minutes of silence, anyone can buy.","line":162,"path":"src/PulseTreasury.sol","reproduction":"Launch shape from test/helpers/IdmLaunchFixture.sol (ETH/IDM, fee 12500, spacing 60, seed [-887220, 193380] with L = 3e22, price at tick 193380), treasury funded with 1 ETH, LP router = AnchorLp from test/PulseTreasuryAnchor.t.sol. Mint four dust positions with liquidity 1 at [199380 - 300(i+1), 199380 - 300(i+1) + 60] for i = 0..3. Park with a free IDM sell: fixture.swap(false, -1e18, getSqrtPriceAtTick(199380)), delta (0, 0). Then repeat five times: warp 900 s, call treasury.pulse(). Expected: every pulse buys a hat-sized amount from the seed (about 0.0002 ETH for about 5e22 IDM here). Actual: pulses 1-4 each return (paid 2 wei, got 60-63 wei IDM), each increments swapCount and resets lastTs; only pulse 5 buys from the seed (paid 202310139510784, got 49943137971282314315478). With a single liquidity-1 position spanning the parked tick ([199320, 199440]) the first pulse likewise returns (2, 63) and does not revert NoFill. Possible fixes (the requester's choice): set a minimum fill (e.g. revert NoFill when got is below a fraction of amount at the anchor price), or anchor to the nearest tick whose cumulative liquidity is not dust.","severity":"low","title":"Dust positions under a parked price turn pulses into 2-wei buys that consume the silence window (the documented residual is wrong: no NoFill, and no spanning position needed)"}],"hash":"08ed80b3144014fdaa23cd5003624d2455562fa3cf5d86c2425bdda93241d47c","nodeId":"b48659e1-5a67-4d23-8de1-1a8f2ee0b341","outcome":"completed","summary":"I added tests for the revised treasury's new price-anchor logic (`priceAnchor()`), and found one new defect. I'm reporting it in `.imd-findings.json` rather than writing a test that treats it as correct. `forge build` succeeds and `forge test` with the verifier's seed passes: 245 tests, 0 failed, 0 skipped. Nothing outside `test/` changed except that findings file, and nothing is committed yet.\n\n**New file `test/PulseTreasuryAnchor.t.sol`:**\n- **Targeted tests:**\n  - **Launch state:** at launch the anchor equals the opening price.\n  - **Parked price:** after a free sell parks the price at any height (fuzzed, 1,000 runs), the anchor stays at the top of the seeded liquidity and the pulse still buys.\n  - **Price gap:** with a gap about 8 bitmap words wide between two positions, the anchor walks down to the lower position's top.\n  - **Unreachable liquidity:** when the only liquidity sits above the price, or the price is below every position, there is nothing to buy. `nextPulse` reports not ready, `pulse()` reverts `NoFill`, and nothing changes.\n  - **Return from a park:** a buy that stops exactly on the top tick puts the pool back in range, and the next pulse is ordinary.\n  - **Recovery:** after a dust park, one real buy brings pulses back.\n- **Invariant campaign (256 runs × depth 64):** random parks, buys, liquidity removal and restore, and time passing. After every step:\n  - `priceAnchor()` matches a separate calculation from the one known position.\n  - `nextPulse` is ready exactly when there is liquidity to reach.\n  - Every pulse ends within 1% under its anchor.\n  - The treasury's ETH and IDM match its pulses, and every swap is recorded.\n\n**Finding (low), `src/PulseTreasury.sol:162`:** the revision notes in `ADAPTATION.md` say a dust position at a parked price makes `pulse()` revert `NoFill`. It doesn't. In a scratch test:\n- **What happens:** pulses \"succeed\", each paying 2 wei for about 60 wei of IDM. Each one resets the 15-minute silence window.\n- **Placement:** the dust positions don't need to span the price.\n- **Cost:** each liquidity-1 position (a few wei plus gas) cancels one pulse. Four positions cancelled four pulses in a row, and the fifth was ordinary.\n- **Impact:** no funds are at risk, and any real buy ends it. But it weakens the guarantee this revision was meant to restore: after 15 minutes of quiet, anyone can buy.\n\nThe finding includes the exact reproduction and possible fixes.\n\n**Not covered:**\n- I couldn't re-run the vector validator script because python3 isn't installed on this machine; it passed in the earlier round.\n- These tests don't verify any deployed Robinhood Chain (4663) addresses or launch receipts. That remains launch-stage work.\n\n`test/ADVERSARIAL_TESTS.md` is updated to describe the new suite and the finding.","treeHash":"d745d46a584054ed5383889d6435163d56a4f638","usage":{"cachedInputTokens":1438626,"inputTokens":36,"model":"claude-opus-5-5","outputTokens":32513,"runtime":"claude","turns":22,"wallClockMs":785255}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"a0f4c3f900dedd4a","findings":[{"citation":"resolved","description":"Settles the write_foundry_tests finding (kept, low) and is the residual of the fix to my earlier medium finding a3a45cc2 (confirmed fixed: the attached proof Proof_a3a45cc2990a.t.sol now passes, a free park at MAX_TICK no longer blocks pulse(), and nextPulse() agrees with pulse()). The fix walks the tick bitmap for the nearest initialized tick at or below slot0 when active liquidity is 0 and measures the 1% limit from it, but any initialized tick qualifies, including the upper tick of a position with liquidity 1. On the launch shape (ETH currency0, IDM-only seed [-887220, 193380], price at the seed top) anyone can mint liquidity-1 positions one spacing wide between the seed top and a parking tick (cost: at most 1 wei per side plus gas) and park slot0 above them with an IDM sell past the empty ETH side (a few hundred wei of IDM). Each pulse then anchors on the next dust position: the 1.99% window below its upper tick holds only that position, the swap delivers ~60 wei of IDM for 2 wei of ETH, got > 0 so the in-callback NoFill guard does not fire, Pulse is emitted, and the hook files the swap (swapCount +1, a 2-wei buy whose size log is clamped to the EMA floor) and resets lastTs, so the next pulse needs another 15 minutes. Each dust position neutralizes one pulse window; after they are consumed one more cheap sell (254 wei of IDM in my run) re-arms all of them, so the cost per neutralized pulse is gas only. No treasury ETH is lost (2 wei per pulse), but the guarantee change 5 restored, that after 15 minutes of silence a pulse buys a hat-sized amount of IDM, is cheaply and repeatedly deniable, and nextPulse() keeps promising a hat-sized amount (0.002 ETH) that the pulse then does not spend. ADAPTATION.md lines 117-118 describe this residual inaccurately: the pulse does not revert NoFill, and the dust position need not span the parked price (positions below it work). Possible fixes, the requester's choice since SPEC section 9 fixes the 1% rule: require a minimum fill in unlockCallback (e.g. revert NoFill when got is below a fraction of what `amount` buys at the anchor price, so a dust pulse reverts without filing or resetting lastTs), or anchor on the first tick at or below which the cumulative crossed liquidity is at least a floor rather than the first initialized tick.","line":173,"path":"src/PulseTreasury.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {SequencerHook} from \"src/SequencerHook.sol\";\nimport {SequencerToken} from \"src/SequencerToken.sol\";\nimport {QuoteCalibration as Q} from \"src/QuoteCalibration.sol\";\nimport {PulseTreasury} from \"src/PulseTreasury.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 {Hooks} from \"v4-core/src/libraries/Hooks.sol\";\nimport {StateLibrary} from \"v4-core/src/libraries/StateLibrary.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {PoolIdLibrary} from \"v4-core/src/types/PoolId.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {BalanceDelta} from \"v4-core/src/types/BalanceDelta.sol\";\nimport {ModifyLiquidityParams, SwapParams} from \"v4-core/src/types/PoolOperation.sol\";\n\n/// Minimal LP/trader that settles from its own balances.\ncontract DustLp is IUnlockCallback {\n    IPoolManager immutable manager;\n    SequencerToken immutable token;\n    PoolKey key;\n\n    constructor(IPoolManager m, SequencerToken t, PoolKey memory k) {\n        manager = m;\n        token = t;\n        key = k;\n    }\n\n    receive() external payable {}\n\n    function modify(int24 lo, int24 hi, int256 liq) external returns (BalanceDelta) {\n        return abi.decode(manager.unlock(abi.encode(true, lo, hi, liq, false, uint160(0))), (BalanceDelta));\n    }\n\n    function swap(bool z, int256 amt, uint160 lim) external returns (BalanceDelta) {\n        return abi.decode(manager.unlock(abi.encode(false, int24(0), int24(0), amt, z, lim)), (BalanceDelta));\n    }\n\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        require(msg.sender == address(manager));\n        (bool mod, int24 lo, int24 hi, int256 amt, bool z, uint160 lim) =\n            abi.decode(data, (bool, int24, int24, int256, bool, uint160));\n        BalanceDelta d;\n        if (mod) (d,) = manager.modifyLiquidity(key, ModifyLiquidityParams(lo, hi, amt, 0), \"\");\n        else d = manager.swap(key, SwapParams(z, amt, lim), \"\");\n        _settle(key.currency0, d.amount0());\n        _settle(key.currency1, d.amount1());\n        return abi.encode(d);\n    }\n\n    function _settle(Currency c, int128 delta) private {\n        if (delta < 0) {\n            uint256 a = uint256(-int256(delta));\n            if (Currency.unwrap(c) == address(0)) manager.settle{value: a}();\n            else {\n                manager.sync(c);\n                require(token.transfer(address(manager), a));\n                manager.settle();\n            }\n        } else if (delta > 0) {\n            manager.take(c, address(this), uint256(uint128(delta)));\n        }\n    }\n}\n\n/// Launch shape: ETH currency0, IDM currency1, fee 12500, spacing 60, IDM-only seed [-887220, 193380],\n/// price at the seed's top tick. The test contract is the launch factory (deploys the hook, initializes).\ncontract DustAnchorProofTest is Test {\n    using StateLibrary for IPoolManager;\n    using PoolIdLibrary for PoolKey;\n\n    int24 constant UPPER = 193380;\n    PoolManager manager;\n    SequencerToken token;\n    SequencerHook hook;\n    PulseTreasury treasury;\n    DustLp lp;\n    PoolKey key;\n\n    receive() external payable {}\n\n    function setUp() public {\n        vm.warp(1_800_000_000);\n        manager = new PoolManager(address(this));\n        token = new SequencerToken();\n        bytes memory init = abi.encodePacked(\n            type(SequencerHook).creationCode,\n            abi.encode(manager, address(token), address(this), Q.T_HAT, Q.T_GLITCH, Q.T_SNARE)\n        );\n        bytes32 hash = keccak256(init);\n        uint256 salt;\n        for (; salt < 300_000; ++salt) {\n            address p = address(\n                uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), address(this), bytes32(salt), hash))))\n            );\n            if ((uint160(p) & Hooks.ALL_HOOK_MASK) == 0x3040) break;\n        }\n        hook = new SequencerHook{salt: bytes32(salt)}(\n            manager, address(token), address(this), Q.T_HAT, Q.T_GLITCH, Q.T_SNARE\n        );\n        key = PoolKey(Currency.wrap(address(0)), Currency.wrap(address(token)), 12500, 60, IHooks(address(hook)));\n        manager.initialize(key, TickMath.getSqrtPriceAtTick(UPPER));\n        lp = new DustLp(IPoolManager(address(manager)), token, key);\n        require(token.transfer(address(lp), 1e27));\n        vm.deal(address(lp), 1 ether);\n        lp.modify(-887220, UPPER, 3e22); // IDM-only seed\n        treasury = new PulseTreasury(IPoolManager(address(manager)), key, address(hook), address(token));\n        vm.deal(address(treasury), 1 ether);\n    }\n\n    /// Four liquidity-1 positions between the seed top and the parked price each absorb one pulse window:\n    /// the pulse pays 2 wei, gets ~60 wei IDM, is filed by the hook and resets lastTs.\n    function test_FirstPulseAfterADustParkStillBuysFromTheSeed() public {\n        uint256 t = block.timestamp;\n        for (int24 i = 0; i < 4; ++i) {\n            int24 lo = 199380 - 300 * (i + 1);\n            BalanceDelta d = lp.modify(lo, lo + 60, 1);\n            assertGe(d.amount0(), -1); // the position costs at most 1 wei of ETH\n            assertGe(d.amount1(), -1); // and at most 1 wei of IDM\n        }\n        // Park: a sell past the (empty) ETH side fills (0, 0) and leaves slot0 at the limit.\n        BalanceDelta park = lp.swap(false, -1e18, TickMath.getSqrtPriceAtTick(199380));\n        assertGe(park.amount1(), -1000); // the park costs a few hundred wei of IDM (bought the dust's ETH)\n        assertEq(IPoolManager(address(manager)).getLiquidity(key.toId()), 0);\n\n        t += 15 minutes;\n        vm.warp(t);\n        (bool ready, uint256 amount,,) = treasury.nextPulse();\n        assertTrue(ready);\n        assertGt(amount, 1e14); // nextPulse() promises a hat-sized buy\n        uint32 countBefore = hook.state().swapCount;\n        (uint256 paid, uint256 got) = treasury.pulse();\n        // The swap was filed and the idle window restarted...\n        assertEq(hook.state().swapCount, countBefore + 1);\n        assertEq(hook.state().lastTs, uint40(t));\n        // ...but the pulse bought from the dust, not from the seed. Expected: a hat-sized buy\n        // (about 2e14 wei of ETH at this anchor); actual: paid 2 wei, got ~63 wei of IDM.\n        assertGt(paid, 1e12, \"pulse after the park bought dust, not the seed\");\n        assertGt(got, 1e18, \"pulse after the park bought dust, not the seed\");\n    }\n}","reproduction":"Real PoolManager, SequencerToken, SequencerHook mined at 0x3040 with factory = test, key (ETH, IDM, 12500, 60, hook), initialize at sqrtPrice of tick 193380, IDM-only liquidity 3e22 in [-887220, 193380] via an LP router, PulseTreasury funded 1 ETH. Attacker (same LP router): modifyLiquidity(lo, lo + 60, 1) for lo = 199380 - 300*(i+1), i = 0..3 (deltas 0 or -1 wei per side); then swap(oneForZero, -1e18, getSqrtPriceAtTick(199380)): delta (0, -254), tick 199380, getLiquidity == 0. Warp +15 min: nextPulse() == (ready true, amount 0.002 ether). Expected: pulse() buys from the seed (about 2e14 wei of ETH for about 5e22 IDM, as the sanity pulse at launch does: paid 2000000000000000, got 493266994160584041565316). Actual: pulse() returns (paid 2, got 63), swapCount +1, lastTs == now, tick 198938. The next four windows: (2, 62), (2, 61), (2, 60), then the fifth pulse reaches the seed; one more sell of 254 wei IDM at the same limit re-parks and the following four pulses are again (2, 63..60). Ran: forge test --match-path test/scratch/DustAnchorProof.t.sol -> [FAIL: pulse after the park bought dust, not the seed: 2 <= 1000000000000] test_FirstPulseAfterADustParkStillBuysFromTheSeed; test/scratch/DustAnchor.t.sol test_DustPositionsAreRearmedByOneSell passes (shows the re-arm).","severity":"low","snippet":"                int24 next = (int24(wordPos) * 256 + int24(uint24(BitMath.mostSignificantBit(word)))) * tickSpacing;","title":"priceAnchor() anchors on the nearest initialized tick whatever its liquidity: liquidity-1 positions under a parked price turn each pulse into a 2-wei buy that still restarts the 15-minute window"}],"hash":"1b3f3f795f6ff4db83de6caf1f76e59219b52f73f7cb7e0f4409af78586ef006","nodeId":"242f88f8-fd64-4e2d-a82a-055061c05422","outcome":"completed","summary":"Review complete. The findings file is written at `.imd-findings.json` with one low finding and an 11-row coverage record. Git status shows nothing tracked changed; only the findings file and my scratch tests under `test/scratch/` exist, which are ignored.\n\n**Settled from last round**\n\n- **Medium, parked price blocks pulse (a3a45cc2): fixed.** My attached proof, copied to the scratch directory, now passes against the revised code. The new `priceAnchor()` view measures the 1% limit from the nearest initialized tick at or below slot0 when active liquidity is zero, and `nextPulse()` uses the same check. The full suite also passes, with 245 tests.\n- **Low, stranded ETH under 0.0025 ETH (d1b58ea3): accepted as documented.** SPEC section 9, README and the runbook now state that remainder is unspendable until new ETH arrives, which was the first option the finding offered.\n- **Three disputed lows (whale threshold at the post-swap tick, zero-delta swaps filed as sells, pulses dragging the EMA): dropped.** Each reproduces as before, but the author is right that all three follow SPEC section 3 or section 9 as written, which this task must preserve exactly. SPEC section 9 explicitly documents the EMA drag. They are recorded in ADAPTATION.md for the requester and are not defects of this task.\n\n**One finding kept, low**\n\nThe independent tester's dust-position report reproduces and is the residual of the fix. Any initialized tick qualifies as the anchor, including the upper tick of a liquidity-1 position. On the launch shape an attacker mints such positions between the seed top and a parking tick, parks the price with an IDM sell past the empty ETH side, and each pulse then buys about 60 wei of IDM for 2 wei of ETH while still being filed by the hook and resetting the 15-minute window. One more sell of a few hundred wei of IDM re-arms all the positions. No ETH is lost, but the restored guarantee that a pulse buys a hat-sized amount after 15 minutes of silence is deniable for gas only, and the ADAPTATION.md residual text describes it wrongly. A self-contained proof is attached that fails now for that reason and will pass once a minimum fill or a liquidity-aware anchor is in place. The choice of fix is the requester's, since SPEC section 9 fixes the 1% rule.\n\n**Nothing new found.** The static-analysis leads are benign on inspection: the strict equalities are zero checks, the uninitialized locals are assigned before use, the reentrancy lead is the transient flag set before the unlock, and the locked-ether lead is the documented design. The manifest matches the constructor order, hook permissions and launch fee tier.","treeHash":null,"usage":{"cachedInputTokens":1762713,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":28470,"runtime":"claude","turns":28,"wallClockMs":652584}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e9049e5b12ba53ba","findings":[{"citation":"resolved","description":"Merges audit_economics (medium, parked price -> NoFill) and audit_flow consequence (1). In v4 a oneForZero swap that runs out of liquidity moves the price through empty ticks to the caller's sqrtPriceLimitX96 at no cost. On the launch pool (ETH currency0, IDM-only liquidity below the opening tick) any IDM sell with limit MAX_SQRT_PRICE-1 that exceeds the ETH side (or, before any buy, any IDM sell at all, with BalanceDelta (0,0)) leaves slot0 at tick 887271. pulse() then bounds its buy at 99% of that parked sqrtPrice, the swap walks ~200 ticks through empty space, buys 0 IDM and unlockCallback reverts NoFill (line 166). nextPulse() does not model the limit and keeps reporting ready=true. The treasury's documented guarantee (after 15 min of silence anyone may pulse) is broken until an unrelated buyer re-anchors the price, i.e. precisely in the silence the pulse exists for; the trigger costs gas only. No funds are lost (the swap reverts atomically). Fix (outside SPEC 3): bound the pulse by its already-capped spend and use TickMath.MIN_SQRT_PRICE + 1 as the limit, or clamp the limit to the nearest initialized tick at/below the current tick, and make nextPulse() agree.","line":147,"path":"src/PulseTreasury.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {SequencerHook} from \"src/SequencerHook.sol\";\nimport {SequencerToken} from \"src/SequencerToken.sol\";\nimport {SequencerState as S} from \"src/SequencerState.sol\";\nimport {QuoteCalibration as Q} from \"src/QuoteCalibration.sol\";\nimport {PulseTreasury} from \"src/PulseTreasury.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 {IERC20Minimal} from \"v4-core/src/interfaces/external/IERC20Minimal.sol\";\nimport {Hooks} from \"v4-core/src/libraries/Hooks.sol\";\nimport {StateLibrary} from \"v4-core/src/libraries/StateLibrary.sol\";\nimport {TransientStateLibrary} from \"v4-core/src/libraries/TransientStateLibrary.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {PoolIdLibrary} from \"v4-core/src/types/PoolId.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {BalanceDelta} from \"v4-core/src/types/BalanceDelta.sol\";\nimport {ModifyLiquidityParams, SwapParams} from \"v4-core/src/types/PoolOperation.sol\";\n\ncontract ScratchRouter is IUnlockCallback {\n    using TransientStateLibrary for IPoolManager;\n\n    IPoolManager immutable manager;\n\n    constructor(IPoolManager m) {\n        manager = m;\n    }\n\n    receive() external payable {}\n\n    function addLiquidity(PoolKey memory key, int24 lo, int24 hi, int256 liq) external {\n        manager.unlock(abi.encode(msg.sender, key, true, ModifyLiquidityParams(lo, hi, liq, 0), SwapParams(false, 0, 0)));\n    }\n\n    function swap(PoolKey memory key, SwapParams memory p) external returns (BalanceDelta d) {\n        d = abi.decode(\n            manager.unlock(abi.encode(msg.sender, key, false, ModifyLiquidityParams(0, 0, 0, 0), p)), (BalanceDelta)\n        );\n    }\n\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        (address payer, PoolKey memory key, bool modify, ModifyLiquidityParams memory mp, SwapParams memory sp) =\n            abi.decode(data, (address, PoolKey, bool, ModifyLiquidityParams, SwapParams));\n        BalanceDelta d;\n        if (modify) (d,) = manager.modifyLiquidity(key, mp, \"\");\n        else d = manager.swap(key, sp, \"\");\n        _settle(key.currency0, payer);\n        _settle(key.currency1, payer);\n        return abi.encode(d);\n    }\n\n    function _settle(Currency c, address payer) private {\n        int256 delta = manager.currencyDelta(address(this), c);\n        if (delta < 0) {\n            manager.sync(c);\n            if (Currency.unwrap(c) == address(0)) {\n                manager.settle{value: uint256(-delta)}();\n                return;\n            }\n            IERC20Minimal(Currency.unwrap(c)).transferFrom(payer, address(manager), uint256(-delta));\n            manager.settle();\n        } else if (delta > 0) {\n            manager.take(c, payer, uint256(delta));\n        }\n    }\n}\n\n/// Launch shape: native ETH currency0, IDM currency1, IDM-only liquidity below the opening tick.\ncontract ParkedPulseProofTest is Test {\n    using StateLibrary for IPoolManager;\n    using PoolIdLibrary for PoolKey;\n\n    PoolManager manager;\n    SequencerToken token;\n    SequencerHook hook;\n    ScratchRouter router;\n    PulseTreasury treasury;\n    PoolKey key;\n\n    receive() external payable {}\n\n    function setUp() public {\n        vm.warp(1_800_000_000);\n        manager = new PoolManager(address(this));\n        token = new SequencerToken();\n        hook = _deployHook();\n        key = PoolKey(Currency.wrap(address(0)), Currency.wrap(address(token)), 12500, 60, IHooks(address(hook)));\n        router = new ScratchRouter(manager);\n        token.approve(address(router), type(uint256).max);\n        vm.deal(address(router), 100 ether);\n        manager.initialize(key, uint160(1 << 96)); // tick 0\n        router.addLiquidity(key, -60000, 0, 1e24); // IDM only (range below the price)\n        treasury = new PulseTreasury(manager, key, address(hook), address(token));\n        vm.deal(address(treasury), 1 ether);\n    }\n\n    function _deployHook() internal returns (SequencerHook) {\n        bytes memory init = abi.encodePacked(\n            type(SequencerHook).creationCode,\n            abi.encode(manager, address(token), address(this), Q.T_HAT, Q.T_GLITCH, Q.T_SNARE)\n        );\n        bytes32 hash = keccak256(init);\n        for (uint256 i; i < 300_000; ++i) {\n            address p =\n                address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), address(this), bytes32(i), hash)))));\n            if ((uint160(p) & Hooks.ALL_HOOK_MASK) == 0x3040) {\n                return new SequencerHook{salt: bytes32(i)}(\n                    manager, address(token), address(this), Q.T_HAT, Q.T_GLITCH, Q.T_SNARE\n                );\n            }\n        }\n        revert(\"no salt\");\n    }\n\n    function _tick() internal view returns (int24 t) {\n        (, t,,) = IPoolManager(address(manager)).getSlot0(key.toId());\n    }\n\n    /// A sell of IDM that crosses no liquidity (free: delta (0,0)) parks the price at the router's limit.\n    /// Liquidity is untouched, yet every pulse afterwards reverts NoFill while nextPulse() says ready.\n    function test_PulseStillBuysAfterAFreeSellParkedThePrice() public {\n        BalanceDelta d = router.swap(key, SwapParams(false, -1e18, TickMath.MAX_SQRT_PRICE - 1));\n        assertEq(d.amount0(), 0);\n        assertEq(d.amount1(), 0);\n        assertEq(_tick(), 887271);\n        vm.warp(block.timestamp + 16 minutes);\n        (bool ready,,,) = treasury.nextPulse();\n        assertTrue(ready);\n        (, uint256 got) = treasury.pulse(); // reverts NoFill() on the current code\n        assertGt(got, 0);\n    }\n}","reproduction":"test/scratch/ParkedPulse.t.sol (proof below). Real PoolManager, SequencerToken, SequencerHook mined at 0x3040 with factory = test, key (ETH, IDM, 12500, 60, hook), initialize at sqrtPrice 2^96 (tick 0), IDM-only liquidity 1e24 in [-60000, 0], PulseTreasury funded 1 ETH. Sanity: warp +16 min, pulse() buys IDM (test_PulseBuysInSilence passes). Attack: router.swap(key, SwapParams(false, -1e18, MAX_SQRT_PRICE-1)) -> BalanceDelta (0,0), tick 887271. Warp +16 min: nextPulse().ready == true; pulse() expected to buy IDM (liquidity is untouched), actual revert NoFill(). Ran: [FAIL: NoFill()] test_PulseStillBuysAfterAFreeSellParkedThePrice.","severity":"medium","snippet":"        (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(poolId);\n        uint160 limit = uint160(uint256(sqrtPriceX96) * SQRT_PRICE_LIMIT_BPS / 10_000);","title":"pulse() takes its price limit from slot0, so a sell that parks the price above all liquidity (free when the ETH side is empty) makes every pulse revert NoFill while nextPulse() reports ready"},{"citation":"resolved","description":"Merges audit_economics (low) and audit_flow consequence (2). afterSwap evaluates SequencerState.whaleThreshold at the post-swap tick (line 177). A sell that drains the ETH side runs to the caller's limit (tick 887271), where whaleThreshold(887271, quoteIs0=true) saturates to WHALE_MIN = 0.005 ETH regardless of the market's real FDV, so any modest sell into a thin ETH side becomes a whale: root += 7, patternId += 1, Drop(fill=false) wipes a track, Movement emitted, and the sizeLogEma upper clamp falls to L(WHALE_MIN). No funds at risk; impact is on the sequencer state the project curates. The SPEC 3.3.1 text mandates the post-swap tick, so the fix (e.g. threshold at min(pre, post) tick FDV) is a SPEC decision for the requester and requires regenerating vectors.","line":172,"path":"src/SequencerHook.sol","reproduction":"Same setup. Buy: router.swap(key, SwapParams(true, -0.02 ether, MIN_SQRT_PRICE+1)) -> tick -1, hook.whaleThresholdAt(-1) = 50e18 (WHALE_MAX). Sell: router.swap(key, SwapParams(false, -1e24, MAX_SQRT_PRICE-1)) -> amount0 = +19749999999999999 wei, tick after = 887271. Expected: 0.01975 ETH < fair threshold, non-whale, patternId unchanged. Actual: patternId 0 -> 1 (whale). Ran: [FAIL: sell below the fair threshold filed as a whale: 1 != 0] test_SellThatParksPriceIsNotAWhale.","severity":"low","snippet":"        (, int24 tick,,) = poolManager.getSlot0(id);","title":"Whale threshold read at a post-swap tick parked outside liquidity: a 0.01975 ETH sell is filed as a whale (Movement, track wiped)"},{"citation":"resolved","description":"Merges audit_flow (low, zero-delta sell), audit_math (low, 27 one-wei sells drag EMA) and audit_math (info, 1-wei ETH buy filed as sell): one root cause, afterSwap files every swap regardless of size and classifies a non-positive IDM delta as a sell. A (0,0) swap across empty liquidity, a 1-wei IDM sell (ETH out rounds to 0) or a 1-wei ETH buy (fee-swallowed, IDM out 0) each increments swapCount, applies pressure -1000 and heat -1, may clear a bass nibble, resets lastTs (postponing the treasury pulse 15 min) and pulls sizeLogEma toward 710 (quoteAmt 0 is clamped up to lo=710, line 211-213), after which ordinary buys file as kick. No funds at risk. The behaviour follows SPEC 3.3.1 literally, so the fix (skip state writes when both deltas are zero / below dust) is a SPEC decision for the requester.","line":170,"path":"src/SequencerHook.sol","reproduction":"Same setup, fresh hook (swapCount 0). warp +10 min; router.swap(key, SwapParams(false, -1e18, MAX_SQRT_PRICE-1)) -> BalanceDelta (0,0), caller balances unchanged. Expected: no sequencer write. Actual: hook.state().swapCount == 1 (and lastTs == now, pressure -1000). Ran: [FAIL: a (0,0) swap was filed as a sell: 1 != 0] test_FreeSellWritesState. EMA drag per line 213: each dust swap sets ema = floor((7*ema + 710)/8), 854 -> 836 -> 820 ... reaching 710 after ~27 swaps.","severity":"low","snippet":"        bool isBuy = (seqIs0 ? delta.amount0() : delta.amount1()) > 0;","title":"Swaps that move no funds (or 1 wei) are written as sells: state mutates, lastTs resets, sizeLogEma is dragged to the floor for gas only"},{"citation":"resolved","description":"From audit_math (low). A pulse of L = ema - 24 feeds SequencerState line 213 floor((7*ema + ema-24)/8) = ema - 3, and with the MAX/MIN clamps every pulse still lowers the EMA; nothing raises it in silence. The EMA is driven monotonically to EMA_FLOOR 710, where the pulse (MIN_PULSE, L 710) files as glitch instead of the documented hat ('the quietest voice'), and the first market-size buy after the silence files as kick. No funds at risk; contradicts the contract's stated design after any long silence. Fix: size pulses without feeding back (e.g. offset from a fixed reference, or have the hook skip EMA updates for the treasury sender, the latter being a SPEC change).","line":122,"path":"src/PulseTreasury.sol","reproduction":"Same setup (fresh hook sizeLogEma 854, treasury 1 ETH). Loop: warp to hook.state().lastTs + 15 min; treasury.pulse(). Observed (test_PulsesDragEma): sizeLogEma reaches 710 after exactly 52 pulses. Expected per the docstring: pulses stay hat-class (relative < -8) at the market's EMA; actual: at 710 the MIN_PULSE pulse has relative 0 (glitch).","severity":"low","snippet":"        amount = sizeLogEma > HAT_OFFSET ? exp2Fixed(sizeLogEma - HAT_OFFSET) : 0;","title":"Treasury pulses lower the size EMA they are sized from: 52 pulses (13 h of silence) pin sizeLogEma at 710 and pulses stop being hats"},{"citation":"resolved","description":"From audit_permissions (low); also covers aderyn's contract-locks-ether lead. pulse() is the only ETH sink and spends at most balance/100, zeroed below MIN_PULSE (line 127), so any balance < 100 * MIN_PULSE = 0.0025 ETH makes pulse() revert NoBudget forever (absent new inflow), and in silence the balance decays geometrically toward that floor. No owner/withdraw by design, so the stranded amount is dust-scale; document it or let a pulse spend min(MIN_PULSE, balance) under the floor.","line":125,"path":"src/PulseTreasury.sol","reproduction":"treasury.pulseSize(854, 2.49e15) returns 0 (observed in test_PulsesDragEma log). Fund a fresh treasury with 0.00249 ether, warp past 15 min idle: pulse() reverts NoBudget(); no function moves the ETH.","severity":"low","snippet":"        uint256 cap = balance / BUDGET_DIVISOR;","title":"ETH below 0.0025 ETH is permanently unspendable in PulseTreasury (1% budget floor, no withdrawal)"}],"hash":"60a4e40e4aa5a45df3e61ecec12311e3f82b78106e3f0c7afff8c71cf7aeaf45","nodeId":"242f88f8-fd64-4e2d-a82a-055061c05422","outcome":"completed","summary":"I've finished the review and written it to `.imd-findings.json`: five findings, none critical or high. I ran each one against the code in scratch Foundry tests. The repo's own suite passes, and I changed no project files (I deleted the scratch directory afterwards).\n\n**Kept findings, most severe first:**\n\n1. **Medium: the treasury's pulse can be blocked for the cost of gas** (`src/PulseTreasury.sol:147`). `pulse()` caps the price at 99% of the pool's current price. On the launch pool all liquidity is IDM below the opening price. So any IDM sell set to run to the maximum price moves the price to the top of the range without trading anything. After that, every `pulse()` reverts with `NoFill()`, while `nextPulse()` still says it is ready. This lasts until some real buyer brings the price back down. No funds are lost, but the \"after 15 minutes of silence anyone can pulse\" guarantee is broken. This merges two specialists' reports. The attached proof test fails today with `NoFill()`. The fix is outside SPEC section 3.\n2. **Low: the whale check uses the price after the swap, even when that price has run past all liquidity** (`src/SequencerHook.sol:172`). A sell that empties the ETH side leaves the price at tick 887271, where the threshold drops to its 0.005 ETH minimum. A sell of 0.01975 ETH was then treated as a whale: a new pattern ID, a wiped track and a `Movement` event. Two specialists' reports merged.\n3. **Low: swaps that move nothing, or 1 wei, are still recorded as sells** (`src/SequencerHook.sol:170`). A swap with zero amounts on both sides changed `swapCount`, `pressure` and `lastTs`. That pushes back the next pulse by 15 minutes. About 27 such swaps also pull the size average down to its 710 floor. Three specialist reports merged.\n4. **Low: pulses lower the size average they are based on** (`src/PulseTreasury.sol:122`). Fifty-two pulses in a row, about 13 hours of silence, take it from 854 to 710. From then on a pulse no longer plays as the \"quietest voice\" (hat) the code's comment describes.\n5. **Low: up to 0.0025 ETH gets stuck in the treasury** (`src/PulseTreasury.sol:125`). Below that balance the 1% spending cap is less than the smallest allowed pulse, so `pulse()` reverts and nothing can withdraw the ETH. The amount is dust.\n\nFindings 2 and 3 follow SPEC section 3 to the letter, and you've asked for that section to stay exactly as it is. Fixing them is your call, and would mean changing the spec and regenerating the test vectors.\n\n**Dropped:** the specialists' notes that `burn()` can be called by anyone (that matches the no-owner design) and that the averages round downward (the spec requires it and it does no harm).\n\n**Coverage:** every listed entry point has a row, plus `launch.json` and the \"hook moves no funds\" check. In `launch.json` the six hook constructor arguments and the three permissions match the code, the 12500 fee is accepted, and the notes are 2,177 characters. Nothing stops the factory from deploying it: the hook is 9,484 bytes, with nothing to set up after deployment. There are no deployed Robinhood Chain addresses or launch receipts yet; the deployment step still has to produce them.","treeHash":null,"usage":{"cachedInputTokens":1146857,"inputTokens":32,"model":"claude-opus-5-5","outputTokens":17465,"runtime":"claude","turns":18,"wallClockMs":505265}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"9b657b3675e34ec5","findings":[{"citation":"resolved","description":"afterSwap derives direction from the sign of the IDM delta and size from |ETH delta| without excluding the case where both are zero. Uniswap v4 calls afterSwap for every swap that passes Pool.swap, including one that crossed only empty liquidity: on the launch pool, seeded single-sided with IDM only (currency0 = native ETH, currency1 = IDM, the position lies below the opening tick), any oneForZero swap (sell IDM) with a non-zero amountSpecified and a limit above the range walks through zero liquidity, settles a (0, 0) BalanceDelta, and leaves the pool price at the caller's limit. The hook then files it as a 0-wei sell: swapCount += 1, pressure -1000, heat -1, bass nibble possibly cleared, sizeLogEma pulled toward the floor, lastTs = now, lastTick = the parked tick. The caller pays no fee and moves no funds; only gas. The same zero-delta sell is what ADAPTATION.md section 2 fixed for the treasury's own pulse (NoFill), but any third party can still produce it against the pool. Two execution consequences: (1) PulseTreasury.pulse() computes its sqrtPriceLimit as 99% of the parked spot price (src/PulseTreasury.sol:147-148); with the price at MAX_SQRT_PRICE-1 the limit is still far above the top of the seeded range, so once the 15-minute window reopens pulse() reverts NoFill until some real buyer moves the price back into range, and the free sell also resets lastTs, closing the window again for 15 minutes. (2) The whale threshold read from the parked post-swap tick clamps to WHALE_MIN (0.005 ETH), and lastTick/bass are written from a tick the market never traded at. A related free write exists while liquidity is present: an exact-input buy of 1 wei ETH is wholly consumed by the 1.25% fee (rounded up), yields amount1 == 0, and is filed as a 1-wei sell (pressure -1000, heat -1) although the caller swapped in the buy direction. No funds are at risk in the hook (it holds none) and the treasury's ETH is not spent, so the impact is limited to the on-chain composition and to the treasury's keep-alive pulse being blockable for gas only. Reproduced with test/scratch/FreeWrite.t.sol on this tree (both tests pass, i.e. the behaviour is as described). Suggested fix, which is a SPEC decision for the requester: return early from afterSwap (no state write, no Mutated event) when both delta components are zero, and/or classify by the swap's input side as well as its output so that a fee-swallowed 1-wei buy is not a sell; on the treasury side, pulse() could derive its limit from the nearest initialized tick below the spot rather than from the spot alone, so a parked price does not make every pulse revert.","line":170,"path":"src/SequencerHook.sol","reproduction":"Setup (test/scratch/FreeWrite.t.sol): fresh PoolManager, SequencerToken, SequencerHook mined at flags 0x3040 with factory = test, key (ETH, IDM, 12500, 60, hook), manager.initialize(key, 2^96), router adds IDM-only liquidity 1e24 in [-887220, 0], PulseTreasury deployed and dealt 1 ETH. Step 1: any account calls router.swap(key, SwapParams(zeroForOne=false, amountSpecified=-1e18, sqrtPriceLimitX96=MAX_SQRT_PRICE-1)). Expected: either a revert or no sequencer write, since nothing was traded. Actual: BalanceDelta == (0, 0), the caller's IDM and ETH balances are unchanged, hook.state().swapCount == 1, pressure == -1000, lastTs == block.timestamp, pool tick == 887271 (MAX_TICK-1), hook.whaleThreshold() == 5000000000000000. Step 2: warp +15 minutes; treasury.nextPulse() returns ready == true; treasury.pulse() reverts PulseTreasury.NoFill (limit = 99% of the parked price, above all liquidity). Step 3 (second test): after a real 0.01 ETH buy, router.swap(key, SwapParams(true, -1, MIN_SQRT_PRICE+1)) returns delta (-1, 0) and the hook files it as a sell: swapCount + 1, pressure == prev - prev/16 - 1000.","severity":"low","snippet":"        bool isBuy = (seqIs0 ? delta.amount0() : delta.amount1()) > 0;","title":"A swap that moves no funds is still written as a sell, resets lastTs and parks the price where PulseTreasury.pulse() always reverts"}],"hash":"68926d77792c97776cedb7e93c4bf8be2af5e02a5608f3e9ea867d59cd2823aa","nodeId":"be61ffd5-1e00-4f1a-a722-c1a06b055ade","outcome":"completed","summary":"The review is complete and the findings file is written and validated.\n\n**Outcome.** The hook and token hold up under the Execution Trace, Periphery and First Principles checks. Both contracts are manager-gated, factory-bound, single-pool, with no owner, fee, return delta or fund path. The project's own 208 tests and both vector suites pass on this tree. I found one low-severity defect and no critical or high issues, so no proof file was attached.\n\n**The finding** is in `src/SequencerHook.sol` at the direction/size derivation in afterSwap. A swap that moves no funds is still written into the composition as a sell. On the launch pool, seeded single-sided with IDM below the opening tick, anyone can submit a sell into the empty side: v4 returns a (0, 0) delta, the caller pays nothing, yet the hook increments swapCount, pushes pressure to -1000, resets lastTs, and the pool price is left parked at the caller's limit. Two concrete consequences, both reproduced in a scratch test that passes on this tree:\n\n- The treasury's pulse computes its price limit as 99% of the parked spot price, which sits above all liquidity, so after the idle window reopens `pulse()` reverts NoFill until a real buyer moves the price back. The free sell also resets lastTs, closing the window again.\n- A 1-wei exact-input buy with liquidity present is fully swallowed by the rounded-up LP fee and is filed as a sell, although the caller swapped in the buy direction.\n\nNo funds are at risk, and the treasury spends nothing, so I rated it low. The suggested fix is a SPEC-level decision for the requester: skip the write when both delta components are zero, consider the input side when classifying direction, and derive the pulse limit from the nearest initialized tick rather than spot alone.\n\n**Coverage.** All nine listed entry points have rows: seven hold, two reference the finding (afterSwap and pulse). Three additional rows record the beforeInitialize invariant, the SequencerState library, and the manifest shape in `launch.reference.json`, which matches the six-argument constructor and the 0x3040 permission set. There is no `launch.json` in the tree yet, which is expected before the manifest step. Nothing outside `.imd-findings.json` and `test/scratch/` was written.","treeHash":null,"usage":{"cachedInputTokens":1129830,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":36822,"runtime":"claude","turns":36,"wallClockMs":785954}},{"artifacts":[],"attempt":1,"bundleHash":"c75c5edc6f69459c4c6646f15ad710b4d3a6dd7779a9d5e4212b506367019b6c","device":"739094f0e08668ee","findings":[],"hash":"7e941bc5e6e0663093c02e18d24fe417bbfc6256f96e3926658b14218d7636f2","nodeId":"dfed7c71-5cf8-41bc-a98c-0546fa264ae1","outcome":"completed","summary":"I left `launch.json` as it was: I checked it against the current source and found nothing to change. No findings came with this revision. `forge build` passes, and `forge test` with the verifier's fuzz seed passes all 214 tests in 11 suites.\n\n**What I checked against the source:**\n- **Contracts:** the hook is `SequencerHook` and the token is `SequencerToken`, named \"Intelligent Dance Market\" with symbol \"IDM\". The token's constructor takes no arguments.\n- **Hook constructor arguments**, in order: `\"$poolManager\"`, `\"$token\"`, `\"$factory\"`, then three thresholds. The thresholds are 1250000000000000, 12500000000000000 and 62500000000000000 wei (0.00125, 0.0125 and 0.0625 ETH), matching `QuoteCalibration`. The constructor reverts if any of them is zero or out of order. The hook has no owner argument, so there is no `$owner`.\n- **Permissions:** `getHookPermissions` returns `beforeInitialize`, `afterInitialize` and `afterSwap`, and the manifest lists the same three. Both initialization callbacks accept only the factory, fee 12500 and tick spacing 60, so the hook accepts the listed fee.\n- **Pool:** paired currency is native ETH (the zero address), fee 12500, tick spacing 60, initial price 79228162514264337593543950336.\n- **Schema:** the first field is `\"kind\": \"univ4_hook\"`, and the notes are 2,177 characters, under the 4,000 cap.\n\n**Not delivered:** the brief asks for deployed hook, token and pool addresses and launch receipts on Robinhood Chain (4663). None exist in the project, and no transaction was sent. The project's Sepolia deployment records don't count as evidence for chain 4663. The notes say this, and the addresses and receipts will come from the launch service's deployment step.\n\nThe commit since my last round (868c91b) changed only `PulseTreasury`, its tests and docs. That contract is not deployed by this manifest, so the manifest stays accurate.","treeHash":"389f6fa7c34ac81656d7963a206d1b2ad24a9193","usage":{"cachedInputTokens":182734,"inputTokens":10,"model":"claude-opus-5-5","outputTokens":1821,"runtime":"claude","turns":5,"wallClockMs":135287}},{"artifacts":[],"attempt":1,"bundleHash":"e213a2a25b98ee201fe73bbe68844034d5a3eabb3047aa1a8895e49f01940a1a","device":"c5a27b25fa718879","findings":[],"hash":"8583b68ce78f0d98d72d9e8674ede931e532b6b0145f002d7a4ac1e5f5e71d18","nodeId":"b48659e1-5a67-4d23-8de1-1a8f2ee0b341","outcome":"completed","summary":"Added failure-path, fuzz, launch integration, and token/treasury invariant tests under `test/`.\n\nValidation passed: 230 tests, 49,152 randomized handler calls with the required seed, and all 684 vectors. Production files remain unchanged.\n\nNo new defect reproduced. Robinhood deployment addresses and receipts remain unverified; the tree contains `launch.reference.json`, not `launch.json`.","treeHash":"e6790e5c147ab69e6693cccc3e605eec92bc5c1f","usage":{"cachedInputTokens":4141824,"inputTokens":155679,"model":"gpt-6-astra","outputTokens":25717,"runtime":"codex","turns":8,"wallClockMs":831275}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"b38bea3c04869138","findings":[{"citation":"resolved","description":"The treasury bounds its buy at 1% below the pool's current sqrtPrice (SQRT_PRICE_LIMIT_BPS = 9900). In a Uniswap v4 pool the current price is wherever the last swap stopped, which is not necessarily anywhere near liquidity: a sell (oneForZero) larger than the ETH-side liquidity consumes that ETH and then moves the price through empty ticks to the swapper's sqrtPriceLimitX96 at no cost (SwapMath with liquidity 0 jumps straight to the target). Upstream v4-periphery's V4Router._swap (not vendored in this tree; lib/v4-periphery holds only HookMiner) passes MAX_SQRT_PRICE - 1 for every oneForZero swap and relies on amountOutMinimum instead, and any direct PoolManager caller can choose that limit, so any seller who sells more IDM than the ETH side can absorb leaves slot0 at tick 887271. This is the natural state of the launch pool: the factory seeds IDM only, so the ETH side holds only what buyers have paid in, and the first airdrop recipient who sells more than that through a standard router parks the price. From that state pulse() computes limit = 0.99 * sqrtPrice(887271), the swap moves at most ~200 ticks down through empty space, delivers 0 IDM, and unlockCallback reverts NoFill (line 166). nextPulse() (line 131) does not model the limit and keeps returning ready = true, so keepers burn gas on reverting calls. The pulse, the treasury's only function, stays unavailable until some other party buys and re-anchors the price, i.e. exactly during the silence the pulse exists to fill. No funds are lost; the treasury's guarantee ('after 15 minutes without any swap, anyone may call pulse() and the treasury buys') is broken under a cheap, unprivileged and naturally occurring condition. Flow-gap seam: execution (limit math) x periphery (v4 price runs through empty liquidity) x first principles (pulse must fire in silence). Minimal fix: bound the pulse by its spend, which is already capped (MAX_PULSE, 1% of balance), and pass TickMath.MIN_SQRT_PRICE + 1 as the limit so the swap walks down to the IDM liquidity; or, to keep the 2% bound, clamp the limit to the sqrtPrice of the nearest initialized tick at or below the current tick (StateLibrary.getTickBitmap / TickBitmap.nextInitializedTickWithinOneWord). Make nextPulse() agree with whatever pulse() does.","line":147,"path":"src/PulseTreasury.sol","reproduction":"State: real PoolManager, ETH/IDM pool at fee 12500 / spacing 60 opened at tick 184200 (FDV ~10 ETH), IDM-only liquidity in [124200, 184200] (the launch shape), SequencerHook initialized, PulseTreasury deployed and funded with 1 ETH. 1) warp +16 min: pulse() succeeds (sanity). 2) Anyone buys 0.001 ETH of IDM, then sells twice that IDM with sqrtPriceLimitX96 = MAX_SQRT_PRICE - 1 (the V4Router default). The sell receives all ETH on that side and leaves slot0 at tick 887271. 3) warp +16 min: nextPulse() returns ready = true; pulse() reverts NoFill(). Expected: the treasury buys IDM (liquidity is still at ticks 124200..184200). Actual: revert NoFill; no pulse is possible until an unrelated buy moves the price back. Run: forge test --match-path test/scratch/ParkedPrice.t.sol --match-test test_PulseStillBuysAfterASellParkedThePrice -vv  ->  [FAIL: NoFill()], log 'tick after the sell: 887271'.","severity":"medium","snippet":"        (uint160 sqrtPriceX96,,,) = poolManager.getSlot0(poolId);\n        uint160 limit = uint160(uint256(sqrtPriceX96) * SQRT_PRICE_LIMIT_BPS / 10_000);","title":"pulse() derives its price limit from slot0, so a sell that parks the pool price away from liquidity makes every pulse revert NoFill while nextPulse() reports ready"},{"citation":"resolved","description":"SPEC 3.1 defines the whale threshold as K*sqrt(FDV) with FDV derived from the pool tick after the swap, intending it to track the market's size (0.063 ETH at the 10 ETH opening FDV). The post-swap tick only reflects FDV while it sits inside liquidity. A sell that consumes the whole ETH side keeps moving through empty ticks to the swapper's sqrtPriceLimitX96 for free (zero liquidity, zero input consumed), so with the limit MAX_SQRT_PRICE - 1 (upstream V4Router's default for oneForZero, or any swapper's choice) the pool is left at tick 887271. SequencerState.whaleThreshold(887271, quoteIs0 = true) evaluates getSqrtPriceAtTick(-887271), which saturates to WHALE_MIN = 0.005 ETH. The seller's |ETH delta| is the real ETH they extracted (0.01975 ETH in the reproduction, 0.02 ETH less fees), well under the legitimate 0.0635 ETH, yet x.quoteAmt >= t.kick holds and the sell is processed as a whale: a whole track is wiped (Drop with fill = false), root advances by 7, patternId increments and Movement is emitted. Anyone holding IDM can trigger a Movement for the cost of a normal sell whenever the ETH side is thin (always true early after launch, since the factory seeds IDM only), 12.7x cheaper than the threshold the spec calibrates. The sizeLogEma upper clamp (hi = log2Fixed(t.kick), SequencerState.sol:210) is pulled down to L(WHALE_MIN) = 833 on the same swap. Buys cannot do the mirror trick (an exhausted IDM side parks at -887272, where the threshold saturates to WHALE_MAX). No funds are at risk: the impact is on the sequencer state the project exists to curate (art-state integrity), which is why this is low. Any fix changes the SPEC 3 transition that the task says to preserve bit-for-bit, so it is a design decision for the requester: e.g. evaluate the threshold at min(pre-swap tick, post-swap tick) FDV, or at the post-swap tick clamped to the range of initialized liquidity, and regenerate vectors.","line":172,"path":"src/SequencerHook.sol","reproduction":"State: ETH/IDM pool at fee 12500 / spacing 60, opened at tick 184200, IDM-only liquidity in [124200, 184200], hook initialized (sizeLogEma 854, patternId 0, root 9). 1) Buyer swaps 0.02 ETH -> IDM with limit MIN_SQRT_PRICE + 1; getSlot0 tick ~184199; hook.whaleThresholdAt(184199) = 63546725111852084 wei (0.0635 ETH). 2) The same account sells 2x that IDM with limit MAX_SQRT_PRICE - 1. BalanceDelta.amount0 = +19749999999999999 wei (0.01975 ETH received); slot0 tick after the swap = 887271. Expected (threshold at the pool's FDV): 0.01975 < 0.0635, a non-whale sell; patternId stays 0, root stays 9. Actual: afterSwap computes whaleThreshold(887271) = 0.005 ETH, m.whale = true, patternId becomes 1, root becomes 4, Drop(fill=false) wipes a track, Movement emitted. Run: forge test --match-path test/scratch/ParkedPrice.t.sol --match-test test_SellThatRunsToTheLimitIsNotAWhale -vv  ->  [FAIL: patternId bumped: sell filed as a whale: 1 != 0].","severity":"low","snippet":"        (, int24 tick,,) = poolManager.getSlot0(id);\n        // Whale threshold from the post-swap tick, i.e. the FDV this swap left behind (SPEC §3.1).","title":"Whale threshold is read at the post-swap tick, which a sell that exhausts ETH-side liquidity parks at 887271: a 0.0197 ETH sell is filed as a whale although the pool's real FDV puts the threshold at 0"},{"citation":"resolved","description":"TREASURY-RUNBOOK.md section 3 leaves it to the owner whether to burn the treasury's IDM regularly or hold it, but burn() has no caller restriction and no schedule, so the decision is not the owner's: the first passer-by can send the full IDM balance (the launcher's IDM fee share pushed by LaunchFactory.claimFees plus every pulse's purchase) to 0x...dEaD immediately after each arrival. The treasury has no other use for IDM and no withdrawal, so no party loses funds and this is consistent with 'no owner'; it is reported so the author documents it as the intended behaviour (or gates/schedules burn if holding was wanted). Not a defect in the code's own terms.","line":173,"path":"src/PulseTreasury.sol","reproduction":"State: treasury holds 1,000 IDM (vm.deal-equivalent: token.transfer(treasury, 1000e18)). Any unrelated account calls treasury.burn(). Expected per runbook: owner decides when/whether to burn. Actual: burn() succeeds, Burned(1000e18) emitted, balanceOf(0x...dEaD) += 1000e18, treasury IDM balance 0.","severity":"info","snippet":"    function burn() external returns (uint256 amount) {\n        amount = IERC20Minimal(idm).balanceOf(address(this));\n        if (amount == 0) revert NothingToBurn();\n        require(IERC20Minimal(idm).transfer(DEAD, amount));","title":"burn() is permissionless, so the runbook's open question 'burn regularly or hold' is already decided by the code: anyone can burn the treasury's whole IDM fee share at any time"}],"hash":"8e54cd784eb715558f9a013cc05c9cb00c5901fb5669ccf380be5b5cc8e50c7a","nodeId":"ce2c310a-d59d-471e-8a29-087591a5714b","outcome":"completed","summary":"Review complete. The findings file is written at `.imd-findings.json` with 3 findings, 15 coverage rows, and one proof test.\n\n**What I found**\n\n- **Medium, PulseTreasury.pulse()**: the price limit is 1% below the pool's current sqrtPrice, but in v4 the current price can sit far from any liquidity. A sell larger than the ETH side runs the price through empty ticks to the swapper's limit at no cost, which leaves the pool at tick 887271. From there the pulse swap buys nothing and reverts `NoFill`, while `nextPulse()` still reports ready. The treasury's only function is unavailable exactly during silence, until an unrelated buy re-anchors the price. Reproduced with the real PoolManager in the launch shape (IDM-only seed at FDV 10 ETH). Proof test attached. Suggested fix: use `MIN_SQRT_PRICE + 1` as the limit since spend is already capped, or clamp the limit to the nearest initialized tick.\n- **Low, SequencerHook.afterSwap**: the whale threshold is read at the post-swap tick. The same parked-price sell makes the threshold collapse to 0.005 ETH, so a sell that extracted 0.0197 ETH is filed as a whale (track wipe, root change, Movement) although the pool's real FDV puts the threshold at 0.0635 ETH. No funds at stake. Any fix touches the SPEC §3 transition the task says to preserve, so I flagged it as a design decision.\n- **Info, PulseTreasury.burn()**: permissionless burn means the runbook's \"burn or hold\" question is already decided by the code.\n\n**What held** in my area: pulse spend bounds and settle accounting, reentry guards on the unlock callback, the hook's no-fund and zero-delta invariants, one-pool binding at fee 12500, token supply conservation, sandwich economics of the pulse, and the reference manifest's constructor order and permissions. All 9 verifier entry points have a row. The existing 208 tests pass unchanged.\n\n**Not reached**: the LaunchFactory `claimFees` and `setRequester` seam, since the factory source is not in the tree.","treeHash":null,"usage":{"cachedInputTokens":1904429,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":45643,"runtime":"claude","turns":33,"wallClockMs":895971}},{"artifacts":[],"attempt":1,"bundleHash":"d5fc23bbcfd69e603049241f928b9f2ac055b1d2d474118dc2fdf800cabcec77","device":"a7ac9f7a7687c25e","findings":[],"hash":"9b6bffa7b4f1bd89a59271112b0a091185fad62c355b6082776ef5b3ceb607a3","nodeId":"17f3fa60-1322-4972-b004-4e483a1d69d9","outcome":"completed","summary":"The adaptation is complete and verified: `forge build` passes, the delivered suite runs 208 tests with 0 failures under the verifier's fuzz seed, the vector validator passes on unchanged vectors, and the formatter reports the tree clean.\n\n**What changed, and why**\n\n- **Hook constructor** in `src/SequencerHook.sol`. The audit's medium finding reproduces: the fourth argument was a hand-written zero address for native ETH, which the manifest check refuses. The quote is no longer an argument. The hook binds it from the PoolKey the factory opens in afterInitialize, native ETH for this launch, and an ERC20 on either side still works. The manifest now writes six values: $poolManager, $token, $factory and the three thresholds. Packed state words stay in slots 0 and 1, SPEC section 3, events and vectors are untouched.\n- **Treasury zero-fill** in `src/PulseTreasury.sol`. The low finding reproduced on the unmodified tree: a pulse with no reachable liquidity returned (0, 0) and the hook filed it as a 0-wei sell, cooling heat and burning the idle window. It now reverts NoFill and leaves the state untouched, with a test.\n- **Reference manifest**. The committed launch.json lacked pool.initialPrice, carried non-schema keys and the zero-address argument. Since launch.json belongs to the manifest step and a broken one in the tree rejects the work, it is renamed to `launch.reference.json` with corrected content.\n- **Docs**. README pulse idle 45 min corrected to 15 min, token SEQ corrected to IDM, stale counts updated, non-existent contracts/ and bin/ instructions removed, and an IMD launch section added. SPEC section 9's opening sentence fixed, section 3 untouched. Launch notes and the Sepolia script comment updated.\n- **Tests**. Six hook suites updated for the new signature. A new binding test replaces the one whose premise was a constructor-given quote. The constructor-rejection and fresh-hook tests now cover pre-init state, the binding and a second initialization.\n\n**What was not changed**\n\nThe coverage finding is informational only. The token already meets the launch token rules. The hook has no owner, so no $owner argument was needed.\n\n**Deployment and addresses**\n\nThe brief asks for verified deployed hook, token and pool addresses and launch receipts. Per the launch rules, IMD's deployer launches through the factory after this work is accepted, so no transaction was broadcast and no address was invented. The deployed addresses will come with the launch itself.\n\n**Files touched**: `src/SequencerHook.sol`, `src/PulseTreasury.sol`, `test/SequencerHook.t.sol`, `test/PulseTreasury.t.sol`, `script/DeploySepolia.s.sol`, `README.md`, `SPEC.md` (section 9 only), `IMD_LAUNCH_NOTES.md`, `launch.json` renamed to `launch.reference.json`, and the new `ADAPTATION.md` listing each change against its rule or finding.","treeHash":"ea939ba4a20ea32eb92eefea549e032aa053b776","usage":{"cachedInputTokens":3123932,"inputTokens":770,"model":"claude-fable-5-1","outputTokens":48164,"runtime":"claude","turns":56,"wallClockMs":904012}},{"artifacts":[],"attempt":1,"bundleHash":"1d6cd458a70b3f7995112c9c64006461434098154ed9fab5df50d7c4034b7f4e","device":"483b1030f62fc40e","findings":[],"hash":"a5c4854bfaac316bbe4604400f930c63f4bfb04c8fcb0d23c4cbe832adb16792","nodeId":"dfed7c71-5cf8-41bc-a98c-0546fa264ae1","outcome":"completed","summary":"Created [launch.json](/home/imd1/.identitymd/work/18ac1075-a6ce-4487-83f3-17e3d795c1f1/dfed7c71-5cf8-41bc-a98c-0546fa264ae1/launch.json) with matching constructor arguments, permissions, and required IDM/ETH pool settings. Only the manifest changed.\n\n`forge build` succeeded; all 208 tests passed with the supplied fuzz seed. Both vector sets validated.\n\nVerified Robinhood deployment addresses and receipts remain pending, explicitly documented in the manifest.","treeHash":"98695a79831fed6483e3da52343fb527be65743a","usage":{"cachedInputTokens":670336,"inputTokens":68792,"model":"gpt-6-astra","outputTokens":5696,"runtime":"codex","turns":5,"wallClockMs":184735}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"c9743cd9807c4c3a","findings":[{"citation":"resolved","description":"SequencerHook's fourth constructor parameter is declared `address quote_` (src/SequencerHook.sol:85) and launch.json writes it as the literal zero address to mean native ETH. The launch manifest rules refuse a stand-in address (zero, 0x...dEaD, all-ones) wherever an address is written by hand; the only zero allowed is native ETH in a Currency-typed field, and the only placeholders resolved by the deployer are $poolManager, $token, $owner, $factory and $launchNumber. There is no placeholder for the paired currency, so as written this manifest cannot pass the manifest check and the launch is blocked before deployment. The hook itself does not need the argument: it already receives the pair in `PoolKey` at beforeInitialize/afterInitialize and the launch is fixed to IDM/ETH. Suggested minimal fix for the adapter, preserving the ABI encoding and SPEC section 3: declare the parameter as `Currency quote_` (a user-defined value type over address, so the ABI type, selector and test vectors are unchanged) and keep `Currency.unwrap(quote_)` in the checks, or remove the argument and bind the quote from `key.currency0`/`key.currency1` in `_validateInitialization`, with the constructor then taking only ($poolManager, $token, $factory, hat, glitch, snare).","line":9,"path":"launch.json","reproduction":"Input: launch.json as committed at 69cddfd, hook.constructorArgs[3] = \"0x0000000000000000000000000000000000000000\" for a parameter whose ABI type and internalType are both `address`. Expected: manifest accepted and the deployer resolves native ETH for the quote. Actual: the manifest check refuses a hand-written zero address for a non-Currency parameter; no hook is deployed. Contrast: pool.pairedCurrency = 0x0 is a Currency field and is accepted. Local confirmation that nothing else depends on the argument: with `quote_` = address(0) the only reads are the constructor checks (lines 92-103) and `_validateInitialization` (line 125), which compare it to the PoolKey currencies that the hook could read directly.","severity":"medium","snippet":"      \"0x0000000000000000000000000000000000000000\",","title":"Hook constructor takes the paired currency as a hand-written zero `address`, which the manifest check refuses"},{"citation":"resolved","description":"The manifest schema keeps only its own keys and expects pool.initialPrice as a decimal sqrtPriceX96 string (written as the launch facts give it, even where the policy's opening market cap decides the real price). The committed manifest has no pool.initialPrice, uses a free-text `openingPrice` key instead, and adds a top-level `economics` object (poolBps 9000, an owner decision). Both extra keys are dropped silently, so the owner's 90% seeding decision described there reaches nobody, and the missing initialPrice is a schema gap the manifest step must fill. The notes also still say \"Build from contracts/\" and cite contracts/src/QuoteCalibration.sol and contracts/GAS.md, but at this commit the Foundry project is the repository root (foundry.toml src = \"src\"), so a reader following the notes looks in a folder that does not exist.","line":30,"path":"launch.json","reproduction":"Input: launch.json at 69cddfd. Expected: pool has keys pairedCurrency, fee, tickSpacing, initialPrice (string); no keys outside the schema. Actual: pool.initialPrice absent; pool.openingPrice and top-level economics present and discarded; notes reference a contracts/ prefix that is not in the tree (`ls contracts` fails at the root).","severity":"low","snippet":"    \"openingPrice\": \"set by the IMD launch policy for pairWith eth, not by this manifest (univ4_hook takes no initialMarketCapWei)\"","title":"launch.json omits pool.initialPrice and carries non-schema keys (pool.openingPrice, economics) that are dropped"},{"citation":"resolved","description":"pulse() is meant to add a hat-sized buy (and heat) to the grid after 15 minutes of silence. When no liquidity is reachable between the current price and the 1% sqrtPriceLimit (position fully withdrawn, or price parked outside every range), PoolManager.swap returns a (0, 0) delta without reverting. The treasury then settles 0, takes 0, emits Pulse(0, 0, idle, heat) and returns normally. Inside that swap SequencerHook.afterSwap sees an IDM delta of 0, so `isBuy` is false and the swap is filed as a 0-wei sell: pressure moves by -1000 and heat is decremented instead of incremented, the opposite of the treasury's purpose, and lastTs is reset so the next pulse must wait another 15 minutes. No funds are lost. Fix: revert (e.g. `if (got == 0) revert NoFill();`) when the swap bought nothing, so the state and the window are untouched.","line":159,"path":"src/PulseTreasury.sol","reproduction":"State: IDM/ETH pool initialized at price 1, 1e26 liquidity in [-600, 600], hook heat = 5, swapCount = 10, lastTs = now; treasury holds 1 ETH. Steps: (1) the LP removes all 1e26 liquidity; (2) warp +15 minutes; (3) anyone calls treasury.pulse(). Expected: revert (nothing to buy) with hook state unchanged. Actual (test/scratch/PulseZeroFill.t.sol, run on this tree): pulse() returns (amountIn 0, amountOut 0), the treasury balance is unchanged, hook.state().heat goes 5 -> 4 and pressure 0 -> -1000, and a second pulse() reverts NotIdle for 15 minutes.","severity":"low","snippet":"        BalanceDelta d = poolManager.swap(poolKey(), SwapParams(true, -int256(amount), limit), \"\");","title":"PulseTreasury.pulse() succeeds on a zero-fill swap, burns the idle window and makes the hook record a sell"},{"citation":"resolved","description":"README says pulse() opens after 45 minutes of silence; PulseTreasury.PULSE_IDLE is 900 seconds (15 minutes), as TREASURY-RUNBOOK.md and the test suite state, and SPEC.md section 9's opening sentence also says 45 minutes while its rule list says 900 s. The next README line calls the token \"1 billion SEQ\" while SequencerToken's symbol is IDM. The README's test count (127) is also stale: `forge test` at this commit runs 207 tests. Documentation only; no code impact, but the adapter and the audit panel read these first.","line":31,"path":"README.md","reproduction":"Compare README.md:31-32 and SPEC.md:233 against src/PulseTreasury.sol:58 (`PULSE_IDLE = 15 minutes`) and src/SequencerToken.sol:7 (`symbol = \"IDM\"`); run `forge test` and compare the 207 total with the README's 127.","severity":"info","snippet":"- `src/PulseTreasury.sol`: optional, separate from the hook. Immutable, ownerless treasury funded by the launcher's fee share; after 45 min without swaps anyone can call `pulse()`, which buys a hat-sized amount of IDM with ETH (<= 0.002 ETH, <= 1% of balance, ~2% price limit) so the track keeps playing. `burn()` sends its IDM to 0xdEaD. Deploy with `script/DeployTreasury.s.sol` after launch; see `TREASURY-RUNBOOK.md` and SPEC.md §9. `pulse()` ~143k gas cold (~169k on a saturated grid).","title":"README contradicts the deployed constants: 45-minute pulse idle and a SEQ ticker"},{"citation":"resolved","description":"Read in full: src/SequencerHook.sol, src/SequencerState.sol, src/QuoteCalibration.sol, src/SequencerToken.sol, src/PulseTreasury.sol; test/SequencerHook.t.sol, test/PulseTreasury.t.sol, test/helpers/PoolRouter.sol; launch.json, foundry.toml, README.md, IMD_LAUNCH_NOTES.md, TREASURY-RUNBOOK.md, SPEC.md sections 3, 6 and 9; the three protected floor tests and the v4-core pin (lib/v4-core at 69cddfd's submodule, PoolManager.initialize and Hooks.afterSwap). Scripts (script/*.s.sol, script/SimRouter.sol) were only grepped for hardcoded addresses and env reads. `forge build` and `forge test` ran on this tree: 207 tests pass (README says 127). Checked and found sound for the launch configuration (IDM/ETH, native ETH as currency0): every enabled callback is gated by msg.sender == poolManager and returns its selector; beforeInitialize/afterInitialize accept only the $factory sender, the sorted (ETH, IDM) pair, fee 12500 and tickSpacing 60, and bind exactly one pool (AlreadyInitialized afterwards); flags 0x3040 match getHookPermissions and the manifest's permissions list; afterSwap returns no delta, holds no funds, has no owner, payable, receive, delegatecall, callcode or selfdestruct; no add/remove-liquidity callbacks, so the factory's zero-liquidity fee collect is untouched; afterSwap gas is 33k-55k cold, under the 100k ceiling; the state transition matches SPEC section 3 clause by clause (hash, relative classes, accumulation ladder and scan, heat/saturation 44, silence reset 3600 s, bass, tempo/pressure/mode, whale Euclid fill and wipe, page 64, EMA clamp to L(whale(tick)), completion snapshot and dropSeed tables) and all arithmetic is widened or saturating; the packed layout occupies physical slots 0 and 1 and the Mutated ABI is as the spec gives it; whaleThreshold saturates ticks and never reverts; the FDV orientation (-tick for ETH as currency0) is right. SequencerToken is a fixed 1e27 supply minted to its deployer with no mint, owner, pause, blocklist or proxy path. Not reached: the live LaunchFactory and PoolManager on Robinhood Chain 4663 (no fork rehearsal and no network use in this review), the IMD manifest validator itself (its rules were taken from the assignment's reference text), the TypeScript packages/core port that SPEC requires to match bit for bit (not in this repository), and scripts/validate-vectors.py was not executed. PulseTreasury is outside launch.json (deployed later by the owner) and was reviewed as delivered.","line":19,"path":"src/SequencerHook.sol","reproduction":"Not a defect. Coverage statement required by the assignment's acceptance criteria; verify with `forge test` (207 passed) and `forge build` on commit 69cddfd.","severity":"info","snippet":"contract SequencerHook is IHooks {","title":"Review coverage: what was read, what was checked, what could not be reached"}],"hash":"af48c1931db79f9f513e3d9c9a0ce942c5da194082be917bb4ad429761994959","nodeId":"d9d25ca2-7f4c-4d84-9ced-631b4e05ad9c","outcome":"completed","summary":"Review complete. The findings are in `.imd-findings.json` at the repository root (valid JSON, every path, line and snippet verified against the tree). No source file was changed; the only writes are the findings file and one scratch test under `test/scratch/`, both git-ignored.\n\n**Verdict.** The hook is in good shape for an immutable, zero-fee launch hook. The one launch-blocking item is in the manifest, not the Solidity. No critical or high defects, so no proof files are attached.\n\n**Findings written**\n\n- **Medium, launch.json line 9.** The hook's fourth constructor parameter is declared `address quote_`, and the manifest writes it as a hand-typed zero address to mean native ETH. The manifest rules refuse stand-in addresses outside Currency-typed fields, and there is no `$pairedCurrency` placeholder, so this manifest cannot pass. Suggested fix keeps the ABI and vectors intact: declare the parameter as `Currency` (same ABI type), or drop it and bind the quote from the PoolKey in `_validateInitialization`.\n- **Low, launch.json line 30.** No `pool.initialPrice`; the free-text `openingPrice` and the top-level `economics` object are non-schema keys and are silently dropped, so the owner's 90% seeding decision reaches nobody. Notes still point at a `contracts/` prefix that does not exist at this commit.\n- **Low, PulseTreasury line 159.** When no liquidity is reachable within the 1% price limit, `pulse()` succeeds with a zero-fill swap. The hook then files it as a 0-wei sell (heat 5→4, pressure −1000) and the 15-minute window is consumed. Reproduced with a scratch test on this tree. Fix: revert when nothing was bought.\n- **Info, README line 31.** README says 45-minute pulse idle (code: 15 minutes), calls the token \"SEQ\" (symbol is IDM), and cites 127 tests (207 run).\n- **Info, coverage statement.** Lists what was read, what was verified, and what could not be reached.\n\n**What was checked and found sound.** All five contracts in `src/` plus the hook, treasury and token tests, the protected floor tests, and the pinned v4-core initialize and afterSwap paths. Callback gating, factory-only single-pool binding, flags 0x3040 versus permissions and manifest, no return deltas or fund handling, no liquidity callbacks blocking the factory's fee collect, afterSwap gas under budget, SPEC section 3 clause-by-clause conformance including the Euclid and dropSeed tables, slot 0/1 layout, whale-threshold orientation and saturation, and the token's fixed supply with no admin path. `forge build` and `forge test` pass on this tree.\n\n**Not reached.** The live LaunchFactory and PoolManager on Robinhood Chain 4663 (no fork rehearsal), the IMD manifest validator itself (rules taken from the assignment text), the TypeScript port that SPEC requires to match bit for bit (not in this repository), and `scripts/validate-vectors.py` was not run.","treeHash":null,"usage":{"cachedInputTokens":1547260,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":34730,"runtime":"claude","turns":35,"wallClockMs":574902}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e0f64c10e30e33e2","findings":[{"citation":"resolved","description":"Access/asymmetry: receive() (line 113) accepts ETH from anyone without restriction, but the only path that spends ETH is pulse(), which clamps each pulse to balance/100 and then zeroes it below MIN_PULSE (0.000025 ETH). Once the balance is below 100 * MIN_PULSE = 0.0025 ETH, pulseSize returns 0 and pulse() reverts NoBudget. The contract has no owner and no withdraw, so that ETH cannot be spent or recovered unless more ETH arrives to lift the balance back over 0.0025 ETH. Each pulse spends at most 1% of the balance, so in silence the balance decays geometrically towards this floor and every treasury ends with up to ~0.0025 ETH locked once fee inflow stops. The runbook also says that factory payouts left owed to the treasury cannot be withdrawn. The impact is small (dust-scale), but the ETH-in and ETH-out sides are asymmetric. Fix: let a pulse spend min(MIN_PULSE, balance) once the balance falls under the 1% budget, or document the stranded floor as accepted.","line":125,"path":"src/PulseTreasury.sol","reproduction":"Deploy PulseTreasury against the initialized IDM/ETH pool and send it 0.00249 ether through receive(). Warp 15 minutes past the hook's lastTs and call pulse(). Expected (if every received wei can eventually be spent on pulses): it buys IDM. Actual: nextPulse() returns amount = pulseSize(sizeLogEma, 2.49e15) = 0 (cap = 2.49e13 < MIN_PULSE = 2.5e13), so pulse() reverts NoBudget() on every call, and no function can move the 0.00249 ETH. The same state is reached from any starting balance after enough pulses with no new inflow: balance * 0.99^n < 0.0025 ETH.","severity":"low","snippet":"        uint256 cap = balance / BUDGET_DIVISOR;\n        if (amount > cap) amount = cap;\n        if (amount < MIN_PULSE) amount = 0;","title":"PulseTreasury permanently strands any ETH balance below 0.0025 ETH: no path spends or withdraws it"}],"hash":"b0990b355711390f2a55f6fb1a7075bedfc21c361350c800878653bb214dc039","nodeId":"9751449c-15b3-4e87-a96d-5fab0a0c8ac5","outcome":"completed","summary":"I found no access-control defect in the hook, the token or the treasury, and one low-severity issue in the treasury. The results are in `.imd-findings.json`: 1 finding and 11 coverage rows, covering all 9 entry points plus 2 checks I added. No repository files were changed, and the full test suite passes (208 tests, 0 failures).\n\n**Finding 1 (low): the treasury can strand a small amount of ETH for good.** `src/PulseTreasury.sol:125`\n- **Cause:** anyone can send ETH to the treasury through `receive()`, but the only way ETH leaves is `pulse()`. Each pulse is capped at 1% of the balance and set to zero if that is below `MIN_PULSE` (0.000025 ETH).\n- **Failing state:** with a balance of 0.00249 ETH, the cap is 2.49e13 wei, below 2.5e13. So `pulse()` reverts `NoBudget()` on every call, and since the contract has no owner and no withdraw function, nothing can move the ETH.\n- **Why it matters:** in silence each pulse spends 1% of the balance, so the balance always shrinks toward this floor. Once fees stop arriving, up to about 0.0025 ETH stays locked. I gave it no Foundry proof because only critical and high findings need one.\n\n**What holds, and why:**\n- **Hook (`SequencerHook`):**\n  - Every enabled callback accepts calls only from the PoolManager.\n  - Both initialize callbacks accept only the launch factory, only once, and only the sorted IDM/ETH pair at fee 12500 and tick spacing 60. They repeat the same checks, so neither is a weaker path.\n  - The address flags (0x3040) match the reference manifest's permissions.\n  - There is no owner, setter, return delta or fund handling.\n  - The remove-liquidity callbacks are never called, so the factory's fee collection isn't blocked.\n- **Token (`SequencerToken`):** no privileged roles. The supply is fixed at 1e27, minted once to the deployer, and allowances are handled the standard way.\n- **Treasury `pulse()`:** anyone may call it, but it needs 15 minutes without a swap. Every swap resets the hook's last-swap time, so nobody can move the price and then trigger a pulse in the same transaction or block. That makes the 2% price limit, which is computed from the current price, safe as documented.\n- **Treasury `unlockCallback`:** it needs both the PoolManager as caller and a temporary flag that only `pulse()` sets.\n- **Treasury `burn()`:** it sends only the treasury's own IDM to `0x…dEaD`.\n- **Treasury's state read:** it reads the hook's packed state words with the same layout `encode()` writes.\n\n**Static-analysis leads I set aside:**\n- **Slither, strict equalities:** these are `== 0` guards that just revert, so they can't be exploited.\n- **Slither, uninitialized locals:** these are meant to start at zero.\n- **Slither, ignored return values:** these are deliberate.\n- **Aderyn, reentrancy:** no external call can re-enter.\n- **Aderyn, \"locks ether\":** this is the same issue as Finding 1.\n\n**Not covered:** the launch factory's own code. The treasury depends on the payer calling `setRequester` to point fees at it, and payouts the factory keeps as owed can't be withdrawn by the treasury. Both are trust assumptions written in `TREASURY-RUNBOOK.md`. I couldn't check them because the factory's source isn't verified on the explorer.","treeHash":null,"usage":{"cachedInputTokens":749079,"inputTokens":24,"model":"claude-opus-5-5","outputTokens":11861,"runtime":"claude","turns":12,"wallClockMs":282201}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"7c748c02cd2ee98f","findings":[{"citation":"resolved","description":"Seam: precision x invariant. The pulse is sized 24 log2Fixed units (1.5 octaves) under the hook's sizeLogEma so that it files as a hat (relative < -8); the docstring calls it 'the quietest voice'. But the pulse is itself a swap and enters the same EMA through src/SequencerState.sol:213 `s.sizeLogEma = uint16((uint256(s.sizeLogEma) * 7 + l) / 8)`. Because the integer floor lowers the EMA by ceil((ema - L)/8) for any L below it, every pulse (L = ema - 24, or 812 while the MAX_PULSE clamp binds, or 710 once the MIN_PULSE clamp binds) lowers the EMA by at least 3 units, and nothing in silence raises it. The EMA therefore does not stay at the market's last size during silence; it is driven monotonically to the QuoteCalibration.EMA_FLOOR value 710. At 710 the pulse (MIN_PULSE, L = 710, relative 0) is a glitch, and the next real buy of the initial market size 0.0125 ETH (L = 854, relative +144) is a kick: the state the guard 'pulses keep the track alive' preserves is not the one trading left behind. The code comment only says a pulse 'at the EMA floor' is a glitch; it does not say the pulses themselves reach that floor in 13 hours. No funds are at risk; the effect is on the sequencer's classification (SPEC 3.3.3) after any overnight silence.","line":122,"path":"src/PulseTreasury.sol","reproduction":"Real PoolManager, IDM/ETH pool initialized at tick 184200 (FDV 10 ETH), liquidity 3e22 over +/-60000 ticks, PulseTreasury funded with 10 ETH, hook fresh (sizeLogEma 854). Repeat: warp to lastTs + 15 min, call treasury.pulse(). Observed: sizeLogEma is non-increasing on every pulse and reaches 710 after 52 pulses (13 h of silence; pulse sizes 0.002 ETH until ema 812, then exp2Fixed(ema-24), then 0.000025 ETH). Then: pulse #53 emits Accumulated/Mutated with fromTrack 3 (glitch), expected 2 (hat) per the docstring; a 0.0125 ETH exact-input buy via a router emits fromTrack 0 (kick), expected glitch (relative 0) had the EMA stayed at 854; the following 0.0001 ETH buy (L 742) files as snare (relative +14 against the now-728 EMA). Test: test/scratch/EmaDrift.t.sol test_PulsesAloneDragEmaToFloor (passes on current code, demonstrating the behaviour).","severity":"low","snippet":"        amount = sizeLogEma > HAT_OFFSET ? exp2Fixed(sizeLogEma - HAT_OFFSET) : 0;","title":"Treasury pulses feed the size EMA they are sized from: 52 pulses of silence (13 h) pin sizeLogEma at the 710 floor, after which pulses file as glitch and the first market-sized trade files as kick"},{"citation":"resolved","description":"Seam: boundary x precision. A sell whose ETH output rounds to zero (exact-input sell of 1 wei IDM: amountIn after the 1.25% fee floors to 0, so amount0 = 0, amount1 = -1) reaches afterSwap with quoteAmt = 0, log2Fixed(0) = 0, and is clamped up to lo = log2Fixed(EMA_FLOOR) = 710 before the EMA update on line 213. The floor was added as 'anti dust drag', but it only bounds the destination, not the drag: with ema - l = 144 each dust sell lowers the EMA by ceil((ema-710)/8) (18, 16, 14, ... units), so 27 swaps costing 27 wei of IDM plus gas pin the EMA at 710 (test counted 27 exactly). From the floor, relative = L - 710, so any buy with L >= 735, i.e. 0.0000737 ETH or more, is classified kick (track 0) and a 0.0125 ETH market-size buy has relative +144; the hat/glitch/snare classes are unreachable for normal trades until ~20 real swaps have re-raised the EMA (it rises only by floor((L-ema)/8) per swap). Each dust sell also cools heat by one and resets lastTs. No funds are at risk; this is a cheap way to deform the sequencer's class mapping and postpone pulses.","line":211,"path":"src/SequencerState.sol","reproduction":"Real PoolManager, IDM/ETH pool at tick 184200 (FDV 10 ETH), liquidity 3e22 over +/-60000 ticks, fresh hook (sizeLogEma 854). Repeat router.swap(key, SwapParams(zeroForOne=false, amountSpecified=-1, MAX_SQRT_PRICE-1)) once per block: BalanceDelta is (0, -1) each time; after 27 swaps hook.state().sizeLogEma == 710. Then a 0.0125 ETH exact-input buy emits Accumulated.fromTrack = 0 (kick); expected 3 (glitch, relative 0) at the untouched EMA 854. Test: test/scratch/EmaDrift.t.sol test_DustSellsDragEmaToFloor.","severity":"low","snippet":"                l = l < lo ? lo : l;","title":"27 one-wei IDM sells (0 ETH out, L(0)=0 clamped to the floor) drag sizeLogEma from 854 to 710, after which every buy of 0.000074 ETH or more files as kick"},{"citation":"resolved","description":"Precision note on the SPEC 3.3.9 formula floor((7*ema + l)/8), which the code implements exactly (and likewise intervalEma on line 191). With ema = 854: l = 861 (7 above) gives floor(6839/8) = 854, unchanged; l = 853 (1 below) gives floor(6831/8) = 853. Under a stream of equal-sized swaps of size L the EMA converges to L from above but stops at L-7 from below, so a market's own size classifies with relative 0..7 (always glitch, so no class boundary is crossed) and symmetric noise drifts the EMA downward. This is mandated by SPEC 3 and the vectors, so it is reported for the record only; it is the mechanism behind findings 1 and 2.","line":213,"path":"src/SequencerState.sol","reproduction":"S.initialV2() with swapCount 5, Thresholds kick = whaleThreshold(184200, true). Input quoteAmt = (16+13) << 49 (log2Fixed = 861): after mutateV2, sizeLogEma == 854. Input quoteAmt = (16+5) << 49 (log2Fixed = 853): sizeLogEma == 853. Test: test/scratch/EmaDrift.t.sol test_EmaOneSidedRounding.","severity":"info","snippet":"                s.sizeLogEma = uint16((uint256(s.sizeLogEma) * 7 + l) / 8);","title":"Both EMAs round one-sidedly: they fall for any input below them but rise only for inputs at least 8 units above, so the size EMA settles 0..7 units under a steady market size"},{"citation":"resolved","description":"Boundary note. For an exact-input buy of 1 wei ETH, v4 floors the post-fee input to 0 (1 * 987500 / 1e6 = 0), so the swap returns amount0 = -1, amount1 = 0. The hook defines isBuy by the IDM delta sign, as SPEC 3.3.1 requires, so this swap is filed as a sell: pressure -1000, heat -1, bass nibble possibly cleared, lastTs reset (postponing the next treasury pulse by 15 min), while the swapper paid ETH. The classification matches the spec and the same effect is available from a 1-wei IDM sell (finding 2), so this is informational: the author may want the TS client to label a swap with a non-positive IDM delta and a paying ETH side consistently.","line":170,"path":"src/SequencerHook.sol","reproduction":"Real PoolManager, IDM/ETH pool at tick 184200 with liquidity; router.swap(key, SwapParams(true, -1, MIN_SQRT_PRICE+1)) returns BalanceDelta (-1, 0); hook.state().pressure goes from 0 to -1000 and swapCount to 1 with Mutated.isBuy = false. Test: test/scratch/EmaDrift.t.sol test_OneWeiEthBuyIsFiledAsSell.","severity":"info","snippet":"        bool isBuy = (seqIs0 ? delta.amount0() : delta.amount1()) > 0;","title":"A 1-wei ETH exact-input buy returns 0 IDM and is filed as a sell with quoteAmount 1"}],"hash":"c1f6082c31ad01c72dc973d40eb1a0e63c86b6d0ecef191798873a49e7f83351","nodeId":"eb854de7-b5a5-40de-bb98-4164de07fc57","outcome":"completed","summary":"The review is complete. No tracked file changed; the findings file and the scratch test are in place and ignored by git.\n\n**Outcome.** The math in `SequencerState`, `SequencerHook`, `QuoteCalibration` and `PulseTreasury` holds against SPEC §3 and the three guides: the packed-word codec, the whale threshold product and clamps, the EMA, bpm and pressure bounds, the ladder and scan in `accumulate`, the Euclid and drop-seed tables, and the treasury's exp2/log2 inverse and price-limit arithmetic all check out with concrete values. The existing 208 tests pass. I found no fund-loss or blocking defect, so no finding carries a proof file.\n\n**Findings written to `.imd-findings.json`** (two low, two informational, all reproduced on a real PoolManager in `test/scratch/EmaDrift.t.sol`):\n\n- **Low: treasury pulses erode the EMA they are sized from.** Each pulse is sized 24 units under the size EMA and then enters that EMA, which only moves down in silence. After 52 pulses (13 hours of silence) the EMA sits at the 710 floor, the next pulse files as glitch rather than the documented hat, and the first 0.0125 ETH trade files as kick.\n- **Low: dust sells drag the EMA to the floor cheaply.** A 1-wei IDM sell yields 0 ETH, so its size is clamped to the floor before the EMA update. 27 such sells cost 27 wei of IDM plus gas and pin the EMA at 710, after which any buy of about 0.00007 ETH or more is a kick.\n- **Info: one-sided EMA rounding.** The spec's floor formula falls for any input below the EMA but rises only for inputs 8 or more units above it. This is the mechanism behind the two findings above and is spec-mandated.\n- **Info: a 1-wei ETH exact-input buy is filed as a sell**, because v4 floors its output to 0 IDM. Consistent with the spec's definition and equivalent in effect to a dust sell.\n\n**Coverage.** All nine listed entry points have a row: seven hold, `pulse()` and `afterSwap` point to the findings above. Extra rows record the transition bounds, the accumulate ladder, the calibration constants and the reference manifest as holding. One row is marked unreached: an ERC20 quote on currency1 with non-18 decimals, which is outside the launch configuration.","treeHash":null,"usage":{"cachedInputTokens":1983254,"inputTokens":482,"model":"claude-fable-5-1","outputTokens":48874,"runtime":"claude","turns":33,"wallClockMs":849250}},{"artifacts":[],"attempt":1,"bundleHash":"a91e1478bf05cbd9d166b3f444b26cb96eca4a4358d75f9f96c41057b927b227","device":"782f24113d209be2","findings":[],"hash":"ca99556867107e5a1163e9a61b40a4dacb9556215115c833388eccf9f3cffadc","nodeId":"17f3fa60-1322-4972-b004-4e483a1d69d9","outcome":"completed","summary":"The harness's own `.git/info/exclude` keeps `.imd-responses.json` out of the tree, so it is collected by the harness rather than committed. The work is complete.\n\n**Outcome.** The reopened medium finding reproduced and is fixed. The reviewer's proof now passes, the full suite passes with the verifier's fuzz seed, and the vectors still validate.\n\n| Check | Result |\n| --- | --- |\n| `Proof_a3a45cc2990a.t.sol` (copied to test/scratch) | failed on the starting tree, passes now |\n| `forge build` | clean |\n| `forge test` with the verifier's fuzz seed | 214 passed, 0 failed (224 with scratch) |\n| `scripts/validate-vectors.py` | 130 v1 + 554 v2 cases valid |\n\n**The fix** is in `src/PulseTreasury.sol` and keeps SPEC section 9's 1.99% price rule. It changes only what the limit is measured from. A new view, `priceAnchor()`, returns the pool price when the pool has active liquidity, so every ordinary pulse is unchanged. When a free sell has parked the price above every position, it walks the tick bitmap to the nearest initialized tick at or below the current tick, which is the top of the liquidity the pulse will reach, and the limit applies from there. If no such tick exists, `nextPulse()` reports not ready and `pulse()` reverts `NoFill` before swapping, so the hook never records the empty swap. I did not take the reviewer's open-limit alternative because the price cap is what keeps a sandwich of a pulse unprofitable against the pool fee, per SPEC section 9.\n\n**Tests added** in `test/PulseTreasury.t.sol` cover the proof's scenario, a partial fill stopped exactly 1% under the anchor, view-and-call agreement across park, empty pool and far-below liquidity, dust liquidity, and gas. One existing test asserted `ready == true` on an empty pool, which the finding asked to change, and now asserts the opposite.\n\n**Advisory findings**, all reproduced in scratch tests and answered in `.imd-responses.json`:\n- **Whale at parked tick** and **zero-delta sells**: disputed. Both follow SPEC section 3.3 literally, which this task must preserve with its vectors. Recorded for the requester in ADAPTATION.md.\n- **Pulses drag the EMA**: disputed. SPEC section 9 states this side effect itself, with the same figures I measured.\n- **Dust under 0.0025 ETH stranded**: documented in SPEC section 9, README and runbook, the reviewer's own option. No code change.\n\n**Docs** updated: ADAPTATION.md section 5 and an advisory section, SPEC section 9's limit bullet and gas figures, README, TREASURY-RUNBOOK.md. One residual is stated there: a parked price plus a dust position spanning it still yields `NoFill`, which needs a position rather than a swap.","treeHash":"cd07d7bd9c6be2ebd16c5eff93df7c10c95cd415","usage":{"cachedInputTokens":3223953,"inputTokens":834,"model":"claude-fable-5-1","outputTokens":49354,"runtime":"claude","turns":43,"wallClockMs":735179}}],"verification":[{"checks":[{"durationMs":127154,"exitCode":0,"name":"build","output":"Compiling 90 files with Solc 0.8.26\nSolc 0.8.26 finished in 127.03s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> test/SequencerV2.t.sol:185:17:\n    |\n185 |                 uint8 st = uint8((uint256(step) + i) % 16);\n    |                 ^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/SequencerV2.t.sol:198:34:\n    |\n198 |         (uint64 actual, uint8 t, uint8 st, bool noop) = S.accumulate(pattern, track, step, buy);\n    |                                  ^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:311:22:\n    |\n311 |         uint64 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:317:36:\n    |\n317 |                 uint64 candidate = uint64(1) << (uint256(next) * 16 + step);\n    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:349:23:\n    |\n349 |                 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n  --> test/SequencerState.t.sol:98:22:\n   |\n98 |         uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:300:41:\n    |\n300 |         assertEq((oldBass ^ a.bass) & ~(uint64(15) << (uint256(m.step) * 4)), 0);\n    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:303:26:\n    |\n303 |             uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:309:32:\n    |\n309 |             uint64 trackBits = uint64(0xffff) << (uint256(m.track) * 16);\n    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:376:35:\n    |\n376 |             assertEq(a.pattern | (uint64(0xffff) << (track * 16)), type(uint64).max, \"other tracks untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:390:35:\n    |\n390 |             assertEq(a.pattern | (uint64(0xffff) << (uint256(m.track) * 16)), type(uint64).max, \"others untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerHook.t.sol:309:22:\n    |\n309 |         s.pattern ^= uint64(1) << (32 + ((step + 15) & 15));\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:109:43:\n    |\n109 |         s.pattern = 0x0000ffff0fffffff ^ (uint64(1) << (32 + step)); // full kick + hat rows, 12 snare bits\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:117:43:\n    |\n117 |         s.pattern = 0x0000ffff0ffffffe ^ (uint64(1) << (32 + step));\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:195:26:\n    |\n195 |             uint64 bit = uint64(1) << (uint256(wantTrack) * 16 + wantStep);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:356:68:\n    |\n356 |                         if (column & (1 << row) != 0) s.pattern |= uint64(1) << (row * 16 + step);\n    |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:365:45:\n    |\n365 |             s.pattern = type(uint64).max ^ (uint64(1) << (32 + st));\n    |                                             ^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/SequencerHook.t.sol:171:5:\n    |\n171 |     function thresholdsAt(int24 tick) internal view returns (S.Thresholds memory) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":7999,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/SequencerGasV2.t.sol:SequencerGasV2Test\n[PASS] test_GasHeatDropIncrement() (gas: 1605885)\nLogs:\n  heat/drop increment normal buy: 436\n  heat/drop increment saturated buy: 496\n  heat/drop increment sell: 338\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 598.09µs (418.51µs CPU time)\n\nRan 6 tests for test/SequencerToken.t.sol:SequencerTokenTest\n[PASS] testFuzz_TransferConservesSupply(uint256) (runs: 512, μ: 67964, ~: 68153)\n[PASS] test_FactoryReceivesEntireFixedSupply() (gas: 28453)\n[PASS] test_InvalidTransfersRevert() (gas: 81362)\n[PASS] test_SelfTransferAndZeroTransferPreserveSupply() (gas: 67183)\n[PASS] test_TransferAndFiniteAllowance() (gas: 125489)\n[PASS] test_UnlimitedAllowancePreserved() (gas: 112218)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 24.79ms (24.79ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1LaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 441014)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34596\n\n[PASS] test_GasColdFirstSell() (gas: 443444)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37602\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475406)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51858\n\n[PASS] test_GasColdScanSpill() (gas: 477129)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38824\n\n[PASS] test_GasColdTrackComplete() (gas: 466119)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42687\n\n[PASS] test_GasColdWhale() (gas: 461051)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37810\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 475236)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37965\n\n[PASS] test_GasColdWhalePage64() (gas: 474708)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37664\n\n[PASS] test_GasColdWhaleSell() (gas: 460174)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37580\n\n[PASS] test_GasColdWorstNormal() (gas: 461469)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38519\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 314533)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99680)\n[PASS] test_RealBuySellExactInput() (gas: 571772)\n[PASS] test_RealBuySellExactOutput() (gas: 568094)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 344933)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2477190)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 228391)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 359063)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 345326)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2034841)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97815)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 67.11ms (77.17ms CPU time)\n\nRan 12 tests for test/IdmLaunchSafety.t.sol:IdmLaunchSafetyTest\n[PASS] testFuzz_ForeignCallersCannotDriveAnyEnabledCallback(address,int128,int128) (runs: 1000, μ: 103996, ~: 103981)\n[PASS] testFuzz_HookDataAndRequestedAmountsCannotChangeTheActualDeltaMutation(int128,int128,int256,uint160,bool,bytes) (runs: 1000, μ: 174714, ~: 176317)\n[PASS] testFuzz_InvalidInitializationCannotBindOrPoisonAValidLaunch(uint8,uint24) (runs: 1000, μ: 253759, ~: 253421)\n[PASS] testFuzz_PulseSizingIsBoundedAndMonotone(uint256,uint256,uint256) (runs: 1000, μ: 22574, ~: 22616)\n[PASS] test_ConstructorRejectsAddressWithIncorrectPermissionBits() (gas: 24012)\n[PASS] test_HookHasNoAdminFundOrUpgradeSurface() (gas: 3109786)\n[PASS] test_InitializationCallbackPreventsPoolOpeningAtAnUndeployedHook() (gas: 50871)\n[PASS] test_NoFillRevertCanRecoverWithinTheSameTransaction() (gas: 1196847)\n[PASS] test_RealSwapOnlyWritesTheTwoPackedStateWords() (gas: 189557)\n[PASS] test_TokenOnlyLaunchFirstBuySellFeeCollectAndExit() (gas: 741330)\n[PASS] test_TransientGuardClearsAfterSuccessWithinOneTransaction() (gas: 539488)\n[PASS] test_UninitializedSwapRejectedEvenFromManager() (gas: 58743)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 104.14ms (219.73ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 440621)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34203\n\n[PASS] test_GasColdFirstSell() (gas: 442973)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37131\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475013)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51465\n\n[PASS] test_GasColdScanSpill() (gas: 476823)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38518\n\n[PASS] test_GasColdTrackComplete() (gas: 465726)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42294\n\n[PASS] test_GasColdWhale() (gas: 460210)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37349\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474395)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37504\n\n[PASS] test_GasColdWhalePage64() (gas: 473931)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37267\n\n[PASS] test_GasColdWhaleSell() (gas: 459255)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37041\n\n[PASS] test_GasColdWorstNormal() (gas: 461076)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38126\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286579)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 98940)\n[PASS] test_RealBuySellExactInput() (gas: 576300)\n[PASS] test_RealBuySellExactOutput() (gas: 566886)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 343330)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2506140)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 230306)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 357596)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 343723)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2041116)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97344)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 96.13ms (76.83ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookNativeEthTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76838)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440277)\nLogs:\n  afterSwap gas (native ETH=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443194)\nLogs:\n  afterSwap gas (native ETH=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474662)\nLogs:\n  afterSwap gas (native ETH=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476472)\nLogs:\n  afterSwap gas (native ETH=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465382)\nLogs:\n  afterSwap gas (native ETH=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 459848)\nLogs:\n  afterSwap gas (native ETH=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474013)\nLogs:\n  afterSwap gas (native ETH=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 473988)\nLogs:\n  afterSwap gas (native ETH=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459400)\nLogs:\n  afterSwap gas (native ETH=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460720)\nLogs:\n  afterSwap gas (native ETH=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 267967)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 521992)\n[PASS] test_RealBuySellExactOutput() (gas: 518416)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 319489)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2498601)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 224063)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 333874)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 319879)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1882455)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 96931)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 240.87ms (67.26ms CPU time)\n\nRan 28 tests for test/SequencerHook.t.sol:SequencerHookNativeEthLaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76860)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440677)\nLogs:\n  afterSwap gas (native ETH=currency0): 34661\n\n[PASS] test_GasColdFirstSell() (gas: 443594)\nLogs:\n  afterSwap gas (native ETH=currency0): 37589\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 478213)\nLogs:\n  afterSwap gas (native ETH=currency0): 55074\n\n[PASS] test_GasColdScanSpill() (gas: 476842)\nLogs:\n  afterSwap gas (native ETH=currency0): 38946\n\n[PASS] test_GasColdTrackComplete() (gas: 465781)\nLogs:\n  afterSwap gas (native ETH=currency0): 42751\n\n[PASS] test_GasColdWhale() (gas: 460695)\nLogs:\n  afterSwap gas (native ETH=currency0): 37875\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474860)\nLogs:\n  afterSwap gas (native ETH=currency0): 38030\n\n[PASS] test_GasColdWhalePage64() (gas: 474836)\nLogs:\n  afterSwap gas (native ETH=currency0): 37793\n\n[PASS] test_GasColdWhaleSell() (gas: 460248)\nLogs:\n  afterSwap gas (native ETH=currency0): 37567\n\n[PASS] test_GasColdWorstNormal() (gas: 461120)\nLogs:\n  afterSwap gas (native ETH=currency0): 38584\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 319294)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99829)\n[PASS] test_RealBuySellExactInput() (gas: 518286)\n[PASS] test_RealBuySellExactOutput() (gas: 514250)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 315660)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2480681)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 216795)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 329615)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 316050)\n[PASS] test_RealWhaleBoundaryAtLaunchFdv() (gas: 819145)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1876869)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97331)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 240.78ms (83.24ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote0Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23440901)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77338)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9030)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109709)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82202)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473765)\n[PASS] test_GasColdFirstBuy() (gas: 440505)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474897)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476707)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465610)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 460072)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 474242)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459615)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460960)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286606)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 576000)\n[PASS] test_RealBuySellExactOutput() (gas: 572422)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 349054)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2518009)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 235885)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 363435)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 349447)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2044896)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97170)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 257.94ms (87.21ms CPU time)\n\nRan 12 tests for test/SequencerV2.t.sol:SequencerV2Test\n[PASS] testFuzz_AccumulateAgainstLoop(uint64,uint8,uint8,bool) (runs: 512, μ: 2581, ~: 2339)\n[PASS] testFuzz_ArbitraryPackedStateNeverReverts(uint256,uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 8957, ~: 8885)\n[PASS] testFuzz_CodecV2(uint256,uint256) (runs: 512, μ: 1847, ~: 1847)\n[PASS] testFuzz_WhaleThresholdMonotoneBoundedSymmetric(int24,int24) (runs: 512, μ: 4817, ~: 4916)\n[PASS] test_DropSnapshotBeforeResetAndCountersWrap() (gas: 14094)\n[PASS] test_EthCalibration() (gas: 2533)\n[PASS] test_LayoutV2() (gas: 7616)\n[PASS] test_Log2FixedKnownValues() (gas: 398)\n[PASS] test_SaturationUsesPostWritePopcount44() (gas: 16986)\n[PASS] test_SilenceBoundaryAndSellCooling() (gas: 39141)\n[PASS] test_WhaleLeavesHeatButSilenceStillResets() (gas: 31919)\n[PASS] test_WhaleThresholdCalibrationAndClamps() (gas: 20193)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 257.98ms (516.03ms CPU time)\n\nRan 30 tests for test/PulseTreasury.t.sol:PulseTreasuryTest\n[PASS] testFuzz_Exp2FixedInvertsLog2Fixed(uint16) (runs: 512, μ: 7399, ~: 7455)\n[PASS] testFuzz_HatClassAcrossEma(uint16) (runs: 512, μ: 14083, ~: 14134)\n[PASS] test_BurnSendsAllIdmToDead() (gas: 324275)\n[PASS] test_CannotDriveTreasuryFromAnotherUnlock() (gas: 383927)\n[PASS] test_ConstantsMatchHookCalibration() (gas: 51903)\n[PASS] test_ConstructorValidatesKey() (gas: 18103)\n[PASS] test_EmaAtFloorFilesGlitchNotHat() (gas: 14014)\n[PASS] test_FirstSwapEverCanBeAPulse() (gas: 201060)\n[PASS] test_GasPulse() (gas: 332942)\nLogs:\n  pulse() gas (cold, normal grid): 147572\n\n[PASS] test_GasPulseParkedAtMaxTick() (gas: 1443028)\nLogs:\n  pulse() gas (cold, price parked at MAX_TICK, liquidity at tick 0): 675671\n\n[PASS] test_GasPulseSaturated() (gas: 215851)\nLogs:\n  pulse() gas (cold, saturated grid): 173889\n\n[PASS] test_NextPulseAgreesWithPulse() (gas: 2832955)\n[PASS] test_ParkedPulseStopsAtOnePercentUnderTheAnchor() (gas: 2119482)\n[PASS] test_PriceAnchorInsideLiquidityIsSlot0() (gas: 29436)\n[PASS] test_PriceLimitBoundsMoveAndKeepsUnspentEth() (gas: 351710)\n[PASS] test_PulseBeforeIdleReverts() (gas: 413887)\n[PASS] test_PulseDustReverts() (gas: 69327)\n[PASS] test_PulseHighEmaUsesMax() (gas: 191718)\n[PASS] test_PulseIsHatBuyRecordedByHook() (gas: 417919)\n[PASS] test_PulseLowEmaUsesMin() (gas: 191806)\n[PASS] test_PulseOnSaturatedGridAddsHeat() (gas: 221316)\n[PASS] test_PulseSizeClamps() (gas: 45909)\n[PASS] test_PulseSmallBalanceUsesOnePercent() (gas: 172883)\n[PASS] test_PulseStillBuysAfterAFreeSellParkedThePrice() (gas: 2128316)\n[PASS] test_PulseWithDustLiquidityRevertsNoFill() (gas: 547028)\n[PASS] test_PulseWithNoFillRevertsAndLeavesStateUntouched() (gas: 1416413)\n[PASS] test_RealTradePostponesPulse() (gas: 327113)\n[PASS] test_ReceivesEthUnderStipendAndIdm() (gas: 100325)\n[PASS] test_SixteenPulsesInSilenceCompleteTrack() (gas: 2764328)\n[PASS] test_UnlockCallbackRejectsOthers() (gas: 62451)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 277.23ms (323.09ms CPU time)\n\nRan 27 tests for test/SequencerState.t.sol:SequencerStateTest\n[PASS] testFuzz_MutationBoundsAndOnlySelectedBits(uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 6844, ~: 6580)\n[PASS] testFuzz_PackingRoundtrip(uint256,uint256) (runs: 512, μ: 2241, ~: 2241)\n[PASS] test_BassDegreeNegativeTickAndMinInt24() (gas: 34325)\n[PASS] test_BuySetsAndSellClearsOnlySelectedBit() (gas: 10916)\n[PASS] test_CountsWrapWithoutRevert() (gas: 6080)\n[PASS] test_EmaSameBlockAndCap() (gas: 11078)\n[PASS] test_EmaUint32MaxDoesNotOverflowAndBpmClamps() (gas: 11556)\n[PASS] test_EuclidTableMatchesSpecLoop() (gas: 33056)\n[PASS] test_ExactBitLayoutAndSignedFields() (gas: 1750)\n[PASS] test_FirstSwapAtTimestampZero() (gas: 10466)\n[PASS] test_FirstSwapKeepsEmaEvenWithHugeTimestamp() (gas: 5420)\n[PASS] test_HashUsesFourThreeEightBytes() (gas: 6177)\n[PASS] test_InitialState() (gas: 1791)\n[PASS] test_ModeBoundaries() (gas: 46701)\n[PASS] test_NonWhaleHasNoDropMask() (gas: 5895)\n[PASS] test_PageAloneDoesNotEmitMovement() (gas: 5633)\n[PASS] test_PressureSignedDivisionRoundsTowardZero() (gas: 10843)\n[PASS] test_ReleaseCountPreserved() (gas: 5837)\n[PASS] test_SellBassBothHashBranches() (gas: 845716)\n[PASS] test_ThresholdEdges() (gas: 79118)\n[PASS] test_TimestampWrapUsesZeroInterval() (gas: 5922)\n[PASS] test_WhaleAndPageHaveSeparateIncrements() (gas: 5763)\n[PASS] test_WhaleBassStillUsesStepAndMovementUnchanged() (gas: 10393)\n[PASS] test_WhaleBuyFillsEveryKWithRotation() (gas: 129051)\n[PASS] test_WhaleBuyRotationWraps() (gas: 113988)\n[PASS] test_WhaleSellWipesEachTrackIncludingKick() (gas: 34695)\n[PASS] test_ZeroSlot1IsReachableAfter38Swaps() (gas: 216155)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 280.17ms (305.93ms CPU time)\n\nRan 7 tests for test/SequencerTokenAdversarial.t.sol:SequencerTokenAdversarialTest\n[PASS] testFuzz_FailedTransferFromRollsBackFiniteAllowance(uint256) (runs: 1000, μ: 221247, ~: 221116)\n[PASS] test_ApprovalReplacementRevocationAndSpenderIsolation() (gas: 294612)\n[PASS] test_FullSupplyRoundTripViaFiniteAllowanceAndSelfTransfer() (gas: 283447)\n[PASS] test_MaxAmountCannotWrapBalancesOrAllowances() (gas: 136079)\n[PASS] test_NoMintUpgradeOwnerOrEtherEntryPoint() (gas: 201583)\n[PASS] test_ZeroAddressPathsRejectEvenZeroAmount() (gas: 126862)\n[PASS] test_ZeroTransferFromWithoutApprovalEmitsTransfer() (gas: 68519)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 280.16ms (280.45ms CPU time)\n\nRan 7 tests for test/PulseTreasuryAnchor.t.sol:PulseTreasuryAnchorTest\n[PASS] testFuzz_AnyParkHeightAnchorsToTheSeedTop(uint256,uint256) (runs: 1000, μ: 1257730, ~: 1350062)\n[PASS] test_AnchorWalksAcrossEmptyBitmapWordsToTheNextPosition() (gas: 1094453)\n[PASS] test_AnyBuyAfterADustParkRestoresThePulse() (gas: 772956)\n[PASS] test_LaunchStateAnchorIsTheOpeningPrice() (gas: 325790)\n[PASS] test_LiquidityOnlyAboveThePriceIsNotReachable() (gas: 1240473)\n[PASS] test_PriceBelowEveryPositionIsNotReachable() (gas: 1460670)\n[PASS] test_ReturnFromParkOntoTheTopTickIsAnOrdinaryPulse() (gas: 1021076)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 280.24ms (274.19ms CPU time)\n\nRan 2 tests for test/Vectors.t.sol:VectorsTest\n[PASS] test_GenerateVectors() (gas: 114679552)\n[PASS] test_GenerateVectorsV2() (gas: 198771842)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 344.00ms (368.36ms CPU time)\n\nRan 2 tests for test/PulseTreasuryInvariant.t.sol:PulseTreasuryInvariantTest\n[PASS]\nPulseTreasuryInvariantTest invariants:\n[PASS] invariant_FixedSupplyIsAccountedForAndHookHasNoSwapRevenue\n[PASS] invariant_OnlySuccessfulSwapsAdvanceTheBoundSequencer\n[PASS] invariant_TreasuryAssetsReconcileWithAllDepositsPulsesAndBurns\n PulseTreasuryInvariantTest invariants (runs: 256, calls: 24576, reverts: 0)\n\n╭--------------------+----------------+-------+---------+----------╮\n| Contract           | Selector       | Calls | Reverts | Discards |\n+==================================================================+\n| IdmTreasuryHandler | burn           | 2684  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | collectFees    | 2701  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | donateEth      | 2812  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | donateIdm      | 2697  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | elapse         | 2798  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | forgedCallback | 2626  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | pulse          | 2715  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | setLiquidity   | 2814  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | trade          | 2729  | 0       | 0        |\n╰--------------------+----------------+-------+---------+----------╯\n\n[PASS] test_HandlerLifecycleVisitsSuccessFailureAndRecovery() (gas: 2486869)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 5.01s (4.99s CPU time)\n\nRan 1 test for test/SequencerTokenAdversarial.t.sol:SequencerTokenInvariantTest\n[PASS]\nSequencerTokenInvariantTest invariants:\n[PASS] invariant_AllowancesMatchApprovalsAndSuccessfulSpending\n[PASS] invariant_FixedSupplyAndEveryHolderMatchTheLedger\n SequencerTokenInvariantTest invariants (runs: 256, calls: 24576, reverts: 0)\n\n╭-----------------+---------------------+-------+---------+----------╮\n| Contract        | Selector            | Calls | Reverts | Discards |\n+====================================================================+\n| IdmTokenHandler | approve             | 3014  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | approveAndSpend     | 3148  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | rejectOverspend     | 3131  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | rejectZeroRecipient | 3069  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | revokeAndReject     | 3053  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | transfer            | 3065  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | transferAll         | 3017  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | transferFrom        | 3079  | 0       | 0        |\n╰-----------------+---------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.38s (6.38s CPU time)\n\nRan 2 tests for test/PulseTreasuryAnchor.t.sol:PulseTreasuryAnchorInvariantTest\n[PASS]\nPulseTreasuryAnchorInvariantTest invariants:\n[PASS] invariant_AnchorMatchesOracleAndEverySwapIsFiled\n[PASS] invariant_TreasuryEthAndIdmMatchPulses\n PulseTreasuryAnchorInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭---------------+--------------+-------+---------+----------╮\n| Contract      | Selector     | Calls | Reverts | Discards |\n+===========================================================+\n| AnchorHandler | buy          | 3323  | 0       | 0        |\n|---------------+--------------+-------+---------+----------|\n| AnchorHandler | elapse       | 3262  | 0       | 0        |\n|---------------+--------------+-------+---------+----------|\n| AnchorHandler | park         | 3408  | 0       | 0        |\n|---------------+--------------+-------+---------+----------|\n| AnchorHandler | pulse        | 3195  | 0       | 0        |\n|---------------+--------------+-------+---------+----------|\n| AnchorHandler | setLiquidity | 3196  | 0       | 0        |\n╰---------------+--------------+-------+---------+----------╯\n\n[PASS] test_AnchorHandlerVisitsParkedAndOrdinaryPulses() (gas: 4400120)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 7.87s (7.85s CPU time)\n\nRan 17 test suites in 7.88s (22.02s CPU time): 245 tests passed, 0 failed, 0 skipped (245 total tests)\n","passed":true},{"durationMs":84,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PulseTreasury.burn()\",\"PulseTreasury.pulse()\",\"PulseTreasury.receive()\",\"PulseTreasury.unlockCallback(bytes)\",\"SequencerHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"SequencerHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"SequencerToken.approve(address,uint256)\",\"SequencerToken.transfer(address,uint256)\",\"SequencerToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":175,\"DEPENDENCIES.md\":16,\"DEPENDENCY_SHA256SUMS\":86,\"GAS.md\":82,\"IMD_LAUNCH_NOTES.md\":70,\"README.md\":43,\"SEPOLIA-V2.md\":146,\"SPEC.md\":250,\"TREASURY-RUNBOOK.md\":81,\"deployments/sepolia-v2.json\":93,\"deployments/sepolia.json\":188,\"foundry.toml\":23,\"gas-report.txt\":387,\"launch.reference.json\":33,\"script/DeploySepolia.s.sol\":74,\"script/DeployTreasury.s.sol\":43,\"script/SimRouter.sol\":108,\"scripts/validate-vectors.py\":125,\"spec/vectors-v2.json\":555,\"spec/vectors.json\":4474,\"src/PulseTreasury.sol\":248,\"src/QuoteCalibration.sol\":42,\"src/SequencerHook.sol\":267,\"src/SequencerState.sol\":354,\"src/SequencerToken.sol\":56,\"test/ADVERSARIAL_TESTS.md\":69,\"test/IdmLaunchSafety.t.sol\":339,\"test/PulseTreasury.t.sol\":631,\"test/PulseTreasuryAnchor.t.sol\":440,\"test/PulseTreasuryInvariant.t.sol\":315,\"test/SequencerGasV2.t.sol\":45,\"test/SequencerHook.t.sol\":701,\"test/SequencerState.t.sol\":422,\"test/SequencerToken.t.sol\":59,\"test/SequencerTokenAdversarial.t.sol\":295,\"test/SequencerV2.t.sol\":223,\"test/Vectors.t.sol\":521,\"test/helpers/IdmLaunchFixture.sol\":110,\"test/helpers/MockQuote.sol\":34,\"test/helpers/PoolRouter.sol\":95,\"vectors.schema.json\":310},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"08ed80b3144014fdaa23cd5003624d2455562fa3cf5d86c2425bdda93241d47c","verifiedTreeHash":"d745d46a584054ed5383889d6435163d56a4f638","verifierVersion":"0.1.0+6a374fcd"},{"checks":[{"durationMs":188577,"exitCode":0,"name":"build","output":"Compiling 85 files with Solc 0.8.26\nSolc 0.8.26 finished in 188.29s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> test/SequencerV2.t.sol:185:17:\n    |\n185 |                 uint8 st = uint8((uint256(step) + i) % 16);\n    |                 ^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/SequencerV2.t.sol:198:34:\n    |\n198 |         (uint64 actual, uint8 t, uint8 st, bool noop) = S.accumulate(pattern, track, step, buy);\n    |                                  ^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:311:22:\n    |\n311 |         uint64 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:317:36:\n    |\n317 |                 uint64 candidate = uint64(1) << (uint256(next) * 16 + step);\n    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:349:23:\n    |\n349 |                 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n  --> test/SequencerState.t.sol:98:22:\n   |\n98 |         uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:300:41:\n    |\n300 |         assertEq((oldBass ^ a.bass) & ~(uint64(15) << (uint256(m.step) * 4)), 0);\n    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:303:26:\n    |\n303 |             uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:309:32:\n    |\n309 |             uint64 trackBits = uint64(0xffff) << (uint256(m.track) * 16);\n    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:376:35:\n    |\n376 |             assertEq(a.pattern | (uint64(0xffff) << (track * 16)), type(uint64).max, \"other tracks untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:390:35:\n    |\n390 |             assertEq(a.pattern | (uint64(0xffff) << (uint256(m.track) * 16)), type(uint64).max, \"others untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerHook.t.sol:309:22:\n    |\n309 |         s.pattern ^= uint64(1) << (32 + ((step + 15) & 15));\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:109:43:\n    |\n109 |         s.pattern = 0x0000ffff0fffffff ^ (uint64(1) << (32 + step)); // full kick + hat rows, 12 snare bits\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:117:43:\n    |\n117 |         s.pattern = 0x0000ffff0ffffffe ^ (uint64(1) << (32 + step));\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:195:26:\n    |\n195 |             uint64 bit = uint64(1) << (uint256(wantTrack) * 16 + wantStep);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:356:68:\n    |\n356 |                         if (column & (1 << row) != 0) s.pattern |= uint64(1) << (row * 16 + step);\n    |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:365:45:\n    |\n365 |             s.pattern = type(uint64).max ^ (uint64(1) << (32 + st));\n    |                                             ^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/SequencerHook.t.sol:171:5:\n    |\n171 |     function thresholdsAt(int24 tick) internal view returns (S.Thresholds memory) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":1007,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/SequencerGasV2.t.sol:SequencerGasV2Test\n[PASS] test_GasHeatDropIncrement() (gas: 1605885)\nLogs:\n  heat/drop increment normal buy: 436\n  heat/drop increment saturated buy: 496\n  heat/drop increment sell: 338\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 675.07µs (528.20µs CPU time)\n\nRan 12 tests for test/SequencerV2.t.sol:SequencerV2Test\n[PASS] testFuzz_AccumulateAgainstLoop(uint64,uint8,uint8,bool) (runs: 512, μ: 2575, ~: 2339)\n[PASS] testFuzz_ArbitraryPackedStateNeverReverts(uint256,uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 8967, ~: 8904)\n[PASS] testFuzz_CodecV2(uint256,uint256) (runs: 512, μ: 1847, ~: 1847)\n[PASS] testFuzz_WhaleThresholdMonotoneBoundedSymmetric(int24,int24) (runs: 512, μ: 4824, ~: 4910)\n[PASS] test_DropSnapshotBeforeResetAndCountersWrap() (gas: 14094)\n[PASS] test_EthCalibration() (gas: 2533)\n[PASS] test_LayoutV2() (gas: 7616)\n[PASS] test_Log2FixedKnownValues() (gas: 398)\n[PASS] test_SaturationUsesPostWritePopcount44() (gas: 16986)\n[PASS] test_SilenceBoundaryAndSellCooling() (gas: 39141)\n[PASS] test_WhaleLeavesHeatButSilenceStillResets() (gas: 31919)\n[PASS] test_WhaleThresholdCalibrationAndClamps() (gas: 20193)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 54.74ms (205.32ms CPU time)\n\nRan 6 tests for test/SequencerToken.t.sol:SequencerTokenTest\n[PASS] testFuzz_TransferConservesSupply(uint256) (runs: 512, μ: 67920, ~: 68153)\n[PASS] test_FactoryReceivesEntireFixedSupply() (gas: 28453)\n[PASS] test_InvalidTransfersRevert() (gas: 81362)\n[PASS] test_SelfTransferAndZeroTransferPreserveSupply() (gas: 67183)\n[PASS] test_TransferAndFiniteAllowance() (gas: 125489)\n[PASS] test_UnlimitedAllowancePreserved() (gas: 112218)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 57.68ms (55.51ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote0Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23440901)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77338)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9030)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109709)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82202)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473765)\n[PASS] test_GasColdFirstBuy() (gas: 440505)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474897)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476707)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465610)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 460072)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 474242)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459615)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460960)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286606)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 576000)\n[PASS] test_RealBuySellExactOutput() (gas: 572422)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 349054)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2518009)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 235885)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 363435)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 349447)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2044896)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97170)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 97.94ms (125.22ms CPU time)\n\nRan 28 tests for test/SequencerHook.t.sol:SequencerHookNativeEthLaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76860)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440677)\nLogs:\n  afterSwap gas (native ETH=currency0): 34661\n\n[PASS] test_GasColdFirstSell() (gas: 443594)\nLogs:\n  afterSwap gas (native ETH=currency0): 37589\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 478213)\nLogs:\n  afterSwap gas (native ETH=currency0): 55074\n\n[PASS] test_GasColdScanSpill() (gas: 476842)\nLogs:\n  afterSwap gas (native ETH=currency0): 38946\n\n[PASS] test_GasColdTrackComplete() (gas: 465781)\nLogs:\n  afterSwap gas (native ETH=currency0): 42751\n\n[PASS] test_GasColdWhale() (gas: 460695)\nLogs:\n  afterSwap gas (native ETH=currency0): 37875\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474860)\nLogs:\n  afterSwap gas (native ETH=currency0): 38030\n\n[PASS] test_GasColdWhalePage64() (gas: 474836)\nLogs:\n  afterSwap gas (native ETH=currency0): 37793\n\n[PASS] test_GasColdWhaleSell() (gas: 460248)\nLogs:\n  afterSwap gas (native ETH=currency0): 37567\n\n[PASS] test_GasColdWorstNormal() (gas: 461120)\nLogs:\n  afterSwap gas (native ETH=currency0): 38584\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 319294)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99829)\n[PASS] test_RealBuySellExactInput() (gas: 518286)\n[PASS] test_RealBuySellExactOutput() (gas: 514250)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 315660)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2480681)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 216795)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 329615)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 316050)\n[PASS] test_RealWhaleBoundaryAtLaunchFdv() (gas: 819145)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1876869)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97331)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 126.49ms (187.22ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1LaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 441014)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34596\n\n[PASS] test_GasColdFirstSell() (gas: 443444)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37602\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475406)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51858\n\n[PASS] test_GasColdScanSpill() (gas: 477129)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38824\n\n[PASS] test_GasColdTrackComplete() (gas: 466119)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42687\n\n[PASS] test_GasColdWhale() (gas: 461051)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37810\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 475236)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37965\n\n[PASS] test_GasColdWhalePage64() (gas: 474708)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37664\n\n[PASS] test_GasColdWhaleSell() (gas: 460174)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37580\n\n[PASS] test_GasColdWorstNormal() (gas: 461469)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38519\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 314533)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99680)\n[PASS] test_RealBuySellExactInput() (gas: 571772)\n[PASS] test_RealBuySellExactOutput() (gas: 568094)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 344933)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2477190)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 228391)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 359063)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 345326)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2034841)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97815)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 135.57ms (169.02ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookNativeEthTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76838)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440277)\nLogs:\n  afterSwap gas (native ETH=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443194)\nLogs:\n  afterSwap gas (native ETH=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474662)\nLogs:\n  afterSwap gas (native ETH=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476472)\nLogs:\n  afterSwap gas (native ETH=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465382)\nLogs:\n  afterSwap gas (native ETH=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 459848)\nLogs:\n  afterSwap gas (native ETH=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474013)\nLogs:\n  afterSwap gas (native ETH=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 473988)\nLogs:\n  afterSwap gas (native ETH=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459400)\nLogs:\n  afterSwap gas (native ETH=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460720)\nLogs:\n  afterSwap gas (native ETH=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 267967)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 521992)\n[PASS] test_RealBuySellExactOutput() (gas: 518416)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 319489)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2498601)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 224063)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 333874)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 319879)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1882455)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 96931)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 216.86ms (280.05ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 440621)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34203\n\n[PASS] test_GasColdFirstSell() (gas: 442973)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37131\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475013)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51465\n\n[PASS] test_GasColdScanSpill() (gas: 476823)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38518\n\n[PASS] test_GasColdTrackComplete() (gas: 465726)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42294\n\n[PASS] test_GasColdWhale() (gas: 460210)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37349\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474395)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37504\n\n[PASS] test_GasColdWhalePage64() (gas: 473931)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37267\n\n[PASS] test_GasColdWhaleSell() (gas: 459255)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37041\n\n[PASS] test_GasColdWorstNormal() (gas: 461076)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38126\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286579)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 98940)\n[PASS] test_RealBuySellExactInput() (gas: 576300)\n[PASS] test_RealBuySellExactOutput() (gas: 566886)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 343330)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2506140)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 230306)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 357596)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 343723)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2041116)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97344)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 239.95ms (200.91ms CPU time)\n\nRan 30 tests for test/PulseTreasury.t.sol:PulseTreasuryTest\n[PASS] testFuzz_Exp2FixedInvertsLog2Fixed(uint16) (runs: 512, μ: 7400, ~: 7455)\n[PASS] testFuzz_HatClassAcrossEma(uint16) (runs: 512, μ: 14081, ~: 14134)\n[PASS] test_BurnSendsAllIdmToDead() (gas: 324275)\n[PASS] test_CannotDriveTreasuryFromAnotherUnlock() (gas: 383927)\n[PASS] test_ConstantsMatchHookCalibration() (gas: 51903)\n[PASS] test_ConstructorValidatesKey() (gas: 18103)\n[PASS] test_EmaAtFloorFilesGlitchNotHat() (gas: 14014)\n[PASS] test_FirstSwapEverCanBeAPulse() (gas: 201060)\n[PASS] test_GasPulse() (gas: 332942)\nLogs:\n  pulse() gas (cold, normal grid): 147572\n\n[PASS] test_GasPulseParkedAtMaxTick() (gas: 1443028)\nLogs:\n  pulse() gas (cold, price parked at MAX_TICK, liquidity at tick 0): 675671\n\n[PASS] test_GasPulseSaturated() (gas: 215851)\nLogs:\n  pulse() gas (cold, saturated grid): 173889\n\n[PASS] test_NextPulseAgreesWithPulse() (gas: 2832955)\n[PASS] test_ParkedPulseStopsAtOnePercentUnderTheAnchor() (gas: 2119482)\n[PASS] test_PriceAnchorInsideLiquidityIsSlot0() (gas: 29436)\n[PASS] test_PriceLimitBoundsMoveAndKeepsUnspentEth() (gas: 351710)\n[PASS] test_PulseBeforeIdleReverts() (gas: 413887)\n[PASS] test_PulseDustReverts() (gas: 69327)\n[PASS] test_PulseHighEmaUsesMax() (gas: 191718)\n[PASS] test_PulseIsHatBuyRecordedByHook() (gas: 417919)\n[PASS] test_PulseLowEmaUsesMin() (gas: 191806)\n[PASS] test_PulseOnSaturatedGridAddsHeat() (gas: 221316)\n[PASS] test_PulseSizeClamps() (gas: 45909)\n[PASS] test_PulseSmallBalanceUsesOnePercent() (gas: 172883)\n[PASS] test_PulseStillBuysAfterAFreeSellParkedThePrice() (gas: 2128316)\n[PASS] test_PulseWithDustLiquidityRevertsNoFill() (gas: 547028)\n[PASS] test_PulseWithNoFillRevertsAndLeavesStateUntouched() (gas: 1416413)\n[PASS] test_RealTradePostponesPulse() (gas: 327113)\n[PASS] test_ReceivesEthUnderStipendAndIdm() (gas: 100325)\n[PASS] test_SixteenPulsesInSilenceCompleteTrack() (gas: 2764328)\n[PASS] test_UnlockCallbackRejectsOthers() (gas: 62451)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 274.01ms (105.85ms CPU time)\n\nRan 2 tests for test/Vectors.t.sol:VectorsTest\n[PASS] test_GenerateVectors() (gas: 114679552)\n[PASS] test_GenerateVectorsV2() (gas: 198771842)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 634.88ms (635.51ms CPU time)\n\nRan 27 tests for test/SequencerState.t.sol:SequencerStateTest\n[PASS] testFuzz_MutationBoundsAndOnlySelectedBits(uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 6855, ~: 6580)\n[PASS] testFuzz_PackingRoundtrip(uint256,uint256) (runs: 512, μ: 2241, ~: 2241)\n[PASS] test_BassDegreeNegativeTickAndMinInt24() (gas: 34325)\n[PASS] test_BuySetsAndSellClearsOnlySelectedBit() (gas: 10916)\n[PASS] test_CountsWrapWithoutRevert() (gas: 6080)\n[PASS] test_EmaSameBlockAndCap() (gas: 11078)\n[PASS] test_EmaUint32MaxDoesNotOverflowAndBpmClamps() (gas: 11556)\n[PASS] test_EuclidTableMatchesSpecLoop() (gas: 33056)\n[PASS] test_ExactBitLayoutAndSignedFields() (gas: 1750)\n[PASS] test_FirstSwapAtTimestampZero() (gas: 10466)\n[PASS] test_FirstSwapKeepsEmaEvenWithHugeTimestamp() (gas: 5420)\n[PASS] test_HashUsesFourThreeEightBytes() (gas: 6177)\n[PASS] test_InitialState() (gas: 1791)\n[PASS] test_ModeBoundaries() (gas: 46701)\n[PASS] test_NonWhaleHasNoDropMask() (gas: 5895)\n[PASS] test_PageAloneDoesNotEmitMovement() (gas: 5633)\n[PASS] test_PressureSignedDivisionRoundsTowardZero() (gas: 10843)\n[PASS] test_ReleaseCountPreserved() (gas: 5837)\n[PASS] test_SellBassBothHashBranches() (gas: 845716)\n[PASS] test_ThresholdEdges() (gas: 79118)\n[PASS] test_TimestampWrapUsesZeroInterval() (gas: 5922)\n[PASS] test_WhaleAndPageHaveSeparateIncrements() (gas: 5763)\n[PASS] test_WhaleBassStillUsesStepAndMovementUnchanged() (gas: 10393)\n[PASS] test_WhaleBuyFillsEveryKWithRotation() (gas: 129051)\n[PASS] test_WhaleBuyRotationWraps() (gas: 113988)\n[PASS] test_WhaleSellWipesEachTrackIncludingKick() (gas: 34695)\n[PASS] test_ZeroSlot1IsReachableAfter38Swaps() (gas: 216155)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 635.20ms (696.76ms CPU time)\n\nRan 11 test suites in 636.75ms (2.47s CPU time): 214 tests passed, 0 failed, 0 skipped (214 total tests)\n","passed":true},{"durationMs":195,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PulseTreasury.burn()\",\"PulseTreasury.pulse()\",\"PulseTreasury.receive()\",\"PulseTreasury.unlockCallback(bytes)\",\"SequencerHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"SequencerHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"SequencerToken.approve(address,uint256)\",\"SequencerToken.transfer(address,uint256)\",\"SequencerToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":175,\"DEPENDENCIES.md\":16,\"DEPENDENCY_SHA256SUMS\":86,\"GAS.md\":82,\"IMD_LAUNCH_NOTES.md\":70,\"README.md\":43,\"SEPOLIA-V2.md\":146,\"SPEC.md\":250,\"TREASURY-RUNBOOK.md\":81,\"deployments/sepolia-v2.json\":93,\"deployments/sepolia.json\":188,\"foundry.toml\":23,\"gas-report.txt\":387,\"launch.json\":32,\"launch.reference.json\":33,\"script/DeploySepolia.s.sol\":74,\"script/DeployTreasury.s.sol\":43,\"script/SimRouter.sol\":108,\"scripts/validate-vectors.py\":125,\"spec/vectors-v2.json\":555,\"spec/vectors.json\":4474,\"src/PulseTreasury.sol\":248,\"src/QuoteCalibration.sol\":42,\"src/SequencerHook.sol\":267,\"src/SequencerState.sol\":354,\"src/SequencerToken.sol\":56,\"test/PulseTreasury.t.sol\":631,\"test/SequencerGasV2.t.sol\":45,\"test/SequencerHook.t.sol\":701,\"test/SequencerState.t.sol\":422,\"test/SequencerToken.t.sol\":59,\"test/SequencerV2.t.sol\":223,\"test/Vectors.t.sol\":521,\"test/helpers/MockQuote.sol\":34,\"test/helpers/PoolRouter.sol\":95,\"vectors.schema.json\":310},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"7e941bc5e6e0663093c02e18d24fe417bbfc6256f96e3926658b14218d7636f2","verifiedTreeHash":"389f6fa7c34ac81656d7963a206d1b2ad24a9193","verifierVersion":"0.1.0+6a374fcd"},{"checks":[{"durationMs":123101,"exitCode":0,"name":"build","output":"Compiling 89 files with Solc 0.8.26\nSolc 0.8.26 finished in 122.98s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> test/SequencerV2.t.sol:185:17:\n    |\n185 |                 uint8 st = uint8((uint256(step) + i) % 16);\n    |                 ^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/SequencerV2.t.sol:198:34:\n    |\n198 |         (uint64 actual, uint8 t, uint8 st, bool noop) = S.accumulate(pattern, track, step, buy);\n    |                                  ^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:311:22:\n    |\n311 |         uint64 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:317:36:\n    |\n317 |                 uint64 candidate = uint64(1) << (uint256(next) * 16 + step);\n    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:349:23:\n    |\n349 |                 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n  --> test/SequencerState.t.sol:98:22:\n   |\n98 |         uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:300:41:\n    |\n300 |         assertEq((oldBass ^ a.bass) & ~(uint64(15) << (uint256(m.step) * 4)), 0);\n    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:303:26:\n    |\n303 |             uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:309:32:\n    |\n309 |             uint64 trackBits = uint64(0xffff) << (uint256(m.track) * 16);\n    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:376:35:\n    |\n376 |             assertEq(a.pattern | (uint64(0xffff) << (track * 16)), type(uint64).max, \"other tracks untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:390:35:\n    |\n390 |             assertEq(a.pattern | (uint64(0xffff) << (uint256(m.track) * 16)), type(uint64).max, \"others untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerHook.t.sol:309:22:\n    |\n309 |         s.pattern ^= uint64(1) << (32 + ((step + 15) & 15));\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:109:43:\n    |\n109 |         s.pattern = 0x0000ffff0fffffff ^ (uint64(1) << (32 + step)); // full kick + hat rows, 12 snare bits\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:117:43:\n    |\n117 |         s.pattern = 0x0000ffff0ffffffe ^ (uint64(1) << (32 + step));\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:195:26:\n    |\n195 |             uint64 bit = uint64(1) << (uint256(wantTrack) * 16 + wantStep);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:356:68:\n    |\n356 |                         if (column & (1 << row) != 0) s.pattern |= uint64(1) << (row * 16 + step);\n    |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:365:45:\n    |\n365 |             s.pattern = type(uint64).max ^ (uint64(1) << (32 + st));\n    |                                             ^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/SequencerHook.t.sol:171:5:\n    |\n171 |     function thresholdsAt(int24 tick) internal view returns (S.Thresholds memory) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":6661,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/SequencerGasV2.t.sol:SequencerGasV2Test\n[PASS] test_GasHeatDropIncrement() (gas: 1605885)\nLogs:\n  heat/drop increment normal buy: 436\n  heat/drop increment saturated buy: 496\n  heat/drop increment sell: 338\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 660.40µs (464.47µs CPU time)\n\nRan 27 tests for test/SequencerState.t.sol:SequencerStateTest\n[PASS] testFuzz_MutationBoundsAndOnlySelectedBits(uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 6846, ~: 6583)\n[PASS] testFuzz_PackingRoundtrip(uint256,uint256) (runs: 512, μ: 2241, ~: 2241)\n[PASS] test_BassDegreeNegativeTickAndMinInt24() (gas: 34325)\n[PASS] test_BuySetsAndSellClearsOnlySelectedBit() (gas: 10916)\n[PASS] test_CountsWrapWithoutRevert() (gas: 6080)\n[PASS] test_EmaSameBlockAndCap() (gas: 11078)\n[PASS] test_EmaUint32MaxDoesNotOverflowAndBpmClamps() (gas: 11556)\n[PASS] test_EuclidTableMatchesSpecLoop() (gas: 33056)\n[PASS] test_ExactBitLayoutAndSignedFields() (gas: 1750)\n[PASS] test_FirstSwapAtTimestampZero() (gas: 10466)\n[PASS] test_FirstSwapKeepsEmaEvenWithHugeTimestamp() (gas: 5420)\n[PASS] test_HashUsesFourThreeEightBytes() (gas: 6177)\n[PASS] test_InitialState() (gas: 1791)\n[PASS] test_ModeBoundaries() (gas: 46701)\n[PASS] test_NonWhaleHasNoDropMask() (gas: 5895)\n[PASS] test_PageAloneDoesNotEmitMovement() (gas: 5633)\n[PASS] test_PressureSignedDivisionRoundsTowardZero() (gas: 10843)\n[PASS] test_ReleaseCountPreserved() (gas: 5837)\n[PASS] test_SellBassBothHashBranches() (gas: 845716)\n[PASS] test_ThresholdEdges() (gas: 79118)\n[PASS] test_TimestampWrapUsesZeroInterval() (gas: 5922)\n[PASS] test_WhaleAndPageHaveSeparateIncrements() (gas: 5763)\n[PASS] test_WhaleBassStillUsesStepAndMovementUnchanged() (gas: 10393)\n[PASS] test_WhaleBuyFillsEveryKWithRotation() (gas: 129051)\n[PASS] test_WhaleBuyRotationWraps() (gas: 113988)\n[PASS] test_WhaleSellWipesEachTrackIncludingKick() (gas: 34695)\n[PASS] test_ZeroSlot1IsReachableAfter38Swaps() (gas: 216155)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 26.48ms (29.76ms CPU time)\n\nRan 24 tests for test/PulseTreasury.t.sol:PulseTreasuryTest\n[PASS] testFuzz_Exp2FixedInvertsLog2Fixed(uint16) (runs: 512, μ: 7241, ~: 7274)\n[PASS] testFuzz_HatClassAcrossEma(uint16) (runs: 512, μ: 13350, ~: 13402)\n[PASS] test_BurnSendsAllIdmToDead() (gas: 320763)\n[PASS] test_CannotDriveTreasuryFromAnotherUnlock() (gas: 378349)\n[PASS] test_ConstantsMatchHookCalibration() (gas: 51551)\n[PASS] test_ConstructorValidatesKey() (gas: 17971)\n[PASS] test_EmaAtFloorFilesGlitchNotHat() (gas: 13150)\n[PASS] test_FirstSwapEverCanBeAPulse() (gas: 188853)\n[PASS] test_GasPulse() (gas: 329253)\nLogs:\n  pulse() gas (cold, normal grid): 144104\n\n[PASS] test_GasPulseSaturated() (gas: 212382)\nLogs:\n  pulse() gas (cold, saturated grid): 170421\n\n[PASS] test_PriceLimitBoundsMoveAndKeepsUnspentEth() (gas: 348048)\n[PASS] test_PulseBeforeIdleReverts() (gas: 401365)\n[PASS] test_PulseDustReverts() (gas: 69089)\n[PASS] test_PulseHighEmaUsesMax() (gas: 188228)\n[PASS] test_PulseIsHatBuyRecordedByHook() (gas: 414284)\n[PASS] test_PulseLowEmaUsesMin() (gas: 188272)\n[PASS] test_PulseOnSaturatedGridAddsHeat() (gas: 217716)\n[PASS] test_PulseSizeClamps() (gas: 45601)\n[PASS] test_PulseSmallBalanceUsesOnePercent() (gas: 169415)\n[PASS] test_PulseWithNoFillRevertsAndLeavesStateUntouched() (gas: 751214)\n[PASS] test_RealTradePostponesPulse() (gas: 326898)\n[PASS] test_ReceivesEthUnderStipendAndIdm() (gas: 100215)\n[PASS] test_SixteenPulsesInSilenceCompleteTrack() (gas: 2708842)\n[PASS] test_UnlockCallbackRejectsOthers() (gas: 62275)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 31.82ms (25.52ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote0Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23440901)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77338)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9030)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109709)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82202)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473765)\n[PASS] test_GasColdFirstBuy() (gas: 440505)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474897)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476707)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465610)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 460072)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 474242)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459615)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460960)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286606)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 576000)\n[PASS] test_RealBuySellExactOutput() (gas: 572422)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 349054)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2518009)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 235885)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 363435)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 349447)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2044896)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97170)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 42.20ms (96.78ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookNativeEthTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76838)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440277)\nLogs:\n  afterSwap gas (native ETH=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443194)\nLogs:\n  afterSwap gas (native ETH=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474662)\nLogs:\n  afterSwap gas (native ETH=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476472)\nLogs:\n  afterSwap gas (native ETH=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465382)\nLogs:\n  afterSwap gas (native ETH=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 459848)\nLogs:\n  afterSwap gas (native ETH=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474013)\nLogs:\n  afterSwap gas (native ETH=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 473988)\nLogs:\n  afterSwap gas (native ETH=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459400)\nLogs:\n  afterSwap gas (native ETH=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460720)\nLogs:\n  afterSwap gas (native ETH=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 267967)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 521992)\n[PASS] test_RealBuySellExactOutput() (gas: 518416)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 319489)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2498601)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 224063)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 333874)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 319879)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1882455)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 96931)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 47.40ms (86.73ms CPU time)\n\nRan 6 tests for test/SequencerToken.t.sol:SequencerTokenTest\n[PASS] testFuzz_TransferConservesSupply(uint256) (runs: 512, μ: 67920, ~: 68153)\n[PASS] test_FactoryReceivesEntireFixedSupply() (gas: 28453)\n[PASS] test_InvalidTransfersRevert() (gas: 81362)\n[PASS] test_SelfTransferAndZeroTransferPreserveSupply() (gas: 67183)\n[PASS] test_TransferAndFiniteAllowance() (gas: 125489)\n[PASS] test_UnlimitedAllowancePreserved() (gas: 112218)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 50.34ms (50.56ms CPU time)\n\nRan 28 tests for test/SequencerHook.t.sol:SequencerHookNativeEthLaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76860)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440677)\nLogs:\n  afterSwap gas (native ETH=currency0): 34661\n\n[PASS] test_GasColdFirstSell() (gas: 443594)\nLogs:\n  afterSwap gas (native ETH=currency0): 37589\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 478213)\nLogs:\n  afterSwap gas (native ETH=currency0): 55074\n\n[PASS] test_GasColdScanSpill() (gas: 476842)\nLogs:\n  afterSwap gas (native ETH=currency0): 38946\n\n[PASS] test_GasColdTrackComplete() (gas: 465781)\nLogs:\n  afterSwap gas (native ETH=currency0): 42751\n\n[PASS] test_GasColdWhale() (gas: 460695)\nLogs:\n  afterSwap gas (native ETH=currency0): 37875\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474860)\nLogs:\n  afterSwap gas (native ETH=currency0): 38030\n\n[PASS] test_GasColdWhalePage64() (gas: 474836)\nLogs:\n  afterSwap gas (native ETH=currency0): 37793\n\n[PASS] test_GasColdWhaleSell() (gas: 460248)\nLogs:\n  afterSwap gas (native ETH=currency0): 37567\n\n[PASS] test_GasColdWorstNormal() (gas: 461120)\nLogs:\n  afterSwap gas (native ETH=currency0): 38584\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 319294)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99829)\n[PASS] test_RealBuySellExactInput() (gas: 518286)\n[PASS] test_RealBuySellExactOutput() (gas: 514250)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 315660)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2480681)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 216795)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 329615)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 316050)\n[PASS] test_RealWhaleBoundaryAtLaunchFdv() (gas: 819145)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1876869)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97331)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 50.39ms (66.89ms CPU time)\n\nRan 7 tests for test/SequencerTokenAdversarial.t.sol:SequencerTokenAdversarialTest\n[PASS] testFuzz_FailedTransferFromRollsBackFiniteAllowance(uint256) (runs: 1000, μ: 221248, ~: 221152)\n[PASS] test_ApprovalReplacementRevocationAndSpenderIsolation() (gas: 294612)\n[PASS] test_FullSupplyRoundTripViaFiniteAllowanceAndSelfTransfer() (gas: 283447)\n[PASS] test_MaxAmountCannotWrapBalancesOrAllowances() (gas: 136079)\n[PASS] test_NoMintUpgradeOwnerOrEtherEntryPoint() (gas: 201583)\n[PASS] test_ZeroAddressPathsRejectEvenZeroAmount() (gas: 126862)\n[PASS] test_ZeroTransferFromWithoutApprovalEmitsTransfer() (gas: 68519)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 50.43ms (49.92ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1LaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 441014)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34596\n\n[PASS] test_GasColdFirstSell() (gas: 443444)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37602\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475406)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51858\n\n[PASS] test_GasColdScanSpill() (gas: 477129)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38824\n\n[PASS] test_GasColdTrackComplete() (gas: 466119)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42687\n\n[PASS] test_GasColdWhale() (gas: 461051)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37810\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 475236)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37965\n\n[PASS] test_GasColdWhalePage64() (gas: 474708)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37664\n\n[PASS] test_GasColdWhaleSell() (gas: 460174)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37580\n\n[PASS] test_GasColdWorstNormal() (gas: 461469)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38519\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 314533)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99680)\n[PASS] test_RealBuySellExactInput() (gas: 571772)\n[PASS] test_RealBuySellExactOutput() (gas: 568094)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 344933)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2477190)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 228391)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 359063)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 345326)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2034841)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97815)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 96.41ms (110.32ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 440621)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34203\n\n[PASS] test_GasColdFirstSell() (gas: 442973)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37131\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475013)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51465\n\n[PASS] test_GasColdScanSpill() (gas: 476823)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38518\n\n[PASS] test_GasColdTrackComplete() (gas: 465726)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42294\n\n[PASS] test_GasColdWhale() (gas: 460210)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37349\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474395)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37504\n\n[PASS] test_GasColdWhalePage64() (gas: 473931)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37267\n\n[PASS] test_GasColdWhaleSell() (gas: 459255)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37041\n\n[PASS] test_GasColdWorstNormal() (gas: 461076)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38126\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286579)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 98940)\n[PASS] test_RealBuySellExactInput() (gas: 576300)\n[PASS] test_RealBuySellExactOutput() (gas: 566886)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 343330)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2506140)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 230306)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 357596)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 343723)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2041116)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97344)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 99.57ms (104.09ms CPU time)\n\nRan 12 tests for test/IdmLaunchSafety.t.sol:IdmLaunchSafetyTest\n[PASS] testFuzz_ForeignCallersCannotDriveAnyEnabledCallback(address,int128,int128) (runs: 1000, μ: 103998, ~: 103993)\n[PASS] testFuzz_HookDataAndRequestedAmountsCannotChangeTheActualDeltaMutation(int128,int128,int256,uint160,bool,bytes) (runs: 1000, μ: 174702, ~: 176321)\n[PASS] testFuzz_InvalidInitializationCannotBindOrPoisonAValidLaunch(uint8,uint24) (runs: 1000, μ: 253763, ~: 253421)\n[PASS] testFuzz_PulseSizingIsBoundedAndMonotone(uint256,uint256,uint256) (runs: 1000, μ: 22471, ~: 22506)\n[PASS] test_ConstructorRejectsAddressWithIncorrectPermissionBits() (gas: 24012)\n[PASS] test_HookHasNoAdminFundOrUpgradeSurface() (gas: 3109786)\n[PASS] test_InitializationCallbackPreventsPoolOpeningAtAnUndeployedHook() (gas: 50871)\n[PASS] test_NoFillRevertCanRecoverWithinTheSameTransaction() (gas: 903268)\n[PASS] test_RealSwapOnlyWritesTheTwoPackedStateWords() (gas: 189557)\n[PASS] test_TokenOnlyLaunchFirstBuySellFeeCollectAndExit() (gas: 741330)\n[PASS] test_TransientGuardClearsAfterSuccessWithinOneTransaction() (gas: 530697)\n[PASS] test_UninitializedSwapRejectedEvenFromManager() (gas: 58743)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 99.34ms (170.93ms CPU time)\n\nRan 2 tests for test/Vectors.t.sol:VectorsTest\n[PASS] test_GenerateVectors() (gas: 114679552)\n[PASS] test_GenerateVectorsV2() (gas: 198771842)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 344.49ms (358.79ms CPU time)\n\nRan 12 tests for test/SequencerV2.t.sol:SequencerV2Test\n[PASS] testFuzz_AccumulateAgainstLoop(uint64,uint8,uint8,bool) (runs: 512, μ: 2586, ~: 2339)\n[PASS] testFuzz_ArbitraryPackedStateNeverReverts(uint256,uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 8963, ~: 8894)\n[PASS] testFuzz_CodecV2(uint256,uint256) (runs: 512, μ: 1847, ~: 1847)\n[PASS] testFuzz_WhaleThresholdMonotoneBoundedSymmetric(int24,int24) (runs: 512, μ: 4824, ~: 4910)\n[PASS] test_DropSnapshotBeforeResetAndCountersWrap() (gas: 14094)\n[PASS] test_EthCalibration() (gas: 2533)\n[PASS] test_LayoutV2() (gas: 7616)\n[PASS] test_Log2FixedKnownValues() (gas: 398)\n[PASS] test_SaturationUsesPostWritePopcount44() (gas: 16986)\n[PASS] test_SilenceBoundaryAndSellCooling() (gas: 39141)\n[PASS] test_WhaleLeavesHeatButSilenceStillResets() (gas: 31919)\n[PASS] test_WhaleThresholdCalibrationAndClamps() (gas: 20193)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 344.54ms (185.30ms CPU time)\n\nRan 2 tests for test/PulseTreasuryInvariant.t.sol:PulseTreasuryInvariantTest\n[PASS]\nPulseTreasuryInvariantTest invariants:\n[PASS] invariant_FixedSupplyIsAccountedForAndHookHasNoSwapRevenue\n[PASS] invariant_OnlySuccessfulSwapsAdvanceTheBoundSequencer\n[PASS] invariant_TreasuryAssetsReconcileWithAllDepositsPulsesAndBurns\n PulseTreasuryInvariantTest invariants (runs: 256, calls: 24576, reverts: 0)\n\n╭--------------------+----------------+-------+---------+----------╮\n| Contract           | Selector       | Calls | Reverts | Discards |\n+==================================================================+\n| IdmTreasuryHandler | burn           | 2684  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | collectFees    | 2701  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | donateEth      | 2812  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | donateIdm      | 2697  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | elapse         | 2798  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | forgedCallback | 2626  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | pulse          | 2715  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | setLiquidity   | 2814  | 0       | 0        |\n|--------------------+----------------+-------+---------+----------|\n| IdmTreasuryHandler | trade          | 2729  | 0       | 0        |\n╰--------------------+----------------+-------+---------+----------╯\n\n[PASS] test_HandlerLifecycleVisitsSuccessFailureAndRecovery() (gas: 2084597)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 4.57s (4.56s CPU time)\n\nRan 1 test for test/SequencerTokenAdversarial.t.sol:SequencerTokenInvariantTest\n[PASS]\nSequencerTokenInvariantTest invariants:\n[PASS] invariant_AllowancesMatchApprovalsAndSuccessfulSpending\n[PASS] invariant_FixedSupplyAndEveryHolderMatchTheLedger\n SequencerTokenInvariantTest invariants (runs: 256, calls: 24576, reverts: 0)\n\n╭-----------------+---------------------+-------+---------+----------╮\n| Contract        | Selector            | Calls | Reverts | Discards |\n+====================================================================+\n| IdmTokenHandler | approve             | 3014  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | approveAndSpend     | 3148  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | rejectOverspend     | 3131  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | rejectZeroRecipient | 3069  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | revokeAndReject     | 3053  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | transfer            | 3065  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | transferAll         | 3017  | 0       | 0        |\n|-----------------+---------------------+-------+---------+----------|\n| IdmTokenHandler | transferFrom        | 3079  | 0       | 0        |\n╰-----------------+---------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.53s (6.53s CPU time)\n\nRan 15 test suites in 6.54s (12.39s CPU time): 230 tests passed, 0 failed, 0 skipped (230 total tests)\n","passed":true},{"durationMs":85,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PulseTreasury.burn()\",\"PulseTreasury.pulse()\",\"PulseTreasury.receive()\",\"PulseTreasury.unlockCallback(bytes)\",\"SequencerHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"SequencerHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"SequencerToken.approve(address,uint256)\",\"SequencerToken.transfer(address,uint256)\",\"SequencerToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":110,\"DEPENDENCIES.md\":16,\"DEPENDENCY_SHA256SUMS\":86,\"GAS.md\":82,\"IMD_LAUNCH_NOTES.md\":70,\"README.md\":43,\"SEPOLIA-V2.md\":146,\"SPEC.md\":250,\"TREASURY-RUNBOOK.md\":78,\"deployments/sepolia-v2.json\":93,\"deployments/sepolia.json\":188,\"foundry.toml\":23,\"gas-report.txt\":387,\"launch.reference.json\":33,\"script/DeploySepolia.s.sol\":74,\"script/DeployTreasury.s.sol\":43,\"script/SimRouter.sol\":108,\"scripts/validate-vectors.py\":125,\"spec/vectors-v2.json\":555,\"spec/vectors.json\":4474,\"src/PulseTreasury.sol\":206,\"src/QuoteCalibration.sol\":42,\"src/SequencerHook.sol\":267,\"src/SequencerState.sol\":354,\"src/SequencerToken.sol\":56,\"test/ADVERSARIAL_TESTS.md\":60,\"test/IdmLaunchSafety.t.sol\":339,\"test/PulseTreasury.t.sol\":479,\"test/PulseTreasuryInvariant.t.sol\":315,\"test/SequencerGasV2.t.sol\":45,\"test/SequencerHook.t.sol\":701,\"test/SequencerState.t.sol\":422,\"test/SequencerToken.t.sol\":59,\"test/SequencerTokenAdversarial.t.sol\":295,\"test/SequencerV2.t.sol\":223,\"test/Vectors.t.sol\":521,\"test/helpers/IdmLaunchFixture.sol\":110,\"test/helpers/MockQuote.sol\":34,\"test/helpers/PoolRouter.sol\":95,\"vectors.schema.json\":310},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"8583b68ce78f0d98d72d9e8674ede931e532b6b0145f002d7a4ac1e5f5e71d18","verifiedTreeHash":"e6790e5c147ab69e6693cccc3e605eec92bc5c1f","verifierVersion":"0.1.0+6a374fcd"},{"checks":[{"durationMs":78354,"exitCode":0,"name":"build","output":"Compiling 85 files with Solc 0.8.26\nSolc 0.8.26 finished in 78.26s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> test/SequencerV2.t.sol:185:17:\n    |\n185 |                 uint8 st = uint8((uint256(step) + i) % 16);\n    |                 ^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/SequencerV2.t.sol:198:34:\n    |\n198 |         (uint64 actual, uint8 t, uint8 st, bool noop) = S.accumulate(pattern, track, step, buy);\n    |                                  ^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:311:22:\n    |\n311 |         uint64 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:317:36:\n    |\n317 |                 uint64 candidate = uint64(1) << (uint256(next) * 16 + step);\n    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:349:23:\n    |\n349 |                 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n  --> test/SequencerState.t.sol:98:22:\n   |\n98 |         uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:300:41:\n    |\n300 |         assertEq((oldBass ^ a.bass) & ~(uint64(15) << (uint256(m.step) * 4)), 0);\n    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:303:26:\n    |\n303 |             uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:309:32:\n    |\n309 |             uint64 trackBits = uint64(0xffff) << (uint256(m.track) * 16);\n    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:376:35:\n    |\n376 |             assertEq(a.pattern | (uint64(0xffff) << (track * 16)), type(uint64).max, \"other tracks untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:390:35:\n    |\n390 |             assertEq(a.pattern | (uint64(0xffff) << (uint256(m.track) * 16)), type(uint64).max, \"others untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerHook.t.sol:309:22:\n    |\n309 |         s.pattern ^= uint64(1) << (32 + ((step + 15) & 15));\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:109:43:\n    |\n109 |         s.pattern = 0x0000ffff0fffffff ^ (uint64(1) << (32 + step)); // full kick + hat rows, 12 snare bits\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:117:43:\n    |\n117 |         s.pattern = 0x0000ffff0ffffffe ^ (uint64(1) << (32 + step));\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:195:26:\n    |\n195 |             uint64 bit = uint64(1) << (uint256(wantTrack) * 16 + wantStep);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:356:68:\n    |\n356 |                         if (column & (1 << row) != 0) s.pattern |= uint64(1) << (row * 16 + step);\n    |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:365:45:\n    |\n365 |             s.pattern = type(uint64).max ^ (uint64(1) << (32 + st));\n    |                                             ^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/SequencerHook.t.sol:171:5:\n    |\n171 |     function thresholdsAt(int24 tick) internal view returns (S.Thresholds memory) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":392,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/SequencerGasV2.t.sol:SequencerGasV2Test\n[PASS] test_GasHeatDropIncrement() (gas: 1605885)\nLogs:\n  heat/drop increment normal buy: 436\n  heat/drop increment saturated buy: 496\n  heat/drop increment sell: 338\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 726.58µs (536.73µs CPU time)\n\nRan 6 tests for test/SequencerToken.t.sol:SequencerTokenTest\n[PASS] testFuzz_TransferConservesSupply(uint256) (runs: 512, μ: 67969, ~: 68141)\n[PASS] test_FactoryReceivesEntireFixedSupply() (gas: 28453)\n[PASS] test_InvalidTransfersRevert() (gas: 81362)\n[PASS] test_SelfTransferAndZeroTransferPreserveSupply() (gas: 67183)\n[PASS] test_TransferAndFiniteAllowance() (gas: 125489)\n[PASS] test_UnlimitedAllowancePreserved() (gas: 112218)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 25.48ms (25.72ms CPU time)\n\nRan 24 tests for test/PulseTreasury.t.sol:PulseTreasuryTest\n[PASS] testFuzz_Exp2FixedInvertsLog2Fixed(uint16) (runs: 512, μ: 7242, ~: 7274)\n[PASS] testFuzz_HatClassAcrossEma(uint16) (runs: 512, μ: 13344, ~: 13402)\n[PASS] test_BurnSendsAllIdmToDead() (gas: 320763)\n[PASS] test_CannotDriveTreasuryFromAnotherUnlock() (gas: 378349)\n[PASS] test_ConstantsMatchHookCalibration() (gas: 51551)\n[PASS] test_ConstructorValidatesKey() (gas: 17971)\n[PASS] test_EmaAtFloorFilesGlitchNotHat() (gas: 13150)\n[PASS] test_FirstSwapEverCanBeAPulse() (gas: 188853)\n[PASS] test_GasPulse() (gas: 329253)\nLogs:\n  pulse() gas (cold, normal grid): 144104\n\n[PASS] test_GasPulseSaturated() (gas: 212382)\nLogs:\n  pulse() gas (cold, saturated grid): 170421\n\n[PASS] test_PriceLimitBoundsMoveAndKeepsUnspentEth() (gas: 348048)\n[PASS] test_PulseBeforeIdleReverts() (gas: 401365)\n[PASS] test_PulseDustReverts() (gas: 69089)\n[PASS] test_PulseHighEmaUsesMax() (gas: 188228)\n[PASS] test_PulseIsHatBuyRecordedByHook() (gas: 414284)\n[PASS] test_PulseLowEmaUsesMin() (gas: 188272)\n[PASS] test_PulseOnSaturatedGridAddsHeat() (gas: 217716)\n[PASS] test_PulseSizeClamps() (gas: 45601)\n[PASS] test_PulseSmallBalanceUsesOnePercent() (gas: 169415)\n[PASS] test_PulseWithNoFillRevertsAndLeavesStateUntouched() (gas: 751214)\n[PASS] test_RealTradePostponesPulse() (gas: 326898)\n[PASS] test_ReceivesEthUnderStipendAndIdm() (gas: 100215)\n[PASS] test_SixteenPulsesInSilenceCompleteTrack() (gas: 2708842)\n[PASS] test_UnlockCallbackRejectsOthers() (gas: 62275)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 25.55ms (19.46ms CPU time)\n\nRan 12 tests for test/SequencerV2.t.sol:SequencerV2Test\n[PASS] testFuzz_AccumulateAgainstLoop(uint64,uint8,uint8,bool) (runs: 512, μ: 2583, ~: 2339)\n[PASS] testFuzz_ArbitraryPackedStateNeverReverts(uint256,uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 8976, ~: 8901)\n[PASS] testFuzz_CodecV2(uint256,uint256) (runs: 512, μ: 1847, ~: 1847)\n[PASS] testFuzz_WhaleThresholdMonotoneBoundedSymmetric(int24,int24) (runs: 512, μ: 4824, ~: 4910)\n[PASS] test_DropSnapshotBeforeResetAndCountersWrap() (gas: 14094)\n[PASS] test_EthCalibration() (gas: 2533)\n[PASS] test_LayoutV2() (gas: 7616)\n[PASS] test_Log2FixedKnownValues() (gas: 398)\n[PASS] test_SaturationUsesPostWritePopcount44() (gas: 16986)\n[PASS] test_SilenceBoundaryAndSellCooling() (gas: 39141)\n[PASS] test_WhaleLeavesHeatButSilenceStillResets() (gas: 31919)\n[PASS] test_WhaleThresholdCalibrationAndClamps() (gas: 20193)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 47.39ms (83.72ms CPU time)\n\nRan 28 tests for test/SequencerHook.t.sol:SequencerHookNativeEthLaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76860)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440677)\nLogs:\n  afterSwap gas (native ETH=currency0): 34661\n\n[PASS] test_GasColdFirstSell() (gas: 443594)\nLogs:\n  afterSwap gas (native ETH=currency0): 37589\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 478213)\nLogs:\n  afterSwap gas (native ETH=currency0): 55074\n\n[PASS] test_GasColdScanSpill() (gas: 476842)\nLogs:\n  afterSwap gas (native ETH=currency0): 38946\n\n[PASS] test_GasColdTrackComplete() (gas: 465781)\nLogs:\n  afterSwap gas (native ETH=currency0): 42751\n\n[PASS] test_GasColdWhale() (gas: 460695)\nLogs:\n  afterSwap gas (native ETH=currency0): 37875\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474860)\nLogs:\n  afterSwap gas (native ETH=currency0): 38030\n\n[PASS] test_GasColdWhalePage64() (gas: 474836)\nLogs:\n  afterSwap gas (native ETH=currency0): 37793\n\n[PASS] test_GasColdWhaleSell() (gas: 460248)\nLogs:\n  afterSwap gas (native ETH=currency0): 37567\n\n[PASS] test_GasColdWorstNormal() (gas: 461120)\nLogs:\n  afterSwap gas (native ETH=currency0): 38584\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 319294)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99829)\n[PASS] test_RealBuySellExactInput() (gas: 518286)\n[PASS] test_RealBuySellExactOutput() (gas: 514250)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 315660)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2480681)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 216795)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 329615)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 316050)\n[PASS] test_RealWhaleBoundaryAtLaunchFdv() (gas: 819145)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1876869)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97331)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 47.47ms (63.42ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 440621)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34203\n\n[PASS] test_GasColdFirstSell() (gas: 442973)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37131\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475013)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51465\n\n[PASS] test_GasColdScanSpill() (gas: 476823)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38518\n\n[PASS] test_GasColdTrackComplete() (gas: 465726)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42294\n\n[PASS] test_GasColdWhale() (gas: 460210)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37349\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474395)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37504\n\n[PASS] test_GasColdWhalePage64() (gas: 473931)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37267\n\n[PASS] test_GasColdWhaleSell() (gas: 459255)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37041\n\n[PASS] test_GasColdWorstNormal() (gas: 461076)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38126\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286579)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 98940)\n[PASS] test_RealBuySellExactInput() (gas: 576300)\n[PASS] test_RealBuySellExactOutput() (gas: 566886)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 343330)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2506140)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 230306)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 357596)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 343723)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2041116)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97344)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 47.44ms (75.14ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote0Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23440901)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77338)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9030)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109709)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82202)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473765)\n[PASS] test_GasColdFirstBuy() (gas: 440505)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474897)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476707)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465610)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 460072)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 474242)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459615)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460960)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286606)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 576000)\n[PASS] test_RealBuySellExactOutput() (gas: 572422)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 349054)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2518009)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 235885)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 363435)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 349447)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2044896)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97170)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 47.50ms (81.32ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1LaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 441014)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34596\n\n[PASS] test_GasColdFirstSell() (gas: 443444)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37602\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475406)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51858\n\n[PASS] test_GasColdScanSpill() (gas: 477129)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38824\n\n[PASS] test_GasColdTrackComplete() (gas: 466119)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42687\n\n[PASS] test_GasColdWhale() (gas: 461051)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37810\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 475236)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37965\n\n[PASS] test_GasColdWhalePage64() (gas: 474708)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37664\n\n[PASS] test_GasColdWhaleSell() (gas: 460174)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37580\n\n[PASS] test_GasColdWorstNormal() (gas: 461469)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38519\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 314533)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99680)\n[PASS] test_RealBuySellExactInput() (gas: 571772)\n[PASS] test_RealBuySellExactOutput() (gas: 568094)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 344933)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2477190)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 228391)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 359063)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 345326)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2034841)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97815)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 50.50ms (79.07ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookNativeEthTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76838)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440277)\nLogs:\n  afterSwap gas (native ETH=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443194)\nLogs:\n  afterSwap gas (native ETH=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474662)\nLogs:\n  afterSwap gas (native ETH=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476472)\nLogs:\n  afterSwap gas (native ETH=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465382)\nLogs:\n  afterSwap gas (native ETH=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 459848)\nLogs:\n  afterSwap gas (native ETH=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474013)\nLogs:\n  afterSwap gas (native ETH=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 473988)\nLogs:\n  afterSwap gas (native ETH=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459400)\nLogs:\n  afterSwap gas (native ETH=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460720)\nLogs:\n  afterSwap gas (native ETH=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 267967)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 521992)\n[PASS] test_RealBuySellExactOutput() (gas: 518416)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 319489)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2498601)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 224063)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 333874)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 319879)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1882455)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 96931)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 50.51ms (89.18ms CPU time)\n\nRan 27 tests for test/SequencerState.t.sol:SequencerStateTest\n[PASS] testFuzz_MutationBoundsAndOnlySelectedBits(uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 6840, ~: 6583)\n[PASS] testFuzz_PackingRoundtrip(uint256,uint256) (runs: 512, μ: 2241, ~: 2241)\n[PASS] test_BassDegreeNegativeTickAndMinInt24() (gas: 34325)\n[PASS] test_BuySetsAndSellClearsOnlySelectedBit() (gas: 10916)\n[PASS] test_CountsWrapWithoutRevert() (gas: 6080)\n[PASS] test_EmaSameBlockAndCap() (gas: 11078)\n[PASS] test_EmaUint32MaxDoesNotOverflowAndBpmClamps() (gas: 11556)\n[PASS] test_EuclidTableMatchesSpecLoop() (gas: 33056)\n[PASS] test_ExactBitLayoutAndSignedFields() (gas: 1750)\n[PASS] test_FirstSwapAtTimestampZero() (gas: 10466)\n[PASS] test_FirstSwapKeepsEmaEvenWithHugeTimestamp() (gas: 5420)\n[PASS] test_HashUsesFourThreeEightBytes() (gas: 6177)\n[PASS] test_InitialState() (gas: 1791)\n[PASS] test_ModeBoundaries() (gas: 46701)\n[PASS] test_NonWhaleHasNoDropMask() (gas: 5895)\n[PASS] test_PageAloneDoesNotEmitMovement() (gas: 5633)\n[PASS] test_PressureSignedDivisionRoundsTowardZero() (gas: 10843)\n[PASS] test_ReleaseCountPreserved() (gas: 5837)\n[PASS] test_SellBassBothHashBranches() (gas: 845716)\n[PASS] test_ThresholdEdges() (gas: 79118)\n[PASS] test_TimestampWrapUsesZeroInterval() (gas: 5922)\n[PASS] test_WhaleAndPageHaveSeparateIncrements() (gas: 5763)\n[PASS] test_WhaleBassStillUsesStepAndMovementUnchanged() (gas: 10393)\n[PASS] test_WhaleBuyFillsEveryKWithRotation() (gas: 129051)\n[PASS] test_WhaleBuyRotationWraps() (gas: 113988)\n[PASS] test_WhaleSellWipesEachTrackIncludingKick() (gas: 34695)\n[PASS] test_ZeroSlot1IsReachableAfter38Swaps() (gas: 216155)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 50.49ms (69.16ms CPU time)\n\nRan 2 tests for test/Vectors.t.sol:VectorsTest\n[PASS] test_GenerateVectors() (gas: 114679552)\n[PASS] test_GenerateVectorsV2() (gas: 198771842)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 288.10ms (310.13ms CPU time)\n\nRan 11 test suites in 289.87ms (681.15ms CPU time): 208 tests passed, 0 failed, 0 skipped (208 total tests)\n","passed":true},{"durationMs":90,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PulseTreasury.burn()\",\"PulseTreasury.pulse()\",\"PulseTreasury.receive()\",\"PulseTreasury.unlockCallback(bytes)\",\"SequencerHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"SequencerHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"SequencerToken.approve(address,uint256)\",\"SequencerToken.transfer(address,uint256)\",\"SequencerToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":110,\"DEPENDENCIES.md\":16,\"DEPENDENCY_SHA256SUMS\":86,\"GAS.md\":82,\"IMD_LAUNCH_NOTES.md\":70,\"README.md\":43,\"SEPOLIA-V2.md\":146,\"SPEC.md\":250,\"TREASURY-RUNBOOK.md\":78,\"deployments/sepolia-v2.json\":93,\"deployments/sepolia.json\":188,\"foundry.toml\":23,\"gas-report.txt\":387,\"launch.reference.json\":33,\"script/DeploySepolia.s.sol\":74,\"script/DeployTreasury.s.sol\":43,\"script/SimRouter.sol\":108,\"scripts/validate-vectors.py\":125,\"spec/vectors-v2.json\":555,\"spec/vectors.json\":4474,\"src/PulseTreasury.sol\":206,\"src/QuoteCalibration.sol\":42,\"src/SequencerHook.sol\":267,\"src/SequencerState.sol\":354,\"src/SequencerToken.sol\":56,\"test/PulseTreasury.t.sol\":479,\"test/SequencerGasV2.t.sol\":45,\"test/SequencerHook.t.sol\":701,\"test/SequencerState.t.sol\":422,\"test/SequencerToken.t.sol\":59,\"test/SequencerV2.t.sol\":223,\"test/Vectors.t.sol\":521,\"test/helpers/MockQuote.sol\":34,\"test/helpers/PoolRouter.sol\":95,\"vectors.schema.json\":310},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":3616,"exitCode":0,"name":"slither","output":"[medium/high] incorrect-equality at src/PulseTreasury.sol:173: PulseTreasury.burn() (src/PulseTreasury.sol#173-178) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PulseTreasury.sol:142: PulseTreasury.pulse() (src/PulseTreasury.sol#142-154) uses a dangerous strict equality:\n[medium/medium] uninitialized-local at src/SequencerState.sol:332: SequencerState.accumulate(uint64,uint8,uint8,bool).offset (src/SequencerState.sol#332) is a local variable never initialized\n[medium/medium] uninitialized-local at src/SequencerState.sol:314: SequencerState.accumulate(uint64,uint8,uint8,bool).found (src/SequencerState.sol#314) is a local variable never initialized\n[medium/medium] uninitialized-local at src/SequencerHook.sol:209: SequencerHook.whaleThreshold().tick (src/SequencerHook.sol#209) is a local variable never initialized\n[medium/medium] uninitialized-local at src/SequencerState.sol:252: SequencerState.log2Fixed(uint128).m (src/SequencerState.sol#252) is a local variable never initialized\n[medium/medium] unused-return at src/SequencerHook.sol:208: SequencerHook.whaleThreshold() (src/SequencerHook.sol#208-212) ignores return value by (None,tick,None,None) = poolManager.getSlot0(poolId) (src/SequencerHook.sol#210)\n[medium/medium] unused-return at src/PulseTreasury.sol:157: PulseTreasury.unlockCallback(bytes) (src/PulseTreasury.sol#157-170) ignores return value by poolManager.settle{value: paid}() (src/PulseTreasury.sol#167)\n[medium/medium] unused-return at src/PulseTreasury.sol:142: PulseTreasury.pulse() (src/PulseTreasury.sol#142-154) ignores return value by (sqrtPriceX96,None,None,None) = poolManager.getSlot0(poolId) (src/PulseTreasury.sol#147)\n[medium/medium] unused-return at src/SequencerHook.sol:161: SequencerHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/SequencerHook.sol#161-192) ignores return value by (None,tick,None,None) = poolManager.getSlot0(id) (src/SequencerHook.sol#172)\n[low/medium] missing-zero-check at src/SequencerHook.sol:149: SequencerHook.afterInitialize(address,PoolKey,uint160,int24).sender (src/SequencerHook.sol#149) lacks a zero-check on :\n[low/medium] reentrancy-events at src/PulseTreasury.sol:173: Reentrancy in PulseTreasury.burn() (src/PulseTreasury.sol#173-178):\n[low/medium] reentrancy-events at src/PulseTreasury.sol:142: Reentrancy in PulseTreasury.pulse() (src/PulseTreasury.sol#142-154):\n[low/medium] timestamp at src/PulseTreasury.sol:142: PulseTreasury.pulse() (src/PulseTreasury.sol#142-154) uses timestamp for comparisons\n[low/medium] timestamp at src/SequencerHook.sol:161: SequencerHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/SequencerHook.sol#161-192) uses timestamp for comparisons\n[low/medium] timestamp at src/PulseTreasury.sol:131: PulseTreasury.nextPulse() (src/PulseTreasury.sol#131-139) uses timestamp for comparisons","passed":true},{"durationMs":484,"exitCode":0,"name":"aderyn","output":"[high] contract-locks-ether at src/PulseTreasury.sol:53: Contract locks Ether without a withdraw function\n[high] reentrancy-state-change at src/PulseTreasury.sol:98: Reentrancy: State change after external call\n[low] empty-require-revert at src/PulseTreasury.sol:176: Empty `require()` / `revert()` Statement\n[low] internal-function-used-once at src/SequencerState.sol:70: Internal Function Used Only Once (5 places)\n[low] large-numeric-literal at src/PulseTreasury.sol:148: Large Numeric Literal\n[low] literal-instead-of-constant at src/PulseTreasury.sol:182: Literal Instead of Constant (133 places)\n[low] missing-inheritance at src/SequencerToken.sol:5: Missing Inheritance\n[low] state-change-without-event at src/SequencerHook.sol:149: State Change Without Event\n[low] state-no-address-check at src/SequencerHook.sol:154: Address State Variable Set Without Checks\n[low] unchecked-return at src/SequencerHook.sol:145: Unchecked Return\n[low] unsafe-erc20-operation at src/PulseTreasury.sol:176: Unsafe ERC20 Operation","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"9b6bffa7b4f1bd89a59271112b0a091185fad62c355b6082776ef5b3ceb607a3","verifiedTreeHash":"ea939ba4a20ea32eb92eefea549e032aa053b776","verifierVersion":"0.1.0+6a374fcd"},{"checks":[{"durationMs":189698,"exitCode":0,"name":"build","output":"Compiling 85 files with Solc 0.8.26\nSolc 0.8.26 finished in 189.46s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> test/SequencerV2.t.sol:185:17:\n    |\n185 |                 uint8 st = uint8((uint256(step) + i) % 16);\n    |                 ^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/SequencerV2.t.sol:198:34:\n    |\n198 |         (uint64 actual, uint8 t, uint8 st, bool noop) = S.accumulate(pattern, track, step, buy);\n    |                                  ^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:311:22:\n    |\n311 |         uint64 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:317:36:\n    |\n317 |                 uint64 candidate = uint64(1) << (uint256(next) * 16 + step);\n    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:349:23:\n    |\n349 |                 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n  --> test/SequencerState.t.sol:98:22:\n   |\n98 |         uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:300:41:\n    |\n300 |         assertEq((oldBass ^ a.bass) & ~(uint64(15) << (uint256(m.step) * 4)), 0);\n    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:303:26:\n    |\n303 |             uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:309:32:\n    |\n309 |             uint64 trackBits = uint64(0xffff) << (uint256(m.track) * 16);\n    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:376:35:\n    |\n376 |             assertEq(a.pattern | (uint64(0xffff) << (track * 16)), type(uint64).max, \"other tracks untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:390:35:\n    |\n390 |             assertEq(a.pattern | (uint64(0xffff) << (uint256(m.track) * 16)), type(uint64).max, \"others untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerHook.t.sol:309:22:\n    |\n309 |         s.pattern ^= uint64(1) << (32 + ((step + 15) & 15));\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:109:43:\n    |\n109 |         s.pattern = 0x0000ffff0fffffff ^ (uint64(1) << (32 + step)); // full kick + hat rows, 12 snare bits\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:117:43:\n    |\n117 |         s.pattern = 0x0000ffff0ffffffe ^ (uint64(1) << (32 + step));\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:195:26:\n    |\n195 |             uint64 bit = uint64(1) << (uint256(wantTrack) * 16 + wantStep);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:356:68:\n    |\n356 |                         if (column & (1 << row) != 0) s.pattern |= uint64(1) << (row * 16 + step);\n    |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:365:45:\n    |\n365 |             s.pattern = type(uint64).max ^ (uint64(1) << (32 + st));\n    |                                             ^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/SequencerHook.t.sol:171:5:\n    |\n171 |     function thresholdsAt(int24 tick) internal view returns (S.Thresholds memory) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":1001,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/SequencerGasV2.t.sol:SequencerGasV2Test\n[PASS] test_GasHeatDropIncrement() (gas: 1605885)\nLogs:\n  heat/drop increment normal buy: 436\n  heat/drop increment saturated buy: 496\n  heat/drop increment sell: 338\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.24ms (781.54µs CPU time)\n\nRan 27 tests for test/SequencerState.t.sol:SequencerStateTest\n[PASS] testFuzz_MutationBoundsAndOnlySelectedBits(uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 6840, ~: 6583)\n[PASS] testFuzz_PackingRoundtrip(uint256,uint256) (runs: 512, μ: 2241, ~: 2241)\n[PASS] test_BassDegreeNegativeTickAndMinInt24() (gas: 34325)\n[PASS] test_BuySetsAndSellClearsOnlySelectedBit() (gas: 10916)\n[PASS] test_CountsWrapWithoutRevert() (gas: 6080)\n[PASS] test_EmaSameBlockAndCap() (gas: 11078)\n[PASS] test_EmaUint32MaxDoesNotOverflowAndBpmClamps() (gas: 11556)\n[PASS] test_EuclidTableMatchesSpecLoop() (gas: 33056)\n[PASS] test_ExactBitLayoutAndSignedFields() (gas: 1750)\n[PASS] test_FirstSwapAtTimestampZero() (gas: 10466)\n[PASS] test_FirstSwapKeepsEmaEvenWithHugeTimestamp() (gas: 5420)\n[PASS] test_HashUsesFourThreeEightBytes() (gas: 6177)\n[PASS] test_InitialState() (gas: 1791)\n[PASS] test_ModeBoundaries() (gas: 46701)\n[PASS] test_NonWhaleHasNoDropMask() (gas: 5895)\n[PASS] test_PageAloneDoesNotEmitMovement() (gas: 5633)\n[PASS] test_PressureSignedDivisionRoundsTowardZero() (gas: 10843)\n[PASS] test_ReleaseCountPreserved() (gas: 5837)\n[PASS] test_SellBassBothHashBranches() (gas: 845716)\n[PASS] test_ThresholdEdges() (gas: 79118)\n[PASS] test_TimestampWrapUsesZeroInterval() (gas: 5922)\n[PASS] test_WhaleAndPageHaveSeparateIncrements() (gas: 5763)\n[PASS] test_WhaleBassStillUsesStepAndMovementUnchanged() (gas: 10393)\n[PASS] test_WhaleBuyFillsEveryKWithRotation() (gas: 129051)\n[PASS] test_WhaleBuyRotationWraps() (gas: 113988)\n[PASS] test_WhaleSellWipesEachTrackIncludingKick() (gas: 34695)\n[PASS] test_ZeroSlot1IsReachableAfter38Swaps() (gas: 216155)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 65.13ms (152.46ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote0Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23440901)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77338)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9030)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109709)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82202)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473765)\n[PASS] test_GasColdFirstBuy() (gas: 440505)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474897)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476707)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465610)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 460072)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 474242)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459615)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460960)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286606)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 576000)\n[PASS] test_RealBuySellExactOutput() (gas: 572422)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 349054)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2518009)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 235885)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 363435)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 349447)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2044896)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97170)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 80.31ms (158.79ms CPU time)\n\nRan 24 tests for test/PulseTreasury.t.sol:PulseTreasuryTest\n[PASS] testFuzz_Exp2FixedInvertsLog2Fixed(uint16) (runs: 512, μ: 7242, ~: 7274)\n[PASS] testFuzz_HatClassAcrossEma(uint16) (runs: 512, μ: 13344, ~: 13402)\n[PASS] test_BurnSendsAllIdmToDead() (gas: 320763)\n[PASS] test_CannotDriveTreasuryFromAnotherUnlock() (gas: 378349)\n[PASS] test_ConstantsMatchHookCalibration() (gas: 51551)\n[PASS] test_ConstructorValidatesKey() (gas: 17971)\n[PASS] test_EmaAtFloorFilesGlitchNotHat() (gas: 13150)\n[PASS] test_FirstSwapEverCanBeAPulse() (gas: 188853)\n[PASS] test_GasPulse() (gas: 329253)\nLogs:\n  pulse() gas (cold, normal grid): 144104\n\n[PASS] test_GasPulseSaturated() (gas: 212382)\nLogs:\n  pulse() gas (cold, saturated grid): 170421\n\n[PASS] test_PriceLimitBoundsMoveAndKeepsUnspentEth() (gas: 348048)\n[PASS] test_PulseBeforeIdleReverts() (gas: 401365)\n[PASS] test_PulseDustReverts() (gas: 69089)\n[PASS] test_PulseHighEmaUsesMax() (gas: 188228)\n[PASS] test_PulseIsHatBuyRecordedByHook() (gas: 414284)\n[PASS] test_PulseLowEmaUsesMin() (gas: 188272)\n[PASS] test_PulseOnSaturatedGridAddsHeat() (gas: 217716)\n[PASS] test_PulseSizeClamps() (gas: 45601)\n[PASS] test_PulseSmallBalanceUsesOnePercent() (gas: 169415)\n[PASS] test_PulseWithNoFillRevertsAndLeavesStateUntouched() (gas: 751214)\n[PASS] test_RealTradePostponesPulse() (gas: 326898)\n[PASS] test_ReceivesEthUnderStipendAndIdm() (gas: 100215)\n[PASS] test_SixteenPulsesInSilenceCompleteTrack() (gas: 2708842)\n[PASS] test_UnlockCallbackRejectsOthers() (gas: 62275)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 84.25ms (97.68ms CPU time)\n\nRan 28 tests for test/SequencerHook.t.sol:SequencerHookNativeEthLaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76860)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440677)\nLogs:\n  afterSwap gas (native ETH=currency0): 34661\n\n[PASS] test_GasColdFirstSell() (gas: 443594)\nLogs:\n  afterSwap gas (native ETH=currency0): 37589\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 478213)\nLogs:\n  afterSwap gas (native ETH=currency0): 55074\n\n[PASS] test_GasColdScanSpill() (gas: 476842)\nLogs:\n  afterSwap gas (native ETH=currency0): 38946\n\n[PASS] test_GasColdTrackComplete() (gas: 465781)\nLogs:\n  afterSwap gas (native ETH=currency0): 42751\n\n[PASS] test_GasColdWhale() (gas: 460695)\nLogs:\n  afterSwap gas (native ETH=currency0): 37875\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474860)\nLogs:\n  afterSwap gas (native ETH=currency0): 38030\n\n[PASS] test_GasColdWhalePage64() (gas: 474836)\nLogs:\n  afterSwap gas (native ETH=currency0): 37793\n\n[PASS] test_GasColdWhaleSell() (gas: 460248)\nLogs:\n  afterSwap gas (native ETH=currency0): 37567\n\n[PASS] test_GasColdWorstNormal() (gas: 461120)\nLogs:\n  afterSwap gas (native ETH=currency0): 38584\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 319294)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99829)\n[PASS] test_RealBuySellExactInput() (gas: 518286)\n[PASS] test_RealBuySellExactOutput() (gas: 514250)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 315660)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2480681)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 216795)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 329615)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 316050)\n[PASS] test_RealWhaleBoundaryAtLaunchFdv() (gas: 819145)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1876869)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97331)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 133.92ms (233.76ms CPU time)\n\nRan 12 tests for test/SequencerV2.t.sol:SequencerV2Test\n[PASS] testFuzz_AccumulateAgainstLoop(uint64,uint8,uint8,bool) (runs: 512, μ: 2583, ~: 2339)\n[PASS] testFuzz_ArbitraryPackedStateNeverReverts(uint256,uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 8976, ~: 8901)\n[PASS] testFuzz_CodecV2(uint256,uint256) (runs: 512, μ: 1847, ~: 1847)\n[PASS] testFuzz_WhaleThresholdMonotoneBoundedSymmetric(int24,int24) (runs: 512, μ: 4824, ~: 4910)\n[PASS] test_DropSnapshotBeforeResetAndCountersWrap() (gas: 14094)\n[PASS] test_EthCalibration() (gas: 2533)\n[PASS] test_LayoutV2() (gas: 7616)\n[PASS] test_Log2FixedKnownValues() (gas: 398)\n[PASS] test_SaturationUsesPostWritePopcount44() (gas: 16986)\n[PASS] test_SilenceBoundaryAndSellCooling() (gas: 39141)\n[PASS] test_WhaleLeavesHeatButSilenceStillResets() (gas: 31919)\n[PASS] test_WhaleThresholdCalibrationAndClamps() (gas: 20193)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 133.90ms (295.29ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookNativeEthTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76838)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440277)\nLogs:\n  afterSwap gas (native ETH=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443194)\nLogs:\n  afterSwap gas (native ETH=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474662)\nLogs:\n  afterSwap gas (native ETH=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476472)\nLogs:\n  afterSwap gas (native ETH=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465382)\nLogs:\n  afterSwap gas (native ETH=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 459848)\nLogs:\n  afterSwap gas (native ETH=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474013)\nLogs:\n  afterSwap gas (native ETH=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 473988)\nLogs:\n  afterSwap gas (native ETH=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459400)\nLogs:\n  afterSwap gas (native ETH=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460720)\nLogs:\n  afterSwap gas (native ETH=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 267967)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 521992)\n[PASS] test_RealBuySellExactOutput() (gas: 518416)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 319489)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2498601)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 224063)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 333874)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 319879)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1882455)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 96931)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 133.92ms (222.73ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1LaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 441014)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34596\n\n[PASS] test_GasColdFirstSell() (gas: 443444)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37602\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475406)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51858\n\n[PASS] test_GasColdScanSpill() (gas: 477129)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38824\n\n[PASS] test_GasColdTrackComplete() (gas: 466119)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42687\n\n[PASS] test_GasColdWhale() (gas: 461051)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37810\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 475236)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37965\n\n[PASS] test_GasColdWhalePage64() (gas: 474708)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37664\n\n[PASS] test_GasColdWhaleSell() (gas: 460174)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37580\n\n[PASS] test_GasColdWorstNormal() (gas: 461469)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38519\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 314533)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99680)\n[PASS] test_RealBuySellExactInput() (gas: 571772)\n[PASS] test_RealBuySellExactOutput() (gas: 568094)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 344933)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2477190)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 228391)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 359063)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 345326)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2034841)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97815)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 150.48ms (180.33ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 440621)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34203\n\n[PASS] test_GasColdFirstSell() (gas: 442973)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37131\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475013)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51465\n\n[PASS] test_GasColdScanSpill() (gas: 476823)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38518\n\n[PASS] test_GasColdTrackComplete() (gas: 465726)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42294\n\n[PASS] test_GasColdWhale() (gas: 460210)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37349\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474395)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37504\n\n[PASS] test_GasColdWhalePage64() (gas: 473931)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37267\n\n[PASS] test_GasColdWhaleSell() (gas: 459255)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37041\n\n[PASS] test_GasColdWorstNormal() (gas: 461076)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38126\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286579)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 98940)\n[PASS] test_RealBuySellExactInput() (gas: 576300)\n[PASS] test_RealBuySellExactOutput() (gas: 566886)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 343330)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2506140)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 230306)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 357596)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 343723)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2041116)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97344)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 163.21ms (157.91ms CPU time)\n\nRan 2 tests for test/Vectors.t.sol:VectorsTest\n[PASS] test_GenerateVectors() (gas: 114679552)\n[PASS] test_GenerateVectorsV2() (gas: 198771842)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 705.66ms (729.67ms CPU time)\n\nRan 6 tests for test/SequencerToken.t.sol:SequencerTokenTest\n[PASS] testFuzz_TransferConservesSupply(uint256) (runs: 512, μ: 67969, ~: 68141)\n[PASS] test_FactoryReceivesEntireFixedSupply() (gas: 28453)\n[PASS] test_InvalidTransfersRevert() (gas: 81362)\n[PASS] test_SelfTransferAndZeroTransferPreserveSupply() (gas: 67183)\n[PASS] test_TransferAndFiniteAllowance() (gas: 125489)\n[PASS] test_UnlimitedAllowancePreserved() (gas: 112218)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 706.32ms (706.74ms CPU time)\n\nRan 11 test suites in 715.56ms (2.36s CPU time): 208 tests passed, 0 failed, 0 skipped (208 total tests)\n","passed":true},{"durationMs":197,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PulseTreasury.burn()\",\"PulseTreasury.pulse()\",\"PulseTreasury.receive()\",\"PulseTreasury.unlockCallback(bytes)\",\"SequencerHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"SequencerHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"SequencerToken.approve(address,uint256)\",\"SequencerToken.transfer(address,uint256)\",\"SequencerToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":110,\"DEPENDENCIES.md\":16,\"DEPENDENCY_SHA256SUMS\":86,\"GAS.md\":82,\"IMD_LAUNCH_NOTES.md\":70,\"README.md\":43,\"SEPOLIA-V2.md\":146,\"SPEC.md\":250,\"TREASURY-RUNBOOK.md\":78,\"deployments/sepolia-v2.json\":93,\"deployments/sepolia.json\":188,\"foundry.toml\":23,\"gas-report.txt\":387,\"launch.json\":32,\"launch.reference.json\":33,\"script/DeploySepolia.s.sol\":74,\"script/DeployTreasury.s.sol\":43,\"script/SimRouter.sol\":108,\"scripts/validate-vectors.py\":125,\"spec/vectors-v2.json\":555,\"spec/vectors.json\":4474,\"src/PulseTreasury.sol\":206,\"src/QuoteCalibration.sol\":42,\"src/SequencerHook.sol\":267,\"src/SequencerState.sol\":354,\"src/SequencerToken.sol\":56,\"test/PulseTreasury.t.sol\":479,\"test/SequencerGasV2.t.sol\":45,\"test/SequencerHook.t.sol\":701,\"test/SequencerState.t.sol\":422,\"test/SequencerToken.t.sol\":59,\"test/SequencerV2.t.sol\":223,\"test/Vectors.t.sol\":521,\"test/helpers/MockQuote.sol\":34,\"test/helpers/PoolRouter.sol\":95,\"vectors.schema.json\":310},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"a5c4854bfaac316bbe4604400f930c63f4bfb04c8fcb0d23c4cbe832adb16792","verifiedTreeHash":"98695a79831fed6483e3da52343fb527be65743a","verifierVersion":"0.1.0+6a374fcd"},{"checks":[{"durationMs":97019,"exitCode":0,"name":"build","output":"Compiling 85 files with Solc 0.8.26\nSolc 0.8.26 finished in 96.91s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> test/SequencerV2.t.sol:185:17:\n    |\n185 |                 uint8 st = uint8((uint256(step) + i) % 16);\n    |                 ^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/SequencerV2.t.sol:198:34:\n    |\n198 |         (uint64 actual, uint8 t, uint8 st, bool noop) = S.accumulate(pattern, track, step, buy);\n    |                                  ^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:311:22:\n    |\n311 |         uint64 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:317:36:\n    |\n317 |                 uint64 candidate = uint64(1) << (uint256(next) * 16 + step);\n    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:349:23:\n    |\n349 |                 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n  --> test/SequencerState.t.sol:98:22:\n   |\n98 |         uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:300:41:\n    |\n300 |         assertEq((oldBass ^ a.bass) & ~(uint64(15) << (uint256(m.step) * 4)), 0);\n    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:303:26:\n    |\n303 |             uint64 bit = uint64(1) << (uint256(m.track) * 16 + m.step);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:309:32:\n    |\n309 |             uint64 trackBits = uint64(0xffff) << (uint256(m.track) * 16);\n    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:376:35:\n    |\n376 |             assertEq(a.pattern | (uint64(0xffff) << (track * 16)), type(uint64).max, \"other tracks untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerState.t.sol:390:35:\n    |\n390 |             assertEq(a.pattern | (uint64(0xffff) << (uint256(m.track) * 16)), type(uint64).max, \"others untouched\");\n    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerHook.t.sol:309:22:\n    |\n309 |         s.pattern ^= uint64(1) << (32 + ((step + 15) & 15));\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:109:43:\n    |\n109 |         s.pattern = 0x0000ffff0fffffff ^ (uint64(1) << (32 + step)); // full kick + hat rows, 12 snare bits\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:117:43:\n    |\n117 |         s.pattern = 0x0000ffff0ffffffe ^ (uint64(1) << (32 + step));\n    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/SequencerV2.t.sol:195:26:\n    |\n195 |             uint64 bit = uint64(1) << (uint256(wantTrack) * 16 + wantStep);\n    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:356:68:\n    |\n356 |                         if (column & (1 << row) != 0) s.pattern |= uint64(1) << (row * 16 + step);\n    |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> test/Vectors.t.sol:365:45:\n    |\n365 |             s.pattern = type(uint64).max ^ (uint64(1) << (32 + st));\n    |                                             ^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/SequencerHook.t.sol:171:5:\n    |\n171 |     function thresholdsAt(int24 tick) internal view returns (S.Thresholds memory) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":495,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/SequencerGasV2.t.sol:SequencerGasV2Test\n[PASS] test_GasHeatDropIncrement() (gas: 1605885)\nLogs:\n  heat/drop increment normal buy: 436\n  heat/drop increment saturated buy: 496\n  heat/drop increment sell: 338\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 765.84µs (553.63µs CPU time)\n\nRan 6 tests for test/SequencerToken.t.sol:SequencerTokenTest\n[PASS] testFuzz_TransferConservesSupply(uint256) (runs: 512, μ: 67920, ~: 68153)\n[PASS] test_FactoryReceivesEntireFixedSupply() (gas: 28453)\n[PASS] test_InvalidTransfersRevert() (gas: 81362)\n[PASS] test_SelfTransferAndZeroTransferPreserveSupply() (gas: 67183)\n[PASS] test_TransferAndFiniteAllowance() (gas: 125489)\n[PASS] test_UnlimitedAllowancePreserved() (gas: 112218)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.65ms (7.71ms CPU time)\n\nRan 27 tests for test/SequencerState.t.sol:SequencerStateTest\n[PASS] testFuzz_MutationBoundsAndOnlySelectedBits(uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 6855, ~: 6580)\n[PASS] testFuzz_PackingRoundtrip(uint256,uint256) (runs: 512, μ: 2241, ~: 2241)\n[PASS] test_BassDegreeNegativeTickAndMinInt24() (gas: 34325)\n[PASS] test_BuySetsAndSellClearsOnlySelectedBit() (gas: 10916)\n[PASS] test_CountsWrapWithoutRevert() (gas: 6080)\n[PASS] test_EmaSameBlockAndCap() (gas: 11078)\n[PASS] test_EmaUint32MaxDoesNotOverflowAndBpmClamps() (gas: 11556)\n[PASS] test_EuclidTableMatchesSpecLoop() (gas: 33056)\n[PASS] test_ExactBitLayoutAndSignedFields() (gas: 1750)\n[PASS] test_FirstSwapAtTimestampZero() (gas: 10466)\n[PASS] test_FirstSwapKeepsEmaEvenWithHugeTimestamp() (gas: 5420)\n[PASS] test_HashUsesFourThreeEightBytes() (gas: 6177)\n[PASS] test_InitialState() (gas: 1791)\n[PASS] test_ModeBoundaries() (gas: 46701)\n[PASS] test_NonWhaleHasNoDropMask() (gas: 5895)\n[PASS] test_PageAloneDoesNotEmitMovement() (gas: 5633)\n[PASS] test_PressureSignedDivisionRoundsTowardZero() (gas: 10843)\n[PASS] test_ReleaseCountPreserved() (gas: 5837)\n[PASS] test_SellBassBothHashBranches() (gas: 845716)\n[PASS] test_ThresholdEdges() (gas: 79118)\n[PASS] test_TimestampWrapUsesZeroInterval() (gas: 5922)\n[PASS] test_WhaleAndPageHaveSeparateIncrements() (gas: 5763)\n[PASS] test_WhaleBassStillUsesStepAndMovementUnchanged() (gas: 10393)\n[PASS] test_WhaleBuyFillsEveryKWithRotation() (gas: 129051)\n[PASS] test_WhaleBuyRotationWraps() (gas: 113988)\n[PASS] test_WhaleSellWipesEachTrackIncludingKick() (gas: 34695)\n[PASS] test_ZeroSlot1IsReachableAfter38Swaps() (gas: 216155)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 9.49ms (25.03ms CPU time)\n\nRan 30 tests for test/PulseTreasury.t.sol:PulseTreasuryTest\n[PASS] testFuzz_Exp2FixedInvertsLog2Fixed(uint16) (runs: 512, μ: 7400, ~: 7455)\n[PASS] testFuzz_HatClassAcrossEma(uint16) (runs: 512, μ: 14081, ~: 14134)\n[PASS] test_BurnSendsAllIdmToDead() (gas: 324275)\n[PASS] test_CannotDriveTreasuryFromAnotherUnlock() (gas: 383927)\n[PASS] test_ConstantsMatchHookCalibration() (gas: 51903)\n[PASS] test_ConstructorValidatesKey() (gas: 18103)\n[PASS] test_EmaAtFloorFilesGlitchNotHat() (gas: 14014)\n[PASS] test_FirstSwapEverCanBeAPulse() (gas: 201060)\n[PASS] test_GasPulse() (gas: 332942)\nLogs:\n  pulse() gas (cold, normal grid): 147572\n\n[PASS] test_GasPulseParkedAtMaxTick() (gas: 1443028)\nLogs:\n  pulse() gas (cold, price parked at MAX_TICK, liquidity at tick 0): 675671\n\n[PASS] test_GasPulseSaturated() (gas: 215851)\nLogs:\n  pulse() gas (cold, saturated grid): 173889\n\n[PASS] test_NextPulseAgreesWithPulse() (gas: 2832955)\n[PASS] test_ParkedPulseStopsAtOnePercentUnderTheAnchor() (gas: 2119482)\n[PASS] test_PriceAnchorInsideLiquidityIsSlot0() (gas: 29436)\n[PASS] test_PriceLimitBoundsMoveAndKeepsUnspentEth() (gas: 351710)\n[PASS] test_PulseBeforeIdleReverts() (gas: 413887)\n[PASS] test_PulseDustReverts() (gas: 69327)\n[PASS] test_PulseHighEmaUsesMax() (gas: 191718)\n[PASS] test_PulseIsHatBuyRecordedByHook() (gas: 417919)\n[PASS] test_PulseLowEmaUsesMin() (gas: 191806)\n[PASS] test_PulseOnSaturatedGridAddsHeat() (gas: 221316)\n[PASS] test_PulseSizeClamps() (gas: 45909)\n[PASS] test_PulseSmallBalanceUsesOnePercent() (gas: 172883)\n[PASS] test_PulseStillBuysAfterAFreeSellParkedThePrice() (gas: 2128316)\n[PASS] test_PulseWithDustLiquidityRevertsNoFill() (gas: 547028)\n[PASS] test_PulseWithNoFillRevertsAndLeavesStateUntouched() (gas: 1416413)\n[PASS] test_RealTradePostponesPulse() (gas: 327113)\n[PASS] test_ReceivesEthUnderStipendAndIdm() (gas: 100325)\n[PASS] test_SixteenPulsesInSilenceCompleteTrack() (gas: 2764328)\n[PASS] test_UnlockCallbackRejectsOthers() (gas: 62451)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 58.91ms (59.54ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookNativeEthTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76838)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440277)\nLogs:\n  afterSwap gas (native ETH=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443194)\nLogs:\n  afterSwap gas (native ETH=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474662)\nLogs:\n  afterSwap gas (native ETH=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476472)\nLogs:\n  afterSwap gas (native ETH=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465382)\nLogs:\n  afterSwap gas (native ETH=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 459848)\nLogs:\n  afterSwap gas (native ETH=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474013)\nLogs:\n  afterSwap gas (native ETH=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 473988)\nLogs:\n  afterSwap gas (native ETH=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459400)\nLogs:\n  afterSwap gas (native ETH=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460720)\nLogs:\n  afterSwap gas (native ETH=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 267967)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 521992)\n[PASS] test_RealBuySellExactOutput() (gas: 518416)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 319489)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2498601)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 224063)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 333874)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 319879)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1882455)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 96931)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 59.72ms (80.49ms CPU time)\n\nRan 28 tests for test/SequencerHook.t.sol:SequencerHookNativeEthLaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23441321)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 76860)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9028)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109689)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 81705)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473203)\n[PASS] test_GasColdFirstBuy() (gas: 440677)\nLogs:\n  afterSwap gas (native ETH=currency0): 34661\n\n[PASS] test_GasColdFirstSell() (gas: 443594)\nLogs:\n  afterSwap gas (native ETH=currency0): 37589\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 478213)\nLogs:\n  afterSwap gas (native ETH=currency0): 55074\n\n[PASS] test_GasColdScanSpill() (gas: 476842)\nLogs:\n  afterSwap gas (native ETH=currency0): 38946\n\n[PASS] test_GasColdTrackComplete() (gas: 465781)\nLogs:\n  afterSwap gas (native ETH=currency0): 42751\n\n[PASS] test_GasColdWhale() (gas: 460695)\nLogs:\n  afterSwap gas (native ETH=currency0): 37875\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474860)\nLogs:\n  afterSwap gas (native ETH=currency0): 38030\n\n[PASS] test_GasColdWhalePage64() (gas: 474836)\nLogs:\n  afterSwap gas (native ETH=currency0): 37793\n\n[PASS] test_GasColdWhaleSell() (gas: 460248)\nLogs:\n  afterSwap gas (native ETH=currency0): 37567\n\n[PASS] test_GasColdWorstNormal() (gas: 461120)\nLogs:\n  afterSwap gas (native ETH=currency0): 38584\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 319294)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99829)\n[PASS] test_RealBuySellExactInput() (gas: 518286)\n[PASS] test_RealBuySellExactOutput() (gas: 514250)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 315660)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2480681)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 216795)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 329615)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 316050)\n[PASS] test_RealWhaleBoundaryAtLaunchFdv() (gas: 819145)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 1876869)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97331)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 59.85ms (85.25ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote0Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 23440901)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77338)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9030)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109709)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82202)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 23473765)\n[PASS] test_GasColdFirstBuy() (gas: 440505)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 34261\n\n[PASS] test_GasColdFirstSell() (gas: 443259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37189\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 474897)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 51523\n\n[PASS] test_GasColdScanSpill() (gas: 476707)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38576\n\n[PASS] test_GasColdTrackComplete() (gas: 465610)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 42352\n\n[PASS] test_GasColdWhale() (gas: 460072)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37407\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474259)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37562\n\n[PASS] test_GasColdWhalePage64() (gas: 474242)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37325\n\n[PASS] test_GasColdWhaleSell() (gas: 459615)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 37099\n\n[PASS] test_GasColdWorstNormal() (gas: 460960)\nLogs:\n  afterSwap gas (ERC20 quote=currency0): 38184\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286606)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99057)\n[PASS] test_RealBuySellExactInput() (gas: 576000)\n[PASS] test_RealBuySellExactOutput() (gas: 572422)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 349054)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2518009)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 235885)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 363435)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 349447)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2044896)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97170)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 60.09ms (70.94ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1Test\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 440621)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34203\n\n[PASS] test_GasColdFirstSell() (gas: 442973)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37131\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475013)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51465\n\n[PASS] test_GasColdScanSpill() (gas: 476823)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38518\n\n[PASS] test_GasColdTrackComplete() (gas: 465726)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42294\n\n[PASS] test_GasColdWhale() (gas: 460210)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37349\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 474395)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37504\n\n[PASS] test_GasColdWhalePage64() (gas: 473931)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37267\n\n[PASS] test_GasColdWhaleSell() (gas: 459255)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37041\n\n[PASS] test_GasColdWorstNormal() (gas: 461076)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38126\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 286579)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 98940)\n[PASS] test_RealBuySellExactInput() (gas: 576300)\n[PASS] test_RealBuySellExactOutput() (gas: 566886)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 343330)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2506140)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 230306)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 357596)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 343723)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2041116)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97344)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 62.35ms (82.52ms CPU time)\n\nRan 27 tests for test/SequencerHook.t.sol:SequencerHookERC20Quote1LaunchFdvTest\n[PASS] test_BindsTheQuoteTheFactoryOpensAndRejectsASecondPool() (gas: 42772638)\n[PASS] test_CannotReinitializeOrUseAnotherPool() (gas: 77490)\n[PASS] test_ConstructorRejectsBadAddressesAndThresholds() (gas: 9026)\n[PASS] test_DisabledCallbacksRefuse() (gas: 109705)\n[PASS] test_EnabledCallbacksRejectNonManager() (gas: 82354)\n[PASS] test_FreshHookOnlyFactoryAndExactPairCanInitialize() (gas: 42806776)\n[PASS] test_GasColdFirstBuy() (gas: 441014)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 34596\n\n[PASS] test_GasColdFirstSell() (gas: 443444)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37602\n\n[PASS] test_GasColdPreviouslyZeroSlot1() (gas: 475406)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 51858\n\n[PASS] test_GasColdScanSpill() (gas: 477129)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38824\n\n[PASS] test_GasColdTrackComplete() (gas: 466119)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 42687\n\n[PASS] test_GasColdWhale() (gas: 461051)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37810\n\n[PASS] test_GasColdWhaleBuyPage64() (gas: 475236)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37965\n\n[PASS] test_GasColdWhalePage64() (gas: 474708)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37664\n\n[PASS] test_GasColdWhaleSell() (gas: 460174)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 37580\n\n[PASS] test_GasColdWorstNormal() (gas: 461469)\nLogs:\n  afterSwap gas (ERC20 quote=currency1): 38519\n\n[PASS] test_LiquidityAddRemoveDoNotMutate() (gas: 314533)\n[PASS] test_PermissionsBindingsAndInitialState() (gas: 99680)\n[PASS] test_RealBuySellExactInput() (gas: 571772)\n[PASS] test_RealBuySellExactOutput() (gas: 568094)\n[PASS] test_RealCountWrapDoesNotBlockSwaps() (gas: 344933)\n[PASS] test_RealPageRolloverAfter64Swaps() (gas: 2477190)\n[PASS] test_RealPartialFillUsesActualDeltaAndPostSwapTick() (gas: 228391)\n[PASS] test_RealTrackCompleteSnapshotAndCompanionEvent() (gas: 359063)\n[PASS] test_RealWhaleAndPage64EventOrder() (gas: 345326)\n[PASS] test_RealWhaleBuyFillsAndWhaleSellDrops() (gas: 2034841)\n[PASS] test_ZeroSeqDeltaIsSellRegardlessOfDirectionAndMinQuoteDeltaSafe() (gas: 97815)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 62.59ms (89.36ms CPU time)\n\nRan 2 tests for test/Vectors.t.sol:VectorsTest\n[PASS] test_GenerateVectors() (gas: 114679552)\n[PASS] test_GenerateVectorsV2() (gas: 198771842)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 375.34ms (389.90ms CPU time)\n\nRan 12 tests for test/SequencerV2.t.sol:SequencerV2Test\n[PASS] testFuzz_AccumulateAgainstLoop(uint64,uint8,uint8,bool) (runs: 512, μ: 2575, ~: 2339)\n[PASS] testFuzz_ArbitraryPackedStateNeverReverts(uint256,uint256,bool,uint128,int24,uint64,uint40) (runs: 512, μ: 8967, ~: 8904)\n[PASS] testFuzz_CodecV2(uint256,uint256) (runs: 512, μ: 1847, ~: 1847)\n[PASS] testFuzz_WhaleThresholdMonotoneBoundedSymmetric(int24,int24) (runs: 512, μ: 4824, ~: 4910)\n[PASS] test_DropSnapshotBeforeResetAndCountersWrap() (gas: 14094)\n[PASS] test_EthCalibration() (gas: 2533)\n[PASS] test_LayoutV2() (gas: 7616)\n[PASS] test_Log2FixedKnownValues() (gas: 398)\n[PASS] test_SaturationUsesPostWritePopcount44() (gas: 16986)\n[PASS] test_SilenceBoundaryAndSellCooling() (gas: 39141)\n[PASS] test_WhaleLeavesHeatButSilenceStillResets() (gas: 31919)\n[PASS] test_WhaleThresholdCalibrationAndClamps() (gas: 20193)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 375.43ms (34.62ms CPU time)\n\nRan 11 test suites in 376.56ms (1.13s CPU time): 214 tests passed, 0 failed, 0 skipped (214 total tests)\n","passed":true},{"durationMs":80,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"PulseTreasury.burn()\",\"PulseTreasury.pulse()\",\"PulseTreasury.receive()\",\"PulseTreasury.unlockCallback(bytes)\",\"SequencerHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"SequencerHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"SequencerToken.approve(address,uint256)\",\"SequencerToken.transfer(address,uint256)\",\"SequencerToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":175,\"DEPENDENCIES.md\":16,\"DEPENDENCY_SHA256SUMS\":86,\"GAS.md\":82,\"IMD_LAUNCH_NOTES.md\":70,\"README.md\":43,\"SEPOLIA-V2.md\":146,\"SPEC.md\":250,\"TREASURY-RUNBOOK.md\":81,\"deployments/sepolia-v2.json\":93,\"deployments/sepolia.json\":188,\"foundry.toml\":23,\"gas-report.txt\":387,\"launch.reference.json\":33,\"script/DeploySepolia.s.sol\":74,\"script/DeployTreasury.s.sol\":43,\"script/SimRouter.sol\":108,\"scripts/validate-vectors.py\":125,\"spec/vectors-v2.json\":555,\"spec/vectors.json\":4474,\"src/PulseTreasury.sol\":248,\"src/QuoteCalibration.sol\":42,\"src/SequencerHook.sol\":267,\"src/SequencerState.sol\":354,\"src/SequencerToken.sol\":56,\"test/PulseTreasury.t.sol\":631,\"test/SequencerGasV2.t.sol\":45,\"test/SequencerHook.t.sol\":701,\"test/SequencerState.t.sol\":422,\"test/SequencerToken.t.sol\":59,\"test/SequencerV2.t.sol\":223,\"test/Vectors.t.sol\":521,\"test/helpers/MockQuote.sol\":34,\"test/helpers/PoolRouter.sol\":95,\"vectors.schema.json\":310},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":5092,"exitCode":0,"name":"slither","output":"[medium/high] incorrect-equality at src/PulseTreasury.sol:215: PulseTreasury.burn() (src/PulseTreasury.sol#215-220) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PulseTreasury.sol:183: PulseTreasury.pulse() (src/PulseTreasury.sol#183-196) uses a dangerous strict equality:\n[medium/medium] uninitialized-local at src/SequencerState.sol:332: SequencerState.accumulate(uint64,uint8,uint8,bool).offset (src/SequencerState.sol#332) is a local variable never initialized\n[medium/medium] uninitialized-local at src/SequencerState.sol:314: SequencerState.accumulate(uint64,uint8,uint8,bool).found (src/SequencerState.sol#314) is a local variable never initialized\n[medium/medium] uninitialized-local at src/SequencerHook.sol:209: SequencerHook.whaleThreshold().tick (src/SequencerHook.sol#209) is a local variable never initialized\n[medium/medium] uninitialized-local at src/SequencerState.sol:252: SequencerState.log2Fixed(uint128).m (src/SequencerState.sol#252) is a local variable never initialized\n[medium/medium] unused-return at src/PulseTreasury.sol:162: PulseTreasury.priceAnchor() (src/PulseTreasury.sol#162-180) ignores return value by (sqrtPriceX96,tick,None,None) = poolManager.getSlot0(poolId) (src/PulseTreasury.sol#164)\n[medium/medium] unused-return at src/PulseTreasury.sol:162: PulseTreasury.priceAnchor() (src/PulseTreasury.sol#162-180) ignores return value by (minWordPos,None) = TickBitmap.position(TickBitmap.compress(TickMath.MIN_TICK,tickSpacing)) (src/PulseTreasury.sol#167)\n[medium/medium] unused-return at src/SequencerHook.sol:208: SequencerHook.whaleThreshold() (src/SequencerHook.sol#208-212) ignores return value by (None,tick,None,None) = poolManager.getSlot0(poolId) (src/SequencerHook.sol#210)\n[medium/medium] unused-return at src/PulseTreasury.sol:199: PulseTreasury.unlockCallback(bytes) (src/PulseTreasury.sol#199-212) ignores return value by poolManager.settle{value: paid}() (src/PulseTreasury.sol#209)\n[medium/medium] unused-return at src/SequencerHook.sol:161: SequencerHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/SequencerHook.sol#161-192) ignores return value by (None,tick,None,None) = poolManager.getSlot0(id) (src/SequencerHook.sol#172)\n[low/medium] missing-zero-check at src/SequencerHook.sol:149: SequencerHook.afterInitialize(address,PoolKey,uint160,int24).sender (src/SequencerHook.sol#149) lacks a zero-check on :\n[low/medium] reentrancy-events at src/PulseTreasury.sol:215: Reentrancy in PulseTreasury.burn() (src/PulseTreasury.sol#215-220):\n[low/medium] reentrancy-events at src/PulseTreasury.sol:183: Reentrancy in PulseTreasury.pulse() (src/PulseTreasury.sol#183-196):\n[low/medium] timestamp at src/PulseTreasury.sol:183: PulseTreasury.pulse() (src/PulseTreasury.sol#183-196) uses timestamp for comparisons\n[low/medium] timestamp at src/SequencerHook.sol:161: SequencerHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/SequencerHook.sol#161-192) uses timestamp for comparisons\n[low/medium] timestamp at src/PulseTreasury.sol:145: PulseTreasury.nextPulse() (src/PulseTreasury.sol#145-154) uses timestamp for comparisons","passed":true},{"durationMs":578,"exitCode":0,"name":"aderyn","output":"[high] contract-locks-ether at src/PulseTreasury.sol:65: Contract locks Ether without a withdraw function\n[high] reentrancy-state-change at src/PulseTreasury.sol:111: Reentrancy: State change after external call\n[low] empty-require-revert at src/PulseTreasury.sol:218: Empty `require()` / `revert()` Statement\n[low] internal-function-used-once at src/SequencerState.sol:70: Internal Function Used Only Once (5 places)\n[low] large-numeric-literal at src/PulseTreasury.sol:190: Large Numeric Literal\n[low] literal-instead-of-constant at src/PulseTreasury.sol:224: Literal Instead of Constant (133 places)\n[low] missing-inheritance at src/SequencerToken.sol:5: Missing Inheritance\n[low] require-revert-in-loop at src/PulseTreasury.sol:170: Loop Contains `require`/`revert`\n[low] state-change-without-event at src/SequencerHook.sol:149: State Change Without Event\n[low] state-no-address-check at src/SequencerHook.sol:154: Address State Variable Set Without Checks\n[low] unchecked-return at src/SequencerHook.sol:145: Unchecked Return\n[low] unsafe-erc20-operation at src/PulseTreasury.sol:218: Unsafe ERC20 Operation","passed":true},{"durationMs":9237,"exitCode":0,"name":"proof a3a45cc2990a","output":"Compiling 74 files with Solc 0.8.26\nSolc 0.8.26 finished in 8.59s\nCompiler run successful with warnings:\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:311:22:\n    |\n311 |         uint64 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:317:36:\n    |\n317 |                 uint64 candidate = uint64(1) << (uint256(next) * 16 + step);\n    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWarning (3149): The result type of the shift operation is equal to the type of the first operand (uint64) ignoring the (larger) type of the second operand (uint256) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other.\n   --> src/SequencerState.sol:349:23:\n    |\n349 |                 bit = uint64(1) << (uint256(track) * 16 + step);\n    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n\nRan 1 test for test/imd-proof-8d6ed855/Proof_a3a45cc2990a.t.sol:ParkedPulseProofTest\n[PASS] test_PulseStillBuysAfterAFreeSellParkedThePrice() (gas: 1337996)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 10.87ms (1.60ms CPU time)\n\nRan 1 test suite in 11.80ms (10.87ms 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":"ca99556867107e5a1163e9a61b40a4dacb9556215115c833388eccf9f3cffadc","verifiedTreeHash":"cd07d7bd9c6be2ebd16c5eff93df7c10c95cd415","verifierVersion":"0.1.0+6a374fcd"}]}