{"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":"672489ef-8304-403f-855c-b9dce583bc31","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"d2688bf4489dd4beee1375660ff703cd50e54d8079c2d954620b08a722ae7799","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"4e548b183a9308212e723118ae92fcfa6d2998ee0100f27c8c32383fe56edf0d","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"e011c13e199fc27620b49ccf20680da9bad035a8e275ff625ae87c687bb83d81","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"f976d9234f3510b2ce15068a8460a3c44ec233a1c9a4bb52bea543c5beedfe58","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"72e9b7198b60ade27e57764062d8b258eb1a40c2ed8af3bb0896fff4372486b4","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"481f5799378441102273b8711a427734383e0dd512bcc53e796890a0e7c6cebc","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"c681aec6c52519d6998f8769d4718da22e5f35cda355142af282b939d530980f","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"fff4c7010c6f5c1794eb7af2403519955d07fe6ec72f8e81c807d7f8fb247749","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Token name: UNLOCK. Token symbol: UNLK. Recover, fix, test, review and DEPLOY on Sepolia: onchain=univ4_hook, chainId=11155111, ETH pair, poolBps=8700. NEW launch, not job.continue. Sepolia deployment/test transactions are authorized, superseding code-only scopes. No mainnet or website. Deliver active quota-enforced trading.\n\nSOURCE: Parent 98dbc132-2f46-4991-ba25-abdd397da90f produced accepted files; continuation 747894ff-efa7-4454-9a66-fa68b991a3e6 failed on an empty repo. Restore the bundles below; an empty initial workspace is expected. Do not restart from launch-1309.\n\nComplete implementation plus tests:\nhttps://api.imd.fun/bundles/0dcbb533b92aca62ac0ac07e8dd827a7fdb68988b0fa974bbd6394383de697ee\nCommit 8bc47cb68deda948f5c2fb1e9a5182bb187d6759.\nAccepted manifest:\nhttps://api.imd.fun/bundles/b89b110f9d9d6236d2570c90bf61be79d183e8827ffa15b7500438e6721176c1\nCommit 7a5e1dc79d05ba7fbeb9166be036cb25b302079e.\n\nVerify each bundle SHA256 against its URL suffix. Temporarily clone https://github.com/identity-md-launches/launch-1401-build-deploy-unlock-unlk, ensure prerequisite 0243d7da4a4337ae8b16bcdf15bb4ead736fd68f exists; run git bundle verify, fetch bundle heads. Export the complete tests commit and overlay ONLY launch.json from the manifest commit: 429 tracked files. Preserve workspace .git/protected checks; record provenance and reconcile newer accepted work. Report exact retrieval errors.\n\nFIX: Keep hook constructor ($poolManager,$token,$factory,$owner); companions bind later. Use verified new launch identities, not legacy payer constants. Verify Sepolia factory/registry/distributor/manager/feed and policy; reproduce dependencies/build/protected tests and update docs/ABIs/manifest.\n\nAuthorized redesign for findings 08f7e7e8/3589008c: depth, TWAP/warm-up, feed freshness, confirmation cadence/gaps, sequential tiers and final delay. Choose justified parameters without asking again. Fix the 10 ETH floor/first-tier conflict without hidden higher thresholds. Measure sustained manipulation/unlock-and-exit gross capital, net exit cost, duration and counter-selling. Test outages/depth dips. Invalid data cannot advance tiers or revoke rights. Delays alone do not prove safety. Independently review and resolve release-blocking findings; disclose residual risks.\n\nDEPLOYMENT: Verify the actual authorized services/actors for both stages and rehearse on a recorded-block Sepolia fork. Never broadcast stage 1 without an executable stage-2 path. Future addresses are outputs, not user prerequisites. If unsupported, publish source/package and specify the missing operation and any required wallet signatures; never request private keys.\n\nSTAGE 1: Factory creates token/hook/distributor and seeds the official pool with this hook in its PoolKey from initialization. Authenticate manager/factory and bind once. Permit seed liquidity. While UNCONFIGURED reject swaps/credits/milestones but allow ordinary transfers and eligible native claims. No later hook attachment or substitute pool.\n\nSTAGE 2: Deploy UnlkSwapRouter, MerkleClaimEvidence and UnlkOracle against actual stage-1 records. Immutable setup authority calls configureAndActivate atomically. Validate reviewed code/settings, manager/token/pool/quote, registry/distributor/payer evidence and reciprocal bindings; balance/ABI alone is insufficient. Failure changes nothing; success seals configuration permanently. No upgrades, pausing, replacements, resets, exemptions or admin withdrawals.\n\nECONOMICS: UNLOCK/UNLK, 1 billion tokens, 18 decimals, minted once to the factory for 10% swarm / 87% official pool / 3% payer. Ordinary ERC-20 transfers have no tax/quota/blacklist/pause. Preserve official 1.25% trading fees: 1% payer, 0.25% IMD. Hook adds zero fee. Verify initial liquidity principal protection and fee withdrawal rights.\n\nCALLBACKS: Before swaps require activation/authenticated trader/router; after swaps enforce quotas and executed deltas atomically. Reject spoofing/replay/bypass; never trust tx.origin. Per-wallet E credits only authenticated official-pool buys, proven initial allocation and proven actual native claims; S counts executed sales. Q=max(0,floor(E*p/10000)-S); sales cannot exceed Q. Transfers/donations/liquidity create no rights. Prove/deduplicate actual rewards including pre-activation claims; verify recipient uniqueness if required by the adapter. Native claims retain eligibility/timing independently of credit sync.\n\nKeep p=2500 initially; verified USD FDV $100K:3500, $250K:4500, $500K:5500, $1M:7000, $2.5M:8500. At $5M permanently bypass quotas for all holders including transfer-only recipients; retain fees/authentication. Price declines never relock. Use implemented token/ETH time-weighted pricing plus validated Chainlink ETH/USD; no assumed built-in v4 TWAP. Disclose other-pool bypass and remaining manipulation risk.\n\nDELIVER: GitHub source/commit, reproducible tests/review, both stages, actual Sepolia addresses/explorer links, transactions, PoolKey/PoolId, ABIs, ve\n\nToken name: UNLOCK\nToken symbol: UNLK","parentJobId":null,"planHash":"d50509e0592905873d4e0eb9b193cbed3cc60ab155f55e49cd53f9232de10b93","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"672489ef-8304-403f-855c-b9dce583bc31","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1534-unlock"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51231","feedbackHash":"bed451e8008cc7251f0a60c611e6205368a311377327d0fcc851cfb625306313","nodeKey":"audit_economics","submissionHash":"d2688bf4489dd4beee1375660ff703cd50e54d8079c2d954620b08a722ae7799","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52251","feedbackHash":"4a2a0780c0688e9bf8209509604ab4c62032a47affde052242e6914c2226aa70","nodeKey":"audit_flow","submissionHash":"4e548b183a9308212e723118ae92fcfa6d2998ee0100f27c8c32383fe56edf0d","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52169","feedbackHash":"a8bd5a7c943fb7f360456e4ec9d250a1c30b4f9a032cf2087cc8955545008a23","nodeKey":"audit_judge","submissionHash":"e011c13e199fc27620b49ccf20680da9bad035a8e275ff625ae87c687bb83d81","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52706","feedbackHash":"dd81d4c2687b02dc483be31318f474d67b266cf828ea7ef0e2432dab12aeddf9","nodeKey":"audit_judge","submissionHash":"eb017134efa111c396e767712fd20193eb62489ce6ec7652be9fe3fdb9296edf","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52121","feedbackHash":"244fb93af61cd810a9e5a4e7d1e2d91a3a130a814d57c7054dc970a2e0477f1f","nodeKey":"audit_math","submissionHash":"f976d9234f3510b2ce15068a8460a3c44ec233a1c9a4bb52bea543c5beedfe58","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52151","feedbackHash":"481b90b333837c6801799dd8177698e840962842f93ceed69e6237e1d5d5bcc4","nodeKey":"audit_permissions","submissionHash":"72e9b7198b60ade27e57764062d8b258eb1a40c2ed8af3bb0896fff4372486b4","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51130","feedbackHash":"4b26cd115b51d740b65de8b1dc80d075b21eb81a35aea51b23ffc2c79038da94","nodeKey":"build_contract_project","submissionHash":"481f5799378441102273b8711a427734383e0dd512bcc53e796890a0e7c6cebc","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51870","feedbackHash":"91ecbd19c52502b348d5d1f14252f6d3fb97e8be20831699d015264217bdd5e1","nodeKey":"build_contract_project","submissionHash":"244435b64432dabceff2dea95f9f2b0099f9c511ced89387e8100d50099fd3ec","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52611","feedbackHash":"3f7173d7b09d736ecd82720e911f44b27dd76b027087f3d15678300f755fe267","nodeKey":"manifest","submissionHash":"c681aec6c52519d6998f8769d4718da22e5f35cda355142af282b939d530980f","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52733","feedbackHash":"bd8df29f955aca89935364a10be2b2fe574431383885f951f35a3380a3e11d61","nodeKey":"manifest","submissionHash":"b2cf962babf23a2d3129b753a6e400d70f1afa27e1eb53948b0f358f05115a06","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52593","feedbackHash":"ea6870fb9329b2ffa96ad106e9de645c895165d4a3dfe87042e736629e5768b1","nodeKey":"write_foundry_tests","submissionHash":"a1390ef7305f941386a7611c580b59779dc87a59d7ad8e0ed9a678c914b52f3a","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52261","feedbackHash":"a78ebe6039eed8c84d27a389a6b85f7edb5d42884f7bf18ad7d09750cd1b0d64","nodeKey":"write_foundry_tests","submissionHash":"fff4c7010c6f5c1794eb7af2403519955d07fe6ec72f8e81c807d7f8fb247749","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"a87a52da175d7cf5293ccaa3b34ef70f0d8bde6b4a118568c4f742570a48eb13","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"de319b702da6aa2e","findings":[],"hash":"1e27d7f92789f79131814ef6b3e7fef41046366dd29b438fb20745333c46fcf5","nodeId":"467a0e27-fcae-4959-bbc3-e06f174522a2","outcome":"failed","summary":"could not restore accepted work: accepted work conflicts with a dependency that changed the same files after it was accepted: ","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"claude","turns":0,"wallClockMs":975}},{"artifacts":[],"attempt":1,"bundleHash":"05e087a88bda1ab0478aa1b60aa713c1829af13353c8210981853ffb865ff02a","device":"403561621f0b349a","findings":[],"hash":"244435b64432dabceff2dea95f9f2b0099f9c511ced89387e8100d50099fd3ec","nodeId":"362f2c47-f978-4cc0-b671-c3eecd205b7e","outcome":"completed","summary":"Recovered and repaired the source package, including contracts, tests, manifest, ABIs and deployment instructions.\n\nValidation passed: **142 tests**, **11 protected checks**, both-stage Sepolia fork rehearsal, `forge build`, and `forge fmt --check`.\n\n**UNLK is not deployed or active.** No executable owner-signed stage-2 service was established, so stage 1 was not broadcast. Public deployment and GitHub publication remain pending.\n\nIndependent review remains required. The documented quiet-market manipulation scenario costs a payer approximately **0.65 ETH net over 56 hours**.\n\nSee [deployment handoff](docs/DEPLOYMENT.md), [validation](docs/VALIDATION.md), and [security findings](docs/SECURITY_REVIEW.md).","treeHash":"babea043e157805f758500cac81af1eb62cb992e","usage":{"cachedInputTokens":10685824,"inputTokens":340213,"model":"gpt-6-astra","outputTokens":96442,"runtime":"codex","turns":16,"wallClockMs":4732252}},{"artifacts":[],"attempt":1,"bundleHash":"b132c0ab94bbda8881288b117f26773fd57ca1251b0a5e3da2b27bc9683c0f84","device":"232b62e021f6f394","findings":[],"hash":"481f5799378441102273b8711a427734383e0dd512bcc53e796890a0e7c6cebc","nodeId":"362f2c47-f978-4cc0-b671-c3eecd205b7e","outcome":"completed","summary":"All checks pass and every finding is answered. Here is the recap.\n\n**Outcome.** Both reopened medium findings reproduced and are fixed in code, with regression tests that replay the reviewer's exact scenarios. Two of the four advisory findings are fixed as well. The remaining two are answered as documented decisions in `.imd-responses.json`. Build, 154 tests, format check, lint, and the reviewed-code hash check all pass offline.\n\n**What changed, by finding**\n\n- **Seed tolerance stranding stage 1 (a4b5f9a2), fixed.** The 1e12-wei dust tolerance became policy bands: the pool must hold 99 to 100 percent of its 870M share, the remainder wallet at least 30M, the distributor exactly 100M, and the three must sum to the supply. The remainder wallet is still credited exactly 30M. All stage-1 preconditions moved into one helper that staging runs before deploying anything, so nothing can be staged for a launch that cannot activate. Staging may now repeat until activation, and an out-of-band seed reverts the launch transaction itself.\n- **Unchecked 17 ETH capacity floor (d8778e80), fixed.** A new internal library holds the single capacity formula used by the oracle, the seed callback, staging and activation. A seed below the floor now reverts inside the factory's launch transaction, and both stage-2 calls recompute it from the live position. The threshold and its 19.54 ETH minimum opening FDV are documented rather than hidden.\n- **Confirmation restart depended on call timing (66b99dca), fixed.** The interrupted flag is gone. Invalid samples never confirm and never advance the cadence clock. Restart depends only on the gap between valid samples, so observed and unobserved outages behave identically. A snapshot-based test proves both runs agree.\n- **1024-leaf certification cap (153c7ae8), fixed.** Added per-submitter chunked certification with cross-chunk recipient uniqueness, tested at 1500 leaves. Duplicate-recipient roots stay uncertifiable by design.\n- **Protocol fee halt (d0e68f0c) and treasury quota power (0147f1a4), disputed.** Both reproduce and both are intentional. The security review now states each as an explicit release decision or trust assumption with the finding id.\n\n**Files to look at**\n\n- `src/UnlkHook.sol`, `src/libraries/SeedDepth.sol`, `src/MerkleClaimEvidence.sol`, `src/UnlkOracle.sol`\n- `test/ActivationRobustness.t.sol` for the new regression and chunked certification tests\n- `docs/SECURITY_REVIEW.md` for the revision table and the two release decisions\n\n**Things worth knowing**\n\n- The oracle and claim-evidence bytecode changed, so the reviewed creation hashes were regenerated and all ABIs, artifact digests, and recorded check outputs were refreshed.\n- The hook runtime now sits 248 bytes under the EIP-170 limit. The off-chain `HookDeployer` helper embeds the hook's init code and exceeds that limit on purpose; the artifact script exempts it.\n- The fork rehearsal against recorded Sepolia state was not re-run here because this machine's verification profile runs without network access. Its code paths are unchanged in signature, but a re-run before stage 1 is still part of the documented deployment checklist.","treeHash":"74c4683c2dee725f3eb7f349588a931ca4bf557e","usage":{"cachedInputTokens":6705356,"inputTokens":1506,"model":"claude-fable-5-1","outputTokens":74949,"runtime":"claude","turns":60,"wallClockMs":1351102}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"1731fbfe0c4574fb","findings":[{"citation":"resolved","description":"beforeSwap re-reads slot0 on every swap and reverts if the PoolManager's protocol fee for this pool is non-zero. The protocol fee controller is Uniswap governance, an actor outside this launch. Because the hook is immutable, has no admin and the official pool cannot be replaced (beforeInitialize refuses a second pool once bound), a single setProtocolFee call by that controller turns every router swap into a permanent InvalidPool revert. Quota-enforced trading, the launch's whole deliverable, then stops forever; earned credits remain recorded but cannot be used on the official pool. The oracle's checkpoint also marks the pool illiquid under the same condition, so milestone progression stops too. This is listed in docs/SECURITY_REVIEW.md as a trust assumption; it is reported here so the judge sees the exact failure input and the fact that nothing in the code or the deployment plan can undo it. A softer design (accept any protocol fee and simply disclose that the promised 1.25% total may rise) would preserve liveness; the current one trades liveness for fee certainty and that trade should be an explicit release decision.","line":417,"path":"src/UnlkHook.sol","reproduction":"State: launch activated, pool bound. Call PoolManager.setProtocolFeeController(C) as the manager owner, then as C call PoolManager.setProtocolFee(key, 1000). Then alice calls UnlkSwapRouter.swap{value: 1 ether}(SwapRequest(true, -1e18, MIN_SQRT_PRICE+1, 1e18, 1, deadline)). Expected (liveness): swap settles at the new total fee. Actual: beforeSwap reverts InvalidPool on this and every later swap; no function in UnlkHook, UnlkSwapRouter, UnlkOracle or the factory can clear the condition. The repository's own test testProtocolFeeChangeCannotSilentlyAlterTradingEconomics (test/Adversarial.t.sol) demonstrates the revert.","severity":"low","snippet":"        if (protocolFee != 0 || lpFee != FEE) revert InvalidPool();","title":"A Uniswap protocol-fee change on the official pool halts all official trading permanently with no recovery path"},{"citation":"resolved","description":"_updateMilestone restarts the pending tier clock whenever a call observes oracle.fdvUsd() reverting. An identical stale interval that no one happens to observe does not restart anything: if the feed is 91 minutes old from 10:00 to 10:03 and the only calls land at 09:58 and 10:04 (gap 6 min, within MAX_CONFIRMATION_GAP), the clock continues. The outcome therefore depends on call timing rather than on the data, and anyone can choose the timing because updateMilestone is permissionless and costs one transaction. On Sepolia the ETH/USD proxy is not SLA-backed and the authors measured heartbeat drift; any gap beyond 90 minutes (or a feed outage of any length) is an opportunity for a third party to call updateMilestone once and push the whole 6-hour (or 24-hour final) confirmation back to zero for every holder. Nothing is lost or revoked (tier never decreases), so the impact is unlock liveness only, but the asymmetry between observed and unobserved invalid intervals is not stated in the docs, which describe the restart as a property of the data. Either treat short invalid intervals uniformly (e.g. restart only if the invalid interval exceeds MAX_CONFIRMATION_GAP, which the window already enforces for oracle-side bad seconds) or document that confirmation can be reset by a single call during any feed lateness.","line":600,"path":"src/UnlkHook.sol","reproduction":"State: activated, TWAP warmed up, FDV above $100K, qualifyingSince[0] = T, lastConfirmation = T+5h55m (5 minutes short of tier 1). Set feed updatedAt = block.timestamp - 91 minutes (MockEthUsd in the fixture, or wait for real Sepolia lateness). Attacker calls hook.updateMilestone(): fdvUsd reverts InvalidOracle, confirmationInterrupted becomes true, return false. Feed refreshes one minute later; keeper calls updateMilestone(): branch `qualifyingSince[next] == 0 || confirmationInterrupted || gap > MAX_CONFIRMATION_GAP` is taken, qualifyingSince[0] is rewritten to now, tier stays 0. Expected per docs: a brief invalid interval that does not touch the 2h TWAP window and is shorter than the 10-minute gap has no effect; actual: six hours of confirmation discarded. Same sequence without the attacker's call (keeper calls at -3 min and +4 min around the stale moment) advances to tier 1 at the second call. test/Oracle.t.sol testInvalidDataCannotCountTowardPendingConfirmationOrRevokeRights shows the restart mechanics.","severity":"low","snippet":"            confirmationInterrupted = true;","title":"Confirmation restart depends on whether an invalid feed interval was observed, so one permissionless call during routine Chainlink lateness resets a 6h/24h clock"},{"citation":"resolved","description":"deployCompanions can run once. It verifies services, the registry record and the feed, but not the conditions configureAndActivate later requires: certified(0) on the evidence contract (impossible if the frozen round-0 tree has more than MAX_LEAVES = 1024 recipients or any duplicate recipient), the factory's recorded position matching the first beforeAddLiquidity ticks, and the token's initial-allocation receipts being within 1e12 wei of 870M / 30M. If any of these is false after staging, configureAndActivate reverts forever, deployCompanions refuses a second bundle, and the stage-1 pool holds 87% of supply with swaps permanently refused. All of these conditions are deterministic from stage-1 state and can be simulated before staging; docs/SECURITY_REVIEW.md and docs/DEPLOYMENT.md call the leaf cap an explicit preflight failure. Recorded as information so the judge can confirm the preflight is part of the stage-2 runbook; no code change is required if it is.","line":212,"path":"src/UnlkHook.sol","reproduction":"State: real launch whose contributor round 0 lists 1025 distinct wallets. Owner calls deployCompanions(number, feed, routerCode, evidenceCode, oracleCode): succeeds. Anyone calls MerkleClaimEvidence.certifyRound(0, accounts[1025], amounts[1025]): reverts InvalidConfig (n > MAX_LEAVES). Owner calls configureAndActivate(r, e, o, number): reverts InvalidEvidence at `!MerkleClaimEvidence(address(rewards_)).certified(0)`. Owner calls deployCompanions again with any arguments: reverts AlreadyActivated. Expected: a staging path that can be retried or a preflight that refuses to stage; actual: unrecoverable.","severity":"info","snippet":"        if (activated || stagedRouter != address(0)) revert AlreadyActivated();","title":"Stage-2 staging is single-shot, so any permanent precondition failure after deployCompanions (round-0 tree over 1024 leaves, unexpected allocation receipt) strands the launch with no second attempt"}],"hash":"4e548b183a9308212e723118ae92fcfa6d2998ee0100f27c8c32383fe56edf0d","nodeId":"2021e30f-813b-46ae-8697-93c927398913","outcome":"completed","summary":"The review is complete. Findings and the coverage record are in `.imd-findings.json` at the repository root, and the scratch test I used was removed, so the tree is unchanged.\n\n**What I covered.** I traced the Execution Trace, Periphery and First Principles guides across UnlkHook, UnlkSwapRouter, UnlkOracle, MerkleClaimEvidence, UnlkToken, the three small libraries, HookDeployer, and the verified LaunchFactory, PoolFees, LaunchRegistry and MerkleDistributor fixtures the hook binds to. The full non-invariant suite passes, and a scratch test confirmed the pinned reviewed creation-code hashes equal the current build, so stage 2 staging is executable.\n\n**Result: no critical or high defects.** The swap path, quota accounting, two-stage activation checks, evidence adapter and oracle accumulator all held against the failure modes in the guides. Three substantiated lower-severity items are reported, each with a concrete input:\n\n- **Low, UnlkHook.sol:417.** A Uniswap protocol-fee change on the official pool makes every swap revert forever. There is no admin, no substitute pool and no recovery. The docs disclose it as a trust assumption; I recorded the exact trigger so the judge can treat the liveness trade-off as a deliberate release decision.\n- **Low, UnlkHook.sol:600.** Confirmation restarts only when an invalid feed interval is observed. One permissionless updateMilestone call during routine Chainlink lateness resets a 6-hour or 24-hour clock, while the same lateness unobserved does not. Rights are never revoked, so this is unlock liveness only, but the asymmetry is undocumented.\n- **Info, UnlkHook.sol:212.** Staging is single-shot. If round 0 has more than 1024 recipients or any other immutable precondition fails after deployCompanions, activation is permanently impossible. The docs name this as a preflight failure; the row asks the judge to confirm the preflight is in the runbook.\n\n**Coverage.** All 25 listed entry points have a row. 22 hold, three reference the findings above, and two invariant rows record the hash check and the quota derivation. One row is marked unreached: the Sepolia fork rehearsal and the Stage2 broadcast script, which were outside my guides and need fork access I did not have.","treeHash":null,"usage":{"cachedInputTokens":1523858,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":51715,"runtime":"claude","turns":34,"wallClockMs":752333}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"cdeffb0cd839cbf7","findings":[{"citation":"resolved","description":"Asymmetry between what activation checks and what the oracle later requires. `_verifyOracle` (UnlkHook.sol:384-398) pins MIN_SEED_QUOTE_CAPACITY to 17 ether, and `UnlkOracle.checkpoint` (UnlkOracle.sol:98-105) marks every observation `liquid=false` whenever the factory seed's opening-boundary value `depth` is below that constant. `depth` is fixed for the life of the pool (principal can never be added or removed: beforeAddLiquidity/beforeRemoveLiquidity) and is decided solely by the IMD deployer's opening tick, which the project does not control (docs/DEPLOYMENT.md:74-75: 'the deployer derives the actual opening price from the 20 ETH policy cap'). With 870M tokens the margin is 17.377 ETH vs 17 ETH, i.e. about 220 ticks (under 4 tick spacings, a 2.2% lower opening cap). Nothing in `configureAndActivate` reads the seed's depth, so a launch whose seed falls under the constant passes every activation check, seals permanently, and `twapTick` reverts `InvalidOracle` on every call forever (`!last.liquid`, UnlkOracle.sol:131). `_updateMilestone` swallows the revert and only sets `confirmationInterrupted`, so p stays 2500 and the $5M full unlock can never happen, while trading, quotas and fees all work normally and no event signals the dead oracle. This is the brief's 'no hidden higher thresholds' concern re-appearing as a hidden threshold on the opening cap: an opening FDV of 19.5 ETH instead of 20 ETH silently disables the whole milestone system with no recovery path (no admin, no re-bind, no re-seed).","line":390,"path":"src/UnlkHook.sol","reproduction":"Real factory launch logic (test/imd/LaunchFactory.sol) with native ETH pair, poolBps 8700, token-only seed [-887220, 177540], sqrtPriceX96 = getSqrtPriceAtTick(177540), liquidity = floor(870e24 * 2^96 / (sqrtUpper - sqrtLower)) (opening FDV about 19.5 ETH). deployCompanions, certify round 0, configureAndActivate -> succeeds, activated()==true. Then a 400 ETH buy through UnlkSwapRouter (spot FDV far above $5M at $2000/ETH) and 30 checkpoints every 5 minutes. Expected: observations become liquid and tiers start confirming. Actual: last observation liquid==false, oracle.fdvUsd() reverts InvalidOracle, hook.updateMilestone() returns false, tier stays 0, forever. Control in the same file: identical flow at tick 177300 is liquid after one buy. Scratch test: test/scratch/ActivationGaps.t.sol::test_activationAcceptsSeedThatOracleNeverCallsLiquid (passes = defect reproduces). Fix direction: have configureAndActivate (or oracle.bind) compute the seed depth from the recorded position and revert when it is below MIN_SEED_QUOTE_CAPACITY, so stage 2 fails loudly before sealing instead of sealing a dead oracle; or derive the capacity threshold from the recorded seed instead of a constant.","severity":"medium","snippet":"                || oracle_.MIN_SEED_QUOTE_CAPACITY() != 17 ether || oracle_.SUPPLY() != token.SUPPLY()","title":"configureAndActivate verifies oracle constants but never that the actual seed can ever satisfy them: a seed opened below ~19.5 ETH FDV activates and leaves the oracle permanently illiquid, so no tier "},{"citation":"resolved","description":"Trust gap between the deployer (who chooses `params.liquidity`) and the hook (which hard-codes what that liquidity must have produced). `configureAndActivate` requires the pool to have received at least 870,000,000e18 - 1e12 wei of UNLK (and the remainder wallet at most 30,000,000e18 + 1e12, line 293). At the opening boundary each unit of liquidity moves about 7,000 wei, so the tolerance corresponds to ~1.4e8 liquidity units out of ~1.2e23, a relative precision of 1e-15. The factory itself only enforces `taken <= allowed` (LaunchFactory.sol:221-222), so any deployer rounding, haircut or 'at most poolBps' safety margin larger than that is accepted by stage 1. `deployCompanions` has no such check and can run only once (`stagedRouter != address(0)` -> AlreadyActivated, line 212), and `configureAndActivate` only accepts the staged addresses. So the sequence launch -> deployCompanions -> configureAndActivate(InvalidEvidence) leaves a hook that is bound, seeded with 87% of supply in an official pool that rejects every swap (NotActivated), with no retry, no re-stage and no admin. This violates the brief's 'never broadcast stage 1 without an executable stage-2 path' unless the deployer's liquidity derivation is proven exact; the rehearsal (rehearsal/Sepolia.t.sol:54) used the project's own exact formula, not the IMD deployer's, so that proof does not exist in the tree. The over-tight check also buys nothing: the payer credit is a fixed 30M regardless (syncPayer), so a slightly larger remainder is already accepted economics ('Seed integer rounding can leave dust with the recipient', README.md:63).","line":291,"path":"src/UnlkHook.sol","reproduction":"Same real-factory launch as above at tick 177300 but liquidity = exact - 1e9 (exact = floor(870e24 * 2^96 / (sqrtUpper - sqrtLower))). Factory launch succeeds (taken < allowed); token.initialAllocation(poolManager) is short of 870M by between 1e12 and 1e14 wei (under 0.0001 UNLK). Owner calls deployCompanions(1, feed, routerCode, evidenceCode, oracleCode) -> succeeds; round 0 certified. Owner calls configureAndActivate(router, evidence, oracle, 1). Expected: activation (allocation within any economically meaningful bound). Actual: revert InvalidEvidence; a second deployCompanions reverts AlreadyActivated; the hook can never activate. Scratch test: test/scratch/ActivationGaps.t.sol::test_tinyLiquidityHaircutKillsStage2Permanently (passes = defect reproduces). Fix direction: move the allocation checks into deployCompanions (so nothing is staged for an unactivatable launch) and widen the tolerance to a bound that matches the factory's own guarantee (e.g. accept any pool allocation in [POOL_ALLOCATION - X, POOL_ALLOCATION] where X is the maximal rounding the deployer documents, or check only `pool <= POOL_ALLOCATION && remainder >= PAYER_ALLOCATION`), or allow re-staging while not activated.","severity":"medium","snippet":"                || token.initialAllocation(address(poolManager)) + 1e12 < token.POOL_ALLOCATION()","title":"Stage 2 dies permanently if the deployer's seed liquidity is even 1e-14 below the exact 87%: the 1e12-wei allocation tolerance is unreachable after a single-shot deployCompanions"},{"citation":"resolved","description":"Access x economics seam, documented as a privileged power rather than a bypass. `MerkleDistributor.openRound` (test/imd/MerkleDistributor.sol:86-96) lets `treasury()` (LaunchFees.treasury, controlled by IMD's LaunchFees owner) open any number of later rounds against tokens the distributor holds, with any root. `MerkleClaimEvidence.attest` accepts any round whose complete tree is certified and whose claim flag is set, and `UnlkHook.syncRewards` credits E for it (kind 2). So the treasury can route tokens it holds (for example the unclaimed round-0 remainder it receives via `sweep`, or tokens bought on the pool) back through the distributor to chosen wallets, giving those wallets 25%-100% sell quota that ordinary transfer recipients never get. Not a code defect: the brief asks that 'proven actual native claims' credit E, and these are real claims. It is a residual trust assumption on the LaunchFees owner that is not listed in docs/SECURITY_REVIEW.md 'Trust and scope'.","line":105,"path":"src/MerkleClaimEvidence.sol","reproduction":"After activation: treasury T transfers 1,000,000 UNLK to the distributor; T calls distributor.openRound(root(T, 1e24), 1e24, 0) -> round 1; T calls distributor.claim(1, T, 1e24, proof); anyone calls evidence.certifyRound(1, [T], [1e24]) and evidence.attest(1, T, 1e24, proof); anyone calls hook.syncRewards(T). Expected under a strict reading of 'swarm/pool/payer only': T has no quota. Actual: eligible[T] += 1e24, so T may sell 250,000 UNLK on the official pool while a wallet that received the same 1,000,000 UNLK by plain transfer may sell nothing.","severity":"info","snippet":"        if (!merkleDistributor.claimed(round, account)) revert NotClaimed();","title":"Trust assumption: the IMD treasury can manufacture sell quota for any wallet by opening and funding a later distributor round; the hook credits every attested native claim regardless of who opened the"}],"hash":"72e9b7198b60ade27e57764062d8b258eb1a40c2ed8af3bb0896fff4372486b4","nodeId":"d9697714-2a27-4315-b677-8f24ea72cc24","outcome":"completed","summary":"The findings file is complete and valid. Here is the recap.\n\n**Scope covered.** I audited the permission model, trust gaps and asymmetries across `UnlkHook`, `UnlkSwapRouter`, `UnlkOracle`, `MerkleClaimEvidence` and `UnlkToken`, plus the manifest and the vendored IMD factory, distributor and fee contracts the hook authenticates against. All 25 listed entry points have a coverage row, plus three invariant rows. Nothing in the permission model itself broke: every callback is manager-only with a sender check, the router only ever pulls from its caller, the setup authority can stage and seal exactly one reviewed bundle, and no admin, pause or withdrawal path exists.\n\n**Findings written to .imd-findings.json**\n\n- **Medium, activation seals a dead oracle.** `configureAndActivate` pins the oracle's 17 ETH depth constant but never checks that the actual seed reaches it. A seed opened about 2% under the 20 ETH cap, which only the IMD deployer controls, activates cleanly and is never `liquid`, so no tier can ever be confirmed and nothing signals it. Reproduced with the real factory logic at opening tick 177540, a 400 ETH buy and 30 checkpoints.\n- **Medium, stage 2 can die permanently.** The 1e12 wei allocation tolerance is a relative precision of 1e-15. A deployer liquidity only 1e-14 below the exact value passes the factory and the single-shot `deployCompanions`, then `configureAndActivate` reverts forever with no re-stage path. Reproduced with liquidity reduced by 1e9 units.\n- **Info, trust assumption.** The IMD treasury can open and fund later distributor rounds, and every attested native claim earns sell quota, so the treasury can manufacture quota for chosen wallets. This is within the brief's design but is not listed in the security review's trust section.\n\n**Dropped after tracing.** Pushing the pool price past the seed range with a far price limit to poison the oracle requires draining all pool ETH, which aggregate quota cannot do once buys exceed roughly 1 ETH. The protocol-fee halt and the 1024-leaf certification cap are already disclosed in the docs. Static-analysis leads on the router's reentrancy and unchecked ETH recipient are false positives.\n\n**Residuals.** Both medium findings hinge on deployer inputs the tree cannot prove, since the Sepolia rehearsal used the project's own exact seed formula rather than the IMD deployer's. The scratch test under test/scratch/ reproduces both and is not part of the submission.","treeHash":null,"usage":{"cachedInputTokens":1415649,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":53853,"runtime":"claude","turns":29,"wallClockMs":867135}},{"artifacts":[],"attempt":1,"bundleHash":"cd41ba7272aedbbe1706f8df077d0503660046c8aa4586a9deba008cc21abda9","device":"cbc3d81ff238201c","findings":[],"hash":"a1390ef7305f941386a7611c580b59779dc87a59d7ad8e0ed9a678c914b52f3a","nodeId":"f571ba87-b559-40ee-99df-d83c48d506a7","outcome":"completed","summary":"Added adversarial batch tests and two stateful invariant suites. Changes are confined to `test/`.\n\nValidation passed: clean build, 151 tests, and all 11 protected checks—including 2,000 fuzz cases and 36,864 randomized invariant calls.\n\nNo new defect reproduced. No deployment performed.","treeHash":"920d600a8852c0dd564b846b677bf4d626f6945c","usage":{"cachedInputTokens":3632512,"inputTokens":160509,"model":"gpt-6-astra","outputTokens":27588,"runtime":"codex","turns":8,"wallClockMs":1291517}},{"artifacts":[],"attempt":1,"bundleHash":"ad6176eef122f7f03148ace16aa9018bf6e3fbcfc601f916456de0b4a5d5a2dd","device":"bda86649c05ae3bf","findings":[],"hash":"b2cf962babf23a2d3129b753a6e400d70f1afa27e1eb53948b0f358f05115a06","nodeId":"467a0e27-fcae-4959-bbc3-e06f174522a2","outcome":"completed","summary":"launch.json is written and verified. Only that file changed.\n\n**What the manifest describes**\n- Hook contract `UnlkHook`, constructor args in declaration order: `$poolManager`, `$token`, `$factory`, `$owner`. This matches `src/UnlkHook.sol:131`.\n- Permissions: the eight callbacks the implementation enables at `src/UnlkHook.sol:149` (beforeInitialize, afterInitialize, before/after add and remove liquidity, beforeSwap, afterSwap). No return-delta flags, flags 0x3fc0.\n- Token `UnlkToken`, name UNLOCK, symbol UNLK, 18 decimals. Pool: native ETH, fee 12500, tickSpacing 60, initialPrice as the launch facts give it.\n- Notes (3968 characters, under the cap) summarize the two-stage design, quota formula and tiers, oracle parameters, provenance of the restored bundles, the other-pool bypass and measured manipulation residual risk, and the current status.\n\n**Verification run**\n- `forge build` succeeds.\n- `forge test`: 142 passed, 0 failed across 28 suites.\n- The pinned protected admission tests, run from a scratch copy with the manifest's values: 11 passed, 0 failed, including the permissions-match-declared-flags and initialize-from-factory checks.\n- `git status` shows only `launch.json` modified. No blocked file was written.\n\n**What this task did not do**\nThe brief also asks for a Sepolia broadcast. This assignment's write scope is the manifest only, so nothing was deployed. The tree's own release status records the fork rehearsal at block 11904506 without broadcast, and the notes state that stage 1 must not be sent until an owner-signed stage-2 route exists. Actual launch addresses, transactions and PoolId remain outputs of the deployer, not values in the manifest.","treeHash":"89f7f64ca3be754a6ebdd997a3bdbad526feabbb","usage":{"cachedInputTokens":528226,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":6841,"runtime":"claude","turns":11,"wallClockMs":122188}},{"artifacts":[],"attempt":1,"bundleHash":"ec5e29aa22d3b3419d5cc740de1628c2d80a3ba4b54d1e40c7215a0f797bd4c6","device":"2a4ad9be53991100","findings":[],"hash":"c681aec6c52519d6998f8769d4718da22e5f35cda355142af282b939d530980f","nodeId":"467a0e27-fcae-4959-bbc3-e06f174522a2","outcome":"completed","summary":"The manifest is written and verified. Only launch.json changed.\n\n**What I found.** The workspace already held the accepted implementation plus newer accepted work from job 362f2c47 at commit ed59c57, layered over the bundle commit 8bc47cb. I re-downloaded both bundles into a scratch directory. Their SHA256 sums match the URL suffixes, both pass git bundle verify, and both heads fetched cleanly against the local prerequisite commit 0243d7d. The upstream launch-1401 repository contains only that empty prerequisite commit. I kept the newer tree intact rather than reverting to the bundle.\n\n**What launch.json now says.** The structure is unchanged from the accepted manifest and matches the source:\n\n- Hook is UnlkHook with constructor order manager, token, launchFactory, setupAuthority, written as the four placeholders.\n- Permissions are the eight callbacks getHookPermissions returns, no return-delta flags, flags 0x3fc0.\n- Token is UnlkToken, UNLOCK, UNLK, 18 decimals. Pool is native ETH, fee 12500, tickSpacing 60, the required initialPrice.\n- Notes were rewritten to record this task's provenance verification, the reconciliation with the newer accepted tree, the stage 1 and stage 2 flow, quota and oracle parameters checked against the constants in source, the other-pool bypass disclosure, and the measured manipulation cost. Notes are 3851 characters.\n\n**Verification results.**\n\n| Check | Result |\n| --- | --- |\n| forge build | passes |\n| forge test | 154 passed, 0 failed |\n| protected admission tests, flags derived from the manifest | 11 passed, 0 failed |\n| ReviewedCode creation hashes vs build | match |\n| docs/abi vs build for all six contracts | match |\n\n**What remains outside this task.** The tree is still a source package. No Sepolia broadcast happened here, and RELEASE_STATUS.json records why: stage 2 needs the setup authority's wallet signatures for deployCompanions and configureAndActivate, and no public service exposes that operation. Addresses, transactions and the PoolId remain deployment outputs.","treeHash":"f3948985462554b32a2e6627d5644c7e156d27c6","usage":{"cachedInputTokens":911781,"inputTokens":514,"model":"claude-fable-5-1","outputTokens":15182,"runtime":"claude","turns":17,"wallClockMs":246032}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"1507f63d3f1b973a","findings":[{"citation":"resolved","description":"configureAndActivate is the only path that ever enables swaps, credits and milestones, and it reverts with InvalidEvidence unless the factory's seed transfer to the PoolManager lies in [870,000,000e18 - 1e12, 870,000,000e18] wei and the remainder lies in [30,000,000e18, 30,000,000e18 + 1e12]. The seed amount is not chosen by this code: LaunchFactory.launch takes a `liquidity` word from the IMD deployer and only enforces `taken <= 87% of supply` (test/imd/LaunchFactory.sol `PoolShareExceeded`). The amount of token actually pulled is ceil(L * (sqrtUpper - sqrtLower) / 2^96), so a liquidity value only 1e9 units (about 1e-14 relative) below the exact figure already seeds 7e12 wei less than 870M and the hook refuses to activate for ever. There is no retry with different evidence, no second seeding path (beforeAddLiquidity only accepts the factory, which only seeds inside launch()), and no owner escape (none exists by design). The result is a live, seeded, UNCONFIGURED pool on Sepolia: every router swap reverts InvalidSwap/NotActivated, syncPayer/syncRewards/updateMilestone revert NotActivated, while token transfers and native claims still work, i.e. exactly the state the brief forbids ('Never broadcast stage 1 without an executable stage-2 path'). The window is also in direct tension with the deployer's own policy row: docs/network/policies.json (version 32, the row launch.policyVersion selects and whose split launch/deploy.ts copies) names liquidityBps 8000, not 8700; a launch seeded at the policy's 80% (800M) is refused the same way. Nothing economic needs a 1e12-wei tolerance: the payer credit is the fixed PAYER_ALLOCATION constant, not the measured remainder, and the oracle's depth test reads the live position, so a tolerance of e.g. 0.1% (or a check that the pool received at least 86.9% and the requester at least 3%) would protect the same invariants without turning a sub-dust rounding difference into a dead pool.","line":290,"path":"src/UnlkHook.sol","reproduction":"Using test/fixtures/SystemFixture.sol: call _deploy(false); compute the exact token-only liquidity exact = _tokenOnlyLiquidity(token, getSqrtPriceAtTick(177300)) for the range [-887220, 177300]; call _launch(sqrt, -887220, 177300, exact - 1e9) (factory.launch succeeds: taken = 869,999,999,999,992,923,343,850,647 wei, 7,076,656,149,353 wei short of 870M; payer receives 30,000,000,000,007,076,656,149,353 wei). Then _deployCompanions() (succeeds) and vm.prank(owner); hook.configureAndActivate(router, rewards, oracle, 1). Expected: activation succeeds for a seed that is 7 millionths of one token short of 87%. Actual: revert InvalidEvidence (line 291 condition `initialAllocation(poolManager) + 1e12 < POOL_ALLOCATION` is true), hook.activated() stays false, router.swap{value:1 ether}(buy 1 ether) reverts InvalidSwap, and no call can ever change that. Same outcome with liquidity = exact * 8000 / 8700 (policy-row 80% seed: pool receives 799,999,999,999,999,999,999,997,825 wei). Both runs were executed locally against the fixture (forge test, 2 passed with the reverts expected above).","severity":"medium","snippet":"                || token.initialAllocation(address(poolManager)) > token.POOL_ALLOCATION()\n                || token.initialAllocation(address(poolManager)) + 1e12 < token.POOL_ALLOCATION()\n                || token.initialAllocation(requester) < token.PAYER_ALLOCATION()\n                || token.initialAllocation(requester) > token.PAYER_ALLOCATION() + 1e12","title":"Activation demands the pool seed within 1e12 wei (one millionth of a token) of exactly 870M; any smaller seed the factory accepts strands the stage-1 pool permanently"},{"citation":"resolved","description":"attest() refuses any round that is not certified, and certifyRound() refuses a tree with more than MAX_LEAVES (1024) leaves or with two leaves for one account (DuplicateRecipient). The IMD MerkleDistributor accepts both shapes: the treasury may open later remediation rounds of any size, and OpenZeppelin StandardMerkleTree permits two (account, amount) leaves for the same account. For round 0 the problem is caught before stage 2 because configureAndActivate requires certified(0), but for any later round it is silent: contributors claim their tokens natively (eligibility is untouched, as specified), yet syncRewards can never credit them, so their quota Q stays 0 and they cannot sell a single token through the official pool until the $5M full unlock, while buyers of the same token can sell 25%. The README discloses the 1024 cap as a round-0 preflight condition but not that it permanently strips sell rights from later rounds. A fix that keeps the design is to allow certification in chunks (persisting the partially built level hashes) or to raise the bound to what the chain's block gas allows (the 1024-leaf certification measured 13.9M gas, so about 2000 leaves fit a 30M block).","line":56,"path":"src/MerkleClaimEvidence.sol","reproduction":"After activation: treasury (fees.treasury()) funds the distributor and calls openRound(root, funded, 0) with a root over 1025 distinct (account, amount) leaves (or over two leaves for the same account with different amounts). A contributor calls distributor.claim(1, account, amount, proof) and receives the tokens. Then anyone calls rewards.certifyRound(1, accounts[1025], amounts[1025]) -> revert InvalidConfig (n > MAX_LEAVES), or with the duplicate tree -> revert DuplicateRecipient. rewards.attest(1, account, amount, proof) -> revert UncertifiedRound. hook.syncRewards(account) returns 0; hook.remainingQuota(account) == 0; a sell of 1 wei through router.swap reverts QuotaExceeded in afterSwap. Expected per spec: 'proven actual native claims' credit E; actual: the proven claim can never be credited.","severity":"low","snippet":"        if (n == 0 || n > MAX_LEAVES || n != amounts.length || certified[round]) revert InvalidConfig();","title":"Claim rounds with more than 1024 leaves or a repeated recipient can never be certified, so every claimant of such a round gets tokens but zero sell rights (E) on the official pool"}],"hash":"d2688bf4489dd4beee1375660ff703cd50e54d8079c2d954620b08a722ae7799","nodeId":"854816bf-8966-4325-ac4b-6a7ea7585e0b","outcome":"completed","summary":"The review is complete. The findings file is in place and valid, the scratch tests were removed, and the working tree holds nothing new beyond `.imd-findings.json` (which the repository already ignores) and the pinned `.imd/` inputs.\n\n**Outcome**\n\nI audited the UNLK hook launch against the Pashov Economic Security, Invariant and Flow Gap guides, tracing the quota ledger, the fee split, the oracle and milestone cadence, the router settlement, and the claim-evidence path. Two defects were substantiated by local Foundry runs; the rest of the assigned area holds.\n\n**Findings written to `.imd-findings.json`**\n\n- **Medium, activation tolerance.** `configureAndActivate` in `src/UnlkHook.sol` only accepts a pool seed within 1e12 wei of exactly 870M tokens. The seed amount is a deployer input the factory accepts with far looser bounds. A liquidity value 1e9 units low seeds about 7 millionths of one token less and activation reverts forever, leaving a seeded Sepolia pool that can never trade. The deployer's own policy row names liquidityBps 8000, which fails the same way. Both cases were reproduced against the project fixture.\n- **Low, uncertifiable rounds.** `certifyRound` in `src/MerkleClaimEvidence.sol` refuses rounds over 1024 leaves or with a repeated recipient. For any later treasury round in that shape, claimants receive tokens natively but can never be credited sell rights, so they cannot sell a single token on the official pool until the $5M unlock. Reproduced with a two-leaf duplicate-recipient round.\n\n**Coverage**\n\nAll 25 listed entry points have a row, plus three invariant rows. Everything is `holds` except the two `finding` rows above. The disclosed sustained-manipulation cost was re-run from the project's own test and matches the documented numbers. No undisclosed cheaper path was found. I also probed whether quota-limited sellers can push the price out of the seed range to poison the oracle, and they cannot before full unlock, so that lead was dropped.\n\n**Not reached**\n\nChain-specific coupling I could not verify offline: whether the IMD deployer's liquidity formula lands inside the 1e12-wei window, and whether its compiled token creation code matches the pinned `ReviewedCode.TOKEN` hash. Both are the same failure class as the first finding and belong in a deployer preflight.","treeHash":null,"usage":{"cachedInputTokens":3024291,"inputTokens":802,"model":"claude-fable-5-1","outputTokens":55102,"runtime":"claude","turns":31,"wallClockMs":845815}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e8816d4386532a66","findings":[{"citation":"resolved","description":"Settled, not reopened. The author disputed the prior low finding and kept the halt: beforeSwap reverts InvalidPool whenever the PoolManager's protocol fee for this pool is non-zero, and UnlkOracle.checkpoint classes observations illiquid under the same condition, so one setProtocolFee call by Uniswap's fee controller ends official trading and tier confirmation with no admin, re-bind or substitute pool. docs/SECURITY_REVIEW.md 'Trust and scope' now states this as an explicit release decision naming the alternative (keep trading at a higher total fee). The behaviour still reproduces exactly as reported; it is recorded here as a residual risk the requester must accept before stage 1, not as a defect requiring a code change. Earned credits remain recorded and the token stays tradable on other venues.","line":471,"path":"src/UnlkHook.sol","reproduction":"State: activated launch (SystemFixture.setUp). manager.setProtocolFeeController(C) by the manager owner; as C call manager.setProtocolFee(key, 1000). alice calls router.swap{value: 1 ether}(SwapRequest(true, -1e18, MIN_SQRT_PRICE + 1, 1e18, 1, deadline)). Expected (liveness reading): swap settles at the new total fee. Actual (intended by the author): beforeSwap reverts InvalidPool on this and every later swap and no function can clear it. test/Adversarial.t.sol testProtocolFeeChangeCannotSilentlyAlterTradingEconomics passes on this tree and demonstrates the revert.","severity":"info","snippet":"        if (protocolFee != 0 || lpFee != FEE) revert InvalidPool();","title":"Accepted release decision (prior d0e68f0c): a Uniswap protocol-fee change on the official pool halts all router trading and milestone progression permanently, by design"},{"citation":"resolved","description":"Settled, not reopened. attest accepts any certified round whose native claim flag is set, and UnlkHook.syncRewards credits E (kind 2) for it; MerkleDistributor.openRound lets LaunchFees.treasury() open later rounds against tokens the distributor holds with any root. The treasury can therefore route tokens it holds to chosen wallets that then hold 25%-100% sell quota a plain transfer recipient never gets. The brief requires proven actual native claims to credit E, so this is a privileged power of an actor outside the code, now named in docs/SECURITY_REVIEW.md 'Trust and scope' with this finding id. No code change requested.","line":190,"path":"src/MerkleClaimEvidence.sol","reproduction":"After activation: treasury T transfers 1,000,000 UNLK to the distributor; T calls distributor.openRound(root(T, 1e24), 1e24, 0) -> round 1; T calls distributor.claim(1, T, 1e24, proof); anyone calls rewards.certifyRound(1, [T], [1e24]) then rewards.attest(1, T, 1e24, proof); anyone calls hook.syncRewards(T). Result: eligible[T] += 1e24, so T may sell 250,000 UNLK on the official pool while a wallet holding the same 1,000,000 UNLK by plain transfer may sell nothing.","severity":"info","snippet":"        if (!merkleDistributor.claimed(round, account)) revert NotClaimed();","title":"Trust assumption (prior 0147f1a4): the IMD treasury can create official-pool sell quota for chosen wallets by opening and funding later distributor rounds"}],"hash":"e011c13e199fc27620b49ccf20680da9bad035a8e275ff625ae87c687bb83d81","nodeId":"22f999f3-9eaf-4dd2-8a31-52f1d754ef03","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written at the repository root.\n\n**Outcome: all four code findings from the prior round are fixed and verified; nothing new reproduces.** The revised tree builds and passes all 170 tests.\n\nWhat I settled, each against my own re-run of the original reproduction:\n\n- **Seed tolerance (medium, a4b5f9a2): fixed.** The exact prior scenario, with the pool short of 870M by about 7e12 wei, now launches, stages, activates and trades. The 1e12 tolerance became a 99% band, every stage-1 precondition now runs inside the staging call, staging can repeat until activation, and a superseded bundle cannot activate. A seed below the band reverts the launch transaction itself.\n- **Seed capacity (medium, d8778e80): fixed.** Launching at tick -177840 now reverts inside the factory's seed callback, so no pool with a permanently dead oracle can exist. Hook, oracle and activation share one capacity formula and the live position is re-read at staging and activation.\n- **Confirmation asymmetry (low, 66b99dca): fixed.** An invalid sample no longer writes anything, so observed and unobserved feed lateness produce the same outcome. The author's snapshot-based test proves it.\n- **Leaf cap (low, 153c7ae8): fixed.** Chunked certification certifies a 1500-leaf round and the claimants' credits sync.\n\nTwo items the author disputed are kept as **info** entries only, with no change requested. The protocol-fee halt and the treasury's power to create quota through later rounds both still reproduce and are now written up as explicit release decisions in the security review document.\n\nI also confirmed the pinned Sepolia service code hashes against the live chain on two public RPCs. All five match. One residual stays documented as a preflight rather than a finding: a round-0 root with a duplicate recipient could never be certified, and that root is known before stage 1 is broadcast.\n\nThe coverage record answers all 28 entry points, plus rows for each settled finding, the manifest, and the Sepolia pins. My scratch tests were removed and no repository file was changed.","treeHash":null,"usage":{"cachedInputTokens":1373514,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":24722,"runtime":"claude","turns":25,"wallClockMs":378002}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f3b611cf8afb513f","findings":[{"citation":"resolved","description":"Merged from audit_economics 0d1c5c46, audit_permissions 84b5146a, audit_math 3018f62a and audit_flow 42f3bee6 (same root cause: configureAndActivate has permanent preconditions that neither the factory nor deployCompanions checks, and nothing can be retried). configureAndActivate is the only path that enables swaps, credits and milestones. It reverts InvalidEvidence unless the pool received at least POOL_ALLOCATION - 1e12 wei (line 291) and the remainder wallet at most PAYER_ALLOCATION + 1e12 wei (line 293). The seed amount is ceil(liquidity * (sqrtUpper - sqrtLower) / 2^96) for a `liquidity` word the IMD deployer chooses off chain; test/imd/LaunchFactory.sol only enforces `taken <= allowed` (lines 220-222), so a liquidity value 1e9 units (about 1e-14 relative) below the exact figure is accepted by stage 1 and refused by stage 2 forever. deployCompanions (line 212, `stagedRouter != address(0)` -> AlreadyActivated) runs once and does not check the allocation receipts, the first-position ticks or certified(0) that configureAndActivate later requires, so after staging there is no second attempt and no admin escape by design. The result is a bound, seeded official pool whose every router swap reverts NotActivated, which is exactly the state the brief forbids ('never broadcast stage 1 without an executable stage-2 path'). The tolerance buys nothing economically: the payer credit is the fixed PAYER_ALLOCATION constant (syncPayer) and the oracle depth test reads the live position. Fix: accept any pool allocation <= POOL_ALLOCATION with remainder >= PAYER_ALLOCATION (or a documented proportional bound), and evaluate every configureAndActivate precondition inside deployCompanions (or allow re-staging while not activated) so nothing can be staged for an unactivatable launch.","line":291,"path":"src/UnlkHook.sol","reproduction":"Reproduced in test/scratch/Judge.t.sol:JudgeSeedTolerance (PASS = defect present). State: SystemFixture._deploy(false); exact = _tokenOnlyLiquidity(token, getSqrtPriceAtTick(177300)) for range [-887220, 177300]; _launch(sqrt, -887220, 177300, exact - 1e9): factory.launch succeeds, token.initialAllocation(poolManager) = 869999999999992923343850647 wei (7076656149353 wei, i.e. 0.000007 UNLK, short of 870M). _deployCompanions() succeeds, round 0 certified. Then vm.prank(owner); hook.configureAndActivate(router, rewards, oracle, 1). Expected: activation (seed is 99.9999999999% of the share and every other check passes). Actual: revert InvalidEvidence; hook.activated() == false; a second deployCompanions reverts AlreadyActivated; no call can ever change that. With the fixture's exact liquidity the same sequence activates, isolating the tolerance as the sole cause.","severity":"medium","snippet":"                || token.initialAllocation(address(poolManager)) + 1e12 < token.POOL_ALLOCATION()","title":"Activation demands the factory seed within 1e12 wei of exactly 870M and staging is single-shot, so any sub-dust deployer rounding strands the stage-1 pool permanently"},{"citation":"resolved","description":"Merged from audit_permissions 8f802252 and audit_math 29b746b8. UnlkOracle.checkpoint (src/UnlkOracle.sol lines 98-105) marks every observation liquid=false unless depth = seedTokens * 2^192 / rangeUpper^2 >= MIN_SEED_QUOTE_CAPACITY (17 ether). depth is fixed for the life of the pool: principal can never be added or removed (beforeAddLiquidity accepts only the factory, beforeRemoveLiquidity refuses nonzero deltas) and the opening tick is chosen by the IMD deployer from the policy's cap, not by this code. With 870M seed tokens the test needs an opening FDV of at least 19.54 ETH against a 20 ETH policy value, a 2.3% margin (under four tick spacings). _verifyOracle checks only the constants (quoted line); it has the verified factory position (liquidity and seed ticks from _verifyPosition) and could evaluate the same depth formula, but does not. A seed below the constant therefore activates normally and seals permanently; twapTick then reverts InvalidOracle on every call (`!last.liquid`, UnlkOracle.sol line 131), _updateMilestone swallows the revert and only sets confirmationInterrupted, so p stays 2500 and the $5M full unlock can never happen while trading, quotas and fees work and nothing signals the dead oracle. This is the brief's 'no hidden higher thresholds' concern reappearing as a hidden threshold on the opening cap. Fix: in configureAndActivate recompute depth from the recorded position (SqrtPriceMath.getAmount1Delta(rangeLower, rangeUpper, liquidity) scaled by 2^192 / rangeUpper^2) and revert InvalidPool when it is below the constant, or derive the threshold from the recorded seed instead of a constant.","line":390,"path":"src/UnlkHook.sol","reproduction":"Reproduced in test/scratch/Judge.t.sol:JudgeSeedCapacity (PASS = defect present). State: SystemFixture with _launchTokenOnly(-177840) instead of -177300 (opening FDV about 18.9 ETH, seed capacity 870M / 5.286e7 = 16.46 ETH < 17 ETH), local quote depth, feed $2000/ETH. deployCompanions, certifyRound(0), owner configureAndActivate -> succeeds, hook.activated() == true. alice buys with 12 ETH (spot FDV far above $100K), then 30 checkpoints every 5 minutes: last observation liquid == false; oracle.fdvUsd() reverts InvalidOracle; 80 further updateMilestone() calls every 5 minutes (6h40m, longer than the 6h first-tier confirmation) all return false; hook.tier() == 0. Expected: tier 1 (p = 3500) confirmed, as the identical sequence at -177300 achieves (test/Oracle.t.sol testSustainedManipulationRequiresWindowAndConfirmation). Actual: milestones permanently disabled with no recovery path.","severity":"medium","snippet":"                || oracle_.MIN_SEED_QUOTE_CAPACITY() != 17 ether || oracle_.SUPPLY() != token.SUPPLY()","title":"configureAndActivate pins the oracle's 17 ETH seed-capacity constant but never checks the real seed satisfies it, so an opening cap 2.3% under 20 ETH seals a hook whose milestones can never confirm"},{"citation":"resolved","description":"From audit_flow b537cd9a. beforeSwap re-reads slot0 on every swap and reverts InvalidPool if the PoolManager's protocol fee for this pool is non-zero. The protocol fee controller is Uniswap governance, an actor outside this launch. The hook is immutable, has no admin and refuses a second pool (beforeInitialize `bound` check), so one setProtocolFee call turns every router swap into a permanent revert; UnlkOracle.checkpoint also marks the pool illiquid under the same condition (UnlkOracle.sol line 104), so tier confirmation stops too. docs/SECURITY_REVIEW.md lists this as a trust assumption; it is kept here as a release decision the requester must make explicitly, because the brief's deliverable (active quota-enforced trading) would end irrecoverably. Earned credits remain recorded. An alternative that keeps liveness is to accept a changed protocol fee and disclose that the promised 1.25% total may rise.","line":417,"path":"src/UnlkHook.sol","reproduction":"State: activated launch (SystemFixture.setUp). manager.setProtocolFeeController(C) by the manager owner; as C call manager.setProtocolFee(key, 1000). alice calls router.swap{value: 1 ether}(SwapRequest(true, -1e18, MIN_SQRT_PRICE + 1, 1e18, 1, deadline)). Expected (liveness): swap settles at the new total fee. Actual: beforeSwap reverts InvalidPool on this and every later swap; oracle observations become liquid=false; no function in UnlkHook, UnlkSwapRouter, UnlkOracle or the factory can clear the condition. The repository's own test test/Adversarial.t.sol testProtocolFeeChangeCannotSilentlyAlterTradingEconomics demonstrates the revert.","severity":"low","snippet":"        if (protocolFee != 0 || lpFee != FEE) revert InvalidPool();","title":"A Uniswap protocol-fee change on the official pool halts all official trading and milestone progression permanently with no recovery path"},{"citation":"resolved","description":"From audit_flow 7a269bc7. _updateMilestone sets confirmationInterrupted whenever a call observes oracle.fdvUsd() reverting, and the next valid call then rewrites qualifyingSince[next] (line 611). Feed staleness is only evaluated at call time: the oracle's badSeconds track pool liquidity, not feed age, so an identical stale interval nobody calls into leaves the clock running. Outcome therefore depends on call timing, and updateMilestone is permissionless, so during any feed gap over 90 minutes (the Sepolia proxy is not SLA-backed and the authors measured heartbeat drift) a third party can reset the 6-hour (or 24-hour final) confirmation for every holder with one transaction. Nothing is revoked (tier never decreases); impact is unlock liveness only, and the docs describe the restart as a property of the data rather than of call timing. Fix: treat short invalid intervals uniformly, e.g. restart only when the invalid interval exceeds MAX_CONFIRMATION_GAP (record the first invalid timestamp and compare on the next valid call), or document that confirmation can be reset by a single call during any feed lateness.","line":600,"path":"src/UnlkHook.sol","reproduction":"Reproduced in test/scratch/Judge2.t.sol:JudgeConfirmationAsymmetry (both tests PASS = asymmetry present). State: activated, feed $3000/ETH, warmed 2h, updateMilestone every 5 minutes for 5h50m (tier 0, qualifyingSince[0] = T). Then feed.setRound(1, now - 91 min, now - 91 min, 1) for one minute, then feed.fresh(). Run A (unobserved): no call during the stale minute; next call keeps qualifyingSince[0] == T and two more 5-minute calls confirm tier 1. Run B (observed): one updateMilestone() during the stale minute returns false and sets confirmationInterrupted; the next valid call rewrites qualifyingSince[0] > T and the same two further calls leave tier at 0. Expected per docs: the same one-minute invalid interval, shorter than the 10-minute gap, has the same effect in both runs. Actual: six hours of confirmation discarded only when someone chose to call. test/Oracle.t.sol testInvalidDataCannotCountTowardPendingConfirmationOrRevokeRights shows the same restart after a 1-minute observed failure.","severity":"low","snippet":"            confirmationInterrupted = true;","title":"Confirmation restart depends on whether an invalid feed interval was observed by a call, so one permissionless updateMilestone during routine Chainlink lateness discards up to 24 hours of confirmation"},{"citation":"resolved","description":"From audit_economics bf72b15c. attest refuses any uncertified round (line 106) and certifyRound refuses trees over MAX_LEAVES = 1024 or with two leaves for one account (DuplicateRecipient, line 64). The IMD MerkleDistributor accepts both shapes (test/imd/MerkleDistributor.sol openRound takes any root; OpenZeppelin StandardMerkleTree permits two (account, amount) leaves per account). For round 0 the condition is caught before stage 2 (configureAndActivate requires certified(0), line 305), but for every later treasury round it is silent: contributors claim natively (eligibility untouched, as specified) yet syncRewards can never credit them, so Q stays 0 and they cannot sell a single token through the official pool until the $5M full unlock, while buyers of the same token can sell 25%. docs disclose the cap only as a round-0 preflight. The brief asks that proven actual native claims credit E. Fix that keeps the design: chunked certification that persists partially built level hashes, or raise the bound toward what the block gas allows (1024 leaves measured 13.9M gas, so about 2000 fit a 30M block).","line":56,"path":"src/MerkleClaimEvidence.sol","reproduction":"Reproduced in test/scratch/Judge2.t.sol:JudgeLeafCap. State: activated launch; treasury funds the distributor and calls openRound(root over 1025 distinct (account, amount) leaves, funded, 0) -> round 1. A contributor claims distributor.claim(1, account, amount, proof) and receives tokens. Anyone calls rewards.certifyRound(1, accounts[1025], amounts[1025]) -> revert InvalidConfig (n > MAX_LEAVES); the duplicate-recipient tree reverts DuplicateRecipient. rewards.attest(1, account, amount, proof) -> revert UncertifiedRound. hook.syncRewards(account) returns 0; hook.remainingQuota(account) == 0; a 1-wei sell through router.swap reverts QuotaExceeded in afterSwap. Expected: the proven native claim credits E. Actual: it can never be credited.","severity":"low","snippet":"        if (n == 0 || n > MAX_LEAVES || n != amounts.length || certified[round]) revert InvalidConfig();","title":"Claim rounds with more than 1024 leaves or a repeated recipient can never be certified, so claimants of such a round receive tokens but zero sell quota on the official pool"},{"citation":"resolved","description":"From audit_permissions 6698b9b2. MerkleDistributor.openRound lets LaunchFees.treasury() open any later round against tokens the distributor holds with any root; attest accepts any certified round whose claim flag is set and UnlkHook.syncRewards credits E (kind 2) for it. The treasury can therefore route tokens it holds (the swept round-0 remainder, or tokens bought elsewhere) to chosen wallets and give them 25%-100% sell quota that plain transfer recipients never get. Not a code defect: the brief asks that proven actual native claims credit E and these are real claims, and docs/SECURITY_REVIEW.md 'Trust and scope' already names the treasury's reward administration as a trust dependency. Recorded so the privileged power and its preconditions (LaunchFees owner controls treasury) are visible to the release decision.","line":105,"path":"src/MerkleClaimEvidence.sol","reproduction":"After activation: treasury T transfers 1,000,000 UNLK to the distributor; T calls distributor.openRound(root(T, 1e24), 1e24, 0) -> round 1; T calls distributor.claim(1, T, 1e24, proof); anyone calls rewards.certifyRound(1, [T], [1e24]) then rewards.attest(1, T, 1e24, proof); anyone calls hook.syncRewards(T). Expected under a strict 'swarm/pool/payer only' reading: T has no quota. Actual: eligible[T] += 1e24, so T may sell 250,000 UNLK on the official pool while a wallet that received the same 1,000,000 UNLK by plain transfer may sell nothing.","severity":"info","snippet":"        if (!merkleDistributor.claimed(round, account)) revert NotClaimed();","title":"Trust assumption: the IMD treasury can manufacture official-pool sell quota for any wallet by opening and funding a later distributor round"}],"hash":"eb017134efa111c396e767712fd20193eb62489ce6ec7652be9fe3fdb9296edf","nodeId":"22f999f3-9eaf-4dd2-8a31-52f1d754ef03","outcome":"completed","summary":"The review is complete. `.imd-findings.json` holds 6 judged findings and a 27-row coverage record (all 25 entry points answered, plus two invariants). The tree is unchanged apart from that file and the scratch tests under `test/scratch/`.\n\n**What I verified first.** The project builds, and all 151 existing tests pass. The manifest matches the implementation: four constructor words in declaration order, the eight permissions equal `getHookPermissions`, fee 12500 with spacing 60 on an ETH pair, notes under the 4,000-character cap, and the hook runtime is 22,388 bytes.\n\n**Findings kept, all reproduced in scratch tests I ran:**\n\n- **Medium, merged from four specialists.** Activation requires the factory seed within 1e12 wei of exactly 870M tokens, while the factory only enforces \"at most 87%\" and staging runs once without checking these preconditions. A liquidity word 1e9 units low seeds 7e12 wei short and leaves the stage-1 pool permanently unactivatable. Reproduced: the factory accepts the launch and `configureAndActivate` reverts with InvalidEvidence forever.\n- **Medium, merged from two specialists.** Activation pins the oracle's 17 ETH depth constant but never evaluates it against the real seed. A seed opened 2.3% or more under the 20 ETH cap activates and seals, and the oracle is never liquid, so no tier can ever confirm. Reproduced at tick -177840: activation succeeds, 80 milestone calls over 6h40m all fail, tier stays 0.\n- **Low.** A Uniswap protocol-fee change halts official trading and milestones permanently. Documented as a trust assumption; kept as an explicit release decision.\n- **Low.** Confirmation restart depends on whether a call observed the stale feed. Reproduced both runs: the same one-minute stale interval keeps the clock when unobserved and discards six hours when one permissionless call lands inside it.\n- **Low.** Rounds over 1024 leaves or with duplicate recipients can never be certified, so later-round claimants get tokens but zero sell quota.\n- **Info.** The treasury can manufacture quota through later distributor rounds. Already disclosed in the security review; recorded as a trust assumption.\n\n**Dropped after checking.** I traced a lead of my own where a sell past the seed boundary would push the pool price above the range and invalidate the TWAP for two hours. At any FDV where tiers matter, draining the pool's ETH needs more quota than the supply allows, so it is not reachable. Every slither and aderyn line was a false positive or already covered.\n\nNo finding reached high or critical, so no proof files were attached. Residual risks the author should keep disclosed: other-pool bypass, keeper dependence of the 10-minute confirmation cadence, and the funded sustained-manipulation path already modeled in the economics results.","treeHash":null,"usage":{"cachedInputTokens":1764016,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":33538,"runtime":"claude","turns":34,"wallClockMs":594589}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"bdd9b74dce66953d","findings":[{"citation":"resolved","description":"Boundary x invariant seam (external return value consumed with an exact-value assumption). LaunchFactory._seedRequesterPool only requires `taken <= totalSupply*poolBps/10000` (at most 870M) and sends every leftover token to the remainder wallet; the seed amount itself is `ceil(liquidity*(sqrtUpper-sqrtLower)/2^96)` for a `liquidity` the off-chain IMD deployer chooses. configureAndActivate then demands `initialAllocation(poolManager) >= 870M - 1e12 wei` and `initialAllocation(requester) <= 30M + 1e12 wei`. 1e12 wei is 1e-6 UNLK, a relative tolerance of 1.1e-15 of the seed. Any deployer-side rounding, floating-point derivation of `liquidity`, or deliberate safety margin below the 87% share (the natural way to guarantee the factory's `taken <= allowed` check never reverts) produces a stage-1 launch the factory accepts but the hook can never activate: the pool is live and the hook is bound in its PoolKey, so there is no substitute pool, no second launch of this token and no way to ever enable official trading, milestones or credits. The brief's rule 'never broadcast stage 1 without an executable stage-2 path' is violated by a precondition the project cannot verify before broadcast (the deployer's liquidity derivation is not part of the manifest, the policy row or the rehearsal). The tolerance should be proportional (e.g. accept pool >= 99% of POOL_ALLOCATION and payer <= PAYER_ALLOCATION + the pool shortfall) or activation should read the factory's recorded liquidity and recompute the seed instead of pinning an absolute 1e12-wei window.","line":290,"path":"src/UnlkHook.sol","reproduction":"State: fixture launch exactly as test/fixtures/SystemFixture.sol but with `liquidity = floor((870_000_000e18 - 1e15) * 2^96 / (sqrtPriceAtTick(177300) - sqrtPriceAtTick(-887220)))`, i.e. a seed short by 0.001 UNLK. Call sequence: factory.launch(params) succeeds (taken = 869_999_999.998999999999993678e18 <= allowed, remainder 30_000_000.001000000000006322e18 to payer); owner calls hook.deployCompanions(1, feed, routerCode, evidenceCode, oracleCode) succeeds; rewards.certifyRound(0, [alice], [REWARD]) succeeds; owner calls hook.configureAndActivate(router, rewards, oracle, 1). Expected: activation succeeds (the seed is 99.9999999999% of the share, every other evidence check passes). Actual: revert InvalidEvidence() at the quoted condition (870M - 869_999_999.998999999999993678e18 = 1_000_000_000_006_322 wei > 1e12), and hook.activated() stays false on every retry forever. Reproduced in test/scratch/SeedTolerance.t.sol (subclass of SystemFixture; overrides setUp to launch with the shortened liquidity, then expectRevert(UnlkHook.InvalidEvidence.selector) on configureAndActivate): PASS, logged pool allocation 869999999998999999999993678 and shortfall 1000000000006322 wei. With the fixture's default liquidity the same sequence activates, which isolates the tolerance as the sole cause.","severity":"medium","snippet":"                || token.initialAllocation(address(poolManager)) > token.POOL_ALLOCATION()\n                || token.initialAllocation(address(poolManager)) + 1e12 < token.POOL_ALLOCATION()\n                || token.initialAllocation(requester) < token.PAYER_ALLOCATION()\n                || token.initialAllocation(requester) > token.PAYER_ALLOCATION() + 1e12","title":"Activation requires the pool seed to be within 1e12 wei (0.000001 UNLK) of exactly 870M; a seed the factory accepts that is short by 0.001 UNLK bricks stage 2 permanently"},{"citation":"resolved","description":"Boundary x precision seam. UnlkOracle.checkpoint marks every observation `liquid=false` unless `depth = seedTokens * 2^192 / rangeUpper^2 >= 17 ether`, and twapTick/fdvUsd revert whenever any second of the 2-hour window is not liquid; _updateMilestone catches that revert and only sets confirmationInterrupted, so a hook whose seed never satisfies the depth test is permanently stuck at tier 0 / p=2500 while trading continues. With 870M seed tokens the test needs an ETH-per-token value at the range's upper boundary of >= 17/870M, i.e. an opening FDV of >= 19.54 ETH; the policy value the docs cite is 20 ETH (fixture uses 19.968 ETH), a 2.3% margin against a number the hook cannot read on chain and that the deployer derives off chain (policy row 'launch_policies', not the manifest). Activation verifies the oracle's constants (quoted line) but never evaluates the depth test against the real position it just verified in _verifyPosition, although all inputs (factory position liquidity, seed ticks) are available there. A seed opened 5.4% under the cap (tick 177840 instead of 177300 in the normalized orientation, or any lower cap in a future policy version) activates normally and silently disables every milestone: price can be above the $5M tier for days and `updateMilestone()` returns false forever. Because activation 'seals configuration permanently' and the oracle cannot be replaced, this is unrecoverable after the owner's single call. Fix: in _verifyOracle/configureAndActivate recompute the seed capacity from the verified factory position and revert InvalidPool when it is below MIN_SEED_QUOTE_CAPACITY (or revert when oracle_.checkpoint() produces a non-liquid first observation while sqrtPrice is at/inside the range), so the failure is visible before sealing.","line":390,"path":"src/UnlkHook.sol","reproduction":"State: fixture launch (test/fixtures/SystemFixture.sol) with `_launchTokenOnly(-177840)` instead of the default -177300 (opening price 5.286e7 UNLK/ETH, FDV 18.92 ETH, seed capacity 870M/5.286e7 = 16.46 ETH < 17 ETH), feed at $2000/ETH, no quote top-up. Call sequence: deployCompanions, certifyRound(0,...), owner configureAndActivate -> succeeds, hook.activated()==true. Then alice buys with 12 ETH (pool FDV far above the $100K tier at $2000/ETH), warp WINDOW+1 and checkpoint, then call hook.updateMilestone() every 5 minutes for 80 iterations (6 h 40 min, more than the 6 h first-tier confirmation). Expected: tier 1 confirmed (p=3500) since the TWAP has been above $100K for the whole window and cadence. Actual: oracle.fdvUsd() reverts InvalidOracle() on every call, every updateMilestone() returns false, hook.tier()==0 and hook.p()==2500 permanently. Reproduced in test/scratch/SeedCapacity.t.sol (PASS). The same sequence with the default -177300 seed advances to tier 1 (existing test/Oracle.t.sol testSustainedManipulationRequiresWindowAndConfirmation).","severity":"medium","snippet":"                || oracle_.MIN_SEED_QUOTE_CAPACITY() != 17 ether || oracle_.SUPPLY() != token.SUPPLY()","title":"configureAndActivate never checks that the actual seed passes the oracle's fixed 17 ETH capacity test, so an opening cap 2.3% under 20 ETH seals a hook whose milestones can never confirm"}],"hash":"f976d9234f3510b2ce15068a8460a3c44ec233a1c9a4bb52bea543c5beedfe58","nodeId":"092fade1-d74f-4d03-b7de-66b1e5ddbee4","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds two substantiated findings plus a coverage row for all 25 entry points and three checked invariants.\n\n**What I covered (Math Precision, Boundary, Numerical Gap guides):**\n- Quota arithmetic in `afterSwap` and `remainingQuota`: floor(E·p/10000) minus S matches the brief, int128 sign handling is safe, and the router makes a zero token delta impossible.\n- Oracle math: the depth formula seedTokens·2^192/rangeUpper² loses about 1e-23 relative precision, the TWAP floor-division for negative ticks is correct, the binary search returns the last observation at or before the window start, and the FDV scale chain (wei/token to USD18 to FDV18, 512-bit branch above 2^128) has no overflow or decimal mismatch.\n- Milestone cadence: the 4-minute minimum, 10-minute maximum gap, 6h/24h durations and array indices (qualifyingSince[0..5], percentages[0..6]) are all in bounds. A try/catch gas-griefing reset is not feasible because fdvUsd costs far less than 63× the catch body.\n- Router settlement: native and ERC-20 branches reconcile pre and post balances, the batch value sum cannot overflow, exact output must fill fully, and withdrawals zero state before the call.\n- Merkle certification: n in [1,1024], the single-leaf edge, heap reconstruction and uniqueness via heapsort hold.\n\n**Findings (both medium, both reproduced by scratch tests under `test/scratch/`):**\n1. **Seed tolerance is 1e12 wei.** Activation requires the pool's initial allocation to be within 0.000001 UNLK of exactly 870M, but the factory accepts any seed up to that share and the off-chain deployer chooses the liquidity. A seed short by 0.001 UNLK launches normally and can never activate, leaving a live pool with no stage-2 path. Reproduced in `SeedTolerance.t.sol`.\n2. **No seed-capacity check before sealing.** The oracle's fixed 17 ETH capacity test needs an opening FDV of at least 19.54 ETH, a 2.3% margin under a policy value the hook cannot read. Activation verifies the constant but never evaluates it against the real position, so an opening 5.4% under the cap activates and then every milestone stays dead forever while trading continues. Reproduced in `SeedCapacity.t.sol`.\n\n**Not reached:** economic manipulation cost modelling, the Sepolia rehearsal script and `script/Stage2.s.sol` are outside my area and were not traced. Static-analysis leads in my area (divide-before-multiply in the depth formula, strict equalities in checkpoint and twapTick, the uninitialized `fdv` local) were checked and are not defects.","treeHash":null,"usage":{"cachedInputTokens":2075070,"inputTokens":514,"model":"claude-fable-5-1","outputTokens":56120,"runtime":"claude","turns":33,"wallClockMs":875947}},{"artifacts":[],"attempt":1,"bundleHash":"70fa49c70aa513cc8267a7c79bf2968fbd0a1bfd0d4f61264e74f28738148182","device":"dedc96e38388cb45","findings":[],"hash":"fff4c7010c6f5c1794eb7af2403519955d07fe6ec72f8e81c807d7f8fb247749","nodeId":"f571ba87-b559-40ee-99df-d83c48d506a7","outcome":"completed","summary":"Done. The suite is green and only test paths changed.\n\n**What I found on arrival.** The build was broken: the other contributor's newer accepted work removed the hook's `confirmationInterrupted` flag, and my previous round's batch-settlement test still read it. The implementation also gained a seed-depth gate, repeatable staging and chunked Merkle certification since my tests were written.\n\n**What I changed.**\n- Removed the one stale line from `test/BatchSettlementProperties.t.sol`. Nothing else in the three earlier files moved.\n- Added `test/RevisionProperties.t.sol` with four suites aimed at the changed code:\n  - Fuzz over 51 opening boundaries and the 98 to 100 percent liquidity band. A seed launches if and only if it clears the capacity floor and pool-share band, every launched seed is classed liquid and priced within 0.2 percent of its boundary FDV, and the remainder wallet is never over-credited.\n  - Fuzz over chunked certification with random chunk sizes and reduce counts. It certifies exactly when the single-shot path would, a corrupted parallel session never certifies or interferes, and abandoned sessions are inert.\n  - A fail-on-revert invariant campaign that samples milestones under six feed corruptions and price swings, with an independent ghost chain of valid samples. No tier advances on invalid data, below threshold, by more than one step, or before the required unbroken confirmation. Nothing relocks.\n  - A re-staging test: mixed bundles are refused, attestations on abandoned evidence create no rights, and the abandoned router and oracle are inert.\n- Documented the revision in `test/ADDITIONAL_COVERAGE.md`.\n\n**Results.** Full run: 170 tests passed across 37 suites, zero failed or skipped. No implementation defect was reproduced, so no findings file was written. The two failures hit during development were harness bugs in my own tests, since the distributor's contributor lock blocks early claims and forge-std's bound wraps rather than clamps.\n\n**Left as is.** Changes are uncommitted in the working tree, matching how prior rounds were committed by the pipeline. The package's recorded deployment status and disclosed manipulation risks are unchanged by this tests-only revision.","treeHash":"3f4fbeae47ed2ab3c58bf791df5b4e7fb18c6a28","usage":{"cachedInputTokens":2146143,"inputTokens":642,"model":"claude-fable-5-1","outputTokens":42697,"runtime":"claude","turns":29,"wallClockMs":884011}}],"verification":[{"checks":[{"durationMs":13968,"exitCode":0,"name":"build","output":"Compiling 124 files with Solc 0.8.26\nSolc 0.8.26 finished in 13.83s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> src/UnlkHook.sol:189:5:\n    |\n189 |     function afterInitialize(address, PoolKey calldata key, uint160, int24)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":3164,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/LocalScript.t.sol:LocalScriptTest\n[PASS] testLocalScriptRefusesPublicChainId() (gas: 13945506)\n[PASS] testLocalSimulationFunctionDoesNotDependOnCaller() (gas: 82068248)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 34.37ms (40.16ms CPU time)\n\nRan 2 tests for test/TwoStage.t.sol:StageOneConstructorTest\n[PASS] testConstructorRejectsMissingOrConflatedInputs() (gas: 8175)\n[PASS] testOnlyFactoryCanInitializeTheHooksPool() (gas: 43150)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 42.69ms (213.44µs CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:EvidenceCertificationRegressionTest\n[PASS] testActualLaterRoundClaimsHaveNoArtificialCumulativeCeiling() (gas: 1526816)\n[PASS] testDuplicateRecipientCannotOvercreditSmallerActualClaim() (gas: 441255)\n[PASS] testIncompleteTreeCannotBeCertified() (gas: 59551)\n[PASS] testOddTreeReconstructionAndPreCertificationNativeClaim() (gas: 580590)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 45.20ms (1.32ms CPU time)\n\nRan 1 test for test/FailurePaths.t.sol:UnpaidLaunchTest\n[PASS] testNoRequesterMeansNoPayerCreditAnywhere() (gas: 1281574)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 47.66ms (1.08ms CPU time)\n\nRan 2 tests for test/SecurityRegression.t.sol:StagingCreationRegressionTest\n[PASS] testCounterfeitConstructorIsRefusedBeforeAnyDeployment() (gas: 5638758)\n[PASS] testOnlySetupAuthorityMayStageAndTheBundleCannotBeReplaced() (gas: 5989428)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 52.47ms (2.29ms CPU time)\n\nRan 8 tests for test/Adversarial.t.sol:AdversarialTest\n[PASS] test100PercentAloneIsNotFullUnlock() (gas: 7311138)\n[PASS] testArbitraryHookDataAndMultihopPayloadCannotSelectVictim() (gas: 87252)\n[PASS] testCallbacksAllRequireCanonicalManager() (gas: 211601)\n[PASS] testForeignPoolKeyRejectedEvenWithManagerPrank() (gas: 49904)\n[PASS] testNoMintPauseBlacklistUpgradeOrCounterResetEntrypoint() (gas: 114792)\n[PASS] testProtocolFeeChangeCannotSilentlyAlterTradingEconomics() (gas: 355367)\n[PASS] testQuotaMultiplicationDoesNotOverflowAtMaxEligible() (gas: 239252)\n[PASS] testTokenMintsWholeSupplyToDeployerOnly() (gas: 32832)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 61.92ms (11.15ms CPU time)\n\nRan 2 tests for test/Stage2Script.t.sol:Stage2ScriptTest\n[PASS] testStage2DeploysFromActualIdentitiesAndOwnerActivates() (gas: 6348536)\n[PASS] testStage2RefusesUnknownLaunchNumber() (gas: 34700)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 67.90ms (1.53ms CPU time)\n\nRan 1 test for test/EvidenceAndOracleProperties.t.sol:RouterDeadlineTest\n[PASS] testDeadlineIsInclusive() (gas: 438525)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 69.77ms (497.62µs CPU time)\n\nRan 8 tests for test/Launch.t.sol:LaunchTest\n[PASS] testCompanionsAreImmutablyBound() (gas: 37797)\n[PASS] testFactoryHoldsPrincipalAndCannotRemoveIt() (gas: 330242)\n[PASS] testLaunchAllocationAndLockedPrincipal() (gas: 191089)\n[PASS] testLaunchIsOnceAndDeployerOnly() (gas: 2535198)\n[PASS] testOnlyCanonicalManagerCanCallHook() (gas: 66434)\n[PASS] testPayerCreditExactDeduplicated() (gas: 137518)\n[PASS] testUnauthorizedFactoryAndWrongPoolRejected() (gas: 80489)\n[PASS] testUnconfiguredComponentsFailClosed() (gas: 42307)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 72.89ms (1.93ms CPU time)\n\nRan 10 tests for test/CreditsAndFees.t.sol:CreditsAndFeesTest\n[PASS] testAttestationRequiresActualClaimAndExactLeaf() (gas: 438858)\n[PASS] testClaimTransferAndPayerTransferDoNotDuplicateCredit() (gas: 578096)\n[PASS] testFeeCollectionDoesNotReducePrincipal() (gas: 661053)\n[PASS] testNativeClaimNeverDependsOnAdapterOrFeed() (gas: 863245)\n[PASS] testNativeClaimThenAttestThenSyncThenSale() (gas: 1294958)\n[PASS] testNegativeLiquidityForbiddenEvenForFactory() (gas: 82486)\n[PASS] testProofReleaseAndDedupRemainNativeRules() (gas: 573246)\n[PASS] testSaleFeesCountGrossInputAndNeverCreditFeeRecipients() (gas: 1202770)\n[PASS] testUnauthorizedLiquidityAndDonationNoCredit() (gas: 231982)\n[PASS] testUnclaimedRewardsNotEligible() (gas: 39420)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 73.84ms (4.98ms CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:CodeAuthenticationRegressionTest\n[PASS] testActivationExternalFailureRollsBackEveryBinding() (gas: 816427)\n[PASS] testInconsistentImmutablePatchesAreRejected() (gas: 1780923)\n[PASS] testLaterFactoryDonationsCannotRewriteInitialAllocationReceipts() (gas: 645016)\n[PASS] testRuntimeMutationCannotPassGetterChecks() (gas: 82704)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 74.19ms (4.54ms CPU time)\n\nRan 5 tests for test/EvidenceAndOracleProperties.t.sol:MultiLeafEvidenceTest\n[PASS] testDecreasingEvidenceCannotRevokePreviouslyCreditedClaims() (gas: 1056937)\n[PASS] testProofsFromTheActualTreeCreditExactlyWhatWasDelivered() (gas: 2254239)\n[PASS] testSiblingCannotAttestAnotherWalletsClaim() (gas: 727383)\n[PASS] testSweptRoundFreezesEvidence() (gas: 1092289)\n[PASS] testTheTreeIsWellFormed() (gas: 40973)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 75.02ms (3.99ms CPU time)\n\nRan 13 tests for test/TwoStage.t.sol:StageOneTest\n[PASS] testActivationSealsAndCannotBeReplayed() (gas: 5408612)\n[PASS] testCrossLaunchNumberRejected() (gas: 4910081)\n[PASS] testFactoryLiquidityAllowedBeforeActivationButPrincipalStaysLocked() (gas: 37250)\n[PASS] testFirstTierConfirmsBelowTenEthActualReserves() (gas: 34928073)\n[PASS] testLaunchSucceedsWithoutCompanions() (gas: 122586)\n[PASS] testPayerCanTransferBeforeActivationWithoutLosingHistoricalCredit() (gas: 5400034)\n[PASS] testPayerCreditOnlyAfterActivationAndFromOriginalTransferReceipt() (gas: 5349170)\n[PASS] testRequesterReassignmentCannotMoveInitialAllocationCredit() (gas: 5355841)\n[PASS] testSepoliaRequiresPublishedChainlinkFeed() (gas: 4926289)\n[PASS] testSwapsSyncAndMilestonesRevertBeforeActivation() (gas: 5399610)\n[PASS] testTransfersAndNativeClaimsWorkBeforeActivationAndClaimIsCreditedLater() (gas: 5704570)\n[PASS] testUnauthorizedActivationRejected() (gas: 4924157)\n[PASS] testWrongContractsRejected() (gas: 5598163)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 78.58ms (34.49ms CPU time)\n\nRan 3 tests for test/ReleaseConfig.t.sol:ReleaseConfigTest\n[PASS] testReadOnlyReleaseChecksOnLocalFixture() (gas: 2007175)\n[PASS] testReadOnlyReleaseChecksRejectWrongChainOrHash() (gas: 1903780)\n[PASS] testStageOneAloneCannotPassReleaseGate() (gas: 104610744)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 104.71ms (58.35ms CPU time)\n\nRan 3 tests for test/FailurePaths.t.sol:ActivationFailurePathsTest\n[PASS] testCompanionConstructorsRejectMissingInputs() (gas: 6057)\n[PASS] testCrossLaunchSetupIsRefusedInEveryDirection() (gas: 68602857)\n[PASS] testSepoliaRefusesLocallyClonedServicesEvenWithFeedAtPublishedAddress() (gas: 674688)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 138.57ms (69.62ms CPU time)\n\nRan 1 test for test/SecurityRegression.t.sol:LargeTreeCertificationTest\n[PASS] testMaximumSortedTreeFitsTransactionGasLimit() (gas: 15977629)\nLogs:\n  1024-leaf sorted certification gas: 13943571\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 140.71ms (62.31ms CPU time)\n\nRan 3 tests for test/ManipulationEconomics.t.sol:ManipulationEconomicsTest\n[PASS] testCounterSellingOfAllInitialNonPoolTokens() (gas: 157882639)\nLogs:\n  gross ETH capital (wei): 404492004375936755769\n  attacker ETH exit (wei): 139667041180374722901\n  net ETH exit cost before fee recapture (wei): 264824963195562032868\n  payer ETH fee receipts (wei): 4044920043759367559\n  counter-seller ETH proceeds (wei): 259768813140862823404\n  duration seconds: 201600\n\n[PASS] testPayerCanRecaptureItsNativeFeeShare() (gas: 144878918)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n  net ETH cost after native fee recapture (wei): 653249186877100125\n\n[PASS] testSustainedManipulationUnlockAndExit() (gas: 144892638)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 209.75ms (321.21ms CPU time)\n\nRan 9 tests for test/Trading.t.sol:TradingTest\n[PASS] testAnotherWalletCannotConsumeVictimsAllowanceOrQuota() (gas: 487139)\n[PASS] testDirectManagerAndForeignRouterSpoofingRejected() (gas: 640118)\n[PASS] testDonatedRouterBalancesCannotCreateCreditOrBeSwept() (gas: 512478)\n[PASS] testExactOutputSaleAccountsActualInput() (gas: 749117)\n[PASS] testExcessSaleRollsBackPoolBalancesOracleAndNonce() (gas: 811734)\n[PASS] testFuzzQuotaBoundary(uint96) (runs: 256, μ: 1048113, ~: 1048115)\n[PASS] testReplayOldCallbackHasNoLiveContext() (gas: 440344)\n[PASS] testSaleBoundaryExecutedInputIncludesPoolFee() (gas: 1077346)\n[PASS] testTransfersDoNotMoveRightsOrAllowChainCredit() (gas: 841817)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 209.69ms (170.14ms CPU time)\n\nRan 11 tests for test/NativeLaunch.t.sol:NativeWithdrawalTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136305473)\n[PASS] testNativeBatchSettlement() (gas: 883303)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1140215)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 468433)\n[PASS] testNativeSettlementResetsPriorSyncCurrency() (gas: 620796)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 91991)\n[PASS] testNativeWithdrawalUsesCEIAndCannotDoubleWithdraw() (gas: 1011298)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62521)\n[PASS] testOtherWalletCannotWithdrawNativeRefund() (gas: 476334)\n[PASS] testRejectingNativeWalletCanTradeAndRetryWithdrawal() (gas: 1089620)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29985485)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 212.84ms (140.11ms CPU time)\n\nRan 15 tests for test/Oracle.t.sol:OracleTest\n[PASS] testBadChainlinkRoundsAndAnswersFailClosed() (gas: 2379231)\n[PASS] testConfirmationGapRestartsRatherThanCountingUnobservedTime() (gas: 14864669)\n[PASS] testEveryTierAndPermanentUnlock() (gas: 136707061)\n[PASS] testFallingPricesNeverLowerReachedTier() (gas: 29279733)\n[PASS] testInvalidDataCannotCountTowardPendingConfirmationOrRevokeRights() (gas: 15090747)\n[PASS] testInvalidDataLongerThanGapRestartsOnNextValidCall() (gas: 683632)\n[PASS] testNegativeTickAveragesRoundConservativelyForBothOrders() (gas: 753196)\n[PASS] testOneBlockSpikeCannotConfirm() (gas: 724914)\n[PASS] testOracleCannotBeReboundOrConfiguredByAnyone() (gas: 73530)\n[PASS] testRealFeedCadenceCannotBeUsedToResetConfirmation() (gas: 18798127)\n[PASS] testSameTimestampManipulationHasNoTimeWeight() (gas: 744167)\n[PASS] testStaleCheckpointAndFeedPreventNewTierButNotTrades() (gas: 1333080)\n[PASS] testSustainedManipulationRequiresWindowAndConfirmation() (gas: 15135794)\n[PASS] testThresholdMappingBoundaries() (gas: 70282)\n[PASS] testWarmupAndExactWindow() (gas: 401264)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 236.24ms (206.82ms CPU time)\n\nRan 3 tests for test/EvidenceAndOracleProperties.t.sol:OracleReferenceTest\n[PASS] testCheckpointReplacementRewritesOnlyTheCurrentSecond() (gas: 995880)\n[PASS] testFuzzFdvIsMonotonicInTheEthUsdAnswer(uint64,uint64) (runs: 256, μ: 766937, ~: 767219)\n[PASS] testFuzzTwapMatchesBruteForceReference(uint256) (runs: 160, μ: 2780693, ~: 2796052)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 288.83ms (329.94ms CPU time)\n\nRan 3 tests for test/SecurityRegression.t.sol:OracleOutageRegressionTest\n[PASS] testDepthDipInvalidatesWholeWindowAndRetainsReachedRights() (gas: 16359514)\n[PASS] testFinalTierRequiresItsOwnTwentyFourHours() (gas: 139055056)\n[PASS] testNextTierClockWaitsForItsOwnThreshold() (gas: 15316716)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 527.96ms (122.47ms CPU time)\n\nRan 7 tests for test/NativeLaunch.t.sol:NativeLaunchTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136305472)\n[PASS] testNativeBatchSettlement() (gas: 883303)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1140204)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 468344)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 92013)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62543)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29985485)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 527.98ms (110.00ms CPU time)\n\nRan 17 tests for test/FailurePaths.t.sol:RouterAndHookFailurePathsTest\n[PASS] testBatchBoundsAndValueMustMatch() (gas: 186819)\n[PASS] testBatchIsAtomicWhenALaterStepFails() (gas: 851118)\n[PASS] testConfirmationRequiresSixHoursAndCannotSkipTiers() (gas: 15363937)\n[PASS] testFullUnlockKeepsFeesAndRouterAuthentication() (gas: 137213772)\n[PASS] testFuzzOperationHashBindsTraderNonceAndChain(address,uint256,uint64) (runs: 256, μ: 17656, ~: 17656)\n[PASS] testFuzzRemainingQuotaFormula(uint128,uint128,uint8) (runs: 512, μ: 7298557, ~: 7298720)\n[PASS] testFuzzTierIsMonotonicInFdv(uint256,uint256) (runs: 512, μ: 17102, ~: 17055)\n[PASS] testFuzzTransfersMoveExactlyTheAmount(address,uint96) (runs: 256, μ: 122201, ~: 122475)\n[PASS] testHookRejectsMalformedRouteDataAndUnknownSenders() (gas: 230888)\n[PASS] testPartialFillAtPriceLimitChargesOnlyExecutedInput() (gas: 1226453)\n[PASS] testQuotaWidensWithTierAndNeverDoubleCounts() (gas: 16805520)\n[PASS] testRequesterChangeAfterActivationDoesNotMoveThePayer() (gas: 146422)\n[PASS] testRouterCallbackNeedsALiveSwap() (gas: 73817)\n[PASS] testRouterRefusesDegenerateRequests() (gas: 500369)\n[PASS] testSecondRoundClaimsAccumulateOncePerRound() (gas: 995717)\n[PASS] testSlippageRefusalsLeaveNoTrace() (gas: 936477)\n[PASS] testSyncForStrangerAndZeroAddressCreatesNothing() (gas: 108559)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 576.96ms (1.58s CPU time)\n\nRan 1 test for test/StageOneInvariants.t.sol:StageOneInvariantTest\n[PASS]\nStageOneInvariantTest invariants:\n[PASS] invariant_onlyTheAuthorizedCallActivates\n[PASS] invariant_tokenAndClaimsIndependentOfTheHook\n[PASS] invariant_unconfiguredPoolIsInert\n StageOneInvariantTest invariants (runs: 96, calls: 3840, reverts: 0)\n\n╭-----------------+------------------+-------+---------+----------╮\n| Contract        | Selector         | Calls | Reverts | Discards |\n+=================================================================+\n| StageOneHandler | advance          | 495   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | attemptActivate  | 473   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | claimAndAttest   | 480   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | directSwap       | 479   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | foreignLiquidity | 448   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | routerSwap       | 486   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | syncAndMilestone | 482   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | transfer         | 497   | 0       | 0        |\n╰-----------------+------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 676.14ms (634.90ms CPU time)\n\nRan 1 test for test/Invariants.t.sol:SystemInvariantTest\n[PASS]\nSystemInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n SystemInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 828   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 800   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 834   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 901   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 864   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 893   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.89s (1.82s CPU time)\n\nRan 1 test for test/Invariants.t.sol:FullyUnlockedInvariantTest\n[PASS]\nFullyUnlockedInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n[PASS] invariantUnlockRemainsPermanentDespiteInvalidFeed\n FullyUnlockedInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 828   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 800   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 834   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 901   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 864   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 893   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.91s (1.66s CPU time)\n\nRan 2 tests for test/QuotaInvariants.t.sol:QuotaInvariantTest\n[PASS]\nQuotaInvariantTest invariants:\n[PASS] invariant_configurationSealedAndRouteEnforced\n[PASS] invariant_ledgerMatchesExecutedDeltas\n[PASS] invariant_milestonesMonotonicAndConsistent\n[PASS] invariant_principalLockedAndFeeTermsFixed\n[PASS] invariant_routerNativeSolvency\n[PASS] invariant_salesNeverExceedQuota\n[PASS] invariant_supplyConservedAndNoCustody\n QuotaInvariantTest invariants (runs: 96, calls: 5760, reverts: 0)\n\n╭--------------+-----------------+-------+---------+----------╮\n| Contract     | Selector        | Calls | Reverts | Discards |\n+=============================================================+\n| QuotaHandler | advance         | 369   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactIn      | 372   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactOut     | 352   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimAndAttest  | 363   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimFees       | 359   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | directSwap      | 353   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | donate          | 370   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | foreignActivate | 359   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellExactOut    | 341   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellOverQuota   | 349   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellWithinQuota | 762   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | setFeed         | 354   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sync            | 351   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | transfer        | 376   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | withdrawNative  | 330   | 0       | 0        |\n╰--------------+-----------------+-------+---------+----------╯\n\n[PASS] testHandlerActionsActuallyExecute() (gas: 23850193)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 3.03s (2.95s CPU time)\n\nRan 28 test suites in 3.03s (11.48s CPU time): 142 tests passed, 0 failed, 0 skipped (142 total tests)\n","passed":true},{"durationMs":104,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MerkleClaimEvidence.attest(uint256,address,uint256,bytes32[])\",\"MerkleClaimEvidence.certifyRound(uint256,address[],uint256[])\",\"UnlkHook.afterAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"UnlkHook.afterRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"UnlkHook.beforeAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"UnlkHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"UnlkHook.configureAndActivate(address,address,address,uint64)\",\"UnlkHook.deployCompanions(uint64,address,bytes,bytes,bytes)\",\"UnlkHook.syncPayer()\",\"UnlkHook.syncRewards(address)\",\"UnlkHook.updateMilestone()\",\"UnlkOracle.bind((address,address,uint24,int24,address),address,int24,int24)\",\"UnlkOracle.checkpoint()\",\"UnlkSwapRouter.receive()\",\"UnlkSwapRouter.swap((bool,int256,uint160,uint256,uint256,uint256))\",\"UnlkSwapRouter.swapBatch((bool,int256,uint160,uint256,uint256,uint256)[])\",\"UnlkSwapRouter.unlockCallback(bytes)\",\"UnlkSwapRouter.withdrawNative()\",\"UnlkToken.approve(address,uint256)\",\"UnlkToken.transfer(address,uint256)\",\"UnlkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"LICENSE\":25,\"README.md\":129,\"RELEASE_STATUS.json\":29,\"dependencies.lock.json\":24,\"docs/ARTIFACTS.json\":52,\"docs/BUILD_RESULTS.txt\":9,\"docs/DEPLOYMENT.md\":132,\"docs/ECONOMICS_RESULTS.txt\":49,\"docs/FMT_RESULTS.txt\":0,\"docs/FORK_RESULTS.txt\":24,\"docs/LINT_RESULTS.txt\":386,\"docs/MINIMAL_ENV_TEST_RESULTS.txt\":355,\"docs/NETWORK_VERIFICATION_RESULTS.txt\":7,\"docs/PROTECTED_TEST_RESULTS.txt\":22,\"docs/RECOVERY.md\":60,\"docs/SECURITY_REVIEW.md\":112,\"docs/SOURCE_SHA256SUMS\":449,\"docs/SOURCE_VERIFICATION_RESULTS.txt\":449,\"docs/TEST_RESULTS.txt\":346,\"docs/VALIDATION.md\":111,\"docs/abi/CheckReleaseConfig.json\":46,\"docs/abi/HookDeployer.json\":84,\"docs/abi/IChainlinkEthUsd.json\":48,\"docs/abi/IClaimEvidence.json\":47,\"docs/abi/IHooks.json\":789,\"docs/abi/ILaunchFactoryView.json\":115,\"docs/abi/ILaunchRegistryView.json\":70,\"docs/abi/IMerkleDistributor.json\":125,\"docs/abi/IPoolManager.json\":1286,\"docs/abi/IRouteContext.json\":20,\"docs/abi/LaunchFactory.json\":896,\"docs/abi/LaunchFees.json\":323,\"docs/abi/LaunchRegistry.json\":320,\"docs/abi/MerkleClaimEvidence.json\":269,\"docs/abi/MerkleDistributor.json\":451,\"docs/abi/Stage2.json\":225,\"docs/abi/UnlkHook.json\":1921,\"docs/abi/UnlkOracle.json\":443,\"docs/abi/UnlkSwapRouter.json\":359,\"docs/abi/UnlkToken.json\":425,\"docs/network/capabilities.json\":345,\"docs/network/factory-artifacts.json\":2201,\"docs/network/factory-reference.json\":420,\"docs/network/factory.runtime.hex\":1,\"docs/network/feed-reference.json\":67,\"docs/network/feed-rounds.json\":134,\"docs/network/feed.runtime.hex\":1,\"docs/network/fees.runtime.hex\":1,\"docs/network/job-identity.json\":14,\"docs/network/manager.runtime.hex\":1,\"docs/network/policies.json\":36,\"docs/network/registry-reference.json\":108,\"docs/network/registry.runtime.hex\":1,\"docs/network/sepolia.json\":309,\"docs/network/services.json\":29,\"foundry.toml\":31,\"launch.json\":35,\"rehearsal/Sepolia.t.sol\":112,\"remappings.txt\":4,\"script/CheckReleaseConfig.s.sol\":85,\"script/LocalDemo.s.sol\":41,\"script/Stage2.s.sol\":100,\"scripts/check.sh\":8,\"scripts/check_protected.py\":31,\"scripts/export_abis.py\":33,\"scripts/generate_code_checks.py\":22,\"scripts/mine-hook.sh\":9,\"scripts/prepare_claim_tree.py\":37,\"scripts/rehearse-sepolia.sh\":4,\"scripts/release_artifacts.py\":49,\"scripts/verify_network.py\":46,\"src/HookDeployer.sol\":29,\"src/HookFlags.sol\":45,\"src/MerkleClaimEvidence.sol\":115,\"src/UnlkHook.sol\":645,\"src/UnlkOracle.sol\":194,\"src/UnlkSwapRouter.sol\":225,\"src/UnlkToken.sol\":42,\"src/interfaces/IIntegration.sol\":86,\"src/libraries/OperationHash.sol\":15,\"src/libraries/ReviewedCode.sol\":10,\"src/libraries/SepoliaRelease.sol\":11,\"test/Adversarial.t.sol\":117,\"test/CreditsAndFees.t.sol\":176,\"test/EvidenceAndOracleProperties.t.sol\":349,\"test/FailurePaths.t.sol\":580,\"test/Invariants.t.sol\":220,\"test/Launch.t.sol\":112,\"test/LocalScript.t.sol\":28,\"test/ManipulationEconomics.t.sol\":117,\"test/NativeLaunch.t.sol\":236,\"test/Oracle.t.sol\":364,\"test/QuotaInvariants.t.sol\":529,\"test/ReleaseConfig.t.sol\":32,\"test/SecurityRegression.t.sol\":318,\"test/Stage2Script.t.sol\":62,\"test/StageOneInvariants.t.sol\":281,\"test/Trading.t.sol\":171,\"test/TwoStage.t.sol\":302,\"test/fixtures/LocalFixtures.sol\":59,\"test/fixtures/SystemFixture.sol\":371,\"test/imd/HookFlags.sol\":45,\"test/imd/LaunchFactory.sol\":375,\"test/imd/LaunchFees.sol\":73,\"test/imd/LaunchRegistry.sol\":109,\"test/imd/MerkleDistributor.sol\":181,\"test/imd/PoolFees.sol\":220,\"test/imd/README.md\":29,\"test/mocks/MockERC20.sol\":11},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":3816,"exitCode":0,"name":"slither","output":"[high/medium] reentrancy-balance at src/UnlkSwapRouter.sol:104: Reentrancy in UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166):\n[high/medium] reentrancy-balance at src/UnlkSwapRouter.sol:104: Reentrancy in UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166):\n[medium/medium] divide-before-multiply at src/UnlkOracle.sol:126: UnlkOracle.twapTick() (src/UnlkOracle.sol#126-151) performs a multiplication on the result of a division:\n[medium/high] incorrect-equality at src/UnlkOracle.sol:90: UnlkOracle.checkpoint() (src/UnlkOracle.sol#90-119) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/UnlkOracle.sol:90: UnlkOracle.checkpoint() (src/UnlkOracle.sol#90-119) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/UnlkOracle.sol:126: UnlkOracle.twapTick() (src/UnlkOracle.sol#126-151) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/UnlkHook.sol:593: UnlkHook._updateMilestone() (src/UnlkHook.sol#593-635) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/UnlkHook.sol:424: Reentrancy in UnlkHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/UnlkHook.sol#424-455):\n[medium/medium] uninitialized-local at src/UnlkHook.sol:353: UnlkHook._verifyLaunchRecord(uint64).hookSeen (src/UnlkHook.sol#353) is a local variable never initialized\n[medium/medium] uninitialized-local at src/UnlkHook.sol:352: UnlkHook._verifyLaunchRecord(uint64).tokenSeen (src/UnlkHook.sol#352) is a local variable never initialized\n[medium/medium] uninitialized-local at src/UnlkHook.sol:595: UnlkHook._updateMilestone().fdv (src/UnlkHook.sol#595) is a local variable never initialized\n[medium/medium] uninitialized-local at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256).state (src/UnlkSwapRouter.sol#114) is a local variable never initialized\n[medium/medium] unused-return at src/UnlkOracle.sol:90: UnlkOracle.checkpoint() (src/UnlkOracle.sol#90-119) ignores return value by (liquidity,None,None) = poolManager.getPositionInfo(poolId,factory,rangeLowerTick,rangeUpperTick,bytes32(0)) (src/UnlkOracle.sol#93-94)\n[medium/medium] unused-return at src/UnlkHook.sol:402: UnlkHook.beforeSwap(address,PoolKey,SwapParams,bytes) (src/UnlkHook.sol#402-422) ignores return value by (None,None,protocolFee,lpFee) = poolManager.getSlot0(poolId) (src/UnlkHook.sol#416)\n[low/medium] events-maths at src/UnlkHook.sol:459: UnlkHook.beforeAddLiquidity(address,PoolKey,ModifyLiquidityParams,bytes) (src/UnlkHook.sol#459-475) should emit an event for: \n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: outputBefore = state.outputToken.balanceOf(msg.sender) (src/UnlkSwapRouter.sol#155)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: key = hook.poolKey() (src/UnlkSwapRouter.sol#113)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: state.baseInput = state.inputToken.balanceOf(address(this)) (src/UnlkSwapRouter.sol#120-122)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: state.outputToken.balanceOf(msg.sender) != outputBefore + output (src/UnlkSwapRouter.sol#157)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: ! hook.activated() || block.timestamp > request.deadline || request.amountSpecified == 0 || request.amountSpecified == type()(int256).min || request.maxInput == 0 || request.maxInput > uint256(uint128(type()(int128).max)) || request.minOutput == 0 (src/UnlkSwapRouter.sol#109-111)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: result = poolManager.unlock(abi.encode(key,params,operationNonce,request.maxInput)) (src/UnlkSwapRouter.sol#139)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: state.baseOutput = state.outputToken.balanceOf(address(this)) (src/UnlkSwapRouter.sol#123-124)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: state.inputToken.balanceOf(address(this)) != state.baseInput + request.maxInput (src/UnlkSwapRouter.sol#129)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:172: UnlkSwapRouter._balance(IERC20) (src/UnlkSwapRouter.sol#172-174) has external calls inside a loop: currency.balanceOf(address(this)) (src/UnlkSwapRouter.sol#173)\n[low/medium] reentrancy-benign at src/UnlkSwapRouter.sol:104: Reentrancy in UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166):\n[low/medium] reentrancy-benign at src/UnlkHook.sol:424: Reentrancy in UnlkHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/UnlkHook.sol#424-455):\n[low/medium] reentrancy-benign at src/UnlkHook.sol:577: Reentrancy in UnlkHook.updateMilestone() (src/UnlkHook.sol#577-581):\n[low/medium] reentrancy-events at src/UnlkHook.sol:577: Reentrancy in UnlkHook.updateMilestone() (src/UnlkHook.sol#577-581):\n[low/medium] reentrancy-events at src/UnlkHook.sol:257: Reentrancy in UnlkHook.configureAndActivate(address,IClaimEvidence,UnlkOracle,uint64) (src/UnlkHook.sol#257-324):\n[low/medium] reentrancy-events at src/UnlkHook.sol:424: Reentrancy in UnlkHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/UnlkHook.sol#424-455):\n[low/medium] timestamp at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkOracle.sol:90: UnlkOracle.checkpoint() (src/UnlkOracle.sol#90-119) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkHook.sol:593: UnlkHook._updateMilestone() (src/UnlkHook.sol#593-635) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkOracle.sol:126: UnlkOracle.twapTick() (src/UnlkOracle.sol#126-151) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkOracle.sol:154: UnlkOracle.fdvUsd() (src/UnlkOracle.sol#154-168) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkOracle.sol:170: UnlkOracle._ethUsd() (src/UnlkOracle.sol#170-183) uses timestamp for comparisons","passed":true},{"durationMs":738,"exitCode":0,"name":"aderyn","output":"[high] eth-send-unchecked-address at src/UnlkSwapRouter.sol:184: ETH transferred without address checks\n[high] reentrancy-state-change at src/MerkleClaimEvidence.sol:70: Reentrancy: State change after external call (12 places)\n[high] unprotected-initializer at src/HookDeployer.sol:19: Unprotected initializer (2 places)\n[low] costly-loop at src/UnlkSwapRouter.sol:95: Costly operations inside loop\n[low] internal-function-used-once at src/HookFlags.sol:35: Internal Function Used Only Once\n[low] large-numeric-literal at src/UnlkHook.sol:445: Large Numeric Literal (15 places)\n[low] literal-instead-of-constant at src/UnlkHook.sol:220: Literal Instead of Constant (17 places)\n[low] missing-inheritance at src/UnlkOracle.sol:15: Missing Inheritance\n[low] require-revert-in-loop at src/MerkleClaimEvidence.sol:58: Loop Contains `require`/`revert` (4 places)\n[low] state-change-without-event at src/UnlkHook.sol:402: State Change Without Event (4 places)\n[low] unchecked-return at src/UnlkHook.sol:282: Unchecked Return (2 places)\n[low] uninitialized-local-variable at src/UnlkHook.sol:354: Uninitialized Local Variable\n[low] unused-import at src/libraries/OperationHash.sol:4: Unused Import","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"244435b64432dabceff2dea95f9f2b0099f9c511ced89387e8100d50099fd3ec","verifiedTreeHash":"babea043e157805f758500cac81af1eb62cb992e","verifierVersion":"0.1.0+327e1e9f"},{"checks":[{"durationMs":17434,"exitCode":0,"name":"build","output":"Compiling 126 files with Solc 0.8.26\nSolc 0.8.26 finished in 17.30s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> src/UnlkHook.sol:205:5:\n    |\n205 |     function afterInitialize(address, PoolKey calldata key, uint160, int24)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":3383,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/LocalScript.t.sol:LocalScriptTest\n[PASS] testLocalScriptRefusesPublicChainId() (gas: 13945506)\n[PASS] testLocalSimulationFunctionDoesNotDependOnCaller() (gas: 67855480)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 14.65ms (14.14ms CPU time)\n\nRan 2 tests for test/Stage2Script.t.sol:Stage2ScriptTest\n[PASS] testStage2DeploysFromActualIdentitiesAndOwnerActivates() (gas: 6832294)\n[PASS] testStage2RefusesUnknownLaunchNumber() (gas: 33767)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 24.45ms (1.66ms CPU time)\n\nRan 1 test for test/FailurePaths.t.sol:UnpaidLaunchTest\n[PASS] testNoRequesterMeansNoPayerCreditAnywhere() (gas: 1264616)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 27.20ms (1.09ms CPU time)\n\nRan 2 tests for test/SecurityRegression.t.sol:StagingCreationRegressionTest\n[PASS] testCounterfeitConstructorIsRefusedBeforeAnyDeployment() (gas: 6161976)\n[PASS] testOnlySetupAuthorityMayStageAndOnlyUntilActivation() (gas: 11784008)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 31.21ms (3.79ms CPU time)\n\nRan 10 tests for test/CreditsAndFees.t.sol:CreditsAndFeesTest\n[PASS] testAttestationRequiresActualClaimAndExactLeaf() (gas: 438961)\n[PASS] testClaimTransferAndPayerTransferDoNotDuplicateCredit() (gas: 577960)\n[PASS] testFeeCollectionDoesNotReducePrincipal() (gas: 646031)\n[PASS] testNativeClaimNeverDependsOnAdapterOrFeed() (gas: 846757)\n[PASS] testNativeClaimThenAttestThenSyncThenSale() (gas: 1280110)\n[PASS] testNegativeLiquidityForbiddenEvenForFactory() (gas: 82464)\n[PASS] testProofReleaseAndDedupRemainNativeRules() (gas: 573172)\n[PASS] testSaleFeesCountGrossInputAndNeverCreditFeeRecipients() (gas: 1188451)\n[PASS] testUnauthorizedLiquidityAndDonationNoCredit() (gas: 232025)\n[PASS] testUnclaimedRewardsNotEligible() (gas: 39399)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 33.54ms (4.70ms CPU time)\n\nRan 1 test for test/EvidenceAndOracleProperties.t.sol:RouterDeadlineTest\n[PASS] testDeadlineIsInclusive() (gas: 422030)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 36.37ms (395.57µs CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:CodeAuthenticationRegressionTest\n[PASS] testActivationExternalFailureRollsBackEveryBinding() (gas: 913067)\n[PASS] testInconsistentImmutablePatchesAreRejected() (gas: 1782922)\n[PASS] testLaterFactoryDonationsCannotRewriteInitialAllocationReceipts() (gas: 688991)\n[PASS] testRuntimeMutationCannotPassGetterChecks() (gas: 84703)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 39.20ms (9.75ms CPU time)\n\nRan 2 tests for test/TwoStage.t.sol:StageOneConstructorTest\n[PASS] testConstructorRejectsMissingOrConflatedInputs() (gas: 8175)\n[PASS] testOnlyFactoryCanInitializeTheHooksPool() (gas: 43150)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 39.98ms (160.25µs CPU time)\n\nRan 8 tests for test/Launch.t.sol:LaunchTest\n[PASS] testCompanionsAreImmutablyBound() (gas: 37886)\n[PASS] testFactoryHoldsPrincipalAndCannotRemoveIt() (gas: 333697)\n[PASS] testLaunchAllocationAndLockedPrincipal() (gas: 191055)\n[PASS] testLaunchIsOnceAndDeployerOnly() (gas: 2730017)\n[PASS] testOnlyCanonicalManagerCanCallHook() (gas: 66479)\n[PASS] testPayerCreditExactDeduplicated() (gas: 137462)\n[PASS] testUnauthorizedFactoryAndWrongPoolRejected() (gas: 80623)\n[PASS] testUnconfiguredComponentsFailClosed() (gas: 42307)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 41.11ms (9.69ms CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:EvidenceCertificationRegressionTest\n[PASS] testActualLaterRoundClaimsHaveNoArtificialCumulativeCeiling() (gas: 1510126)\n[PASS] testDuplicateRecipientCannotOvercreditSmallerActualClaim() (gas: 441218)\n[PASS] testIncompleteTreeCannotBeCertified() (gas: 59593)\n[PASS] testOddTreeReconstructionAndPreCertificationNativeClaim() (gas: 580532)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 43.01ms (1.57ms CPU time)\n\nRan 3 tests for test/FailurePaths.t.sol:ActivationFailurePathsTest\n[PASS] testCompanionConstructorsRejectMissingInputs() (gas: 6057)\n[PASS] testCrossLaunchSetupIsRefusedInEveryDirection() (gas: 30758204)\n[PASS] testSepoliaRefusesLocallyClonedServicesEvenWithFeedAtPublishedAddress() (gas: 676754)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 64.58ms (38.59ms CPU time)\n\nRan 1 test for test/SecurityRegression.t.sol:LargeTreeCertificationTest\n[PASS] testMaximumSortedTreeFitsTransactionGasLimit() (gas: 15973574)\nLogs:\n  1024-leaf sorted certification gas: 13939470\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 72.71ms (47.02ms CPU time)\n\nRan 5 tests for test/EvidenceAndOracleProperties.t.sol:MultiLeafEvidenceTest\n[PASS] testDecreasingEvidenceCannotRevokePreviouslyCreditedClaims() (gas: 1100787)\n[PASS] testProofsFromTheActualTreeCreditExactlyWhatWasDelivered() (gas: 2298120)\n[PASS] testSiblingCannotAttestAnotherWalletsClaim() (gas: 771379)\n[PASS] testSweptRoundFreezesEvidence() (gas: 1136221)\n[PASS] testTheTreeIsWellFormed() (gas: 40973)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 117.07ms (18.22ms CPU time)\n\nRan 3 tests for test/SecurityRegression.t.sol:OracleOutageRegressionTest\n[PASS] testDepthDipInvalidatesWholeWindowAndRetainsReachedRights() (gas: 16312506)\n[PASS] testFinalTierRequiresItsOwnTwentyFourHours() (gas: 138827744)\n[PASS] testNextTierClockWaitsForItsOwnThreshold() (gas: 15293513)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 121.46ms (121.92ms CPU time)\n\nRan 11 tests for test/NativeLaunch.t.sol:NativeWithdrawalTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136092723)\n[PASS] testNativeBatchSettlement() (gas: 865791)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1124527)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 451977)\n[PASS] testNativeSettlementResetsPriorSyncCurrency() (gas: 604340)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 91930)\n[PASS] testNativeWithdrawalUsesCEIAndCannotDoubleWithdraw() (gas: 994842)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62586)\n[PASS] testOtherWalletCannotWithdrawNativeRefund() (gas: 459878)\n[PASS] testRejectingNativeWalletCanTradeAndRetryWithdrawal() (gas: 1073164)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29938965)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 121.93ms (136.37ms CPU time)\n\nRan 6 tests for test/ActivationRobustness.t.sol:ActivationRobustnessTest\n[PASS] testPolicySeedRecordsCapacityAndConfirmsTiers() (gas: 30335357)\n[PASS] testSeedBelowOpeningValueFloorCannotLaunch() (gas: 9047798)\n[PASS] testSeedBelowThePoolShareBandCannotLaunch() (gas: 9043839)\n[PASS] testSeedInsideTheOnePercentBandActivates() (gas: 15647267)\n[PASS] testStagingRunsActivationPreconditionsAndCanRepeat() (gas: 21081828)\n[PASS] testSubDustSeedRoundingStillActivates() (gas: 16005370)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 134.91ms (35.46ms CPU time)\n\nRan 8 tests for test/Adversarial.t.sol:AdversarialTest\n[PASS] test100PercentAloneIsNotFullUnlock() (gas: 7307385)\n[PASS] testArbitraryHookDataAndMultihopPayloadCannotSelectVictim() (gas: 89207)\n[PASS] testCallbacksAllRequireCanonicalManager() (gas: 211512)\n[PASS] testForeignPoolKeyRejectedEvenWithManagerPrank() (gas: 49882)\n[PASS] testNoMintPauseBlacklistUpgradeOrCounterResetEntrypoint() (gas: 114793)\n[PASS] testProtocolFeeChangeCannotSilentlyAlterTradingEconomics() (gas: 357261)\n[PASS] testQuotaMultiplicationDoesNotOverflowAtMaxEligible() (gas: 239235)\n[PASS] testTokenMintsWholeSupplyToDeployerOnly() (gas: 32832)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 160.42ms (12.07ms CPU time)\n\nRan 9 tests for test/Trading.t.sol:TradingTest\n[PASS] testAnotherWalletCannotConsumeVictimsAllowanceOrQuota() (gas: 470687)\n[PASS] testDirectManagerAndForeignRouterSpoofingRejected() (gas: 644028)\n[PASS] testDonatedRouterBalancesCannotCreateCreditOrBeSwept() (gas: 496022)\n[PASS] testExactOutputSaleAccountsActualInput() (gas: 732168)\n[PASS] testExcessSaleRollsBackPoolBalancesOracleAndNonce() (gas: 797176)\n[PASS] testFuzzQuotaBoundary(uint96) (runs: 256, μ: 1032857, ~: 1032869)\n[PASS] testReplayOldCallbackHasNoLiveContext() (gas: 425843)\n[PASS] testSaleBoundaryExecutedInputIncludesPoolFee() (gas: 1062165)\n[PASS] testTransfersDoNotMoveRightsOrAllowChainCredit() (gas: 827129)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 168.95ms (83.03ms CPU time)\n\nRan 7 tests for test/NativeLaunch.t.sol:NativeLaunchTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136092722)\n[PASS] testNativeBatchSettlement() (gas: 865791)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1124516)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 451888)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 91952)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62608)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29938965)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 189.81ms (159.37ms CPU time)\n\nRan 3 tests for test/ManipulationEconomics.t.sol:ManipulationEconomicsTest\n[PASS] testCounterSellingOfAllInitialNonPoolTokens() (gas: 157719009)\nLogs:\n  gross ETH capital (wei): 404492004375936755769\n  attacker ETH exit (wei): 139667041180374722901\n  net ETH exit cost before fee recapture (wei): 264824963195562032868\n  payer ETH fee receipts (wei): 4044920043759367559\n  counter-seller ETH proceeds (wei): 259768813140862823404\n  duration seconds: 201600\n\n[PASS] testPayerCanRecaptureItsNativeFeeShare() (gas: 144653849)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n  net ETH cost after native fee recapture (wei): 653249186877100125\n\n[PASS] testSustainedManipulationUnlockAndExit() (gas: 144667569)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 206.27ms (368.12ms CPU time)\n\nRan 3 tests for test/EvidenceAndOracleProperties.t.sol:OracleReferenceTest\n[PASS] testCheckpointReplacementRewritesOnlyTheCurrentSecond() (gas: 994219)\n[PASS] testFuzzFdvIsMonotonicInTheEthUsdAnswer(uint64,uint64) (runs: 256, μ: 750361, ~: 750529)\n[PASS] testFuzzTwapMatchesBruteForceReference(uint256) (runs: 160, μ: 2839929, ~: 2781288)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 304.20ms (366.62ms CPU time)\n\nRan 4 tests for test/ActivationRobustness.t.sol:ChunkedCertificationTest\n[PASS] testChunkBoundsAndSizeAreFixedByTheFirstChunk() (gas: 29517535)\n[PASS] testDuplicateAcrossChunksWrongRootAndForeignSessionsAreRefused() (gas: 231631551)\n[PASS] testSingleLeafRoundCertifiesThroughTheChunkedPath() (gas: 398202)\n[PASS] testSingleShotRefusesButChunksCertifyAndCredit() (gas: 124071664)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 486.74ms (144.37ms CPU time)\n\nRan 3 tests for test/ReleaseConfig.t.sol:ReleaseConfigTest\n[PASS] testReadOnlyReleaseChecksOnLocalFixture() (gas: 2011487)\n[PASS] testReadOnlyReleaseChecksRejectWrongChainOrHash() (gas: 1903758)\n[PASS] testStageOneAloneCannotPassReleaseGate() (gas: 74944069)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 534.01ms (88.32ms CPU time)\n\nRan 17 tests for test/Oracle.t.sol:OracleTest\n[PASS] testBadChainlinkRoundsAndAnswersFailClosed() (gas: 2352246)\n[PASS] testConfirmationGapRestartsRatherThanCountingUnobservedTime() (gas: 14857451)\n[PASS] testEveryTierAndPermanentUnlock() (gas: 136511302)\n[PASS] testFallingPricesNeverLowerReachedTier() (gas: 29259665)\n[PASS] testInvalidDataCannotCountTowardPendingConfirmationOrRevokeRights() (gas: 15083422)\n[PASS] testInvalidDataLongerThanGapRestartsOnNextValidCall() (gas: 694951)\n[PASS] testLongInvalidIntervalRestartsWhetherObservedOrNot() (gas: 807692)\n[PASS] testNegativeTickAveragesRoundConservativelyForBothOrders() (gas: 767868)\n[PASS] testObservedAndUnobservedInvalidIntervalsAgree() (gas: 29667292)\n[PASS] testOneBlockSpikeCannotConfirm() (gas: 739290)\n[PASS] testOracleCannotBeReboundOrConfiguredByAnyone() (gas: 73530)\n[PASS] testRealFeedCadenceCannotBeUsedToResetConfirmation() (gas: 18790257)\n[PASS] testSameTimestampManipulationHasNoTimeWeight() (gas: 758610)\n[PASS] testStaleCheckpointAndFeedPreventNewTierButNotTrades() (gas: 1329158)\n[PASS] testSustainedManipulationRequiresWindowAndConfirmation() (gas: 15126515)\n[PASS] testThresholdMappingBoundaries() (gas: 69776)\n[PASS] testWarmupAndExactWindow() (gas: 400906)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 587.46ms (266.92ms CPU time)\n\nRan 13 tests for test/TwoStage.t.sol:StageOneTest\n[PASS] testActivationSealsAndCannotBeReplayed() (gas: 5901690)\n[PASS] testCrossLaunchNumberRejected() (gas: 5361101)\n[PASS] testFactoryLiquidityAllowedBeforeActivationButPrincipalStaysLocked() (gas: 37293)\n[PASS] testFirstTierConfirmsBelowTenEthActualReserves() (gas: 35384808)\n[PASS] testLaunchSucceedsWithoutCompanions() (gas: 122562)\n[PASS] testPayerCanTransferBeforeActivationWithoutLosingHistoricalCredit() (gas: 5893013)\n[PASS] testPayerCreditOnlyAfterActivationAndFromOriginalTransferReceipt() (gas: 5842154)\n[PASS] testRequesterReassignmentCannotMoveInitialAllocationCredit() (gas: 5848820)\n[PASS] testSepoliaRequiresPublishedChainlinkFeed() (gas: 5377611)\n[PASS] testSwapsSyncAndMilestonesRevertBeforeActivation() (gas: 5849964)\n[PASS] testTransfersAndNativeClaimsWorkBeforeActivationAndClaimIsCreditedLater() (gas: 6199971)\n[PASS] testUnauthorizedActivationRejected() (gas: 5373249)\n[PASS] testWrongContractsRejected() (gas: 6061423)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 587.54ms (25.95ms CPU time)\n\nRan 17 tests for test/FailurePaths.t.sol:RouterAndHookFailurePathsTest\n[PASS] testBatchBoundsAndValueMustMatch() (gas: 186758)\n[PASS] testBatchIsAtomicWhenALaterStepFails() (gas: 830450)\n[PASS] testConfirmationRequiresSixHoursAndCannotSkipTiers() (gas: 15340175)\n[PASS] testFullUnlockKeepsFeesAndRouterAuthentication() (gas: 137004282)\n[PASS] testFuzzOperationHashBindsTraderNonceAndChain(address,uint256,uint64) (runs: 256, μ: 17656, ~: 17656)\n[PASS] testFuzzRemainingQuotaFormula(uint128,uint128,uint8) (runs: 512, μ: 7293364, ~: 7293203)\n[PASS] testFuzzTierIsMonotonicInFdv(uint256,uint256) (runs: 512, μ: 16965, ~: 16923)\n[PASS] testFuzzTransfersMoveExactlyTheAmount(address,uint96) (runs: 256, μ: 122349, ~: 122463)\n[PASS] testHookRejectsMalformedRouteDataAndUnknownSenders() (gas: 238753)\n[PASS] testPartialFillAtPriceLimitChargesOnlyExecutedInput() (gas: 1208964)\n[PASS] testQuotaWidensWithTierAndNeverDoubleCounts() (gas: 16785891)\n[PASS] testRequesterChangeAfterActivationDoesNotMoveThePayer() (gas: 146383)\n[PASS] testRouterCallbackNeedsALiveSwap() (gas: 73817)\n[PASS] testRouterRefusesDegenerateRequests() (gas: 500273)\n[PASS] testSecondRoundClaimsAccumulateOncePerRound() (gas: 995639)\n[PASS] testSlippageRefusalsLeaveNoTrace() (gas: 895597)\n[PASS] testSyncForStrangerAndZeroAddressCreatesNothing() (gas: 108400)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 587.61ms (1.29s CPU time)\n\nRan 1 test for test/StageOneInvariants.t.sol:StageOneInvariantTest\n[PASS]\nStageOneInvariantTest invariants:\n[PASS] invariant_onlyTheAuthorizedCallActivates\n[PASS] invariant_tokenAndClaimsIndependentOfTheHook\n[PASS] invariant_unconfiguredPoolIsInert\n StageOneInvariantTest invariants (runs: 96, calls: 3840, reverts: 0)\n\n╭-----------------+------------------+-------+---------+----------╮\n| Contract        | Selector         | Calls | Reverts | Discards |\n+=================================================================+\n| StageOneHandler | advance          | 428   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | attemptActivate  | 464   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | claimAndAttest   | 511   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | directSwap       | 497   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | foreignLiquidity | 474   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | routerSwap       | 457   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | syncAndMilestone | 503   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | transfer         | 506   | 0       | 0        |\n╰-----------------+------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 818.29ms (777.92ms CPU time)\n\nRan 1 test for test/Invariants.t.sol:SystemInvariantTest\n[PASS]\nSystemInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n SystemInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 833   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 812   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 896   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 816   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 898   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 865   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.96s (1.93s CPU time)\n\nRan 1 test for test/Invariants.t.sol:FullyUnlockedInvariantTest\n[PASS]\nFullyUnlockedInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n[PASS] invariantUnlockRemainsPermanentDespiteInvalidFeed\n FullyUnlockedInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 833   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 812   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 896   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 816   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 898   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 865   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.00s (1.82s CPU time)\n\nRan 2 tests for test/QuotaInvariants.t.sol:QuotaInvariantTest\n[PASS]\nQuotaInvariantTest invariants:\n[PASS] invariant_configurationSealedAndRouteEnforced\n[PASS] invariant_ledgerMatchesExecutedDeltas\n[PASS] invariant_milestonesMonotonicAndConsistent\n[PASS] invariant_principalLockedAndFeeTermsFixed\n[PASS] invariant_routerNativeSolvency\n[PASS] invariant_salesNeverExceedQuota\n[PASS] invariant_supplyConservedAndNoCustody\n QuotaInvariantTest invariants (runs: 96, calls: 5760, reverts: 0)\n\n╭--------------+-----------------+-------+---------+----------╮\n| Contract     | Selector        | Calls | Reverts | Discards |\n+=============================================================+\n| QuotaHandler | advance         | 334   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactIn      | 343   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactOut     | 369   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimAndAttest  | 376   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimFees       | 359   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | directSwap      | 359   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | donate          | 368   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | foreignActivate | 360   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellExactOut    | 377   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellOverQuota   | 384   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellWithinQuota | 702   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | setFeed         | 369   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sync            | 321   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | transfer        | 380   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | withdrawNative  | 359   | 0       | 0        |\n╰--------------+-----------------+-------+---------+----------╯\n\n[PASS] testHandlerActionsActuallyExecute() (gas: 23814275)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 3.22s (3.24s CPU time)\n\nRan 30 test suites in 3.23s (12.78s CPU time): 154 tests passed, 0 failed, 0 skipped (154 total tests)\n","passed":true},{"durationMs":135,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MerkleClaimEvidence.abandonSession(uint256)\",\"MerkleClaimEvidence.attest(uint256,address,uint256,bytes32[])\",\"MerkleClaimEvidence.certifyRound(uint256,address[],uint256[])\",\"MerkleClaimEvidence.reduce(uint256,uint256)\",\"MerkleClaimEvidence.submitLeaves(uint256,uint256,address[],uint256[])\",\"UnlkHook.afterAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"UnlkHook.afterRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"UnlkHook.beforeAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"UnlkHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"UnlkHook.configureAndActivate(address,address,address,uint64)\",\"UnlkHook.deployCompanions(uint64,address,bytes,bytes,bytes)\",\"UnlkHook.syncPayer()\",\"UnlkHook.syncRewards(address)\",\"UnlkHook.updateMilestone()\",\"UnlkOracle.bind((address,address,uint24,int24,address),address,int24,int24)\",\"UnlkOracle.checkpoint()\",\"UnlkSwapRouter.receive()\",\"UnlkSwapRouter.swap((bool,int256,uint160,uint256,uint256,uint256))\",\"UnlkSwapRouter.swapBatch((bool,int256,uint160,uint256,uint256,uint256)[])\",\"UnlkSwapRouter.unlockCallback(bytes)\",\"UnlkSwapRouter.withdrawNative()\",\"UnlkToken.approve(address,uint256)\",\"UnlkToken.transfer(address,uint256)\",\"UnlkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"LICENSE\":25,\"README.md\":146,\"RELEASE_STATUS.json\":29,\"dependencies.lock.json\":24,\"docs/ARTIFACTS.json\":52,\"docs/BUILD_RESULTS.txt\":9,\"docs/DEPLOYMENT.md\":139,\"docs/ECONOMICS_RESULTS.txt\":49,\"docs/FMT_RESULTS.txt\":0,\"docs/FORK_RESULTS.txt\":24,\"docs/LINT_RESULTS.txt\":372,\"docs/MINIMAL_ENV_TEST_RESULTS.txt\":355,\"docs/NETWORK_VERIFICATION_RESULTS.txt\":7,\"docs/PROTECTED_TEST_RESULTS.txt\":22,\"docs/RECOVERY.md\":65,\"docs/SECURITY_REVIEW.md\":123,\"docs/SOURCE_SHA256SUMS\":451,\"docs/SOURCE_VERIFICATION_RESULTS.txt\":449,\"docs/TEST_RESULTS.txt\":364,\"docs/VALIDATION.md\":115,\"docs/abi/CheckReleaseConfig.json\":46,\"docs/abi/HookDeployer.json\":84,\"docs/abi/IChainlinkEthUsd.json\":48,\"docs/abi/IClaimEvidence.json\":47,\"docs/abi/IHooks.json\":789,\"docs/abi/ILaunchFactoryView.json\":115,\"docs/abi/ILaunchRegistryView.json\":70,\"docs/abi/IMerkleDistributor.json\":125,\"docs/abi/IPoolManager.json\":1286,\"docs/abi/IRouteContext.json\":20,\"docs/abi/LaunchFactory.json\":896,\"docs/abi/LaunchFees.json\":323,\"docs/abi/LaunchRegistry.json\":320,\"docs/abi/MerkleClaimEvidence.json\":461,\"docs/abi/MerkleDistributor.json\":451,\"docs/abi/Stage2.json\":225,\"docs/abi/UnlkHook.json\":1973,\"docs/abi/UnlkOracle.json\":443,\"docs/abi/UnlkSwapRouter.json\":359,\"docs/abi/UnlkToken.json\":425,\"docs/network/capabilities.json\":345,\"docs/network/factory-artifacts.json\":2201,\"docs/network/factory-reference.json\":420,\"docs/network/factory.runtime.hex\":1,\"docs/network/feed-reference.json\":67,\"docs/network/feed-rounds.json\":134,\"docs/network/feed.runtime.hex\":1,\"docs/network/fees.runtime.hex\":1,\"docs/network/job-identity.json\":14,\"docs/network/manager.runtime.hex\":1,\"docs/network/policies.json\":36,\"docs/network/registry-reference.json\":108,\"docs/network/registry.runtime.hex\":1,\"docs/network/sepolia.json\":309,\"docs/network/services.json\":29,\"foundry.toml\":31,\"launch.json\":35,\"rehearsal/Sepolia.t.sol\":112,\"remappings.txt\":4,\"script/CheckReleaseConfig.s.sol\":85,\"script/LocalDemo.s.sol\":41,\"script/Stage2.s.sol\":98,\"scripts/check.sh\":8,\"scripts/check_protected.py\":31,\"scripts/export_abis.py\":33,\"scripts/generate_code_checks.py\":22,\"scripts/mine-hook.sh\":9,\"scripts/prepare_claim_tree.py\":37,\"scripts/rehearse-sepolia.sh\":4,\"scripts/release_artifacts.py\":51,\"scripts/verify_network.py\":46,\"src/HookDeployer.sol\":29,\"src/HookFlags.sol\":45,\"src/MerkleClaimEvidence.sol\":200,\"src/UnlkHook.sol\":719,\"src/UnlkOracle.sol\":190,\"src/UnlkSwapRouter.sol\":225,\"src/UnlkToken.sol\":42,\"src/interfaces/IIntegration.sol\":86,\"src/libraries/OperationHash.sol\":15,\"src/libraries/ReviewedCode.sol\":10,\"src/libraries/SeedDepth.sol\":41,\"src/libraries/SepoliaRelease.sol\":11,\"test/ActivationRobustness.t.sol\":303,\"test/Adversarial.t.sol\":117,\"test/CreditsAndFees.t.sol\":176,\"test/EvidenceAndOracleProperties.t.sol\":349,\"test/FailurePaths.t.sol\":580,\"test/Invariants.t.sol\":220,\"test/Launch.t.sol\":112,\"test/LocalScript.t.sol\":28,\"test/ManipulationEconomics.t.sol\":117,\"test/NativeLaunch.t.sol\":236,\"test/Oracle.t.sol\":422,\"test/QuotaInvariants.t.sol\":529,\"test/ReleaseConfig.t.sol\":32,\"test/SecurityRegression.t.sol\":337,\"test/Stage2Script.t.sol\":62,\"test/StageOneInvariants.t.sol\":281,\"test/Trading.t.sol\":171,\"test/TwoStage.t.sol\":302,\"test/fixtures/LocalFixtures.sol\":59,\"test/fixtures/SystemFixture.sol\":371,\"test/imd/HookFlags.sol\":45,\"test/imd/LaunchFactory.sol\":375,\"test/imd/LaunchFees.sol\":73,\"test/imd/LaunchRegistry.sol\":109,\"test/imd/MerkleDistributor.sol\":181,\"test/imd/PoolFees.sol\":220,\"test/imd/README.md\":29,\"test/mocks/MockERC20.sol\":11},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":4501,"exitCode":0,"name":"slither","output":"[high/medium] reentrancy-balance at src/UnlkSwapRouter.sol:104: Reentrancy in UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166):\n[high/medium] reentrancy-balance at src/UnlkSwapRouter.sol:104: Reentrancy in UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166):\n[medium/medium] divide-before-multiply at src/UnlkOracle.sol:122: UnlkOracle.twapTick() (src/UnlkOracle.sol#122-147) performs a multiplication on the result of a division:\n[medium/high] incorrect-equality at src/UnlkOracle.sol:122: UnlkOracle.twapTick() (src/UnlkOracle.sol#122-147) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/UnlkOracle.sol:90: UnlkOracle.checkpoint() (src/UnlkOracle.sol#90-115) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/UnlkOracle.sol:90: UnlkOracle.checkpoint() (src/UnlkOracle.sol#90-115) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/UnlkHook.sol:478: Reentrancy in UnlkHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/UnlkHook.sol#478-509):\n[medium/medium] uninitialized-local at src/UnlkHook.sol:411: UnlkHook._verifyLaunchRecord(uint64).hookSeen (src/UnlkHook.sol#411) is a local variable never initialized\n[medium/medium] uninitialized-local at src/UnlkHook.sol:410: UnlkHook._verifyLaunchRecord(uint64).tokenSeen (src/UnlkHook.sol#410) is a local variable never initialized\n[medium/medium] uninitialized-local at src/UnlkHook.sol:669: UnlkHook._updateMilestone().fdv (src/UnlkHook.sol#669) is a local variable never initialized\n[medium/medium] uninitialized-local at src/UnlkSwapRouter.sol:114: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256).state (src/UnlkSwapRouter.sol#114) is a local variable never initialized\n[medium/medium] unused-return at src/UnlkHook.sol:363: UnlkHook._verifySeed() (src/UnlkHook.sol#363-374) ignores return value by (liquidity,None,None) = poolManager.getPositionInfo(poolId,launchFactory,seedTickLower,seedTickUpper,bytes32(0)) (src/UnlkHook.sol#364-365)\n[medium/medium] unused-return at src/UnlkOracle.sol:90: UnlkOracle.checkpoint() (src/UnlkOracle.sol#90-115) ignores return value by (liquidity,None,None) = poolManager.getPositionInfo(poolId,factory,rangeLowerTick,rangeUpperTick,bytes32(0)) (src/UnlkOracle.sol#93-94)\n[medium/medium] unused-return at src/UnlkHook.sol:531: UnlkHook._recordSeed(ModifyLiquidityParams) (src/UnlkHook.sol#531-549) ignores return value by (sqrtPrice,None,None,None) = poolManager.getSlot0(poolId) (src/UnlkHook.sol#536)\n[medium/medium] unused-return at src/UnlkHook.sol:456: UnlkHook.beforeSwap(address,PoolKey,SwapParams,bytes) (src/UnlkHook.sol#456-476) ignores return value by (None,None,protocolFee,lpFee) = poolManager.getSlot0(poolId) (src/UnlkHook.sol#470)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: outputBefore = state.outputToken.balanceOf(msg.sender) (src/UnlkSwapRouter.sol#155)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: key = hook.poolKey() (src/UnlkSwapRouter.sol#113)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: state.baseInput = state.inputToken.balanceOf(address(this)) (src/UnlkSwapRouter.sol#120-122)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: state.outputToken.balanceOf(msg.sender) != outputBefore + output (src/UnlkSwapRouter.sol#157)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: ! hook.activated() || block.timestamp > request.deadline || request.amountSpecified == 0 || request.amountSpecified == type()(int256).min || request.maxInput == 0 || request.maxInput > uint256(uint128(type()(int128).max)) || request.minOutput == 0 (src/UnlkSwapRouter.sol#109-111)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: result = poolManager.unlock(abi.encode(key,params,operationNonce,request.maxInput)) (src/UnlkSwapRouter.sol#139)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: state.baseOutput = state.outputToken.balanceOf(address(this)) (src/UnlkSwapRouter.sol#123-124)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) has external calls inside a loop: state.inputToken.balanceOf(address(this)) != state.baseInput + request.maxInput (src/UnlkSwapRouter.sol#129)\n[low/medium] calls-loop at src/UnlkSwapRouter.sol:172: UnlkSwapRouter._balance(IERC20) (src/UnlkSwapRouter.sol#172-174) has external calls inside a loop: currency.balanceOf(address(this)) (src/UnlkSwapRouter.sol#173)\n[low/medium] reentrancy-benign at src/UnlkHook.sol:651: Reentrancy in UnlkHook.updateMilestone() (src/UnlkHook.sol#651-655):\n[low/medium] reentrancy-benign at src/UnlkSwapRouter.sol:104: Reentrancy in UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166):\n[low/medium] reentrancy-benign at src/UnlkHook.sol:478: Reentrancy in UnlkHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/UnlkHook.sol#478-509):\n[low/medium] reentrancy-events at src/UnlkHook.sol:478: Reentrancy in UnlkHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/UnlkHook.sol#478-509):\n[low/medium] reentrancy-events at src/UnlkHook.sol:275: Reentrancy in UnlkHook.configureAndActivate(address,IClaimEvidence,UnlkOracle,uint64) (src/UnlkHook.sol#275-324):\n[low/medium] reentrancy-events at src/UnlkHook.sol:651: Reentrancy in UnlkHook.updateMilestone() (src/UnlkHook.sol#651-655):\n[low/medium] timestamp at src/UnlkOracle.sol:122: UnlkOracle.twapTick() (src/UnlkOracle.sol#122-147) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkOracle.sol:90: UnlkOracle.checkpoint() (src/UnlkOracle.sol#90-115) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkSwapRouter.sol:104: UnlkSwapRouter._swap(UnlkSwapRouter.SwapRequest,uint256) (src/UnlkSwapRouter.sol#104-166) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkOracle.sol:166: UnlkOracle._ethUsd() (src/UnlkOracle.sol#166-179) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkHook.sol:667: UnlkHook._updateMilestone() (src/UnlkHook.sol#667-709) uses timestamp for comparisons\n[low/medium] timestamp at src/UnlkOracle.sol:150: UnlkOracle.fdvUsd() (src/UnlkOracle.sol#150-164) uses timestamp for comparisons","passed":true},{"durationMs":974,"exitCode":0,"name":"aderyn","output":"[high] eth-send-unchecked-address at src/UnlkSwapRouter.sol:184: ETH transferred without address checks\n[high] reentrancy-state-change at src/MerkleClaimEvidence.sol:190: Reentrancy: State change after external call (8 places)\n[high] unprotected-initializer at src/HookDeployer.sol:19: Unprotected initializer (2 places)\n[low] costly-loop at src/MerkleClaimEvidence.sol:121: Costly operations inside loop (3 places)\n[low] internal-function-used-once at src/HookFlags.sol:35: Internal Function Used Only Once (2 places)\n[low] large-numeric-literal at src/UnlkHook.sol:69: Large Numeric Literal (16 places)\n[low] literal-instead-of-constant at src/UnlkHook.sol:463: Literal Instead of Constant (13 places)\n[low] missing-inheritance at src/UnlkOracle.sol:15: Missing Inheritance\n[low] require-revert-in-loop at src/MerkleClaimEvidence.sol:75: Loop Contains `require`/`revert` (5 places)\n[low] state-change-without-event at src/UnlkHook.sol:456: State Change Without Event (4 places)\n[low] unchecked-return at src/UnlkHook.sol:335: Unchecked Return (2 places)\n[low] uninitialized-local-variable at src/MerkleClaimEvidence.sol:121: Uninitialized Local Variable (2 places)\n[low] unused-import at src/libraries/OperationHash.sol:4: Unused Import","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"481f5799378441102273b8711a427734383e0dd512bcc53e796890a0e7c6cebc","verifiedTreeHash":"74c4683c2dee725f3eb7f349588a931ca4bf557e","verifierVersion":"0.1.0+327e1e9f"},{"checks":[{"durationMs":18159,"exitCode":0,"name":"build","output":"Compiling 128 files with Solc 0.8.26\nSolc 0.8.26 finished in 17.99s\nCompiler run successful with warnings:\nWarning (5159): \"selfdestruct\" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode.\n  --> test/BatchSettlementProperties.t.sol:14:9:\n   |\n14 |         selfdestruct(recipient);\n   |         ^^^^^^^^^^^^\n\nWarning (5159): \"selfdestruct\" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode.\n  --> test/NativeCustodyInvariants.t.sol:15:9:\n   |\n15 |         selfdestruct(recipient);\n   |         ^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/UnlkHook.sol:189:5:\n    |\n189 |     function afterInitialize(address, PoolKey calldata key, uint160, int24)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":12462,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/LocalScript.t.sol:LocalScriptTest\n[PASS] testLocalScriptRefusesPublicChainId() (gas: 13945506)\n[PASS] testLocalSimulationFunctionDoesNotDependOnCaller() (gas: 82068248)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 39.29ms (38.76ms CPU time)\n\nRan 2 tests for test/TwoStage.t.sol:StageOneConstructorTest\n[PASS] testConstructorRejectsMissingOrConflatedInputs() (gas: 8175)\n[PASS] testOnlyFactoryCanInitializeTheHooksPool() (gas: 43150)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 55.35ms (250.50µs CPU time)\n\nRan 10 tests for test/CreditsAndFees.t.sol:CreditsAndFeesTest\n[PASS] testAttestationRequiresActualClaimAndExactLeaf() (gas: 438858)\n[PASS] testClaimTransferAndPayerTransferDoNotDuplicateCredit() (gas: 578096)\n[PASS] testFeeCollectionDoesNotReducePrincipal() (gas: 661053)\n[PASS] testNativeClaimNeverDependsOnAdapterOrFeed() (gas: 863245)\n[PASS] testNativeClaimThenAttestThenSyncThenSale() (gas: 1294958)\n[PASS] testNegativeLiquidityForbiddenEvenForFactory() (gas: 82486)\n[PASS] testProofReleaseAndDedupRemainNativeRules() (gas: 573246)\n[PASS] testSaleFeesCountGrossInputAndNeverCreditFeeRecipients() (gas: 1202770)\n[PASS] testUnauthorizedLiquidityAndDonationNoCredit() (gas: 231982)\n[PASS] testUnclaimedRewardsNotEligible() (gas: 39420)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 58.46ms (6.21ms CPU time)\n\nRan 5 tests for test/EvidenceAndOracleProperties.t.sol:MultiLeafEvidenceTest\n[PASS] testDecreasingEvidenceCannotRevokePreviouslyCreditedClaims() (gas: 1056937)\n[PASS] testProofsFromTheActualTreeCreditExactlyWhatWasDelivered() (gas: 2254239)\n[PASS] testSiblingCannotAttestAnotherWalletsClaim() (gas: 727383)\n[PASS] testSweptRoundFreezesEvidence() (gas: 1092289)\n[PASS] testTheTreeIsWellFormed() (gas: 40973)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 58.71ms (5.91ms CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:EvidenceCertificationRegressionTest\n[PASS] testActualLaterRoundClaimsHaveNoArtificialCumulativeCeiling() (gas: 1526816)\n[PASS] testDuplicateRecipientCannotOvercreditSmallerActualClaim() (gas: 441255)\n[PASS] testIncompleteTreeCannotBeCertified() (gas: 59551)\n[PASS] testOddTreeReconstructionAndPreCertificationNativeClaim() (gas: 580590)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 61.40ms (1.97ms CPU time)\n\nRan 2 tests for test/Stage2Script.t.sol:Stage2ScriptTest\n[PASS] testStage2DeploysFromActualIdentitiesAndOwnerActivates() (gas: 6348536)\n[PASS] testStage2RefusesUnknownLaunchNumber() (gas: 34700)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 74.60ms (2.38ms CPU time)\n\nRan 8 tests for test/Adversarial.t.sol:AdversarialTest\n[PASS] test100PercentAloneIsNotFullUnlock() (gas: 7311138)\n[PASS] testArbitraryHookDataAndMultihopPayloadCannotSelectVictim() (gas: 87252)\n[PASS] testCallbacksAllRequireCanonicalManager() (gas: 211601)\n[PASS] testForeignPoolKeyRejectedEvenWithManagerPrank() (gas: 49904)\n[PASS] testNoMintPauseBlacklistUpgradeOrCounterResetEntrypoint() (gas: 114792)\n[PASS] testProtocolFeeChangeCannotSilentlyAlterTradingEconomics() (gas: 355367)\n[PASS] testQuotaMultiplicationDoesNotOverflowAtMaxEligible() (gas: 239252)\n[PASS] testTokenMintsWholeSupplyToDeployerOnly() (gas: 32832)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 81.25ms (12.42ms CPU time)\n\nRan 8 tests for test/Launch.t.sol:LaunchTest\n[PASS] testCompanionsAreImmutablyBound() (gas: 37797)\n[PASS] testFactoryHoldsPrincipalAndCannotRemoveIt() (gas: 330242)\n[PASS] testLaunchAllocationAndLockedPrincipal() (gas: 191089)\n[PASS] testLaunchIsOnceAndDeployerOnly() (gas: 2535198)\n[PASS] testOnlyCanonicalManagerCanCallHook() (gas: 66434)\n[PASS] testPayerCreditExactDeduplicated() (gas: 137518)\n[PASS] testUnauthorizedFactoryAndWrongPoolRejected() (gas: 80489)\n[PASS] testUnconfiguredComponentsFailClosed() (gas: 42307)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 80.82ms (1.67ms CPU time)\n\nRan 13 tests for test/TwoStage.t.sol:StageOneTest\n[PASS] testActivationSealsAndCannotBeReplayed() (gas: 5408612)\n[PASS] testCrossLaunchNumberRejected() (gas: 4910081)\n[PASS] testFactoryLiquidityAllowedBeforeActivationButPrincipalStaysLocked() (gas: 37250)\n[PASS] testFirstTierConfirmsBelowTenEthActualReserves() (gas: 34928073)\n[PASS] testLaunchSucceedsWithoutCompanions() (gas: 122586)\n[PASS] testPayerCanTransferBeforeActivationWithoutLosingHistoricalCredit() (gas: 5400034)\n[PASS] testPayerCreditOnlyAfterActivationAndFromOriginalTransferReceipt() (gas: 5349170)\n[PASS] testRequesterReassignmentCannotMoveInitialAllocationCredit() (gas: 5355841)\n[PASS] testSepoliaRequiresPublishedChainlinkFeed() (gas: 4926289)\n[PASS] testSwapsSyncAndMilestonesRevertBeforeActivation() (gas: 5399610)\n[PASS] testTransfersAndNativeClaimsWorkBeforeActivationAndClaimIsCreditedLater() (gas: 5704570)\n[PASS] testUnauthorizedActivationRejected() (gas: 4924157)\n[PASS] testWrongContractsRejected() (gas: 5598163)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 87.57ms (33.32ms CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:CodeAuthenticationRegressionTest\n[PASS] testActivationExternalFailureRollsBackEveryBinding() (gas: 816427)\n[PASS] testInconsistentImmutablePatchesAreRejected() (gas: 1780923)\n[PASS] testLaterFactoryDonationsCannotRewriteInitialAllocationReceipts() (gas: 645016)\n[PASS] testRuntimeMutationCannotPassGetterChecks() (gas: 82704)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 90.08ms (8.39ms CPU time)\n\nRan 1 test for test/EvidenceAndOracleProperties.t.sol:RouterDeadlineTest\n[PASS] testDeadlineIsInclusive() (gas: 438525)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 103.87ms (677.74µs CPU time)\n\nRan 1 test for test/FailurePaths.t.sol:UnpaidLaunchTest\n[PASS] testNoRequesterMeansNoPayerCreditAnywhere() (gas: 1281574)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 110.46ms (3.84ms CPU time)\n\nRan 2 tests for test/SecurityRegression.t.sol:StagingCreationRegressionTest\n[PASS] testCounterfeitConstructorIsRefusedBeforeAnyDeployment() (gas: 5638758)\n[PASS] testOnlySetupAuthorityMayStageAndTheBundleCannotBeReplaced() (gas: 5989428)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 119.61ms (6.45ms CPU time)\n\nRan 3 tests for test/FailurePaths.t.sol:ActivationFailurePathsTest\n[PASS] testCompanionConstructorsRejectMissingInputs() (gas: 6057)\n[PASS] testCrossLaunchSetupIsRefusedInEveryDirection() (gas: 68602857)\n[PASS] testSepoliaRefusesLocallyClonedServicesEvenWithFeedAtPublishedAddress() (gas: 674688)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 153.71ms (73.70ms CPU time)\n\nRan 1 test for test/SecurityRegression.t.sol:LargeTreeCertificationTest\n[PASS] testMaximumSortedTreeFitsTransactionGasLimit() (gas: 15977629)\nLogs:\n  1024-leaf sorted certification gas: 13943571\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 171.65ms (73.84ms CPU time)\n\nRan 11 tests for test/NativeLaunch.t.sol:NativeWithdrawalTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136305473)\n[PASS] testNativeBatchSettlement() (gas: 883303)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1140215)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 468433)\n[PASS] testNativeSettlementResetsPriorSyncCurrency() (gas: 620796)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 91991)\n[PASS] testNativeWithdrawalUsesCEIAndCannotDoubleWithdraw() (gas: 1011298)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62521)\n[PASS] testOtherWalletCannotWithdrawNativeRefund() (gas: 476334)\n[PASS] testRejectingNativeWalletCanTradeAndRetryWithdrawal() (gas: 1089620)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29985485)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 200.08ms (159.50ms CPU time)\n\nRan 3 tests for test/ReleaseConfig.t.sol:ReleaseConfigTest\n[PASS] testReadOnlyReleaseChecksOnLocalFixture() (gas: 2007175)\n[PASS] testReadOnlyReleaseChecksRejectWrongChainOrHash() (gas: 1903780)\n[PASS] testStageOneAloneCannotPassReleaseGate() (gas: 104610744)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 216.30ms (127.27ms CPU time)\n\nRan 7 tests for test/NativeLaunch.t.sol:NativeLaunchTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136305472)\n[PASS] testNativeBatchSettlement() (gas: 883303)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1140204)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 468344)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 92013)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62543)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29985485)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 216.55ms (150.99ms CPU time)\n\nRan 15 tests for test/Oracle.t.sol:OracleTest\n[PASS] testBadChainlinkRoundsAndAnswersFailClosed() (gas: 2379231)\n[PASS] testConfirmationGapRestartsRatherThanCountingUnobservedTime() (gas: 14864669)\n[PASS] testEveryTierAndPermanentUnlock() (gas: 136707061)\n[PASS] testFallingPricesNeverLowerReachedTier() (gas: 29279733)\n[PASS] testInvalidDataCannotCountTowardPendingConfirmationOrRevokeRights() (gas: 15090747)\n[PASS] testInvalidDataLongerThanGapRestartsOnNextValidCall() (gas: 683632)\n[PASS] testNegativeTickAveragesRoundConservativelyForBothOrders() (gas: 753196)\n[PASS] testOneBlockSpikeCannotConfirm() (gas: 724914)\n[PASS] testOracleCannotBeReboundOrConfiguredByAnyone() (gas: 73530)\n[PASS] testRealFeedCadenceCannotBeUsedToResetConfirmation() (gas: 18798127)\n[PASS] testSameTimestampManipulationHasNoTimeWeight() (gas: 744167)\n[PASS] testStaleCheckpointAndFeedPreventNewTierButNotTrades() (gas: 1333080)\n[PASS] testSustainedManipulationRequiresWindowAndConfirmation() (gas: 15135794)\n[PASS] testThresholdMappingBoundaries() (gas: 70282)\n[PASS] testWarmupAndExactWindow() (gas: 401264)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 372.57ms (212.88ms CPU time)\n\nRan 1 test for test/StageOneInvariants.t.sol:StageOneInvariantTest\n[PASS]\nStageOneInvariantTest invariants:\n[PASS] invariant_onlyTheAuthorizedCallActivates\n[PASS] invariant_tokenAndClaimsIndependentOfTheHook\n[PASS] invariant_unconfiguredPoolIsInert\n StageOneInvariantTest invariants (runs: 96, calls: 3840, reverts: 0)\n\n╭-----------------+------------------+-------+---------+----------╮\n| Contract        | Selector         | Calls | Reverts | Discards |\n+=================================================================+\n| StageOneHandler | advance          | 453   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | attemptActivate  | 484   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | claimAndAttest   | 527   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | directSwap       | 452   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | foreignLiquidity | 513   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | routerSwap       | 485   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | syncAndMilestone | 454   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | transfer         | 472   | 0       | 0        |\n╰-----------------+------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 986.31ms (916.01ms CPU time)\n\nRan 3 tests for test/SecurityRegression.t.sol:OracleOutageRegressionTest\n[PASS] testDepthDipInvalidatesWholeWindowAndRetainsReachedRights() (gas: 16359514)\n[PASS] testFinalTierRequiresItsOwnTwentyFourHours() (gas: 139055056)\n[PASS] testNextTierClockWaitsForItsOwnThreshold() (gas: 15316716)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.28s (163.17ms CPU time)\n\nRan 17 tests for test/FailurePaths.t.sol:RouterAndHookFailurePathsTest\n[PASS] testBatchBoundsAndValueMustMatch() (gas: 186819)\n[PASS] testBatchIsAtomicWhenALaterStepFails() (gas: 851118)\n[PASS] testConfirmationRequiresSixHoursAndCannotSkipTiers() (gas: 15363937)\n[PASS] testFullUnlockKeepsFeesAndRouterAuthentication() (gas: 137213772)\n[PASS] testFuzzOperationHashBindsTraderNonceAndChain(address,uint256,uint64) (runs: 256, μ: 17656, ~: 17656)\n[PASS] testFuzzRemainingQuotaFormula(uint128,uint128,uint8) (runs: 512, μ: 7298538, ~: 7298377)\n[PASS] testFuzzTierIsMonotonicInFdv(uint256,uint256) (runs: 512, μ: 17089, ~: 17055)\n[PASS] testFuzzTransfersMoveExactlyTheAmount(address,uint96) (runs: 256, μ: 122295, ~: 122469)\n[PASS] testHookRejectsMalformedRouteDataAndUnknownSenders() (gas: 230888)\n[PASS] testPartialFillAtPriceLimitChargesOnlyExecutedInput() (gas: 1226453)\n[PASS] testQuotaWidensWithTierAndNeverDoubleCounts() (gas: 16805520)\n[PASS] testRequesterChangeAfterActivationDoesNotMoveThePayer() (gas: 146422)\n[PASS] testRouterCallbackNeedsALiveSwap() (gas: 73817)\n[PASS] testRouterRefusesDegenerateRequests() (gas: 500369)\n[PASS] testSecondRoundClaimsAccumulateOncePerRound() (gas: 995717)\n[PASS] testSlippageRefusalsLeaveNoTrace() (gas: 936477)\n[PASS] testSyncForStrangerAndZeroAddressCreatesNothing() (gas: 108559)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 1.74s (1.38s CPU time)\n\nRan 3 tests for test/ManipulationEconomics.t.sol:ManipulationEconomicsTest\n[PASS] testCounterSellingOfAllInitialNonPoolTokens() (gas: 157882639)\nLogs:\n  gross ETH capital (wei): 404492004375936755769\n  attacker ETH exit (wei): 139667041180374722901\n  net ETH exit cost before fee recapture (wei): 264824963195562032868\n  payer ETH fee receipts (wei): 4044920043759367559\n  counter-seller ETH proceeds (wei): 259768813140862823404\n  duration seconds: 201600\n\n[PASS] testPayerCanRecaptureItsNativeFeeShare() (gas: 144878918)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n  net ETH cost after native fee recapture (wei): 653249186877100125\n\n[PASS] testSustainedManipulationUnlockAndExit() (gas: 144892638)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.74s (423.34ms CPU time)\n\nRan 9 tests for test/Trading.t.sol:TradingTest\n[PASS] testAnotherWalletCannotConsumeVictimsAllowanceOrQuota() (gas: 487139)\n[PASS] testDirectManagerAndForeignRouterSpoofingRejected() (gas: 640118)\n[PASS] testDonatedRouterBalancesCannotCreateCreditOrBeSwept() (gas: 512478)\n[PASS] testExactOutputSaleAccountsActualInput() (gas: 749117)\n[PASS] testExcessSaleRollsBackPoolBalancesOracleAndNonce() (gas: 811734)\n[PASS] testFuzzQuotaBoundary(uint96) (runs: 256, μ: 1048085, ~: 1048115)\n[PASS] testReplayOldCallbackHasNoLiveContext() (gas: 440344)\n[PASS] testSaleBoundaryExecutedInputIncludesPoolFee() (gas: 1077346)\n[PASS] testTransfersDoNotMoveRightsOrAllowChainCredit() (gas: 841817)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 1.74s (1.67s CPU time)\n\nRan 3 tests for test/EvidenceAndOracleProperties.t.sol:OracleReferenceTest\n[PASS] testCheckpointReplacementRewritesOnlyTheCurrentSecond() (gas: 995880)\n[PASS] testFuzzFdvIsMonotonicInTheEthUsdAnswer(uint64,uint64) (runs: 256, μ: 766993, ~: 767219)\n[PASS] testFuzzTwapMatchesBruteForceReference(uint256) (runs: 160, μ: 2761853, ~: 2721520)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.98s (2.21s CPU time)\n\nRan 5 tests for test/BatchSettlementProperties.t.sol:BatchSettlementPropertiesTest\n[PASS] testFuzz_BatchEqualsSequentialExecution(uint256,uint8,bool) (runs: 1000, μ: 4546553, ~: 4095896)\n[PASS] testFuzz_FailureAtAnyBatchIndexRestoresAllowancesFeesAndCredits(uint256,uint8) (runs: 1000, μ: 11424416, ~: 11115393)\n[PASS] test_MaximumMixedBatchOnFreshTokenOnlyManager() (gas: 9268599)\n[PASS] test_OneWeiShortAllowanceRestoresEntireBatchAndRetryWorks() (gas: 1919667)\n[PASS] test_PartialSaleMayPrefundMoreThanQuotaButChargesOnlyExecution() (gas: 920549)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 1.98s (3.81s CPU time)\n\nRan 1 test for test/Invariants.t.sol:FullyUnlockedInvariantTest\n[PASS]\nFullyUnlockedInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n[PASS] invariantUnlockRemainsPermanentDespiteInvalidFeed\n FullyUnlockedInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 863   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 858   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 861   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 859   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 830   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 849   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.29s (2.03s CPU time)\n\nRan 1 test for test/Invariants.t.sol:SystemInvariantTest\n[PASS]\nSystemInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n SystemInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 863   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 858   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 861   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 859   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 830   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 849   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.30s (2.22s CPU time)\n\nRan 2 tests for test/QuotaInvariants.t.sol:QuotaInvariantTest\n[PASS]\nQuotaInvariantTest invariants:\n[PASS] invariant_configurationSealedAndRouteEnforced\n[PASS] invariant_ledgerMatchesExecutedDeltas\n[PASS] invariant_milestonesMonotonicAndConsistent\n[PASS] invariant_principalLockedAndFeeTermsFixed\n[PASS] invariant_routerNativeSolvency\n[PASS] invariant_salesNeverExceedQuota\n[PASS] invariant_supplyConservedAndNoCustody\n QuotaInvariantTest invariants (runs: 96, calls: 5760, reverts: 0)\n\n╭--------------+-----------------+-------+---------+----------╮\n| Contract     | Selector        | Calls | Reverts | Discards |\n+=============================================================+\n| QuotaHandler | advance         | 352   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactIn      | 372   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactOut     | 362   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimAndAttest  | 363   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimFees       | 357   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | directSwap      | 354   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | donate          | 360   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | foreignActivate | 378   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellExactOut    | 332   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellOverQuota   | 372   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellWithinQuota | 700   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | setFeed         | 353   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sync            | 356   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | transfer        | 389   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | withdrawNative  | 360   | 0       | 0        |\n╰--------------+-----------------+-------+---------+----------╯\n\n[PASS] testHandlerActionsActuallyExecute() (gas: 23850193)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 3.69s (3.64s CPU time)\n\nRan 2 tests for test/ClaimLifecycleInvariants.t.sol:ClaimLifecycleInvariantsTest\n[PASS]\nClaimLifecycleInvariantsTest invariants:\n[PASS] invariant_DistributorReservesAndCashMatchIndependentRoundModel\n[PASS] invariant_FixedSupplyAndInitialReceiptsSurviveAllClaimSequences\n[PASS] invariant_OnlyDeliveredAttestedAndSyncedClaimsCreateRights\n ClaimLifecycleInvariantsTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| ClaimLifecycleHandler | advance           | 1892  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | attest            | 1910  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | certify           | 1912  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | claim             | 1893  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | deliverAndSync    | 1847  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | openRound         | 1808  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | sweep             | 1826  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | sync              | 1879  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | syncPayer         | 1840  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | transferOrDonate  | 1843  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | unauthorizedRound | 1830  | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\n[PASS] test_ModelExercisesDelayedCertificationSweepsAndRecycledFunding() (gas: 4966315)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 11.10s (10.99s CPU time)\n\nRan 2 tests for test/NativeCustodyInvariants.t.sol:NativeCustodyInvariantsTest\n[PASS]\nNativeCustodyInvariantsTest invariants:\n[PASS] invariant_ManagerHasNoUnsettledDeltaOrReusableRouteContext\n[PASS] invariant_NativeLiabilitiesRemainFullyBackedAndBelongToTheirWallet\n[PASS] invariant_TransfersDonationsAndFailedBatchesCannotCreateOrMoveRights\n NativeCustodyInvariantsTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------------+--------------+-------+---------+----------╮\n| Contract             | Selector     | Calls | Reverts | Discards |\n+==================================================================+\n| NativeCustodyHandler | donateTokens | 2715  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| NativeCustodyHandler | failBatch    | 2725  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| NativeCustodyHandler | forceEther   | 2789  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| NativeCustodyHandler | tradeBatch   | 2640  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| NativeCustodyHandler | transfer     | 2734  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| NativeCustodyHandler | withdraw     | 2781  | 0       | 0        |\n╰----------------------+--------------+-------+---------+----------╯\n\n[PASS] test_HandlerTradesRejectsReentersAndDrainsWithoutTakingDonations() (gas: 5324179)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 12.26s (12.18s CPU time)\n\nRan 31 test suites in 12.26s (45.46s CPU time): 151 tests passed, 0 failed, 0 skipped (151 total tests)\n","passed":true},{"durationMs":134,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MerkleClaimEvidence.attest(uint256,address,uint256,bytes32[])\",\"MerkleClaimEvidence.certifyRound(uint256,address[],uint256[])\",\"UnlkHook.afterAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"UnlkHook.afterRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"UnlkHook.beforeAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"UnlkHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"UnlkHook.configureAndActivate(address,address,address,uint64)\",\"UnlkHook.deployCompanions(uint64,address,bytes,bytes,bytes)\",\"UnlkHook.syncPayer()\",\"UnlkHook.syncRewards(address)\",\"UnlkHook.updateMilestone()\",\"UnlkOracle.bind((address,address,uint24,int24,address),address,int24,int24)\",\"UnlkOracle.checkpoint()\",\"UnlkSwapRouter.receive()\",\"UnlkSwapRouter.swap((bool,int256,uint160,uint256,uint256,uint256))\",\"UnlkSwapRouter.swapBatch((bool,int256,uint160,uint256,uint256,uint256)[])\",\"UnlkSwapRouter.unlockCallback(bytes)\",\"UnlkSwapRouter.withdrawNative()\",\"UnlkToken.approve(address,uint256)\",\"UnlkToken.transfer(address,uint256)\",\"UnlkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"LICENSE\":25,\"README.md\":129,\"RELEASE_STATUS.json\":29,\"dependencies.lock.json\":24,\"docs/ARTIFACTS.json\":52,\"docs/BUILD_RESULTS.txt\":9,\"docs/DEPLOYMENT.md\":132,\"docs/ECONOMICS_RESULTS.txt\":49,\"docs/FMT_RESULTS.txt\":0,\"docs/FORK_RESULTS.txt\":24,\"docs/LINT_RESULTS.txt\":386,\"docs/MINIMAL_ENV_TEST_RESULTS.txt\":355,\"docs/NETWORK_VERIFICATION_RESULTS.txt\":7,\"docs/PROTECTED_TEST_RESULTS.txt\":22,\"docs/RECOVERY.md\":60,\"docs/SECURITY_REVIEW.md\":112,\"docs/SOURCE_SHA256SUMS\":449,\"docs/SOURCE_VERIFICATION_RESULTS.txt\":449,\"docs/TEST_RESULTS.txt\":346,\"docs/VALIDATION.md\":111,\"docs/abi/CheckReleaseConfig.json\":46,\"docs/abi/HookDeployer.json\":84,\"docs/abi/IChainlinkEthUsd.json\":48,\"docs/abi/IClaimEvidence.json\":47,\"docs/abi/IHooks.json\":789,\"docs/abi/ILaunchFactoryView.json\":115,\"docs/abi/ILaunchRegistryView.json\":70,\"docs/abi/IMerkleDistributor.json\":125,\"docs/abi/IPoolManager.json\":1286,\"docs/abi/IRouteContext.json\":20,\"docs/abi/LaunchFactory.json\":896,\"docs/abi/LaunchFees.json\":323,\"docs/abi/LaunchRegistry.json\":320,\"docs/abi/MerkleClaimEvidence.json\":269,\"docs/abi/MerkleDistributor.json\":451,\"docs/abi/Stage2.json\":225,\"docs/abi/UnlkHook.json\":1921,\"docs/abi/UnlkOracle.json\":443,\"docs/abi/UnlkSwapRouter.json\":359,\"docs/abi/UnlkToken.json\":425,\"docs/network/capabilities.json\":345,\"docs/network/factory-artifacts.json\":2201,\"docs/network/factory-reference.json\":420,\"docs/network/factory.runtime.hex\":1,\"docs/network/feed-reference.json\":67,\"docs/network/feed-rounds.json\":134,\"docs/network/feed.runtime.hex\":1,\"docs/network/fees.runtime.hex\":1,\"docs/network/job-identity.json\":14,\"docs/network/manager.runtime.hex\":1,\"docs/network/policies.json\":36,\"docs/network/registry-reference.json\":108,\"docs/network/registry.runtime.hex\":1,\"docs/network/sepolia.json\":309,\"docs/network/services.json\":29,\"foundry.toml\":31,\"launch.json\":35,\"rehearsal/Sepolia.t.sol\":112,\"remappings.txt\":4,\"script/CheckReleaseConfig.s.sol\":85,\"script/LocalDemo.s.sol\":41,\"script/Stage2.s.sol\":100,\"scripts/check.sh\":8,\"scripts/check_protected.py\":31,\"scripts/export_abis.py\":33,\"scripts/generate_code_checks.py\":22,\"scripts/mine-hook.sh\":9,\"scripts/prepare_claim_tree.py\":37,\"scripts/rehearse-sepolia.sh\":4,\"scripts/release_artifacts.py\":49,\"scripts/verify_network.py\":46,\"src/HookDeployer.sol\":29,\"src/HookFlags.sol\":45,\"src/MerkleClaimEvidence.sol\":115,\"src/UnlkHook.sol\":645,\"src/UnlkOracle.sol\":194,\"src/UnlkSwapRouter.sol\":225,\"src/UnlkToken.sol\":42,\"src/interfaces/IIntegration.sol\":86,\"src/libraries/OperationHash.sol\":15,\"src/libraries/ReviewedCode.sol\":10,\"src/libraries/SepoliaRelease.sol\":11,\"test/ADDITIONAL_COVERAGE.md\":68,\"test/Adversarial.t.sol\":117,\"test/BatchSettlementProperties.t.sol\":273,\"test/ClaimLifecycleInvariants.t.sol\":444,\"test/CreditsAndFees.t.sol\":176,\"test/EvidenceAndOracleProperties.t.sol\":349,\"test/FailurePaths.t.sol\":580,\"test/Invariants.t.sol\":220,\"test/Launch.t.sol\":112,\"test/LocalScript.t.sol\":28,\"test/ManipulationEconomics.t.sol\":117,\"test/NativeCustodyInvariants.t.sol\":296,\"test/NativeLaunch.t.sol\":236,\"test/Oracle.t.sol\":364,\"test/QuotaInvariants.t.sol\":529,\"test/ReleaseConfig.t.sol\":32,\"test/SecurityRegression.t.sol\":318,\"test/Stage2Script.t.sol\":62,\"test/StageOneInvariants.t.sol\":281,\"test/Trading.t.sol\":171,\"test/TwoStage.t.sol\":302,\"test/fixtures/LocalFixtures.sol\":59,\"test/fixtures/SystemFixture.sol\":371,\"test/imd/HookFlags.sol\":45,\"test/imd/LaunchFactory.sol\":375,\"test/imd/LaunchFees.sol\":73,\"test/imd/LaunchRegistry.sol\":109,\"test/imd/MerkleDistributor.sol\":181,\"test/imd/PoolFees.sol\":220,\"test/imd/README.md\":29,\"test/mocks/MockERC20.sol\":11},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"a1390ef7305f941386a7611c580b59779dc87a59d7ad8e0ed9a678c914b52f3a","verifiedTreeHash":"920d600a8852c0dd564b846b677bf4d626f6945c","verifierVersion":"0.1.0+327e1e9f"},{"checks":[{"durationMs":16063,"exitCode":0,"name":"build","output":"Compiling 124 files with Solc 0.8.26\nSolc 0.8.26 finished in 15.90s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> src/UnlkHook.sol:189:5:\n    |\n189 |     function afterInitialize(address, PoolKey calldata key, uint160, int24)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":3682,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/TwoStage.t.sol:StageOneConstructorTest\n[PASS] testConstructorRejectsMissingOrConflatedInputs() (gas: 8175)\n[PASS] testOnlyFactoryCanInitializeTheHooksPool() (gas: 43150)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 37.37ms (311.28µs CPU time)\n\nRan 1 test for test/FailurePaths.t.sol:UnpaidLaunchTest\n[PASS] testNoRequesterMeansNoPayerCreditAnywhere() (gas: 1281574)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 57.36ms (3.85ms CPU time)\n\nRan 8 tests for test/Launch.t.sol:LaunchTest\n[PASS] testCompanionsAreImmutablyBound() (gas: 37797)\n[PASS] testFactoryHoldsPrincipalAndCannotRemoveIt() (gas: 330242)\n[PASS] testLaunchAllocationAndLockedPrincipal() (gas: 191089)\n[PASS] testLaunchIsOnceAndDeployerOnly() (gas: 2535198)\n[PASS] testOnlyCanonicalManagerCanCallHook() (gas: 66434)\n[PASS] testPayerCreditExactDeduplicated() (gas: 137518)\n[PASS] testUnauthorizedFactoryAndWrongPoolRejected() (gas: 80489)\n[PASS] testUnconfiguredComponentsFailClosed() (gas: 42307)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 60.25ms (2.22ms CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:EvidenceCertificationRegressionTest\n[PASS] testActualLaterRoundClaimsHaveNoArtificialCumulativeCeiling() (gas: 1526816)\n[PASS] testDuplicateRecipientCannotOvercreditSmallerActualClaim() (gas: 441255)\n[PASS] testIncompleteTreeCannotBeCertified() (gas: 59551)\n[PASS] testOddTreeReconstructionAndPreCertificationNativeClaim() (gas: 580590)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 68.56ms (1.56ms CPU time)\n\nRan 8 tests for test/Adversarial.t.sol:AdversarialTest\n[PASS] test100PercentAloneIsNotFullUnlock() (gas: 7311138)\n[PASS] testArbitraryHookDataAndMultihopPayloadCannotSelectVictim() (gas: 87252)\n[PASS] testCallbacksAllRequireCanonicalManager() (gas: 211601)\n[PASS] testForeignPoolKeyRejectedEvenWithManagerPrank() (gas: 49904)\n[PASS] testNoMintPauseBlacklistUpgradeOrCounterResetEntrypoint() (gas: 114792)\n[PASS] testProtocolFeeChangeCannotSilentlyAlterTradingEconomics() (gas: 355367)\n[PASS] testQuotaMultiplicationDoesNotOverflowAtMaxEligible() (gas: 239252)\n[PASS] testTokenMintsWholeSupplyToDeployerOnly() (gas: 32832)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 74.44ms (6.63ms CPU time)\n\nRan 1 test for test/EvidenceAndOracleProperties.t.sol:RouterDeadlineTest\n[PASS] testDeadlineIsInclusive() (gas: 438525)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 77.52ms (500.90µs CPU time)\n\nRan 10 tests for test/CreditsAndFees.t.sol:CreditsAndFeesTest\n[PASS] testAttestationRequiresActualClaimAndExactLeaf() (gas: 438858)\n[PASS] testClaimTransferAndPayerTransferDoNotDuplicateCredit() (gas: 578096)\n[PASS] testFeeCollectionDoesNotReducePrincipal() (gas: 661053)\n[PASS] testNativeClaimNeverDependsOnAdapterOrFeed() (gas: 863245)\n[PASS] testNativeClaimThenAttestThenSyncThenSale() (gas: 1294958)\n[PASS] testNegativeLiquidityForbiddenEvenForFactory() (gas: 82486)\n[PASS] testProofReleaseAndDedupRemainNativeRules() (gas: 573246)\n[PASS] testSaleFeesCountGrossInputAndNeverCreditFeeRecipients() (gas: 1202770)\n[PASS] testUnauthorizedLiquidityAndDonationNoCredit() (gas: 231982)\n[PASS] testUnclaimedRewardsNotEligible() (gas: 39420)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 82.69ms (4.68ms CPU time)\n\nRan 2 tests for test/Stage2Script.t.sol:Stage2ScriptTest\n[PASS] testStage2DeploysFromActualIdentitiesAndOwnerActivates() (gas: 6348536)\n[PASS] testStage2RefusesUnknownLaunchNumber() (gas: 34700)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 87.57ms (2.13ms CPU time)\n\nRan 2 tests for test/SecurityRegression.t.sol:StagingCreationRegressionTest\n[PASS] testCounterfeitConstructorIsRefusedBeforeAnyDeployment() (gas: 5638758)\n[PASS] testOnlySetupAuthorityMayStageAndTheBundleCannotBeReplaced() (gas: 5989428)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 94.62ms (2.36ms CPU time)\n\nRan 5 tests for test/EvidenceAndOracleProperties.t.sol:MultiLeafEvidenceTest\n[PASS] testDecreasingEvidenceCannotRevokePreviouslyCreditedClaims() (gas: 1056937)\n[PASS] testProofsFromTheActualTreeCreditExactlyWhatWasDelivered() (gas: 2254239)\n[PASS] testSiblingCannotAttestAnotherWalletsClaim() (gas: 727383)\n[PASS] testSweptRoundFreezesEvidence() (gas: 1092289)\n[PASS] testTheTreeIsWellFormed() (gas: 40973)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 95.94ms (2.82ms CPU time)\n\nRan 13 tests for test/TwoStage.t.sol:StageOneTest\n[PASS] testActivationSealsAndCannotBeReplayed() (gas: 5408612)\n[PASS] testCrossLaunchNumberRejected() (gas: 4910081)\n[PASS] testFactoryLiquidityAllowedBeforeActivationButPrincipalStaysLocked() (gas: 37250)\n[PASS] testFirstTierConfirmsBelowTenEthActualReserves() (gas: 34928073)\n[PASS] testLaunchSucceedsWithoutCompanions() (gas: 122586)\n[PASS] testPayerCanTransferBeforeActivationWithoutLosingHistoricalCredit() (gas: 5400034)\n[PASS] testPayerCreditOnlyAfterActivationAndFromOriginalTransferReceipt() (gas: 5349170)\n[PASS] testRequesterReassignmentCannotMoveInitialAllocationCredit() (gas: 5355841)\n[PASS] testSepoliaRequiresPublishedChainlinkFeed() (gas: 4926289)\n[PASS] testSwapsSyncAndMilestonesRevertBeforeActivation() (gas: 5399610)\n[PASS] testTransfersAndNativeClaimsWorkBeforeActivationAndClaimIsCreditedLater() (gas: 5704570)\n[PASS] testUnauthorizedActivationRejected() (gas: 4924157)\n[PASS] testWrongContractsRejected() (gas: 5598163)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 99.98ms (32.11ms CPU time)\n\nRan 1 test for test/SecurityRegression.t.sol:LargeTreeCertificationTest\n[PASS] testMaximumSortedTreeFitsTransactionGasLimit() (gas: 15977629)\nLogs:\n  1024-leaf sorted certification gas: 13943571\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 133.82ms (55.71ms CPU time)\n\nRan 3 tests for test/ReleaseConfig.t.sol:ReleaseConfigTest\n[PASS] testReadOnlyReleaseChecksOnLocalFixture() (gas: 2007175)\n[PASS] testReadOnlyReleaseChecksRejectWrongChainOrHash() (gas: 1903780)\n[PASS] testStageOneAloneCannotPassReleaseGate() (gas: 104610744)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 149.75ms (90.22ms CPU time)\n\nRan 9 tests for test/Trading.t.sol:TradingTest\n[PASS] testAnotherWalletCannotConsumeVictimsAllowanceOrQuota() (gas: 487139)\n[PASS] testDirectManagerAndForeignRouterSpoofingRejected() (gas: 640118)\n[PASS] testDonatedRouterBalancesCannotCreateCreditOrBeSwept() (gas: 512478)\n[PASS] testExactOutputSaleAccountsActualInput() (gas: 749117)\n[PASS] testExcessSaleRollsBackPoolBalancesOracleAndNonce() (gas: 811734)\n[PASS] testFuzzQuotaBoundary(uint96) (runs: 256, μ: 1048058, ~: 1048115)\n[PASS] testReplayOldCallbackHasNoLiveContext() (gas: 440344)\n[PASS] testSaleBoundaryExecutedInputIncludesPoolFee() (gas: 1077346)\n[PASS] testTransfersDoNotMoveRightsOrAllowChainCredit() (gas: 841817)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 160.88ms (104.85ms CPU time)\n\nRan 15 tests for test/Oracle.t.sol:OracleTest\n[PASS] testBadChainlinkRoundsAndAnswersFailClosed() (gas: 2379231)\n[PASS] testConfirmationGapRestartsRatherThanCountingUnobservedTime() (gas: 14864669)\n[PASS] testEveryTierAndPermanentUnlock() (gas: 136707061)\n[PASS] testFallingPricesNeverLowerReachedTier() (gas: 29279733)\n[PASS] testInvalidDataCannotCountTowardPendingConfirmationOrRevokeRights() (gas: 15090747)\n[PASS] testInvalidDataLongerThanGapRestartsOnNextValidCall() (gas: 683632)\n[PASS] testNegativeTickAveragesRoundConservativelyForBothOrders() (gas: 753196)\n[PASS] testOneBlockSpikeCannotConfirm() (gas: 724914)\n[PASS] testOracleCannotBeReboundOrConfiguredByAnyone() (gas: 73530)\n[PASS] testRealFeedCadenceCannotBeUsedToResetConfirmation() (gas: 18798127)\n[PASS] testSameTimestampManipulationHasNoTimeWeight() (gas: 744167)\n[PASS] testStaleCheckpointAndFeedPreventNewTierButNotTrades() (gas: 1333080)\n[PASS] testSustainedManipulationRequiresWindowAndConfirmation() (gas: 15135794)\n[PASS] testThresholdMappingBoundaries() (gas: 70282)\n[PASS] testWarmupAndExactWindow() (gas: 401264)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 182.70ms (178.33ms CPU time)\n\nRan 3 tests for test/SecurityRegression.t.sol:OracleOutageRegressionTest\n[PASS] testDepthDipInvalidatesWholeWindowAndRetainsReachedRights() (gas: 16359514)\n[PASS] testFinalTierRequiresItsOwnTwentyFourHours() (gas: 139055056)\n[PASS] testNextTierClockWaitsForItsOwnThreshold() (gas: 15316716)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 207.64ms (141.65ms CPU time)\n\nRan 11 tests for test/NativeLaunch.t.sol:NativeWithdrawalTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136305473)\n[PASS] testNativeBatchSettlement() (gas: 883303)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1140215)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 468433)\n[PASS] testNativeSettlementResetsPriorSyncCurrency() (gas: 620796)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 91991)\n[PASS] testNativeWithdrawalUsesCEIAndCannotDoubleWithdraw() (gas: 1011298)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62521)\n[PASS] testOtherWalletCannotWithdrawNativeRefund() (gas: 476334)\n[PASS] testRejectingNativeWalletCanTradeAndRetryWithdrawal() (gas: 1089620)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29985485)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 209.18ms (150.22ms CPU time)\n\nRan 7 tests for test/NativeLaunch.t.sol:NativeLaunchTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136305472)\n[PASS] testNativeBatchSettlement() (gas: 883303)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1140204)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 468344)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 92013)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62543)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29985485)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 220.64ms (161.58ms CPU time)\n\nRan 3 tests for test/ManipulationEconomics.t.sol:ManipulationEconomicsTest\n[PASS] testCounterSellingOfAllInitialNonPoolTokens() (gas: 157882639)\nLogs:\n  gross ETH capital (wei): 404492004375936755769\n  attacker ETH exit (wei): 139667041180374722901\n  net ETH exit cost before fee recapture (wei): 264824963195562032868\n  payer ETH fee receipts (wei): 4044920043759367559\n  counter-seller ETH proceeds (wei): 259768813140862823404\n  duration seconds: 201600\n\n[PASS] testPayerCanRecaptureItsNativeFeeShare() (gas: 144878918)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n  net ETH cost after native fee recapture (wei): 653249186877100125\n\n[PASS] testSustainedManipulationUnlockAndExit() (gas: 144892638)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 224.99ms (427.85ms CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:CodeAuthenticationRegressionTest\n[PASS] testActivationExternalFailureRollsBackEveryBinding() (gas: 816427)\n[PASS] testInconsistentImmutablePatchesAreRejected() (gas: 1780923)\n[PASS] testLaterFactoryDonationsCannotRewriteInitialAllocationReceipts() (gas: 645016)\n[PASS] testRuntimeMutationCannotPassGetterChecks() (gas: 82704)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 306.36ms (10.61ms CPU time)\n\nRan 3 tests for test/EvidenceAndOracleProperties.t.sol:OracleReferenceTest\n[PASS] testCheckpointReplacementRewritesOnlyTheCurrentSecond() (gas: 995880)\n[PASS] testFuzzFdvIsMonotonicInTheEthUsdAnswer(uint64,uint64) (runs: 256, μ: 767051, ~: 767219)\n[PASS] testFuzzTwapMatchesBruteForceReference(uint256) (runs: 160, μ: 2839389, ~: 2771953)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 569.52ms (743.43ms CPU time)\n\nRan 3 tests for test/FailurePaths.t.sol:ActivationFailurePathsTest\n[PASS] testCompanionConstructorsRejectMissingInputs() (gas: 6057)\n[PASS] testCrossLaunchSetupIsRefusedInEveryDirection() (gas: 68602857)\n[PASS] testSepoliaRefusesLocallyClonedServicesEvenWithFeedAtPublishedAddress() (gas: 674688)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 591.01ms (43.36ms CPU time)\n\nRan 2 tests for test/LocalScript.t.sol:LocalScriptTest\n[PASS] testLocalScriptRefusesPublicChainId() (gas: 13945506)\n[PASS] testLocalSimulationFunctionDoesNotDependOnCaller() (gas: 82068248)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 601.05ms (61.96ms CPU time)\n\nRan 17 tests for test/FailurePaths.t.sol:RouterAndHookFailurePathsTest\n[PASS] testBatchBoundsAndValueMustMatch() (gas: 186819)\n[PASS] testBatchIsAtomicWhenALaterStepFails() (gas: 851118)\n[PASS] testConfirmationRequiresSixHoursAndCannotSkipTiers() (gas: 15363937)\n[PASS] testFullUnlockKeepsFeesAndRouterAuthentication() (gas: 137213772)\n[PASS] testFuzzOperationHashBindsTraderNonceAndChain(address,uint256,uint64) (runs: 256, μ: 17656, ~: 17656)\n[PASS] testFuzzRemainingQuotaFormula(uint128,uint128,uint8) (runs: 512, μ: 7298539, ~: 7298377)\n[PASS] testFuzzTierIsMonotonicInFdv(uint256,uint256) (runs: 512, μ: 17090, ~: 17055)\n[PASS] testFuzzTransfersMoveExactlyTheAmount(address,uint96) (runs: 256, μ: 122299, ~: 122475)\n[PASS] testHookRejectsMalformedRouteDataAndUnknownSenders() (gas: 230888)\n[PASS] testPartialFillAtPriceLimitChargesOnlyExecutedInput() (gas: 1226453)\n[PASS] testQuotaWidensWithTierAndNeverDoubleCounts() (gas: 16805520)\n[PASS] testRequesterChangeAfterActivationDoesNotMoveThePayer() (gas: 146422)\n[PASS] testRouterCallbackNeedsALiveSwap() (gas: 73817)\n[PASS] testRouterRefusesDegenerateRequests() (gas: 500369)\n[PASS] testSecondRoundClaimsAccumulateOncePerRound() (gas: 995717)\n[PASS] testSlippageRefusalsLeaveNoTrace() (gas: 936477)\n[PASS] testSyncForStrangerAndZeroAddressCreatesNothing() (gas: 108559)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 602.49ms (1.77s CPU time)\n\nRan 1 test for test/StageOneInvariants.t.sol:StageOneInvariantTest\n[PASS]\nStageOneInvariantTest invariants:\n[PASS] invariant_onlyTheAuthorizedCallActivates\n[PASS] invariant_tokenAndClaimsIndependentOfTheHook\n[PASS] invariant_unconfiguredPoolIsInert\n StageOneInvariantTest invariants (runs: 96, calls: 3840, reverts: 0)\n\n╭-----------------+------------------+-------+---------+----------╮\n| Contract        | Selector         | Calls | Reverts | Discards |\n+=================================================================+\n| StageOneHandler | advance          | 480   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | attemptActivate  | 519   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | claimAndAttest   | 429   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | directSwap       | 503   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | foreignLiquidity | 489   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | routerSwap       | 480   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | syncAndMilestone | 451   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | transfer         | 489   | 0       | 0        |\n╰-----------------+------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 902.20ms (819.19ms CPU time)\n\nRan 1 test for test/Invariants.t.sol:SystemInvariantTest\n[PASS]\nSystemInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n SystemInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 819   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 892   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 877   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 900   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 817   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 815   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.16s (2.07s CPU time)\n\nRan 1 test for test/Invariants.t.sol:FullyUnlockedInvariantTest\n[PASS]\nFullyUnlockedInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n[PASS] invariantUnlockRemainsPermanentDespiteInvalidFeed\n FullyUnlockedInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 819   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 892   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 877   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 900   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 817   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 815   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.16s (1.92s CPU time)\n\nRan 2 tests for test/QuotaInvariants.t.sol:QuotaInvariantTest\n[PASS]\nQuotaInvariantTest invariants:\n[PASS] invariant_configurationSealedAndRouteEnforced\n[PASS] invariant_ledgerMatchesExecutedDeltas\n[PASS] invariant_milestonesMonotonicAndConsistent\n[PASS] invariant_principalLockedAndFeeTermsFixed\n[PASS] invariant_routerNativeSolvency\n[PASS] invariant_salesNeverExceedQuota\n[PASS] invariant_supplyConservedAndNoCustody\n QuotaInvariantTest invariants (runs: 96, calls: 5760, reverts: 0)\n\n╭--------------+-----------------+-------+---------+----------╮\n| Contract     | Selector        | Calls | Reverts | Discards |\n+=============================================================+\n| QuotaHandler | advance         | 365   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactIn      | 320   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactOut     | 369   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimAndAttest  | 371   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimFees       | 337   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | directSwap      | 313   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | donate          | 419   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | foreignActivate | 370   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellExactOut    | 337   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellOverQuota   | 379   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellWithinQuota | 690   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | setFeed         | 349   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sync            | 372   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | transfer        | 384   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | withdrawNative  | 385   | 0       | 0        |\n╰--------------+-----------------+-------+---------+----------╯\n\n[PASS] testHandlerActionsActuallyExecute() (gas: 23850193)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 3.51s (3.45s CPU time)\n\nRan 28 test suites in 3.51s (13.74s CPU time): 142 tests passed, 0 failed, 0 skipped (142 total tests)\n","passed":true},{"durationMs":136,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MerkleClaimEvidence.attest(uint256,address,uint256,bytes32[])\",\"MerkleClaimEvidence.certifyRound(uint256,address[],uint256[])\",\"UnlkHook.afterAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"UnlkHook.afterRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"UnlkHook.beforeAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"UnlkHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"UnlkHook.configureAndActivate(address,address,address,uint64)\",\"UnlkHook.deployCompanions(uint64,address,bytes,bytes,bytes)\",\"UnlkHook.syncPayer()\",\"UnlkHook.syncRewards(address)\",\"UnlkHook.updateMilestone()\",\"UnlkOracle.bind((address,address,uint24,int24,address),address,int24,int24)\",\"UnlkOracle.checkpoint()\",\"UnlkSwapRouter.receive()\",\"UnlkSwapRouter.swap((bool,int256,uint160,uint256,uint256,uint256))\",\"UnlkSwapRouter.swapBatch((bool,int256,uint160,uint256,uint256,uint256)[])\",\"UnlkSwapRouter.unlockCallback(bytes)\",\"UnlkSwapRouter.withdrawNative()\",\"UnlkToken.approve(address,uint256)\",\"UnlkToken.transfer(address,uint256)\",\"UnlkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"LICENSE\":25,\"README.md\":129,\"RELEASE_STATUS.json\":29,\"dependencies.lock.json\":24,\"docs/ARTIFACTS.json\":52,\"docs/BUILD_RESULTS.txt\":9,\"docs/DEPLOYMENT.md\":132,\"docs/ECONOMICS_RESULTS.txt\":49,\"docs/FMT_RESULTS.txt\":0,\"docs/FORK_RESULTS.txt\":24,\"docs/LINT_RESULTS.txt\":386,\"docs/MINIMAL_ENV_TEST_RESULTS.txt\":355,\"docs/NETWORK_VERIFICATION_RESULTS.txt\":7,\"docs/PROTECTED_TEST_RESULTS.txt\":22,\"docs/RECOVERY.md\":60,\"docs/SECURITY_REVIEW.md\":112,\"docs/SOURCE_SHA256SUMS\":449,\"docs/SOURCE_VERIFICATION_RESULTS.txt\":449,\"docs/TEST_RESULTS.txt\":346,\"docs/VALIDATION.md\":111,\"docs/abi/CheckReleaseConfig.json\":46,\"docs/abi/HookDeployer.json\":84,\"docs/abi/IChainlinkEthUsd.json\":48,\"docs/abi/IClaimEvidence.json\":47,\"docs/abi/IHooks.json\":789,\"docs/abi/ILaunchFactoryView.json\":115,\"docs/abi/ILaunchRegistryView.json\":70,\"docs/abi/IMerkleDistributor.json\":125,\"docs/abi/IPoolManager.json\":1286,\"docs/abi/IRouteContext.json\":20,\"docs/abi/LaunchFactory.json\":896,\"docs/abi/LaunchFees.json\":323,\"docs/abi/LaunchRegistry.json\":320,\"docs/abi/MerkleClaimEvidence.json\":269,\"docs/abi/MerkleDistributor.json\":451,\"docs/abi/Stage2.json\":225,\"docs/abi/UnlkHook.json\":1921,\"docs/abi/UnlkOracle.json\":443,\"docs/abi/UnlkSwapRouter.json\":359,\"docs/abi/UnlkToken.json\":425,\"docs/network/capabilities.json\":345,\"docs/network/factory-artifacts.json\":2201,\"docs/network/factory-reference.json\":420,\"docs/network/factory.runtime.hex\":1,\"docs/network/feed-reference.json\":67,\"docs/network/feed-rounds.json\":134,\"docs/network/feed.runtime.hex\":1,\"docs/network/fees.runtime.hex\":1,\"docs/network/job-identity.json\":14,\"docs/network/manager.runtime.hex\":1,\"docs/network/policies.json\":36,\"docs/network/registry-reference.json\":108,\"docs/network/registry.runtime.hex\":1,\"docs/network/sepolia.json\":309,\"docs/network/services.json\":29,\"foundry.toml\":31,\"launch.json\":35,\"rehearsal/Sepolia.t.sol\":112,\"remappings.txt\":4,\"script/CheckReleaseConfig.s.sol\":85,\"script/LocalDemo.s.sol\":41,\"script/Stage2.s.sol\":100,\"scripts/check.sh\":8,\"scripts/check_protected.py\":31,\"scripts/export_abis.py\":33,\"scripts/generate_code_checks.py\":22,\"scripts/mine-hook.sh\":9,\"scripts/prepare_claim_tree.py\":37,\"scripts/rehearse-sepolia.sh\":4,\"scripts/release_artifacts.py\":49,\"scripts/verify_network.py\":46,\"src/HookDeployer.sol\":29,\"src/HookFlags.sol\":45,\"src/MerkleClaimEvidence.sol\":115,\"src/UnlkHook.sol\":645,\"src/UnlkOracle.sol\":194,\"src/UnlkSwapRouter.sol\":225,\"src/UnlkToken.sol\":42,\"src/interfaces/IIntegration.sol\":86,\"src/libraries/OperationHash.sol\":15,\"src/libraries/ReviewedCode.sol\":10,\"src/libraries/SepoliaRelease.sol\":11,\"test/Adversarial.t.sol\":117,\"test/CreditsAndFees.t.sol\":176,\"test/EvidenceAndOracleProperties.t.sol\":349,\"test/FailurePaths.t.sol\":580,\"test/Invariants.t.sol\":220,\"test/Launch.t.sol\":112,\"test/LocalScript.t.sol\":28,\"test/ManipulationEconomics.t.sol\":117,\"test/NativeLaunch.t.sol\":236,\"test/Oracle.t.sol\":364,\"test/QuotaInvariants.t.sol\":529,\"test/ReleaseConfig.t.sol\":32,\"test/SecurityRegression.t.sol\":318,\"test/Stage2Script.t.sol\":62,\"test/StageOneInvariants.t.sol\":281,\"test/Trading.t.sol\":171,\"test/TwoStage.t.sol\":302,\"test/fixtures/LocalFixtures.sol\":59,\"test/fixtures/SystemFixture.sol\":371,\"test/imd/HookFlags.sol\":45,\"test/imd/LaunchFactory.sol\":375,\"test/imd/LaunchFees.sol\":73,\"test/imd/LaunchRegistry.sol\":109,\"test/imd/MerkleDistributor.sol\":181,\"test/imd/PoolFees.sol\":220,\"test/imd/README.md\":29,\"test/mocks/MockERC20.sol\":11},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"b2cf962babf23a2d3129b753a6e400d70f1afa27e1eb53948b0f358f05115a06","verifiedTreeHash":"89f7f64ca3be754a6ebdd997a3bdbad526feabbb","verifierVersion":"0.1.0+327e1e9f"},{"checks":[{"durationMs":13884,"exitCode":0,"name":"build","output":"Compiling 126 files with Solc 0.8.26\nSolc 0.8.26 finished in 13.76s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> src/UnlkHook.sol:205:5:\n    |\n205 |     function afterInitialize(address, PoolKey calldata key, uint160, int24)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":2813,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/TwoStage.t.sol:StageOneConstructorTest\n[PASS] testConstructorRejectsMissingOrConflatedInputs() (gas: 8175)\n[PASS] testOnlyFactoryCanInitializeTheHooksPool() (gas: 43150)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 15.95ms (357.76µs CPU time)\n\nRan 1 test for test/EvidenceAndOracleProperties.t.sol:RouterDeadlineTest\n[PASS] testDeadlineIsInclusive() (gas: 422030)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 20.83ms (349.69µs CPU time)\n\nRan 2 tests for test/Stage2Script.t.sol:Stage2ScriptTest\n[PASS] testStage2DeploysFromActualIdentitiesAndOwnerActivates() (gas: 6832294)\n[PASS] testStage2RefusesUnknownLaunchNumber() (gas: 33767)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 21.27ms (1.53ms CPU time)\n\nRan 1 test for test/FailurePaths.t.sol:UnpaidLaunchTest\n[PASS] testNoRequesterMeansNoPayerCreditAnywhere() (gas: 1264616)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 21.44ms (779.67µs CPU time)\n\nRan 8 tests for test/Launch.t.sol:LaunchTest\n[PASS] testCompanionsAreImmutablyBound() (gas: 37886)\n[PASS] testFactoryHoldsPrincipalAndCannotRemoveIt() (gas: 333697)\n[PASS] testLaunchAllocationAndLockedPrincipal() (gas: 191055)\n[PASS] testLaunchIsOnceAndDeployerOnly() (gas: 2730017)\n[PASS] testOnlyCanonicalManagerCanCallHook() (gas: 66479)\n[PASS] testPayerCreditExactDeduplicated() (gas: 137462)\n[PASS] testUnauthorizedFactoryAndWrongPoolRejected() (gas: 80623)\n[PASS] testUnconfiguredComponentsFailClosed() (gas: 42307)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 21.50ms (1.13ms CPU time)\n\nRan 2 tests for test/SecurityRegression.t.sol:StagingCreationRegressionTest\n[PASS] testCounterfeitConstructorIsRefusedBeforeAnyDeployment() (gas: 6161976)\n[PASS] testOnlySetupAuthorityMayStageAndOnlyUntilActivation() (gas: 11784008)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 24.79ms (2.08ms CPU time)\n\nRan 5 tests for test/EvidenceAndOracleProperties.t.sol:MultiLeafEvidenceTest\n[PASS] testDecreasingEvidenceCannotRevokePreviouslyCreditedClaims() (gas: 1100787)\n[PASS] testProofsFromTheActualTreeCreditExactlyWhatWasDelivered() (gas: 2298120)\n[PASS] testSiblingCannotAttestAnotherWalletsClaim() (gas: 771379)\n[PASS] testSweptRoundFreezesEvidence() (gas: 1136221)\n[PASS] testTheTreeIsWellFormed() (gas: 40973)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 26.07ms (2.21ms CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:EvidenceCertificationRegressionTest\n[PASS] testActualLaterRoundClaimsHaveNoArtificialCumulativeCeiling() (gas: 1510126)\n[PASS] testDuplicateRecipientCannotOvercreditSmallerActualClaim() (gas: 441218)\n[PASS] testIncompleteTreeCannotBeCertified() (gas: 59593)\n[PASS] testOddTreeReconstructionAndPreCertificationNativeClaim() (gas: 580532)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 25.30ms (1.28ms CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:CodeAuthenticationRegressionTest\n[PASS] testActivationExternalFailureRollsBackEveryBinding() (gas: 913067)\n[PASS] testInconsistentImmutablePatchesAreRejected() (gas: 1782922)\n[PASS] testLaterFactoryDonationsCannotRewriteInitialAllocationReceipts() (gas: 688991)\n[PASS] testRuntimeMutationCannotPassGetterChecks() (gas: 84703)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 31.94ms (3.88ms CPU time)\n\nRan 2 tests for test/LocalScript.t.sol:LocalScriptTest\n[PASS] testLocalScriptRefusesPublicChainId() (gas: 13945506)\n[PASS] testLocalSimulationFunctionDoesNotDependOnCaller() (gas: 67855480)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 34.22ms (25.67ms CPU time)\n\nRan 3 tests for test/FailurePaths.t.sol:ActivationFailurePathsTest\n[PASS] testCompanionConstructorsRejectMissingInputs() (gas: 6057)\n[PASS] testCrossLaunchSetupIsRefusedInEveryDirection() (gas: 30758204)\n[PASS] testSepoliaRefusesLocallyClonedServicesEvenWithFeedAtPublishedAddress() (gas: 676754)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 37.08ms (16.93ms CPU time)\n\nRan 8 tests for test/Adversarial.t.sol:AdversarialTest\n[PASS] test100PercentAloneIsNotFullUnlock() (gas: 7307385)\n[PASS] testArbitraryHookDataAndMultihopPayloadCannotSelectVictim() (gas: 89207)\n[PASS] testCallbacksAllRequireCanonicalManager() (gas: 211512)\n[PASS] testForeignPoolKeyRejectedEvenWithManagerPrank() (gas: 49882)\n[PASS] testNoMintPauseBlacklistUpgradeOrCounterResetEntrypoint() (gas: 114793)\n[PASS] testProtocolFeeChangeCannotSilentlyAlterTradingEconomics() (gas: 357261)\n[PASS] testQuotaMultiplicationDoesNotOverflowAtMaxEligible() (gas: 239235)\n[PASS] testTokenMintsWholeSupplyToDeployerOnly() (gas: 32832)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 46.73ms (11.15ms CPU time)\n\nRan 6 tests for test/ActivationRobustness.t.sol:ActivationRobustnessTest\n[PASS] testPolicySeedRecordsCapacityAndConfirmsTiers() (gas: 30335357)\n[PASS] testSeedBelowOpeningValueFloorCannotLaunch() (gas: 9047798)\n[PASS] testSeedBelowThePoolShareBandCannotLaunch() (gas: 9043839)\n[PASS] testSeedInsideTheOnePercentBandActivates() (gas: 15647267)\n[PASS] testStagingRunsActivationPreconditionsAndCanRepeat() (gas: 21081828)\n[PASS] testSubDustSeedRoundingStillActivates() (gas: 16005370)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 62.60ms (20.39ms CPU time)\n\nRan 1 test for test/SecurityRegression.t.sol:LargeTreeCertificationTest\n[PASS] testMaximumSortedTreeFitsTransactionGasLimit() (gas: 15973574)\nLogs:\n  1024-leaf sorted certification gas: 13939470\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 85.81ms (49.77ms CPU time)\n\nRan 11 tests for test/NativeLaunch.t.sol:NativeWithdrawalTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136092723)\n[PASS] testNativeBatchSettlement() (gas: 865791)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1124527)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 451977)\n[PASS] testNativeSettlementResetsPriorSyncCurrency() (gas: 604340)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 91930)\n[PASS] testNativeWithdrawalUsesCEIAndCannotDoubleWithdraw() (gas: 994842)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62586)\n[PASS] testOtherWalletCannotWithdrawNativeRefund() (gas: 459878)\n[PASS] testRejectingNativeWalletCanTradeAndRetryWithdrawal() (gas: 1073164)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29938965)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 99.14ms (101.06ms CPU time)\n\nRan 4 tests for test/ActivationRobustness.t.sol:ChunkedCertificationTest\n[PASS] testChunkBoundsAndSizeAreFixedByTheFirstChunk() (gas: 29517535)\n[PASS] testDuplicateAcrossChunksWrongRootAndForeignSessionsAreRefused() (gas: 231631551)\n[PASS] testSingleLeafRoundCertifiesThroughTheChunkedPath() (gas: 398202)\n[PASS] testSingleShotRefusesButChunksCertifyAndCredit() (gas: 124071664)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 100.17ms (66.93ms CPU time)\n\nRan 3 tests for test/ReleaseConfig.t.sol:ReleaseConfigTest\n[PASS] testReadOnlyReleaseChecksOnLocalFixture() (gas: 2011487)\n[PASS] testReadOnlyReleaseChecksRejectWrongChainOrHash() (gas: 1903758)\n[PASS] testStageOneAloneCannotPassReleaseGate() (gas: 74944069)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 101.67ms (66.19ms CPU time)\n\nRan 3 tests for test/ManipulationEconomics.t.sol:ManipulationEconomicsTest\n[PASS] testCounterSellingOfAllInitialNonPoolTokens() (gas: 157719009)\nLogs:\n  gross ETH capital (wei): 404492004375936755769\n  attacker ETH exit (wei): 139667041180374722901\n  net ETH exit cost before fee recapture (wei): 264824963195562032868\n  payer ETH fee receipts (wei): 4044920043759367559\n  counter-seller ETH proceeds (wei): 259768813140862823404\n  duration seconds: 201600\n\n[PASS] testPayerCanRecaptureItsNativeFeeShare() (gas: 144653849)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n  net ETH cost after native fee recapture (wei): 653249186877100125\n\n[PASS] testSustainedManipulationUnlockAndExit() (gas: 144667569)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 123.09ms (275.70ms CPU time)\n\nRan 13 tests for test/TwoStage.t.sol:StageOneTest\n[PASS] testActivationSealsAndCannotBeReplayed() (gas: 5901690)\n[PASS] testCrossLaunchNumberRejected() (gas: 5361101)\n[PASS] testFactoryLiquidityAllowedBeforeActivationButPrincipalStaysLocked() (gas: 37293)\n[PASS] testFirstTierConfirmsBelowTenEthActualReserves() (gas: 35384808)\n[PASS] testLaunchSucceedsWithoutCompanions() (gas: 122562)\n[PASS] testPayerCanTransferBeforeActivationWithoutLosingHistoricalCredit() (gas: 5893013)\n[PASS] testPayerCreditOnlyAfterActivationAndFromOriginalTransferReceipt() (gas: 5842154)\n[PASS] testRequesterReassignmentCannotMoveInitialAllocationCredit() (gas: 5848820)\n[PASS] testSepoliaRequiresPublishedChainlinkFeed() (gas: 5377611)\n[PASS] testSwapsSyncAndMilestonesRevertBeforeActivation() (gas: 5849964)\n[PASS] testTransfersAndNativeClaimsWorkBeforeActivationAndClaimIsCreditedLater() (gas: 6199971)\n[PASS] testUnauthorizedActivationRejected() (gas: 5373249)\n[PASS] testWrongContractsRejected() (gas: 6061423)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 126.65ms (27.90ms CPU time)\n\nRan 17 tests for test/Oracle.t.sol:OracleTest\n[PASS] testBadChainlinkRoundsAndAnswersFailClosed() (gas: 2352246)\n[PASS] testConfirmationGapRestartsRatherThanCountingUnobservedTime() (gas: 14857451)\n[PASS] testEveryTierAndPermanentUnlock() (gas: 136511302)\n[PASS] testFallingPricesNeverLowerReachedTier() (gas: 29259665)\n[PASS] testInvalidDataCannotCountTowardPendingConfirmationOrRevokeRights() (gas: 15083422)\n[PASS] testInvalidDataLongerThanGapRestartsOnNextValidCall() (gas: 694951)\n[PASS] testLongInvalidIntervalRestartsWhetherObservedOrNot() (gas: 807692)\n[PASS] testNegativeTickAveragesRoundConservativelyForBothOrders() (gas: 767868)\n[PASS] testObservedAndUnobservedInvalidIntervalsAgree() (gas: 29667292)\n[PASS] testOneBlockSpikeCannotConfirm() (gas: 739290)\n[PASS] testOracleCannotBeReboundOrConfiguredByAnyone() (gas: 73530)\n[PASS] testRealFeedCadenceCannotBeUsedToResetConfirmation() (gas: 18790257)\n[PASS] testSameTimestampManipulationHasNoTimeWeight() (gas: 758610)\n[PASS] testStaleCheckpointAndFeedPreventNewTierButNotTrades() (gas: 1329158)\n[PASS] testSustainedManipulationRequiresWindowAndConfirmation() (gas: 15126515)\n[PASS] testThresholdMappingBoundaries() (gas: 69776)\n[PASS] testWarmupAndExactWindow() (gas: 400906)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 126.71ms (186.57ms CPU time)\n\nRan 7 tests for test/NativeLaunch.t.sol:NativeLaunchTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136092722)\n[PASS] testNativeBatchSettlement() (gas: 865791)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1124516)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 451888)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 91952)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62608)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29938965)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 126.83ms (96.30ms CPU time)\n\nRan 3 tests for test/EvidenceAndOracleProperties.t.sol:OracleReferenceTest\n[PASS] testCheckpointReplacementRewritesOnlyTheCurrentSecond() (gas: 994219)\n[PASS] testFuzzFdvIsMonotonicInTheEthUsdAnswer(uint64,uint64) (runs: 256, μ: 750356, ~: 750529)\n[PASS] testFuzzTwapMatchesBruteForceReference(uint256) (runs: 160, μ: 2749874, ~: 2703655)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 213.50ms (228.19ms CPU time)\n\nRan 3 tests for test/SecurityRegression.t.sol:OracleOutageRegressionTest\n[PASS] testDepthDipInvalidatesWholeWindowAndRetainsReachedRights() (gas: 16312506)\n[PASS] testFinalTierRequiresItsOwnTwentyFourHours() (gas: 138827744)\n[PASS] testNextTierClockWaitsForItsOwnThreshold() (gas: 15293513)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 407.94ms (112.19ms CPU time)\n\nRan 9 tests for test/Trading.t.sol:TradingTest\n[PASS] testAnotherWalletCannotConsumeVictimsAllowanceOrQuota() (gas: 470687)\n[PASS] testDirectManagerAndForeignRouterSpoofingRejected() (gas: 644028)\n[PASS] testDonatedRouterBalancesCannotCreateCreditOrBeSwept() (gas: 496022)\n[PASS] testExactOutputSaleAccountsActualInput() (gas: 732168)\n[PASS] testExcessSaleRollsBackPoolBalancesOracleAndNonce() (gas: 797176)\n[PASS] testFuzzQuotaBoundary(uint96) (runs: 256, μ: 1032829, ~: 1032869)\n[PASS] testReplayOldCallbackHasNoLiveContext() (gas: 425843)\n[PASS] testSaleBoundaryExecutedInputIncludesPoolFee() (gas: 1062165)\n[PASS] testTransfersDoNotMoveRightsOrAllowChainCredit() (gas: 827129)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 415.53ms (396.10ms CPU time)\n\nRan 17 tests for test/FailurePaths.t.sol:RouterAndHookFailurePathsTest\n[PASS] testBatchBoundsAndValueMustMatch() (gas: 186758)\n[PASS] testBatchIsAtomicWhenALaterStepFails() (gas: 830450)\n[PASS] testConfirmationRequiresSixHoursAndCannotSkipTiers() (gas: 15340175)\n[PASS] testFullUnlockKeepsFeesAndRouterAuthentication() (gas: 137004282)\n[PASS] testFuzzOperationHashBindsTraderNonceAndChain(address,uint256,uint64) (runs: 256, μ: 17656, ~: 17656)\n[PASS] testFuzzRemainingQuotaFormula(uint128,uint128,uint8) (runs: 512, μ: 7293360, ~: 7293203)\n[PASS] testFuzzTierIsMonotonicInFdv(uint256,uint256) (runs: 512, μ: 16965, ~: 16923)\n[PASS] testFuzzTransfersMoveExactlyTheAmount(address,uint96) (runs: 256, μ: 122373, ~: 122475)\n[PASS] testHookRejectsMalformedRouteDataAndUnknownSenders() (gas: 238753)\n[PASS] testPartialFillAtPriceLimitChargesOnlyExecutedInput() (gas: 1208964)\n[PASS] testQuotaWidensWithTierAndNeverDoubleCounts() (gas: 16785891)\n[PASS] testRequesterChangeAfterActivationDoesNotMoveThePayer() (gas: 146383)\n[PASS] testRouterCallbackNeedsALiveSwap() (gas: 73817)\n[PASS] testRouterRefusesDegenerateRequests() (gas: 500273)\n[PASS] testSecondRoundClaimsAccumulateOncePerRound() (gas: 995639)\n[PASS] testSlippageRefusalsLeaveNoTrace() (gas: 895597)\n[PASS] testSyncForStrangerAndZeroAddressCreatesNothing() (gas: 108400)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 442.54ms (592.80ms CPU time)\n\nRan 10 tests for test/CreditsAndFees.t.sol:CreditsAndFeesTest\n[PASS] testAttestationRequiresActualClaimAndExactLeaf() (gas: 438961)\n[PASS] testClaimTransferAndPayerTransferDoNotDuplicateCredit() (gas: 577960)\n[PASS] testFeeCollectionDoesNotReducePrincipal() (gas: 646031)\n[PASS] testNativeClaimNeverDependsOnAdapterOrFeed() (gas: 846757)\n[PASS] testNativeClaimThenAttestThenSyncThenSale() (gas: 1280110)\n[PASS] testNegativeLiquidityForbiddenEvenForFactory() (gas: 82464)\n[PASS] testProofReleaseAndDedupRemainNativeRules() (gas: 573172)\n[PASS] testSaleFeesCountGrossInputAndNeverCreditFeeRecipients() (gas: 1188451)\n[PASS] testUnauthorizedLiquidityAndDonationNoCredit() (gas: 232025)\n[PASS] testUnclaimedRewardsNotEligible() (gas: 39399)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 442.58ms (4.34ms CPU time)\n\nRan 1 test for test/StageOneInvariants.t.sol:StageOneInvariantTest\n[PASS]\nStageOneInvariantTest invariants:\n[PASS] invariant_onlyTheAuthorizedCallActivates\n[PASS] invariant_tokenAndClaimsIndependentOfTheHook\n[PASS] invariant_unconfiguredPoolIsInert\n StageOneInvariantTest invariants (runs: 96, calls: 3840, reverts: 0)\n\n╭-----------------+------------------+-------+---------+----------╮\n| Contract        | Selector         | Calls | Reverts | Discards |\n+=================================================================+\n| StageOneHandler | advance          | 484   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | attemptActivate  | 510   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | claimAndAttest   | 519   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | directSwap       | 462   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | foreignLiquidity | 481   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | routerSwap       | 429   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | syncAndMilestone | 477   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | transfer         | 478   | 0       | 0        |\n╰-----------------+------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 632.08ms (611.05ms CPU time)\n\nRan 1 test for test/Invariants.t.sol:SystemInvariantTest\n[PASS]\nSystemInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n SystemInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 829   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 849   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 896   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 888   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 826   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 832   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.62s (1.58s CPU time)\n\nRan 1 test for test/Invariants.t.sol:FullyUnlockedInvariantTest\n[PASS]\nFullyUnlockedInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n[PASS] invariantUnlockRemainsPermanentDespiteInvalidFeed\n FullyUnlockedInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 829   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 849   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 896   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 888   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 826   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 832   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.66s (1.51s CPU time)\n\nRan 2 tests for test/QuotaInvariants.t.sol:QuotaInvariantTest\n[PASS]\nQuotaInvariantTest invariants:\n[PASS] invariant_configurationSealedAndRouteEnforced\n[PASS] invariant_ledgerMatchesExecutedDeltas\n[PASS] invariant_milestonesMonotonicAndConsistent\n[PASS] invariant_principalLockedAndFeeTermsFixed\n[PASS] invariant_routerNativeSolvency\n[PASS] invariant_salesNeverExceedQuota\n[PASS] invariant_supplyConservedAndNoCustody\n QuotaInvariantTest invariants (runs: 96, calls: 5760, reverts: 0)\n\n╭--------------+-----------------+-------+---------+----------╮\n| Contract     | Selector        | Calls | Reverts | Discards |\n+=============================================================+\n| QuotaHandler | advance         | 394   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactIn      | 358   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactOut     | 356   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimAndAttest  | 349   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimFees       | 322   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | directSwap      | 326   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | donate          | 374   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | foreignActivate | 359   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellExactOut    | 370   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellOverQuota   | 374   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellWithinQuota | 716   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | setFeed         | 368   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sync            | 373   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | transfer        | 364   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | withdrawNative  | 357   | 0       | 0        |\n╰--------------+-----------------+-------+---------+----------╯\n\n[PASS] testHandlerActionsActuallyExecute() (gas: 23814275)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.68s (2.67s CPU time)\n\nRan 30 test suites in 2.69s (9.80s CPU time): 154 tests passed, 0 failed, 0 skipped (154 total tests)\n","passed":true},{"durationMs":98,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MerkleClaimEvidence.abandonSession(uint256)\",\"MerkleClaimEvidence.attest(uint256,address,uint256,bytes32[])\",\"MerkleClaimEvidence.certifyRound(uint256,address[],uint256[])\",\"MerkleClaimEvidence.reduce(uint256,uint256)\",\"MerkleClaimEvidence.submitLeaves(uint256,uint256,address[],uint256[])\",\"UnlkHook.afterAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"UnlkHook.afterRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"UnlkHook.beforeAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"UnlkHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"UnlkHook.configureAndActivate(address,address,address,uint64)\",\"UnlkHook.deployCompanions(uint64,address,bytes,bytes,bytes)\",\"UnlkHook.syncPayer()\",\"UnlkHook.syncRewards(address)\",\"UnlkHook.updateMilestone()\",\"UnlkOracle.bind((address,address,uint24,int24,address),address,int24,int24)\",\"UnlkOracle.checkpoint()\",\"UnlkSwapRouter.receive()\",\"UnlkSwapRouter.swap((bool,int256,uint160,uint256,uint256,uint256))\",\"UnlkSwapRouter.swapBatch((bool,int256,uint160,uint256,uint256,uint256)[])\",\"UnlkSwapRouter.unlockCallback(bytes)\",\"UnlkSwapRouter.withdrawNative()\",\"UnlkToken.approve(address,uint256)\",\"UnlkToken.transfer(address,uint256)\",\"UnlkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"LICENSE\":25,\"README.md\":146,\"RELEASE_STATUS.json\":29,\"dependencies.lock.json\":24,\"docs/ARTIFACTS.json\":52,\"docs/BUILD_RESULTS.txt\":9,\"docs/DEPLOYMENT.md\":139,\"docs/ECONOMICS_RESULTS.txt\":49,\"docs/FMT_RESULTS.txt\":0,\"docs/FORK_RESULTS.txt\":24,\"docs/LINT_RESULTS.txt\":372,\"docs/MINIMAL_ENV_TEST_RESULTS.txt\":355,\"docs/NETWORK_VERIFICATION_RESULTS.txt\":7,\"docs/PROTECTED_TEST_RESULTS.txt\":22,\"docs/RECOVERY.md\":65,\"docs/SECURITY_REVIEW.md\":123,\"docs/SOURCE_SHA256SUMS\":451,\"docs/SOURCE_VERIFICATION_RESULTS.txt\":449,\"docs/TEST_RESULTS.txt\":364,\"docs/VALIDATION.md\":115,\"docs/abi/CheckReleaseConfig.json\":46,\"docs/abi/HookDeployer.json\":84,\"docs/abi/IChainlinkEthUsd.json\":48,\"docs/abi/IClaimEvidence.json\":47,\"docs/abi/IHooks.json\":789,\"docs/abi/ILaunchFactoryView.json\":115,\"docs/abi/ILaunchRegistryView.json\":70,\"docs/abi/IMerkleDistributor.json\":125,\"docs/abi/IPoolManager.json\":1286,\"docs/abi/IRouteContext.json\":20,\"docs/abi/LaunchFactory.json\":896,\"docs/abi/LaunchFees.json\":323,\"docs/abi/LaunchRegistry.json\":320,\"docs/abi/MerkleClaimEvidence.json\":461,\"docs/abi/MerkleDistributor.json\":451,\"docs/abi/Stage2.json\":225,\"docs/abi/UnlkHook.json\":1973,\"docs/abi/UnlkOracle.json\":443,\"docs/abi/UnlkSwapRouter.json\":359,\"docs/abi/UnlkToken.json\":425,\"docs/network/capabilities.json\":345,\"docs/network/factory-artifacts.json\":2201,\"docs/network/factory-reference.json\":420,\"docs/network/factory.runtime.hex\":1,\"docs/network/feed-reference.json\":67,\"docs/network/feed-rounds.json\":134,\"docs/network/feed.runtime.hex\":1,\"docs/network/fees.runtime.hex\":1,\"docs/network/job-identity.json\":14,\"docs/network/manager.runtime.hex\":1,\"docs/network/policies.json\":36,\"docs/network/registry-reference.json\":108,\"docs/network/registry.runtime.hex\":1,\"docs/network/sepolia.json\":309,\"docs/network/services.json\":29,\"foundry.toml\":31,\"launch.json\":35,\"rehearsal/Sepolia.t.sol\":112,\"remappings.txt\":4,\"script/CheckReleaseConfig.s.sol\":85,\"script/LocalDemo.s.sol\":41,\"script/Stage2.s.sol\":98,\"scripts/check.sh\":8,\"scripts/check_protected.py\":31,\"scripts/export_abis.py\":33,\"scripts/generate_code_checks.py\":22,\"scripts/mine-hook.sh\":9,\"scripts/prepare_claim_tree.py\":37,\"scripts/rehearse-sepolia.sh\":4,\"scripts/release_artifacts.py\":51,\"scripts/verify_network.py\":46,\"src/HookDeployer.sol\":29,\"src/HookFlags.sol\":45,\"src/MerkleClaimEvidence.sol\":200,\"src/UnlkHook.sol\":719,\"src/UnlkOracle.sol\":190,\"src/UnlkSwapRouter.sol\":225,\"src/UnlkToken.sol\":42,\"src/interfaces/IIntegration.sol\":86,\"src/libraries/OperationHash.sol\":15,\"src/libraries/ReviewedCode.sol\":10,\"src/libraries/SeedDepth.sol\":41,\"src/libraries/SepoliaRelease.sol\":11,\"test/ActivationRobustness.t.sol\":303,\"test/Adversarial.t.sol\":117,\"test/CreditsAndFees.t.sol\":176,\"test/EvidenceAndOracleProperties.t.sol\":349,\"test/FailurePaths.t.sol\":580,\"test/Invariants.t.sol\":220,\"test/Launch.t.sol\":112,\"test/LocalScript.t.sol\":28,\"test/ManipulationEconomics.t.sol\":117,\"test/NativeLaunch.t.sol\":236,\"test/Oracle.t.sol\":422,\"test/QuotaInvariants.t.sol\":529,\"test/ReleaseConfig.t.sol\":32,\"test/SecurityRegression.t.sol\":337,\"test/Stage2Script.t.sol\":62,\"test/StageOneInvariants.t.sol\":281,\"test/Trading.t.sol\":171,\"test/TwoStage.t.sol\":302,\"test/fixtures/LocalFixtures.sol\":59,\"test/fixtures/SystemFixture.sol\":371,\"test/imd/HookFlags.sol\":45,\"test/imd/LaunchFactory.sol\":375,\"test/imd/LaunchFees.sol\":73,\"test/imd/LaunchRegistry.sol\":109,\"test/imd/MerkleDistributor.sol\":181,\"test/imd/PoolFees.sol\":220,\"test/imd/README.md\":29,\"test/mocks/MockERC20.sol\":11},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c681aec6c52519d6998f8769d4718da22e5f35cda355142af282b939d530980f","verifiedTreeHash":"f3948985462554b32a2e6627d5644c7e156d27c6","verifierVersion":"0.1.0+327e1e9f"},{"checks":[{"durationMs":21066,"exitCode":0,"name":"build","output":"Compiling 131 files with Solc 0.8.26\nSolc 0.8.26 finished in 20.84s\nCompiler run successful with warnings:\nWarning (5159): \"selfdestruct\" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode.\n  --> test/BatchSettlementProperties.t.sol:14:9:\n   |\n14 |         selfdestruct(recipient);\n   |         ^^^^^^^^^^^^\n\nWarning (5159): \"selfdestruct\" has been deprecated. Note that, starting from the Cancun hard fork, the underlying opcode no longer deletes the code and data associated with an account and only transfers its Ether to the beneficiary, unless executed in the same transaction in which the contract was created (see EIP-6780). Any use in newly deployed contracts is strongly discouraged even if the new behavior is taken into account. Future changes to the EVM might further reduce the functionality of the opcode.\n  --> test/NativeCustodyInvariants.t.sol:15:9:\n   |\n15 |         selfdestruct(recipient);\n   |         ^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/UnlkHook.sol:205:5:\n    |\n205 |     function afterInitialize(address, PoolKey calldata key, uint160, int24)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":13453,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 5 tests for test/EvidenceAndOracleProperties.t.sol:MultiLeafEvidenceTest\n[PASS] testDecreasingEvidenceCannotRevokePreviouslyCreditedClaims() (gas: 1100787)\n[PASS] testProofsFromTheActualTreeCreditExactlyWhatWasDelivered() (gas: 2298120)\n[PASS] testSiblingCannotAttestAnotherWalletsClaim() (gas: 771379)\n[PASS] testSweptRoundFreezesEvidence() (gas: 1136221)\n[PASS] testTheTreeIsWellFormed() (gas: 40973)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 38.63ms (2.38ms CPU time)\n\nRan 2 tests for test/LocalScript.t.sol:LocalScriptTest\n[PASS] testLocalScriptRefusesPublicChainId() (gas: 13945506)\n[PASS] testLocalSimulationFunctionDoesNotDependOnCaller() (gas: 67855480)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 39.02ms (38.36ms CPU time)\n\nRan 2 tests for test/TwoStage.t.sol:StageOneConstructorTest\n[PASS] testConstructorRejectsMissingOrConflatedInputs() (gas: 8175)\n[PASS] testOnlyFactoryCanInitializeTheHooksPool() (gas: 43150)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 40.37ms (292.43µs CPU time)\n\nRan 10 tests for test/CreditsAndFees.t.sol:CreditsAndFeesTest\n[PASS] testAttestationRequiresActualClaimAndExactLeaf() (gas: 438961)\n[PASS] testClaimTransferAndPayerTransferDoNotDuplicateCredit() (gas: 577960)\n[PASS] testFeeCollectionDoesNotReducePrincipal() (gas: 646031)\n[PASS] testNativeClaimNeverDependsOnAdapterOrFeed() (gas: 846757)\n[PASS] testNativeClaimThenAttestThenSyncThenSale() (gas: 1280110)\n[PASS] testNegativeLiquidityForbiddenEvenForFactory() (gas: 82464)\n[PASS] testProofReleaseAndDedupRemainNativeRules() (gas: 573172)\n[PASS] testSaleFeesCountGrossInputAndNeverCreditFeeRecipients() (gas: 1188451)\n[PASS] testUnauthorizedLiquidityAndDonationNoCredit() (gas: 232025)\n[PASS] testUnclaimedRewardsNotEligible() (gas: 39399)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 43.61ms (4.55ms CPU time)\n\nRan 8 tests for test/Launch.t.sol:LaunchTest\n[PASS] testCompanionsAreImmutablyBound() (gas: 37886)\n[PASS] testFactoryHoldsPrincipalAndCannotRemoveIt() (gas: 333697)\n[PASS] testLaunchAllocationAndLockedPrincipal() (gas: 191055)\n[PASS] testLaunchIsOnceAndDeployerOnly() (gas: 2730017)\n[PASS] testOnlyCanonicalManagerCanCallHook() (gas: 66479)\n[PASS] testPayerCreditExactDeduplicated() (gas: 137462)\n[PASS] testUnauthorizedFactoryAndWrongPoolRejected() (gas: 80623)\n[PASS] testUnconfiguredComponentsFailClosed() (gas: 42307)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 48.63ms (1.24ms CPU time)\n\nRan 2 tests for test/Stage2Script.t.sol:Stage2ScriptTest\n[PASS] testStage2DeploysFromActualIdentitiesAndOwnerActivates() (gas: 6832294)\n[PASS] testStage2RefusesUnknownLaunchNumber() (gas: 33767)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 54.07ms (4.23ms CPU time)\n\nRan 1 test for test/FailurePaths.t.sol:UnpaidLaunchTest\n[PASS] testNoRequesterMeansNoPayerCreditAnywhere() (gas: 1264616)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 65.84ms (1.04ms CPU time)\n\nRan 1 test for test/EvidenceAndOracleProperties.t.sol:RouterDeadlineTest\n[PASS] testDeadlineIsInclusive() (gas: 422030)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 21.81ms (361.61µs CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:EvidenceCertificationRegressionTest\n[PASS] testActualLaterRoundClaimsHaveNoArtificialCumulativeCeiling() (gas: 1510126)\n[PASS] testDuplicateRecipientCannotOvercreditSmallerActualClaim() (gas: 441218)\n[PASS] testIncompleteTreeCannotBeCertified() (gas: 59593)\n[PASS] testOddTreeReconstructionAndPreCertificationNativeClaim() (gas: 580532)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 75.17ms (1.20ms CPU time)\n\nRan 2 tests for test/SecurityRegression.t.sol:StagingCreationRegressionTest\n[PASS] testCounterfeitConstructorIsRefusedBeforeAnyDeployment() (gas: 6161976)\n[PASS] testOnlySetupAuthorityMayStageAndOnlyUntilActivation() (gas: 11784008)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 90.95ms (8.05ms CPU time)\n\nRan 4 tests for test/SecurityRegression.t.sol:CodeAuthenticationRegressionTest\n[PASS] testActivationExternalFailureRollsBackEveryBinding() (gas: 913067)\n[PASS] testInconsistentImmutablePatchesAreRejected() (gas: 1782922)\n[PASS] testLaterFactoryDonationsCannotRewriteInitialAllocationReceipts() (gas: 688991)\n[PASS] testRuntimeMutationCannotPassGetterChecks() (gas: 84703)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 96.52ms (15.28ms CPU time)\n\nRan 8 tests for test/Adversarial.t.sol:AdversarialTest\n[PASS] test100PercentAloneIsNotFullUnlock() (gas: 7307385)\n[PASS] testArbitraryHookDataAndMultihopPayloadCannotSelectVictim() (gas: 89207)\n[PASS] testCallbacksAllRequireCanonicalManager() (gas: 211512)\n[PASS] testForeignPoolKeyRejectedEvenWithManagerPrank() (gas: 49882)\n[PASS] testNoMintPauseBlacklistUpgradeOrCounterResetEntrypoint() (gas: 114793)\n[PASS] testProtocolFeeChangeCannotSilentlyAlterTradingEconomics() (gas: 357261)\n[PASS] testQuotaMultiplicationDoesNotOverflowAtMaxEligible() (gas: 239235)\n[PASS] testTokenMintsWholeSupplyToDeployerOnly() (gas: 32832)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 104.63ms (18.77ms CPU time)\n\nRan 6 tests for test/ActivationRobustness.t.sol:ActivationRobustnessTest\n[PASS] testPolicySeedRecordsCapacityAndConfirmsTiers() (gas: 30335357)\n[PASS] testSeedBelowOpeningValueFloorCannotLaunch() (gas: 9047798)\n[PASS] testSeedBelowThePoolShareBandCannotLaunch() (gas: 9043839)\n[PASS] testSeedInsideTheOnePercentBandActivates() (gas: 15647267)\n[PASS] testStagingRunsActivationPreconditionsAndCanRepeat() (gas: 21081828)\n[PASS] testSubDustSeedRoundingStillActivates() (gas: 16005370)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 104.75ms (34.20ms CPU time)\n\nRan 3 tests for test/FailurePaths.t.sol:ActivationFailurePathsTest\n[PASS] testCompanionConstructorsRejectMissingInputs() (gas: 6057)\n[PASS] testCrossLaunchSetupIsRefusedInEveryDirection() (gas: 30758204)\n[PASS] testSepoliaRefusesLocallyClonedServicesEvenWithFeedAtPublishedAddress() (gas: 676754)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 118.81ms (43.79ms CPU time)\n\nRan 1 test for test/RevisionProperties.t.sol:RestagingIsolationTest\n[PASS] testAbandonedBundleIsInertAndMixedBundlesAreRefused() (gas: 6919999)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 51.90ms (1.97ms CPU time)\n\nRan 4 tests for test/ActivationRobustness.t.sol:ChunkedCertificationTest\n[PASS] testChunkBoundsAndSizeAreFixedByTheFirstChunk() (gas: 29517535)\n[PASS] testDuplicateAcrossChunksWrongRootAndForeignSessionsAreRefused() (gas: 231631551)\n[PASS] testSingleLeafRoundCertifiesThroughTheChunkedPath() (gas: 398202)\n[PASS] testSingleShotRefusesButChunksCertifyAndCredit() (gas: 124071664)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 146.56ms (93.32ms CPU time)\n\nRan 1 test for test/SecurityRegression.t.sol:LargeTreeCertificationTest\n[PASS] testMaximumSortedTreeFitsTransactionGasLimit() (gas: 15973574)\nLogs:\n  1024-leaf sorted certification gas: 13939470\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 153.00ms (91.83ms CPU time)\n\nRan 3 tests for test/ReleaseConfig.t.sol:ReleaseConfigTest\n[PASS] testReadOnlyReleaseChecksOnLocalFixture() (gas: 2011487)\n[PASS] testReadOnlyReleaseChecksRejectWrongChainOrHash() (gas: 1903758)\n[PASS] testStageOneAloneCannotPassReleaseGate() (gas: 74944069)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 192.72ms (98.38ms CPU time)\n\nRan 11 tests for test/NativeLaunch.t.sol:NativeWithdrawalTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136092723)\n[PASS] testNativeBatchSettlement() (gas: 865791)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1124527)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 451977)\n[PASS] testNativeSettlementResetsPriorSyncCurrency() (gas: 604340)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 91930)\n[PASS] testNativeWithdrawalUsesCEIAndCannotDoubleWithdraw() (gas: 994842)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62586)\n[PASS] testOtherWalletCannotWithdrawNativeRefund() (gas: 459878)\n[PASS] testRejectingNativeWalletCanTradeAndRetryWithdrawal() (gas: 1073164)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29938965)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 214.26ms (229.09ms CPU time)\n\nRan 7 tests for test/NativeLaunch.t.sol:NativeLaunchTest\n[PASS] testDeepNativePoolWarmsUpAndCanUnlock() (gas: 136092722)\n[PASS] testNativeBatchSettlement() (gas: 865791)\n[PASS] testNativeBuySellAndFeeDistribution() (gas: 1124516)\n[PASS] testNativeExactOutputRefundToAuthenticatedCaller() (gas: 451888)\n[PASS] testNativeValueMismatchAndUnsolicitedSendRejected() (gas: 91952)\n[PASS] testOneSidedOpeningLocks87PercentWithoutEthFunding() (gas: 62608)\n[PASS] testThinLaunchCannotUnlockFromInitialSpotOrTinyBuy() (gas: 29938965)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 319.69ms (285.73ms CPU time)\n\nRan 3 tests for test/SecurityRegression.t.sol:OracleOutageRegressionTest\n[PASS] testDepthDipInvalidatesWholeWindowAndRetainsReachedRights() (gas: 16312506)\n[PASS] testFinalTierRequiresItsOwnTwentyFourHours() (gas: 138827744)\n[PASS] testNextTierClockWaitsForItsOwnThreshold() (gas: 15293513)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 528.12ms (195.84ms CPU time)\n\nRan 3 tests for test/EvidenceAndOracleProperties.t.sol:OracleReferenceTest\n[PASS] testCheckpointReplacementRewritesOnlyTheCurrentSecond() (gas: 994219)\n[PASS] testFuzzFdvIsMonotonicInTheEthUsdAnswer(uint64,uint64) (runs: 256, μ: 750321, ~: 750531)\n[PASS] testFuzzTwapMatchesBruteForceReference(uint256) (runs: 160, μ: 2728334, ~: 2707011)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 604.69ms (873.62ms CPU time)\n\nRan 2 tests for test/RevisionProperties.t.sol:ChunkedCertificationPropertiesTest\n[PASS] testFuzz_abandonedSessionIsInertAndRestartable(uint8,uint256) (runs: 128, μ: 2506707, ~: 2135980)\n[PASS] testFuzz_anyChunkingAndReductionScheduleMatchesSingleShot(uint8,uint256,uint256,uint256,uint8,uint8) (runs: 128, μ: 3722254, ~: 3028855)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 886.08ms (831.06ms CPU time)\n\nRan 1 test for test/StageOneInvariants.t.sol:StageOneInvariantTest\n[PASS]\nStageOneInvariantTest invariants:\n[PASS] invariant_onlyTheAuthorizedCallActivates\n[PASS] invariant_tokenAndClaimsIndependentOfTheHook\n[PASS] invariant_unconfiguredPoolIsInert\n StageOneInvariantTest invariants (runs: 96, calls: 3840, reverts: 0)\n\n╭-----------------+------------------+-------+---------+----------╮\n| Contract        | Selector         | Calls | Reverts | Discards |\n+=================================================================+\n| StageOneHandler | advance          | 468   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | attemptActivate  | 501   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | claimAndAttest   | 514   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | directSwap       | 489   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | foreignLiquidity | 493   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | routerSwap       | 463   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | syncAndMilestone | 446   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| StageOneHandler | transfer         | 466   | 0       | 0        |\n╰-----------------+------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.05s (973.02ms CPU time)\n\nRan 3 tests for test/ManipulationEconomics.t.sol:ManipulationEconomicsTest\n[PASS] testCounterSellingOfAllInitialNonPoolTokens() (gas: 157719009)\nLogs:\n  gross ETH capital (wei): 404492004375936755769\n  attacker ETH exit (wei): 139667041180374722901\n  net ETH exit cost before fee recapture (wei): 264824963195562032868\n  payer ETH fee receipts (wei): 4044920043759367559\n  counter-seller ETH proceeds (wei): 259768813140862823404\n  duration seconds: 201600\n\n[PASS] testPayerCanRecaptureItsNativeFeeShare() (gas: 144653849)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n  net ETH cost after native fee recapture (wei): 653249186877100125\n\n[PASS] testSustainedManipulationUnlockAndExit() (gas: 144667569)\nLogs:\n  gross ETH capital (wei): 181211119085726918584\n  attacker ETH exit (wei): 178745758707992549273\n  net ETH exit cost before fee recapture (wei): 2465360377734369311\n  payer ETH fee receipts (wei): 1812111190857269186\n  counter-seller ETH proceeds (wei): 0\n  duration seconds: 201600\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.14s (518.30ms CPU time)\n\nRan 17 tests for test/FailurePaths.t.sol:RouterAndHookFailurePathsTest\n[PASS] testBatchBoundsAndValueMustMatch() (gas: 186758)\n[PASS] testBatchIsAtomicWhenALaterStepFails() (gas: 830450)\n[PASS] testConfirmationRequiresSixHoursAndCannotSkipTiers() (gas: 15340175)\n[PASS] testFullUnlockKeepsFeesAndRouterAuthentication() (gas: 137004282)\n[PASS] testFuzzOperationHashBindsTraderNonceAndChain(address,uint256,uint64) (runs: 256, μ: 17656, ~: 17656)\n[PASS] testFuzzRemainingQuotaFormula(uint128,uint128,uint8) (runs: 512, μ: 7293378, ~: 7293546)\n[PASS] testFuzzTierIsMonotonicInFdv(uint256,uint256) (runs: 512, μ: 16961, ~: 16918)\n[PASS] testFuzzTransfersMoveExactlyTheAmount(address,uint96) (runs: 256, μ: 122329, ~: 122463)\n[PASS] testHookRejectsMalformedRouteDataAndUnknownSenders() (gas: 238753)\n[PASS] testPartialFillAtPriceLimitChargesOnlyExecutedInput() (gas: 1208964)\n[PASS] testQuotaWidensWithTierAndNeverDoubleCounts() (gas: 16785891)\n[PASS] testRequesterChangeAfterActivationDoesNotMoveThePayer() (gas: 146383)\n[PASS] testRouterCallbackNeedsALiveSwap() (gas: 73817)\n[PASS] testRouterRefusesDegenerateRequests() (gas: 500273)\n[PASS] testSecondRoundClaimsAccumulateOncePerRound() (gas: 995639)\n[PASS] testSlippageRefusalsLeaveNoTrace() (gas: 895597)\n[PASS] testSyncForStrangerAndZeroAddressCreatesNothing() (gas: 108400)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 1.58s (1.71s CPU time)\n\nRan 2 tests for test/RevisionProperties.t.sol:SeedGatePropertiesTest\n[PASS] testFuzz_launchedSeedIsAlwaysLiquidAndRefusedSeedIsAlwaysBelowFloor(uint8) (runs: 96, μ: 10945755, ~: 9043277)\n[PASS] testFuzz_poolShareBandDecidesLaunchAndActivation(uint16) (runs: 96, μ: 11107125, ~: 9040781)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 1.48s (522.04ms CPU time)\n\nRan 17 tests for test/Oracle.t.sol:OracleTest\n[PASS] testBadChainlinkRoundsAndAnswersFailClosed() (gas: 2352246)\n[PASS] testConfirmationGapRestartsRatherThanCountingUnobservedTime() (gas: 14857451)\n[PASS] testEveryTierAndPermanentUnlock() (gas: 136511302)\n[PASS] testFallingPricesNeverLowerReachedTier() (gas: 29259665)\n[PASS] testInvalidDataCannotCountTowardPendingConfirmationOrRevokeRights() (gas: 15083422)\n[PASS] testInvalidDataLongerThanGapRestartsOnNextValidCall() (gas: 694951)\n[PASS] testLongInvalidIntervalRestartsWhetherObservedOrNot() (gas: 807692)\n[PASS] testNegativeTickAveragesRoundConservativelyForBothOrders() (gas: 767868)\n[PASS] testObservedAndUnobservedInvalidIntervalsAgree() (gas: 29667292)\n[PASS] testOneBlockSpikeCannotConfirm() (gas: 739290)\n[PASS] testOracleCannotBeReboundOrConfiguredByAnyone() (gas: 73530)\n[PASS] testRealFeedCadenceCannotBeUsedToResetConfirmation() (gas: 18790257)\n[PASS] testSameTimestampManipulationHasNoTimeWeight() (gas: 758610)\n[PASS] testStaleCheckpointAndFeedPreventNewTierButNotTrades() (gas: 1329158)\n[PASS] testSustainedManipulationRequiresWindowAndConfirmation() (gas: 15126515)\n[PASS] testThresholdMappingBoundaries() (gas: 69776)\n[PASS] testWarmupAndExactWindow() (gas: 400906)\nSuite result: ok. 17 passed; 0 failed; 0 skipped; finished in 1.91s (221.16ms CPU time)\n\nRan 1 test for test/Invariants.t.sol:SystemInvariantTest\n[PASS]\nSystemInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n SystemInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 867   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 904   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 836   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 829   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 853   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 831   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.03s (1.94s CPU time)\n\nRan 9 tests for test/Trading.t.sol:TradingTest\n[PASS] testAnotherWalletCannotConsumeVictimsAllowanceOrQuota() (gas: 470687)\n[PASS] testDirectManagerAndForeignRouterSpoofingRejected() (gas: 644028)\n[PASS] testDonatedRouterBalancesCannotCreateCreditOrBeSwept() (gas: 496022)\n[PASS] testExactOutputSaleAccountsActualInput() (gas: 732168)\n[PASS] testExcessSaleRollsBackPoolBalancesOracleAndNonce() (gas: 797176)\n[PASS] testFuzzQuotaBoundary(uint96) (runs: 256, μ: 1032808, ~: 1032869)\n[PASS] testReplayOldCallbackHasNoLiveContext() (gas: 425843)\n[PASS] testSaleBoundaryExecutedInputIncludesPoolFee() (gas: 1062165)\n[PASS] testTransfersDoNotMoveRightsOrAllowChainCredit() (gas: 827129)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 2.12s (2.06s CPU time)\n\nRan 13 tests for test/TwoStage.t.sol:StageOneTest\n[PASS] testActivationSealsAndCannotBeReplayed() (gas: 5901690)\n[PASS] testCrossLaunchNumberRejected() (gas: 5361101)\n[PASS] testFactoryLiquidityAllowedBeforeActivationButPrincipalStaysLocked() (gas: 37293)\n[PASS] testFirstTierConfirmsBelowTenEthActualReserves() (gas: 35384808)\n[PASS] testLaunchSucceedsWithoutCompanions() (gas: 122562)\n[PASS] testPayerCanTransferBeforeActivationWithoutLosingHistoricalCredit() (gas: 5893013)\n[PASS] testPayerCreditOnlyAfterActivationAndFromOriginalTransferReceipt() (gas: 5842154)\n[PASS] testRequesterReassignmentCannotMoveInitialAllocationCredit() (gas: 5848820)\n[PASS] testSepoliaRequiresPublishedChainlinkFeed() (gas: 5377611)\n[PASS] testSwapsSyncAndMilestonesRevertBeforeActivation() (gas: 5849964)\n[PASS] testTransfersAndNativeClaimsWorkBeforeActivationAndClaimIsCreditedLater() (gas: 6199971)\n[PASS] testUnauthorizedActivationRejected() (gas: 5373249)\n[PASS] testWrongContractsRejected() (gas: 6061423)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 2.12s (25.36ms CPU time)\n\nRan 5 tests for test/BatchSettlementProperties.t.sol:BatchSettlementPropertiesTest\n[PASS] testFuzz_BatchEqualsSequentialExecution(uint256,uint8,bool) (runs: 1000, μ: 4664863, ~: 4310101)\n[PASS] testFuzz_FailureAtAnyBatchIndexRestoresAllowancesFeesAndCredits(uint256,uint8) (runs: 1000, μ: 11378895, ~: 11051494)\n[PASS] test_MaximumMixedBatchOnFreshTokenOnlyManager() (gas: 9205385)\n[PASS] test_OneWeiShortAllowanceRestoresEntireBatchAndRetryWorks() (gas: 1867639)\n[PASS] test_PartialSaleMayPrefundMoreThanQuotaButChargesOnlyExecution() (gas: 903643)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 2.12s (3.63s CPU time)\n\nRan 1 test for test/Invariants.t.sol:FullyUnlockedInvariantTest\n[PASS]\nFullyUnlockedInvariantTest invariants:\n[PASS] invariantEligibleEqualsOnlyExecutedBuysAndSynchronizedProofs\n[PASS] invariantNoActorExceedsItsQuotaBeforeUnlock\n[PASS] invariantPrincipalLiquidityNeverDecreases\n[PASS] invariantSupplyConservedAndRouterHasNoCustody\n[PASS] invariantUnlockRemainsPermanentDespiteInvalidFeed\n FullyUnlockedInvariantTest invariants (runs: 128, calls: 5120, reverts: 0)\n\n╭---------------+----------+-------+---------+----------╮\n| Contract      | Selector | Calls | Reverts | Discards |\n+=======================================================+\n| ActionHandler | advance  | 867   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | buy      | 904   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | claim    | 836   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sell     | 829   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | sync     | 853   | 0       | 0        |\n|---------------+----------+-------+---------+----------|\n| ActionHandler | transfer | 831   | 0       | 0        |\n╰---------------+----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.17s (1.90s CPU time)\n\nRan 2 tests for test/RevisionProperties.t.sol:MilestoneSampleInvariantTest\n[PASS]\nMilestoneSampleInvariantTest invariants:\n[PASS] invariant_confirmationNeedsAnUnbrokenChainOfValidSamples\n[PASS] invariant_invalidSamplesNeverAdvanceTiers\n[PASS] invariant_nothingEverRelocksAndStateIsConsistent\n MilestoneSampleInvariantTest invariants (runs: 48, calls: 1920, reverts: 0)\n\n╭------------------------+----------+-------+---------+----------╮\n| Contract               | Selector | Calls | Reverts | Discards |\n+================================================================+\n| MilestoneSampleHandler | advance  | 333   | 0       | 0        |\n|------------------------+----------+-------+---------+----------|\n| MilestoneSampleHandler | corrupt  | 309   | 0       | 0        |\n|------------------------+----------+-------+---------+----------|\n| MilestoneSampleHandler | heal     | 305   | 0       | 0        |\n|------------------------+----------+-------+---------+----------|\n| MilestoneSampleHandler | march    | 320   | 0       | 0        |\n|------------------------+----------+-------+---------+----------|\n| MilestoneSampleHandler | sample   | 327   | 0       | 0        |\n|------------------------+----------+-------+---------+----------|\n| MilestoneSampleHandler | setPrice | 326   | 0       | 0        |\n╰------------------------+----------+-------+---------+----------╯\n\n[PASS] testHandlerReachesTiersAndEveryCorruptionIsInvalid() (gas: 12640787)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.70s (2.68s CPU time)\n\nRan 2 tests for test/QuotaInvariants.t.sol:QuotaInvariantTest\n[PASS]\nQuotaInvariantTest invariants:\n[PASS] invariant_configurationSealedAndRouteEnforced\n[PASS] invariant_ledgerMatchesExecutedDeltas\n[PASS] invariant_milestonesMonotonicAndConsistent\n[PASS] invariant_principalLockedAndFeeTermsFixed\n[PASS] invariant_routerNativeSolvency\n[PASS] invariant_salesNeverExceedQuota\n[PASS] invariant_supplyConservedAndNoCustody\n QuotaInvariantTest invariants (runs: 96, calls: 5760, reverts: 0)\n\n╭--------------+-----------------+-------+---------+----------╮\n| Contract     | Selector        | Calls | Reverts | Discards |\n+=============================================================+\n| QuotaHandler | advance         | 381   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactIn      | 356   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | buyExactOut     | 341   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimAndAttest  | 378   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | claimFees       | 383   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | directSwap      | 385   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | donate          | 365   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | foreignActivate | 380   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellExactOut    | 321   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellOverQuota   | 347   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sellWithinQuota | 727   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | setFeed         | 365   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | sync            | 334   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | transfer        | 341   | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| QuotaHandler | withdrawNative  | 356   | 0       | 0        |\n╰--------------+-----------------+-------+---------+----------╯\n\n[PASS] testHandlerActionsActuallyExecute() (gas: 23814275)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 3.17s (3.17s CPU time)\n\nRan 2 tests for test/ClaimLifecycleInvariants.t.sol:ClaimLifecycleInvariantsTest\n[PASS]\nClaimLifecycleInvariantsTest invariants:\n[PASS] invariant_DistributorReservesAndCashMatchIndependentRoundModel\n[PASS] invariant_FixedSupplyAndInitialReceiptsSurviveAllClaimSequences\n[PASS] invariant_OnlyDeliveredAttestedAndSyncedClaimsCreateRights\n ClaimLifecycleInvariantsTest invariants (runs: 256, calls: 20480, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| ClaimLifecycleHandler | advance           | 1919  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | attest            | 1943  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | certify           | 1767  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | claim             | 1831  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | deliverAndSync    | 1800  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | openRound         | 1876  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | sweep             | 1898  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | sync              | 1901  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | syncPayer         | 1831  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | transferOrDonate  | 1876  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| ClaimLifecycleHandler | unauthorizedRound | 1838  | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\n[PASS] test_ModelExercisesDelayedCertificationSweepsAndRecycledFunding() (gas: 4966220)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 11.46s (11.41s CPU time)\n\nRan 2 tests for test/NativeCustodyInvariants.t.sol:NativeCustodyInvariantsTest\n[PASS]\nNativeCustodyInvariantsTest invariants:\n[PASS] invariant_ManagerHasNoUnsettledDeltaOrReusableRouteContext\n[PASS] invariant_NativeLiabilitiesRemainFullyBackedAndBelongToTheirWallet\n[PASS] invariant_TransfersDonationsAndFailedBatchesCannotCreateOrMoveRights\n NativeCustodyInvariantsTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------------+--------------+-------+---------+----------╮\n| Contract             | Selector     | Calls | Reverts | Discards |\n+==================================================================+\n| NativeCustodyHandler | donateTokens | 2823  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| NativeCustodyHandler | failBatch    | 2661  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| NativeCustodyHandler | forceEther   | 2760  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| NativeCustodyHandler | tradeBatch   | 2694  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| NativeCustodyHandler | transfer     | 2728  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| NativeCustodyHandler | withdraw     | 2718  | 0       | 0        |\n╰----------------------+--------------+-------+---------+----------╯\n\n[PASS] test_HandlerTradesRejectsReentersAndDrainsWithoutTakingDonations() (gas: 5300451)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 13.22s (13.16s CPU time)\n\nRan 37 test suites in 13.23s (52.31s CPU time): 170 tests passed, 0 failed, 0 skipped (170 total tests)\n","passed":true},{"durationMs":164,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MerkleClaimEvidence.abandonSession(uint256)\",\"MerkleClaimEvidence.attest(uint256,address,uint256,bytes32[])\",\"MerkleClaimEvidence.certifyRound(uint256,address[],uint256[])\",\"MerkleClaimEvidence.reduce(uint256,uint256)\",\"MerkleClaimEvidence.submitLeaves(uint256,uint256,address[],uint256[])\",\"UnlkHook.afterAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"UnlkHook.afterRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),int256,int256,bytes)\",\"UnlkHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"UnlkHook.beforeAddLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"UnlkHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"UnlkHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"UnlkHook.configureAndActivate(address,address,address,uint64)\",\"UnlkHook.deployCompanions(uint64,address,bytes,bytes,bytes)\",\"UnlkHook.syncPayer()\",\"UnlkHook.syncRewards(address)\",\"UnlkHook.updateMilestone()\",\"UnlkOracle.bind((address,address,uint24,int24,address),address,int24,int24)\",\"UnlkOracle.checkpoint()\",\"UnlkSwapRouter.receive()\",\"UnlkSwapRouter.swap((bool,int256,uint160,uint256,uint256,uint256))\",\"UnlkSwapRouter.swapBatch((bool,int256,uint160,uint256,uint256,uint256)[])\",\"UnlkSwapRouter.unlockCallback(bytes)\",\"UnlkSwapRouter.withdrawNative()\",\"UnlkToken.approve(address,uint256)\",\"UnlkToken.transfer(address,uint256)\",\"UnlkToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"LICENSE\":25,\"README.md\":146,\"RELEASE_STATUS.json\":29,\"dependencies.lock.json\":24,\"docs/ARTIFACTS.json\":52,\"docs/BUILD_RESULTS.txt\":9,\"docs/DEPLOYMENT.md\":139,\"docs/ECONOMICS_RESULTS.txt\":49,\"docs/FMT_RESULTS.txt\":0,\"docs/FORK_RESULTS.txt\":24,\"docs/LINT_RESULTS.txt\":372,\"docs/MINIMAL_ENV_TEST_RESULTS.txt\":355,\"docs/NETWORK_VERIFICATION_RESULTS.txt\":7,\"docs/PROTECTED_TEST_RESULTS.txt\":22,\"docs/RECOVERY.md\":65,\"docs/SECURITY_REVIEW.md\":123,\"docs/SOURCE_SHA256SUMS\":451,\"docs/SOURCE_VERIFICATION_RESULTS.txt\":449,\"docs/TEST_RESULTS.txt\":364,\"docs/VALIDATION.md\":115,\"docs/abi/CheckReleaseConfig.json\":46,\"docs/abi/HookDeployer.json\":84,\"docs/abi/IChainlinkEthUsd.json\":48,\"docs/abi/IClaimEvidence.json\":47,\"docs/abi/IHooks.json\":789,\"docs/abi/ILaunchFactoryView.json\":115,\"docs/abi/ILaunchRegistryView.json\":70,\"docs/abi/IMerkleDistributor.json\":125,\"docs/abi/IPoolManager.json\":1286,\"docs/abi/IRouteContext.json\":20,\"docs/abi/LaunchFactory.json\":896,\"docs/abi/LaunchFees.json\":323,\"docs/abi/LaunchRegistry.json\":320,\"docs/abi/MerkleClaimEvidence.json\":461,\"docs/abi/MerkleDistributor.json\":451,\"docs/abi/Stage2.json\":225,\"docs/abi/UnlkHook.json\":1973,\"docs/abi/UnlkOracle.json\":443,\"docs/abi/UnlkSwapRouter.json\":359,\"docs/abi/UnlkToken.json\":425,\"docs/network/capabilities.json\":345,\"docs/network/factory-artifacts.json\":2201,\"docs/network/factory-reference.json\":420,\"docs/network/factory.runtime.hex\":1,\"docs/network/feed-reference.json\":67,\"docs/network/feed-rounds.json\":134,\"docs/network/feed.runtime.hex\":1,\"docs/network/fees.runtime.hex\":1,\"docs/network/job-identity.json\":14,\"docs/network/manager.runtime.hex\":1,\"docs/network/policies.json\":36,\"docs/network/registry-reference.json\":108,\"docs/network/registry.runtime.hex\":1,\"docs/network/sepolia.json\":309,\"docs/network/services.json\":29,\"foundry.toml\":31,\"launch.json\":35,\"rehearsal/Sepolia.t.sol\":112,\"remappings.txt\":4,\"script/CheckReleaseConfig.s.sol\":85,\"script/LocalDemo.s.sol\":41,\"script/Stage2.s.sol\":98,\"scripts/check.sh\":8,\"scripts/check_protected.py\":31,\"scripts/export_abis.py\":33,\"scripts/generate_code_checks.py\":22,\"scripts/mine-hook.sh\":9,\"scripts/prepare_claim_tree.py\":37,\"scripts/rehearse-sepolia.sh\":4,\"scripts/release_artifacts.py\":51,\"scripts/verify_network.py\":46,\"src/HookDeployer.sol\":29,\"src/HookFlags.sol\":45,\"src/MerkleClaimEvidence.sol\":200,\"src/UnlkHook.sol\":719,\"src/UnlkOracle.sol\":190,\"src/UnlkSwapRouter.sol\":225,\"src/UnlkToken.sol\":42,\"src/interfaces/IIntegration.sol\":86,\"src/libraries/OperationHash.sol\":15,\"src/libraries/ReviewedCode.sol\":10,\"src/libraries/SeedDepth.sol\":41,\"src/libraries/SepoliaRelease.sol\":11,\"test/ADDITIONAL_COVERAGE.md\":94,\"test/ActivationRobustness.t.sol\":303,\"test/Adversarial.t.sol\":117,\"test/BatchSettlementProperties.t.sol\":272,\"test/ClaimLifecycleInvariants.t.sol\":444,\"test/CreditsAndFees.t.sol\":176,\"test/EvidenceAndOracleProperties.t.sol\":349,\"test/FailurePaths.t.sol\":580,\"test/Invariants.t.sol\":220,\"test/Launch.t.sol\":112,\"test/LocalScript.t.sol\":28,\"test/ManipulationEconomics.t.sol\":117,\"test/NativeCustodyInvariants.t.sol\":296,\"test/NativeLaunch.t.sol\":236,\"test/Oracle.t.sol\":422,\"test/QuotaInvariants.t.sol\":529,\"test/ReleaseConfig.t.sol\":32,\"test/RevisionProperties.t.sol\":593,\"test/SecurityRegression.t.sol\":337,\"test/Stage2Script.t.sol\":62,\"test/StageOneInvariants.t.sol\":281,\"test/Trading.t.sol\":171,\"test/TwoStage.t.sol\":302,\"test/fixtures/LocalFixtures.sol\":59,\"test/fixtures/SystemFixture.sol\":371,\"test/imd/HookFlags.sol\":45,\"test/imd/LaunchFactory.sol\":375,\"test/imd/LaunchFees.sol\":73,\"test/imd/LaunchRegistry.sol\":109,\"test/imd/MerkleDistributor.sol\":181,\"test/imd/PoolFees.sol\":220,\"test/imd/README.md\":29,\"test/mocks/MockERC20.sol\":11},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"fff4c7010c6f5c1794eb7af2403519955d07fe6ec72f8e81c807d7f8fb247749","verifiedTreeHash":"3f4fbeae47ed2ab3c58bf791df5b4e7fb18c6a28","verifierVersion":"0.1.0+327e1e9f"}]}