{"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":"0c8421fb-4f6d-4650-8c90-d9fd7d7a79c5","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"999ef21d4e5d4cad7b2cd78fe1fdae810acc1dd749fc5603faf9acd88be1625c","dependsOn":["audit_imported_code"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"2d7d84a1a9972f1497e5bc68a704cbf42294d08c62d2868f102ffe3b909b9b51","skillId":"adapt-contract-project","tools":[]},"key":"adapt_contract_project","kind":"code","role":"implement","skillHash":"2d7d84a1a9972f1497e5bc68a704cbf42294d08c62d2868f102ffe3b909b9b51","skillId":"adapt-contract-project","state":"accepted"},{"acceptedSubmissionHash":"529d38fdd06164bed54a44e5d46785212e6a3dd8fd6e0ec1e3b2ef3cd9179567","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"7810c15f6628b38f6ea65417bc199ddcd4bcc1611c02dd9b62d73473234185bb","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"573ea9d5650bafcdc892589b64157aecbe9239f7efb89fa37b3d9bed699654f2","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","tools":[]},"key":"audit_imported_code","kind":"code","role":"review","skillHash":"9897597976b0e72440db7ca402d225aea20f3d37205ba53e7df2400ff80f29cc","skillId":"audit-imported-code","state":"accepted"},{"acceptedSubmissionHash":"bcc2c7f0e65702844015ae996a88c3e6382cdfe7e8740abaa72dd50dc52db968","dependsOn":["adapt_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"78e6ceadcdd6c1e725b8c3a61ba5ba3e0e4eeacaa772f085f796449a6aa30c9d","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"f2993750d85039bb717ac74377d17e11a7909de6944a598eed061ac09272a98e","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"62017509fad038fc14ec8244d879910b11188b3ac12b4c17cb08f6df30620d1c","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"2e709afce4669909e00d09e7d2fd589e14a61c7619e4db6036c7435edaf62918","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Launch the exact pinned IMD-compatible MUGI V1 source on Ethereum mainnet through the contracts-only path. Inspect ADAPTATION.md, README.md, docs/IMD_CONSTRUCTOR_DEPLOYMENT.md, docs/validation/compatible, inventory.json, launch.json, src and all tests. This supersedes the earlier rejected mint/freeze/pause/post-initialization design. Review this new source on its merits; no policy exception is requested. Preserve Solidity 0.8.26, Cancun, optimizer 200, viaIR and bytecode_hash none. Packaging/manifest adjustments are allowed; if source fixes are necessary, report them before deployment rather than deploying modified code automatically. The initial IMD transaction creates exactly four full-code owner-bound factories in manifest order. Each constructor is nonpayable and has only one static address owner argument; none creates children, calls dependencies or checks external code in its constructor. The main factory constructor pins the hash and length of the exact raw hook creation code compiled from this source, without unresolved constructor arguments. Do not introduce a standard token launch, distributor, swarm allocation, proxy, delegatecall route or token-launch economics. FULL APPLICATION DISCLOSURE: all nineteen later descendants are in scope for audit and admission: ten crew ERC20s, the hook, airdrop, swap router, VRF adapter, IMD verifier, ledger, budget controller, price oracle and V4 liquidity engine. After the four factories exist, five separate owner transactions create these applications with complete final constructor configuration. Fixed CREATE nonces predict future dependencies, breaking cycles. The complete fourteen-static-field hook tuple and a mined CREATE2 salt are committed during service-module creation; deployHook checks the complete commitment and the constructor-pinned raw creation code. All child constructor arguments are static. No application initialize/configure/bindAccounting/dependency replacement is needed or available. Economic activation validates reciprocal bindings, token identity and all ledger exclusions. The four registry entries index factories only, not their descendants. Do not claim the whole game is deployed or active when only factories exist. Service coordinator/subscription, attestor and signer settings and final graph addresses need a reviewed subsequent deployment plan; mock values are forbidden for live operation. GAME RULES: ten crews, initial 95/5 LP/airdrop allocation, fixed daily cutoffs, nine VRF eliminations, seventy-five-percent loser conversions, pro-rata treasures, LP redistribution, bounded buybacks, team fees, timeout recovery and thirty-day final claims remain. Every crew token creates its entire finite reserve once in its constructor. There is no external mint capability; the hook releases already-held reserve under bounded game rules. totalSupply includes the unused reserve and must not be called circulating supply. Unused reserve is excluded from eligibility and burned when its crew or season closes. Tokens transfer freely at all times, including cutoff and after elimination; no holder confiscation or hook token callbacks remain. Burn only burns the caller own balance. There is no owner trading pause. Timestamp snapshots strictly before scheduled cutoffs preserve earned rights; official game pools and token reward materialization retain published round/alive/cutoff gates. Disclose and assess these gates explicitly instead of equating them to ERC20 freezes. V2 CONTINUITY: V2 is separate future work. After ordinary finale V1 retires unused reserve, retains player token backing and reserved player/team ETH, then permits an owner-only one-shot atomic handoff of only available inventory/ETH to a deployed receiveV1Finale(uint8,address,uint256) receiver. A zero constructor target allows the owner to choose a future receiver; a nonzero pin is enforced. Receiver failure rolls everything back. Claims continue in V1; emergency closure cannot migrate. This is protocol-fund continuity, not automatic wallet-level V2 allocation. Actual V2 receive, configure, seed, launch and buy integration is tested separately. Return explicit admission outcome, final source pin, IMD launch record, four factory addresses and transaction receipts. Do not deploy the nineteen children or seed pools as part of this request. Do not submit source verification to Etherscan, Blockscout, Sourcify or any explorer. If source verification is mandatory, stop with needs_input before deployment. Manifest: {\"contracts\":[{\"constructorArgs\":[\"0x20714d50f4675c366de30b603728a90ddddb240f\"],\"contract\":\"MugiIMDCrewFactory\"},{\"constructorArgs\":[\"0x20714d50f4675c366de30b603728a90ddddb240f\"],\"contract\":\"MugiV1IMDDeploymentFactory\"},{\"constructorArgs\":[\"0x20714d50f4675c366de30b603728a90ddddb240f\"],\"contract\":\"MugiIMDAccountingFactory\"},{\"constructorArgs\":[\"0x20714d50f4675c366de30b603728a90ddddb240f\"],\"contract\":\"MugiIMDEngineFactory\"}],\"kind\":\"evm_contracts\",\"notes\":\"Four owner-bound operational factories, each with one static owner constructor argument; no constructor dependency calls, code checks or child creation. Disclose and review all nineteen later full-code application descendants and five owner creation transactions. Every application is fully constructor-configured: no initialize/configure/bindAccounting or mutable dependencies. Tokens have constructor-only fixed reserves, no later mint, no transfer freeze or owner pause; game elimination/rewards use timestamp cutoffs and bounded reserve releases. V1 competition, reward distribution and V2 handoff remain. Raw hook creation code is pinned by the main factory constructor; full hook initcode/salt are committed during module creation. See docs/IMD_CONSTRUCTOR_DEPLOYMENT.md. Remote admission and deployment remain unproven. Factory registry entries do not individually index descendants. No explorer source verification.\"}","parentJobId":null,"planHash":"d09857c5064d809a40919d8d722c018727be809ed0328c1242a618caeed9ada8","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"0c8421fb-4f6d-4650-8c90-d9fd7d7a79c5","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2433-mugiimdcrewfactory-mugiv1imddeploymentfa"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52116","feedbackHash":"c7795181ec48ae5bf0233346b8c82dc81e28f3f6932f5bb89d4b7bd9c174e694","nodeKey":"adapt_contract_project","submissionHash":"a16d382bc8d3b9bb6905340f898c381f6748ba0190b97334668a7749cf2440f3","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51196","feedbackHash":"7fa425ce7d1629d7c7fcd8db51a51c0b22636d18f41363215a6e277eae27ed47","nodeKey":"adapt_contract_project","submissionHash":"8dd84fd9fd0aac050f7c530fac4bbb15b5b1cd010b80f99bf89c0a13fd8388d7","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51368","feedbackHash":"97cecea13b54de84a3f2ee7d6a5df27bef2c086692ed60b42dfa1026587b22fa","nodeKey":"adapt_contract_project","submissionHash":"999ef21d4e5d4cad7b2cd78fe1fdae810acc1dd749fc5603faf9acd88be1625c","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51744","feedbackHash":"b3e24558f16b3d45395bd2cbd909e023fa9232131ca2b432329e47fbff6b9c84","nodeKey":"audit_economics","submissionHash":"529d38fdd06164bed54a44e5d46785212e6a3dd8fd6e0ec1e3b2ef3cd9179567","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52162","feedbackHash":"87a2b6c49289afaf8409c1d43889e4e68c074e4fb22e722b5a79c4ece177c909","nodeKey":"audit_flow","submissionHash":"7810c15f6628b38f6ea65417bc199ddcd4bcc1611c02dd9b62d73473234185bb","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52680","feedbackHash":"929bf3b9a60c46889546e8ff6ce08003e67a6b9780aba663708e5c84be35844d","nodeKey":"audit_imported_code","submissionHash":"573ea9d5650bafcdc892589b64157aecbe9239f7efb89fa37b3d9bed699654f2","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50962","feedbackHash":"9e7619bec801419884b8de9c6f3fc060b03c3615575050659d8008e11922f0db","nodeKey":"audit_judge","submissionHash":"bcc2c7f0e65702844015ae996a88c3e6382cdfe7e8740abaa72dd50dc52db968","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52628","feedbackHash":"4e249fd473ab487dc68fd98d767abcc45acd0ed6bf1a618f8898ce69ace15d7e","nodeKey":"audit_judge","submissionHash":"7e60a3630d747a82e588965412393a97afcaf919918100e5827c3b38b1a01652","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52548","feedbackHash":"add742cbdfca3d48c5e6c382e7f7522b7ea7a0748c34140df43251e7a4e52fdf","nodeKey":"audit_judge","submissionHash":"7edd376c1aa3db4ebe3d96d62ec7825964b5d1cbfa26678c8186621c9a33bad0","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52552","feedbackHash":"396604a19b32a907ff5232401d513eb5dfc12eae3f465cdc00ed45ad35c3204e","nodeKey":"audit_math","submissionHash":"78e6ceadcdd6c1e725b8c3a61ba5ba3e0e4eeacaa772f085f796449a6aa30c9d","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52173","feedbackHash":"59cfed32f45b88dee63be7c4f0105d046978de020ca3c40ad0b68799babf8f93","nodeKey":"audit_permissions","submissionHash":"f2993750d85039bb717ac74377d17e11a7909de6944a598eed061ac09272a98e","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52375","feedbackHash":"4f597dec6eebdb38aad032042cc21b39b6bf4a867bdd736defcf03ac1869f86a","nodeKey":"manifest","submissionHash":"c4e3738010ac51a187576511ab94bf07075dd223cbd6bc9d352c618946ab0a74","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52231","feedbackHash":"231ae3353f43d9df3faaee488477a094866d952caffd125b8bcae189e368d17f","nodeKey":"manifest","submissionHash":"3ccde9f146bbb4b0d63d13ea5c24561e7717d0e4f8bd51b69879291a3b4c3465","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52263","feedbackHash":"fe8ea334e3f7f6cfe127713b3786daf58e8a92ba38b74649889a7a28461f141a","nodeKey":"manifest","submissionHash":"62017509fad038fc14ec8244d879910b11188b3ac12b4c17cb08f6df30620d1c","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"53911","feedbackHash":"9e410b2f0631f9596953caac3352e6fa82f5cab9c581fd56d2a60f89b782cf34","nodeKey":"write_foundry_tests","submissionHash":"c36fd6e3b2c3b4487e6cebb5ef0fb0682045d82d96f924aa708f3b2a1f18d099","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52261","feedbackHash":"e571ca73ede9924879d29a2163185cb9e80b8577a20743db1935cecee66ca28f","nodeKey":"write_foundry_tests","submissionHash":"d3d45bc7980f55636bd4be537086bbbda7c4f0e55de1efca600bbdccd0b2b7a9","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52671","feedbackHash":"18d2bbfb0116fb1c6c464371337530bb0b0417d2d82478ac5097a0d048e02532","nodeKey":"write_foundry_tests","submissionHash":"2e709afce4669909e00d09e7d2fd589e14a61c7619e4db6036c7435edaf62918","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"fd1bace4aa52ef79004536fb421a504a80798497509d39ecb3f04d40c774b0cd","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"c7f1439ef40385e3da0f051fedf53e084b66173474e7b272d3bf87176c1abf85","device":"e293ff3324f7ddb5","findings":[],"hash":"2e709afce4669909e00d09e7d2fd589e14a61c7619e4db6036c7435edaf62918","nodeId":"1c377897-7d57-453d-ac44-4e9a893c96c6","outcome":"completed","summary":"I fixed the one failing test, and the full suite was clean apart from it. I didn't change any source or configuration.\n\n**What failed:** at the verifier's fuzz seed, the suite ran 177 tests: 174 passed, 2 were skipped and one failed. The failure was `testFuzzGuardAtNowMatchesConsultBand` in `test/imd/modules/MugiIMDPriceOracleGuard.t.sol`, and the fault was in that test, not in the oracle.\n\n**Why it was wrong:** the test assumed the settlement price check uses the same average as `consult()`, but they average over different windows.\n- `settlementPriceValid` compares the price against the average over the whole round: up to one day, starting from the first update when there is less history than that. This is what the contract's own comments describe.\n- `consult()` averages only from the newest stored observation at least 15 minutes old.\n\nWhen the price history is uneven the two averages differ, so the old assertion failed on a correctly behaving contract.\n\n**The fix:** I replaced it with `testFuzzGuardAtNowMatchesRoundMeanBand`. The test works out the expected average itself, by weighting each tick by how long it held, rounding down. It expects `false` when there is under 15 minutes of history, and otherwise `true` exactly when the price is within 488 ticks of that average. It passes 512 runs at the verifier's seed (`0x17f6…72f1`).\n\nAfter the edit I re-ran only that test file (5 of 5 pass), not the full suite. The edit touches nothing outside that file. I filed no findings because this failure was a test error, not a contract defect.","treeHash":"bf92727fdab1b6965da67ae000ea6a4c57dc3e79","usage":{"cachedInputTokens":197359,"inputTokens":12,"model":"claude-opus-5-5","outputTokens":2919,"runtime":"claude","turns":6,"wallClockMs":515929}},{"artifacts":[],"attempt":1,"bundleHash":"cfc70528c970a53cde280c0cd4dfe9c7f801add8df593a8dc3a71ee14d14984e","device":"4f2ce49dc630c86e","findings":[],"hash":"3ccde9f146bbb4b0d63d13ea5c24561e7717d0e4f8bd51b69879291a3b4c3465","nodeId":"a019d455-9843-4b7b-bec6-9d5ba61810df","outcome":"completed","summary":"I confirmed the finding and fixed it in `launch.json`. The brief's own manifest gives `0x20714d50f4675c366de30b603728a90ddddb240f` as the owner for all four factories. The launch rules say an owner address the brief states is written as that fixed address, not as `$owner`. `$owner` is filled in later by the launch service, so if it pointed at a different wallet, ownership of all four factories would go there permanently.\n\n- **Change:** all four factory entries (`MugiIMDCrewFactory`, `MugiV1IMDDeploymentFactory`, `MugiIMDAccountingFactory`, `MugiIMDEngineFactory`) now pass `0x20714d50f4675c366de30b603728a90ddddb240f` directly. I also reworded the one sentence in the notes that described `$owner`.\n- **Manifest check:** the file still has only `kind`, `contracts` and `notes`, and the notes are 3,918 characters (the limit is 4,000).\n- **Build and tests:** `forge build` succeeded. `forge test` with the verifier's fuzz seed passed 146 tests with 0 failures and 2 skipped.\n- **Reviewer answer:** I wrote `.imd-responses.json` answering the finding as \"fixed\".\n\n`launch.json` is the only file in the diff, and no source code changed.\n\nThe things the brief asks to have returned (admission outcome, IMD launch record, the four factory addresses and transaction receipts) don't exist yet. They only come from the deployment service, so none of them are claimed here. Nothing was deployed and nothing was sent to a block explorer for source verification.","treeHash":"dcd127809a68139302e5df2378f134aeabdb7d8e","usage":{"cachedInputTokens":111036,"inputTokens":8,"model":"claude-opus-5-5","outputTokens":1441,"runtime":"claude","turns":4,"wallClockMs":454552}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"81314195390981c7","findings":[{"citation":"resolved","description":"_addMatchedLiquidity (called from settleRound for every survivor) prices the 'LP redistribution' purely from the pool's current slot0 (MugiIMDV4Engine.quoteLiquidityForEth reads manager.getSlot0 and returns tokensNeeded for ethBudget at that price). Official-pool swaps are blocked from nextCutoff until the last settleRound batch, so the price used is whatever the last pre-cutoff trader left. Unlike the buyback path (_buyAndBurn -> prices.quoteMinimum enforces MAX_SPOT_DEVIATION_TICKS against the TWAP), the settlement path has no reference-price check. A trader buys a crew heavily just before cutoff (pushing ETH-per-token up), the protocol then deposits settlementLiquidityEth/survivors of ETH plus only the few reserve tokens that price implies, and when the pool reopens the trader sells into the much deeper ETH side. The value comes out of the protocol-owned LP (the ETH that later funds emergency recovery or the V2 handoff). Note a 15-minute TWAP consulted at settlement would not help either: no swaps happen during resolution, so the oracle's cumulative extends the pumped tick; the reference must be taken from the window before nextCutoff. Economic seam: execution (settleRound) x periphery (PoolManager slot0) x principle (LP redistribution should not be extractable). Condition: the pumped crew must survive the draw (the attacker holds across the VRF window, risk 1/survivors), so this is medium rather than high; the attacker additionally receives the round's treasure share as a large crew holder.","line":369,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Scratch test using the repository's MugiGameTestBase (PoolManager + PoolSwapTest, SUPPLY=1e6 ether, POOL_ETH=100 ether): run _round(0) eight times (crews 0..7 eliminated, crews 8 and 9 alive). Mallory (10,000 ETH) buys crew 9 with exact-input 300 ETH just before cutoff; _requestAndFulfill(0) eliminates crew 8; settleRound(10) adds settlementLiquidityEth = 93.97 ETH to crew 9 at the pumped price; Mallory then sells all crew-9 tokens. Mallory's ETH balance change: +19.06 ETH (19057074374016289333 wei), excluding her claimable treasure reward. Control: the identical 300 ETH buy followed immediately by the sell (no settlement in between) yields -13.13 ETH (-13128401461288847986 wei, game+LP fees). The 32.19 ETH swing is protocol LP ETH transferred to the trader. Expected: settlement liquidity is priced against a manipulation-resistant reference (e.g. TWAP ending at nextCutoff) and deferred (LiquidityDeferred) when spot deviates beyond the same 488-tick bound used for buybacks; actual: added at any spot price.","severity":"medium","snippet":"        (uint128 liquidity,, uint256 needed) = engine.quoteLiquidityForEth(crew, ethAmount);","title":"Settlement adds protocol ETH liquidity at the frozen pre-cutoff spot price with no TWAP/deviation guard, so a holder who pumps a crew before cutoff extracts the matched ETH after reopen"},{"citation":"resolved","description":"The brief requires that unused reserve is burned when its crew or season closes. _retireReserve is only reachable from _beginSettlement, finalize and recoverStalledRandomness, none of which can run once phase == Aborted (every path checks Live/AwaitingRandomness/OutcomeReady/Settling/EmergencyUnwinding). abortPrelaunch removes the seeded LP and refunds ETH but leaves unreleasedReserve[i] and the LP tokens returned by engine.removeLiquidity in the hook, and the airdrop's 5% drop can never be retired because airdrop.launchedAt stays 0 (retireRemaining requires launchedAt != 0). The closed season therefore leaves every token with a permanent totalSupply of reserveFor(I) held by contracts, contradicting the disclosed reserve-retirement rule; no holder funds are at risk.","line":251,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Verified in a scratch test: MugiGameTestBase._deployGame(new PoolManager) (test contract is owner); seedPool{value:1 ether}(0); abortPrelaunch(); then phase()==Aborted, unreleasedReserve(1)==reserveCap, tokens(1).totalSupply()==reserveCap, and retireAirdrop() reverts InvalidState. Expected: unreleasedReserve(i) == 0 and token totalSupply reduced for every crew once the season is closed. Actual: phase == Aborted, unreleasedReserve(1..9) == reserveCap and MugiCrewToken(tokens[i]).totalSupply() == reserveCap for crews 1..9 (and reserveCap - burned 0 for crew 0, with initialSupply/20 stuck in the airdrop); every subsequent hook entry point reverts InvalidState, so no call can retire it.","severity":"low","snippet":"        phase = Phase.Aborted;","title":"abortPrelaunch closes the season without retiring any crew reserve; totalSupply stays at 10I+100M forever"},{"citation":"resolved","description":"ADAPTATION.md and the brief preserve 'fixed daily cutoffs' and the requestElimination comment says 'Fixed clock cutoff applies even when nobody submits this transaction promptly'. Only the first cutoff (launch + 1 day) is fixed. Every later cutoff is block.timestamp of the final settleRound batch plus 24h, so it absorbs the delay before requestElimination (up to 7 days), VRF latency (64 confirmations) and settlement latency. Players and keepers cannot know future cutoff times in advance, and the official-pool trading window plus buyback window shift every round.","line":341,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Launch at T (nextCutoff = T+1d). At T+1d+3h someone calls requestElimination; VRF fulfils at T+1d+3h15m; settleRound(10) at T+1d+4h. Expected (fixed daily schedule): nextCutoff == T+2d. Actual: nextCutoff == T+2d+4h; repeating with a 4h delay each round leaves the ninth cutoff 32h later than the fixed schedule.","severity":"low","snippet":"            nextCutoff = uint64(block.timestamp + 1 days); phase = Phase.Live;","title":"Round cutoffs are not fixed daily: each nextCutoff is set from settlement completion time, so request/VRF/settlement latency shifts every later cutoff"}],"hash":"529d38fdd06164bed54a44e5d46785212e6a3dd8fd6e0ec1e3b2ef3cd9179567","nodeId":"81cbb429-5e57-4c77-b0b2-4f783a2bd19a","outcome":"completed","summary":"I found three defects in the economics area: one medium and two low. They are in `.imd-findings.json` with copied snippets and reproductions, and all three snippets match the tree. Coverage has 74 rows: 68 entry points plus 2 invariants hold, 2 entry points have findings, and the 4 `MugiIMDVerifier` admin functions are unreached because they are outside the economics area. No repository files were changed. I wrote scratch tests under `test/scratch/` to check the claims and then deleted them.\n\n**Findings**\n\n1. **Medium: an attacker can buy a crew up before the cutoff and take part of the protocol's settlement liquidity** (`src/imd/MugiIMDGameHook.sol:369`). When a round settles, `settleRound` adds protocol ETH to each surviving crew's pool at whatever price the last trade left. That price is frozen, because official-pool swaps are blocked from the cutoff until settlement ends. Buybacks check the price against a time-weighted average and refuse large deviations; this step has no such check.\n   - **Setup:** the repo's test base, rounds played until only crews 8 and 9 are left.\n   - **With settlement in between:** an attacker buys 300 ETH of crew 9 before the cutoff, crew 8 is eliminated, settlement adds 93.97 ETH to crew 9's pool, and the attacker sells everything. The attacker's ETH goes up by 19.06 ETH, not counting the treasure reward they can also claim.\n   - **Control:** the same buy and sell with no settlement between them loses 13.13 ETH to fees.\n   - **Result:** the 32.19 ETH difference comes out of protocol-owned liquidity.\n   - **Why medium:** it only pays if the pumped crew survives the draw, so the attacker carries elimination risk.\n   - **Fix:** compare against an average price taken over the period *before* the cutoff, and defer the liquidity when the price is too far off. An average read at settlement time would not help, because no trades happen during settlement, so it just repeats the pumped price.\n2. **Low: `abortPrelaunch` closes the season without burning any reserve** (line 251). Once the phase is `Aborted`, nothing can burn the reserve. Each token's total supply stays at the full reserve cap forever, and the 5% airdrop allocation is stuck. A scratch test confirmed this, including `retireAirdrop()` reverting. That contradicts the rule that unused reserve is burned when the season closes. No player funds are at risk.\n3. **Low: cutoffs are not on a fixed daily schedule** (line 341). Only the first cutoff is fixed. After that, each cutoff is 24 hours after the last `settleRound` batch, so every delay adds up. For example, a 4-hour delay each round puts the ninth cutoff 32 hours late, while the docs promise \"fixed daily cutoffs\". I did not run a test for this one; it follows directly from that line.\n\n**Checked and holding:**\n- **Ledger:** the 75% conversion always divides exactly for 9 down to 1 survivors. Each round's eligible supply uses the token balances recorded just before the original cutoff. Claims and escrow use the same timestamp-snapshot rule, and every ledger exclusion is applied.\n- **Hook ETH:** the ETH balance always covers reserved player ETH plus team fees on every outflow (ETH claims, team fee withdrawals, emergency recovery, the 30-day sweep and the V2 handoff).\n- **Reserve and fees:** the reserve proof's release limits hold. Swap-fee directions are correct. Buyback bounds work, and buybacks are only exposed to a small (about 3%) sandwich loss, which is within their designed tolerance.\n\nI did not re-report what `ADAPTATION.md` already discloses: the owner's discretion when the V2 target is zero, the survivor leftover that only the owner can migrate, team and community being the same wallet as the owner, and excluding the PoolManager from eligibility. I found no high or critical issue, so no finding carries a Foundry proof.","treeHash":null,"usage":{"cachedInputTokens":2762645,"inputTokens":54,"model":"claude-opus-5-5","outputTokens":50163,"runtime":"claude","turns":28,"wallClockMs":665561}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"d7e6877fd9e388bb","findings":[{"citation":"resolved","description":"migrateToV2 only requires Finalized phase, a non-migrated flag and that `target` has code. hook-constructor.json line 9 plans v2MigrationTarget = 0x0, so the nonzero-pin branch never applies and the owner picks the receiver after the season. The amount sent is address(this).balance - teamEth - ledger.reservedEth(), i.e. the survivor pool's entire LP ETH principal (seed ETH plus every player buy that grew the pool), treasure[survivor], ownBurnBudget[survivor], unallocated reward dust and deferred settlement ETH, plus every survivor token the hook holds beyond escrow. Nothing checks that the receiver is a V2 game, that it is not owner-controlled, or that holders of the surviving crew receive anything. ADAPTATION.md discloses this as 'owner discretion', but functionally it is an owner withdrawal of all post-finale protocol ETH, which the reference guide classes as funds paid to a privileged party. The adapter should either require a nonzero pinned receiver whose code is reviewed, or add a non-owner exit for the finale ETH.","line":485,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"State: hook constructed with v2MigrationTarget == address(0) (as in hook-constructor.json), season played to finalize() so phase == Finalized, survivor pool removed, hook holds e.g. 300 ETH of LP principal + treasure. Owner deploys `contract Sink { address immutable o = msg.sender; function receiveV1Finale(uint8,address,uint256) external payable { payable(o).transfer(msg.value); } }` and calls migrateToV2(address(sink)). Expected under the stated game rules: finale ETH stays protocol-bound or reaches a reviewed V2. Actual: the call succeeds (target.code.length != 0, no pin), transfers all survivor inventory tokens to Sink and sends ethAmount = balance - teamEth - reservedEth to Sink, which forwards it to the owner EOA in the same transaction. Player ETH/token claims remain intact; everything else leaves.","severity":"medium","snippet":"        if (phase != Phase.Finalized || migrated || target.code.length == 0","title":"Owner-chosen V2 receiver (zero pin in planned config) can route all finale ETH and survivor inventory to any contract, including one that forwards to the owner"},{"citation":"resolved","description":"At every elimination the loser's treasure is recorded as an ETH reward round for survivors, but finalize() records no reward: it withdraws the survivor pool's full liquidity into the hook, calls ledger.finalizeMigration (which only freezes terminalSupply) and retires reserve. Survivor-crew holders keep ERC20s whose only official pool now has zero liquidity and no ETH entitlement. The removed LP ETH, treasure[survivor], ownBurnBudget[survivor], unallocatedEth and deferred settlement ETH have exactly one outbound path, migrateToV2, which is onlyOwner and has no deadline. sweepExpiredFinalClaims in Finalized pays only ledger reservedEth to the community treasury (line 503); the EmergencyClosed branch that sweeps the full balance does not apply to the ordinary finale. If the owner key is lost or the owner declines, this ETH is stuck forever. This contradicts 'LP redistribution' for the final round and should be disclosed as such; the adapter should add a fallback (e.g. after the 30-day window, sweep to community or distribute pro rata to terminalSupply).","line":474,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"State: season with nine eliminations settled, phase Live, eliminations == 9, block.timestamp >= nextCutoff. Anyone calls finalize(). Observe: engine.positionLiquidity(survivor) == 0, hook ETH balance increased by the removed principal, ledger.previewAccount(holder) for a survivor-crew holder shows earnedEth unchanged (no new round), eligibleSupply(survivor) == terminalSupply. Warp 30 days and call sweepExpiredFinalClaims(): community receives only the previously reserved player ETH; address(hook).balance still holds LP principal + treasure[survivor] + unallocated. No non-owner function can move it: withdrawTeamFees moves only teamEth, claimEth only earnedEth, migrateToV2 reverts for non-owner with Unauthorized. Expected: a time-bounded, permissionless resolution of the finale ETH; actual: indefinitely owner-gated.","severity":"medium","snippet":"        MugiV4Engine.LiquidityResult memory removed = engine.removeLiquidity(survivor, 0, 0);","title":"finalize() distributes nothing to surviving-crew holders and leaves all finale ETH owner-gated indefinitely: no permissionless exit exists if the owner never calls migrateToV2"},{"citation":"resolved","description":"MugiIMDGameHook.sweepExpiredFinalClaims pays expired player ETH (Finalized) or the whole non-team balance (EmergencyClosed) to the immutable communityTreasury, and the source comment says 'neither can be redirected to owner'. The season constants file that the deployment plan says to encode into the hook tuple (and into the ledger tuple's team/community fields) uses the owner wallet 0x2071...240f for team, community and owner. With that configuration every expired player claim, every unallocated emergency share and all team fees land in the owner's wallet. The ledger exclusion set also collapses to five distinct addresses, which is harmless. This is a configuration defect in the submitted artifacts, not in Solidity, but the hook and ledger tuples are immutable once the graph is created, so it must be corrected before the five owner transactions.","line":8,"path":"hook-constructor.json","reproduction":"Encode the hook Configuration from hook-constructor.json (team = community = owner = 0x2071...240f), deploy the graph, play to Finalized or EmergencyClosed, warp past claimsExpireAt and call sweepExpiredFinalClaims(). Expected per source comments and ADAPTATION.md: ETH leaves to a community treasury distinct from the owner. Actual: _pay(payable(communityTreasury), expiredEth) credits 0x2071...240f, the same wallet that receives withdrawTeamFees and controls migrateToV2.","severity":"medium","snippet":"  \"communityTreasury\": \"0x20714d50f4675c366de30b603728a90ddddb240f\",","title":"Planned hook configuration sets teamTreasury == communityTreasury == owner, so 'expired claims go to community, never owner' is false for the live graph"},{"citation":"resolved","description":"_walletBefore and eligibleSupply subtract balanceBefore(manager) from totalSupplyBefore. The PoolManager is a singleton holding the tokens of every v4 pool, not only the official hook pool. Tokens are freely transferable, so any user can create a hookless v4 pool for a crew token and add liquidity; those tokens then vanish from that user's cutoff balance and from the crew's eligible supply, so the user's share of loser conversions and treasure ETH is silently redistributed to other holders. Non-v4 contracts (v2/v3 pools, lending markets) are counted normally and their rewards are stranded in the contract instead. Disclose, or document that only wallet balances count.","line":105,"path":"src/imd/modules/MugiIMDLedger.sol","reproduction":"After launch, user U holds 1,000 crew-0 tokens. U initializes a v4 pool (crew0, WETH, no hook) and adds all 1,000 as liquidity before the round cutoff. At recordElimination for a round where crew 1 loses, _preview(U) reads balanceBefore(U, cutoff) == 0 for crew 0 and credits U nothing, while round.eligibleScaled[0] also excludes those 1,000 units; the ETH U would have earned is paid to the remaining crew-0 holders. Expected: a free-transfer token that U still economically owns earns its pro-rata share; actual: zero.","severity":"low","snippet":"        _exclude(c.manager);","title":"Excluding the PoolManager singleton strips cutoff eligibility from any holder who LPs a crew token in a third-party Uniswap v4 pool"},{"citation":"resolved","description":"testFactoryCreationBatchHasConservativeGasHeadroom logs 'Four factory creation execution gas: 26942'. The four runtimes total 60,375 bytes (21,064 + 7,180 + 18,963 + 13,168), so EIP-170 code deposit alone costs 12,075,000 gas on a real chain, plus 4 x 32,000 CREATE2 base, initcode word costs for 85,703 initcode bytes, keccak of the initcode and ~1.37M calldata gas. A realistic estimate for the single launch transaction is about 13.5-14M gas, which the test cannot see. The docs cite this test as 'a conservative gas bound for creating the four manifest factories together'. The adapter/manifest step should simulate the real ProjectFactory call (as the deployer does) against the policy gasCeilingWei instead of relying on this assertion; test/scratch reproduction below.","line":51,"path":"test/imd/MugiV1IMDDeploymentFactory.t.sol","reproduction":"Run `forge test --match-contract MugiV1IMDDeploymentFactoryTest -vv`: output shows 'Four factory creation execution gas: 26942', below the 12,075,000 gas deposit floor for 60,375 runtime bytes, so the metered value excludes creation costs. A scratch test doing the same four `new` calls reports 6,400 gas. Expected: a measurement >= 12.1M gas that can be compared with the policy ceiling; actual: a number that cannot represent the on-chain cost.","severity":"low","snippet":"        assertLt(execution + calldataUpperBound + 100_000, 16_777_216);","title":"Gas-headroom test measures 26,942 gas for four factory creations because forge does not meter CREATE code deposit; the asserted headroom is not evidence for the launch gas ceiling"},{"citation":"resolved","description":"beforeSwap calls _requireLive, so from block.timestamp >= nextCutoff until settleRound's last batch resets nextCutoff, and in every non-Live phase (Setup, AwaitingRandomness, OutcomeReady, Settling, Finalized, Emergency*), any swap routed through the PoolManager into an official pool reverts with InvalidState, for live and dead crews alike. Dead crews' pools additionally have zero liquidity after _beginSettlement. This is not an ERC20 freeze (transfer/transferFrom/burn never consult the hook, and third-party pools keep working) but it is a daily trading halt of the only seeded venue whose length depends on when requestElimination/settleRound are called. Claims, buybacks, approvePlan and collectTeamFees share the same gate. Disclose this explicitly in the admission text as requested.","line":590,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Live season, nextCutoff = T. At block.timestamp == T, call MugiIMDSwapRouter.buy{value: 1 ether}(crew, 0, T + 1 hours) for an alive crew: PoolManager.swap -> hook.beforeSwap -> _requireLive reverts InvalidState (wrapped by the PoolManager). Simultaneously MugiCrewToken.transfer(to, amount) by the same holder succeeds. Swaps resume only after settleRound's final batch sets nextCutoff = block.timestamp + 1 days.","severity":"info","snippet":"        if (crew >= 10 || phase != Phase.Live || block.timestamp >= nextCutoff || (aliveMask & (uint16(1) << crew)) == 0)","title":"Official-pool gate: every swap in all ten hook pools reverts from each round cutoff until settlement completes (VRF latency up to 7 days plus settlement), while wallet transfers continue"},{"citation":"resolved","description":"Read in full: all four manifest factories (MugiIMDCrewFactory, MugiV1IMDDeploymentFactory, MugiIMDAccountingFactory, MugiIMDEngineFactory), MugiIMDDeploymentAddresses, MugiIMDCrewToken/MugiCrewToken, MugiReserveMath, MugiIMDGameHook, MugiIMDLedger, MugiIMDV4Engine, MugiIMDV4Fees, MugiIMDBuybacks, MugiIMDPriceOracle, MugiAirdrop, MugiVRFAdapter, MugiIMDVerifier, MugiIMDSwapRouter, plus launch.json, hook-constructor.json, inventory.json summary, ADAPTATION.md, README.md, docs/IMD_CONSTRUCTOR_DEPLOYMENT.md, docs/validation/compatible/VALIDATION.md and the deployment/game test fixtures. Checks that passed on this tree: forge build with the pinned settings; 141 non-fork tests pass; main factory initcode 45,804 B (+32 B args) < 49,152 and all runtimes < 24,576 (hook 22,663 B); a re-implementation of the protected reachable-opcode scan finds no DELEGATECALL/CALLCODE/SELFDESTRUCT in the runtime or initcode of the four factories or any of the ten descendant types; factory constructors make no calls, create no children and take one static owner; CREATE nonce prediction uses canonical one-byte RLP for nonces 1..127; crew token supply is constructor-only with no mint/pause/freeze/hook callback and holder-only burn; strict `< cutoff` snapshots; SCALE = 4^9*9! makes every 3/(4n) conversion exact including after partial claims; 7-address exclusion set matches all protocol custodians; reserve 10I+100M bounds releases (own <= I+9M, escrow <= 0.75(10I+45M)); migrateToV2 subtracts reservedEth, teamEth and escrowBacking so synced and lazy claims survive the handoff; receiver revert rolls back. Not reachable: MugiIMDProjectFactoryFork and MugiGameHookMainnetFork (no RPC configured, skipped), the IMD floor/OwnerChecks.sol referenced by Owners.protected.t.sol (not in the tree; all four factories expose owner() == 0x2071...240f, which is neither the factory nor tx.origin), the real policy gas ceiling, and the actual V2 receiver code. Manifest: schema-valid, four unique names <= 32 chars, one static address per constructor, notes < 4,000 chars; the owner address is a static literal as the brief requires.","line":1,"path":"README.md","reproduction":"Not a defect. Commands: `forge build --sizes`; `forge test --no-match-contract Fork`; opcode scan over out/*.json deployedBytecode.","severity":"info","snippet":"# Mugi V1 IMD compatibility candidate","title":"Scope, admission checks performed, and what could not be reached"}],"hash":"573ea9d5650bafcdc892589b64157aecbe9239f7efb89fa37b3d9bed699654f2","nodeId":"8c24a59f-1039-48e8-aca8-761dadcd47ec","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds seven entries. No source file was changed; the scratch gas test was removed.\n\n**Verdict.** No critical or high defect reproduced in the game logic. The core compatibility claims hold on this tree: constructor-only supply, no mint/pause/freeze/hook callbacks, holder-only burn, strict before-cutoff snapshots, exact 3/(4n) conversions under SCALE = 4^9·9!, a complete seven-address custodian exclusion, a reserve bound that covers worst-case releases, and a V2 handoff that subtracts reserved ETH, team ETH and escrow before sending anything. Build passes with the pinned settings, 141 non-fork tests pass, all four factory initcodes fit EIP-3860 (largest 45,804 B plus args), all runtimes fit EIP-170 (hook 22,663 B), and a re-run of the protected reachable-opcode scan finds no forbidden opcode in any factory or descendant.\n\n**Findings written:**\n- **Medium, hook `migrateToV2`:** with the planned zero V2 pin, the owner can send all finale ETH and survivor inventory to any contract they deploy, including one that forwards to themselves.\n- **Medium, hook `finalize`:** survivor-crew holders receive no final reward round, and the removed LP ETH has no exit except the owner-only migration, so it is stranded if the owner never acts.\n- **Medium, hook-constructor.json:** team, community and owner are the same wallet, so expired player claims and emergency remainders go to the owner, contradicting the source's \"never owner\" guarantee.\n- **Low, ledger exclusion:** excluding the PoolManager singleton strips eligibility from anyone who LPs a crew token in a third-party v4 pool.\n- **Low, gas-headroom test:** it meters 26,942 gas for four creations whose code deposit alone is about 12.1M gas, so it is not evidence against the policy ceiling.\n- **Info:** the official-pool trading gate from each cutoff to settlement, disclosed explicitly as the brief asked.\n- **Info:** scope and reachability, including what could not be checked.\n\n**Not reachable:** the two mainnet fork suites (no RPC), the IMD `floor/OwnerChecks.sol` behind the Owners protected test, the policy gas ceiling, and the real V2 receiver code.","treeHash":null,"usage":{"cachedInputTokens":1623751,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":52464,"runtime":"claude","turns":37,"wallClockMs":935328}},{"artifacts":[],"attempt":1,"bundleHash":"6488c4d7d0f89718854ec49c45bc3b228b0e56f76657543d88bd5701a8958c42","device":"6b16b4979d227241","findings":[],"hash":"62017509fad038fc14ec8244d879910b11188b3ac12b4c17cb08f6df30620d1c","nodeId":"a019d455-9843-4b7b-bec6-9d5ba61810df","outcome":"completed","summary":"The manifest is complete and verified. No findings required a change this round, so launch.json stays as accepted.\n\n**Outcome:** launch.json already describes the accepted source exactly, and the tree builds and tests cleanly.\n\n- **Manifest shape** uses only kind, contracts and notes. Kind is evm_contracts. Notes are 3918 characters, under the 4000 limit.\n- **Four contracts** are listed in manifest order: MugiIMDCrewFactory, MugiV1IMDDeploymentFactory, MugiIMDAccountingFactory, MugiIMDEngineFactory. All names are unique and under 32 characters.\n- **Constructor arguments** match each factory's single `constructor(address owner_)`. Each receives the static owner the brief states, 0x20714d50f4675c366de30b603728a90ddddb240f, which is the paying owner, not the factory or IMD.\n- **Main factory constructor** only stores the owner and pins the hash and length of the raw hook creation code. No child creation, dependency call or code check happens in any factory constructor, so the empty-chain rehearsal in the protected test passes.\n- **Notes** disclose the nineteen later descendants, the five owner creation transactions, the fixed reserve and cutoff gate semantics, the V2 handoff limits, and that only the four factories are indexed and deployed by this request. No explorer verification is claimed.\n\n**Checks run:**\n\n| Check | Result |\n|---|---|\n| forge build | success, lint warnings only |\n| forge test with verifier fuzz seed | 150 passed, 0 failed, 2 skipped |\n| git status | clean, no file other than launch.json differs from accepted work |\n\nNo .imd-blocked.json was written. The deliverable is the existing launch.json, ready for attestation and the deployment service.","treeHash":"0fb197c5e8cc94cc3222f6a500c30c75cb3ada51","usage":{"cachedInputTokens":204043,"inputTokens":162,"model":"claude-fable-5-1","outputTokens":2556,"runtime":"claude","turns":6,"wallClockMs":169564}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f9cb4fd544aa3c68","findings":[{"citation":"resolved","description":"Execution trace / first principles. settleRound() -> _addMatchedLiquidity(crew, share) quotes the full-range position from the pool's current sqrtPrice (MugiIMDV4Engine.quoteLiquidityForEth reads manager.getSlot0 at lines 214-234) and adds `share` ETH plus matching reserve tokens at that price with no TWAP, deviation or minimum-price check, unlike the hook's own buybacks which go through MugiIMDPriceOracle.quoteMinimum (SpotDeviation 488 ticks, 3% slippage). The implicit assumption is that the spot price at settlement is fair. Under the protocol's own control flow it is whatever the last swap before nextCutoff left: beforeSwap's _requireLive (line 590) freezes every official pool from nextCutoff until settleRound completes, so no arbitrage can correct a pushed price before the protocol deposits at it. Measured with the project's harness (100 ETH pools, crew 0 eliminated, attacker buys crew 1 with 8 ETH in the last second before the cutoff and sells everything after settlement): round-trip PnL is -0.334 ETH when the buy precedes the cutoff versus -0.361 ETH for the identical round trip done entirely after settlement, i.e. about 0.027 ETH of the ~5.5 ETH matched share is transferred to the pusher, and the position opened for crew 1 is 502.2e18 liquidity units instead of 541.5e18 (less depth bought with the same ETH). Because the 2% game fee plus 0.3% LP fee on each leg (~0.37 ETH on 8 ETH) exceed the transfer, the sequence is not profitable on its own and the pusher also carries elimination risk on crew 1 across the VRF draw; that is why this is low, not medium. It remains a correctness gap in the stated guarantee that settlement reinforces survivors at a fair price, and it is cheap to close (quote against prices.consult and defer via the existing LiquidityDeferred path when spot deviates beyond MAX_SPOT_DEVIATION_TICKS). The probe is in test/scratch/SettlementPriceProbe.t.sol; it reuses the project's MugiGameTestBase so it is a measurement, not an attached proof (none is required at this severity).","line":369,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"State: season Live after launch with ten pools seeded at 100 ETH each (MugiGameTestBase._setup), eliminations = 0, nextCutoff = T. Inputs: at block.timestamp = T-1 the attacker swaps 8 ETH exact-input into crew 1 through the PoolSwapTest/MugiIMDSwapRouter path; at T anyone calls requestElimination(); the VRF word 0 eliminates crew 0; settleRound(10) runs; the attacker then sells all crew-1 tokens. Expected: the matched addition for crew 1 is valued independently of the attacker's last-second price (or deferred when spot deviates from the oracle's 15-minute TWAP), so the attacker's round trip is no better than the same round trip executed after settlement. Actual: positionLiquidity(1) grows by 502231731838777435245 instead of 541488574711609105923 for the same ETH, and the attacker's PnL improves from -361250081262822183 wei (control, buy after settlement) to -334010169362481988 wei (buy before cutoff): 27239911900340195 wei moved from the protocol's share to the attacker.","severity":"low","snippet":"        (uint128 liquidity,, uint256 needed) = engine.quoteLiquidityForEth(crew, ethAmount);","title":"Settlement matched-liquidity is added at the unprotected spot price left by the last pre-cutoff swap; a pre-cutoff price push shifts part of the share to the pusher (measured below round-trip fees)"},{"citation":"resolved","description":"Periphery / execution trace. The comment above this call says 'No treasury call can block LP recovery', but _pay (line 607) reverts with EthTransferFailed when the recipient's call fails, and communityTreasury is an immutable constructor input with no code check and no pull-payment fallback. After EmergencyClosed the sweep pays expiredEth = address(this).balance - teamEth (line 510), i.e. every unallocated share, expired claim and dust, so a reverting treasury locks all of it forever: no other function can move ETH out of the hook in that phase (migrateToV2 requires Finalized, claims are closed once claimsExpireAt passes). In Finalized the expired reservedEth is likewise locked and the token backing burn in the same function never happens, though migrateToV2 can still move the non-reserved remainder. The constants in hook-constructor.json bind communityTreasury to the owner EOA, so the shipped tuple is not affected; the failing input is any contract treasury without a payable receive/fallback (a multisig module that reverts, a contract that selfdestructed to an EOA is fine, a contract with a reverting receive is not), which the encoding step cannot detect because the constructor accepts any nonzero address.","line":511,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Deploy the graph with Configuration.community = address of a contract whose receive() reverts (and the same address in MugiIMDLedger.Configuration.community so configurationHash matches). Seed and launch, then let a round's randomness deadline pass and call recoverStalledRandomness(10) until phase == EmergencyClosed. Warp to claimsExpireAt. Expected (per the inline comment): sweepExpiredFinalClaims() clears liabilities and the recovered ETH reaches the community beneficiary or at least becomes claimable. Actual: sweepExpiredFinalClaims() reverts with EthTransferFailed on every call; ledger.expireFinalClaims is rolled back; address(this).balance - teamEth stays in the hook with no code path that can release it.","severity":"low","snippet":"        _pay(payable(communityTreasury), expiredEth);","title":"Terminal sweep is a push payment to the immutable communityTreasury; a treasury that rejects ETH permanently blocks sweepExpiredFinalClaims and, in EmergencyClosed, strands the whole remaining balance"}],"hash":"7810c15f6628b38f6ea65417bc199ddcd4bcc1611c02dd9b62d73473234185bb","nodeId":"49012288-3cac-491c-af35-46975f801174","outcome":"completed","summary":"Review complete. The findings file is written and verified against the tree; nothing in the repository was modified.\n\n**Outcome.** The control flow of the pinned MUGI V1 IMD source holds up under the Execution Trace, Periphery and First Principles checks. I found no critical or high defect and no path that permanently bricks a season. Two low-severity findings are recorded in `.imd-findings.json`, with a coverage row for every one of the 80 listed entry points plus four invariant rows.\n\n**What I verified in depth**\n- The five-transaction child creation graph: fixed CREATE nonces, the CREATE2 hook commitment, raw creation-code pin and tuple cross-checks in the main factory, and the reciprocal binding validation that seedPool enforces.\n- The Settling state, which has no emergency exit: LP removal on alive pools never hits zero liquidity, the ledger's cutoff ordering is guaranteed by the claim gates, every 75% conversion divides exactly because SCALE is 4^9 times 9 factorial, the buyback fallback never leaves excess, and the per-crew reserve of 10I plus 100M covers all releases.\n- Fee flow through beforeSwap and afterSwap for all four exact-input and exact-output cases, ERC-6909 claim minting and materialization, engine settlement, router callbacks and reentrancy guards.\n- VRF request, late-fulfilment and stall-recovery interleavings, V2 handoff accounting, terminal sweeps, and the airdrop signature lifecycle.\n- The manifest, hook-constructor constants and commitment script against the compiled factories. The full suite passes locally with 142 tests and the mainnet fork test skipped.\n\n**Findings**\n1. **Low.** Settlement adds matched liquidity at the spot price left by the last pre-cutoff swap with no TWAP or deviation bound, unlike buybacks. A probe against the project's local PoolManager harness showed a pre-cutoff 8 ETH push on a 100 ETH pool moves about 0.027 ETH of the ~5.5 ETH share to the pusher, but the 2% game fee still leaves the round trip negative, so it is a guarantee gap rather than a profitable attack.\n2. **Low.** The terminal sweep pushes ETH to the immutable community treasury and reverts on failure, contradicting the inline comment. With the shipped constants the treasury is the owner EOA, so it is not triggered, but a contract treasury that rejects ETH would strand the entire EmergencyClosed balance.\n\n**Not reached.** No live-chain simulation of the factory launch transaction, the Chainlink coordinator, or the IMD oracle signer. The economic sandwich measurement is a scratch probe that reuses the project test base, not a self-contained proof, which is acceptable at low severity.","treeHash":null,"usage":{"cachedInputTokens":3019110,"inputTokens":610,"model":"claude-fable-5-1","outputTokens":69138,"runtime":"claude","turns":37,"wallClockMs":1297158}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"809ae05b6282abad","findings":[],"hash":"78e6ceadcdd6c1e725b8c3a61ba5ba3e0e4eeacaa772f085f796449a6aa30c9d","nodeId":"2e87a7f0-849e-4212-a409-49d33840ea5a","outcome":"completed","summary":"Admission outcome: the assigned math review found no blocking defect. The deliverable is `.imd-findings.json`, with an empty findings list and 84 coverage rows: one for each of the 72 listed entry points and 12 for the math invariants, all `holds`.\n\nSource pin: `038ffc665b00229cd6794b48251e7eba71d84909`. The tree is clean; the only writes are the findings file and the ignored scratch harness.\n\nVerification:\n- `forge test`: 146 passed, 0 failed, 2 skipped fork suites.\n- Scratch checks covered the three math seams the suite did not: the oracle's 128-slot ring wrap with positive and negative ticks, the buyback fallback after an expired partially spent plan, and a 1-wei nine-round conversion chain exercising `SCALE = 4^9 * 9!` exactness.\n\nNo IMD launch record, factory addresses, or transaction receipts exist from this review. The four factories were not deployed, the nineteen descendants were not created, no pools were seeded, and no explorer verification was submitted. The manifest's static owner is `0x20714d50f4675c366de30b603728a90ddddb240f`.\n\nPreserved disclosures, not defects: with the published zero V2 pin the owner selects the finale receiver; team, community and owner share one wallet in `hook-constructor.json`; official-pool cutoff and resolution gates stop swaps and token materialization but never ERC20 transfers. These match the brief and are documented in ADAPTATION.md and hook-constructor.json.\n\nFull source admission, the disclosed 19-descendant bootstrap and the deployment itself remain for IMD and the deployment phase.","treeHash":null,"usage":{"cachedInputTokens":4425728,"inputTokens":356090,"model":"claude-fable-5-1","outputTokens":203402,"runtime":"claude","turns":64,"wallClockMs":1086861}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"764cd99b4c628a47","findings":[{"citation":"resolved","description":"Follow-up to my earlier medium e1d28ad3 (settlement matched liquidity priced at the unprotected pre-cutoff spot). The fix adds MugiIMDPriceOracle.settlementPriceValid(crew, cutoff, tick), which MugiIMDGameHook._addMatchedLiquidity (src/imd/MugiIMDGameHook.sol:459, `if (liquidity == 0 || !prices.settlementPriceValid(crew, nextCutoff, tick))`) consults before depositing a survivor's matched share, deferring the share when spot is more than 488 ticks from 'the TWAP ending at the cutoff'. But _meanBefore(series, end) averages from the newest observation whose timestamp is <= end - MIN_HISTORY (15 min) up to end. Every official-pool swap writes an observation at its own timestamp (beforeSwap -> _observe -> update, observations spaced >= 60 s). So a pump executed at or before cutoff - 15 min becomes the start observation, the cumulative from there to the cutoff is entirely at the pumped tick, the 'TWAP' equals the pumped spot, deviation is 0 and the guard returns true. The matched settlement ETH is then deposited at the pumped price exactly as before the fix; the attacker only has to hold the position through the last 15 minutes before the cutoff instead of pumping in the last second. The reviewer scenario reproduces with identical numbers (crew-9 liquidity 22898085733661968682982 -> 27991789041817648579719, attacker +19057074374016289333 wei). Same root cause, same impact and same victim (protocol-owned LP ETH that funds emergency recovery, the finale residual and the V2 handoff) as e1d28ad3; the author's test only covers a pump in the last ~14.7 minutes. Merged with write_foundry_tests 9493fe6f (its proof fails on this code for the stated reason and is attached). Severity stays medium: the attacker still carries the VRF survival risk and the 2.3% round-trip fee, and additionally risks being sold into during the 15-minute hold, but on a thin pool with no other venue nothing forces that and in the final rounds the matched share is largest. Minimal fix keeping the design: measure the settlement reference over the whole round (from the previous final settleRound batch, or launch, to the cutoff) rather than a 15-minute tail, i.e. give settlementPriceValid its own window start = max(previous settlement time, cutoff - 1 day) and pick the newest observation at or before it; or require the spot to be within the band of both the round-long mean and the 15-minute mean. Disclose that a pump held across the whole window still passes, at the cost of being exposed to arbitrage for that long.","line":121,"path":"src/imd/modules/MugiIMDPriceOracle.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\n// Proof: the settlement price guard (MugiIMDPriceOracle.settlementPriceValid)\n// only averages the newest observation at least MIN_HISTORY (15 min) before the\n// cutoff. A pump made 16 minutes before the cutoff becomes that observation, so\n// the \"TWAP ending at the cutoff\" equals the pumped tick and the guard accepts\n// it. Matched settlement ETH is deposited at the pumped price and the reviewer's\n// 300 ETH round trip is profitable again. Expected after a fix: the share defers\n// (crew-9 liquidity unchanged) and the attacker's round trip loses.\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {MugiIMDLedger} from \"src/imd/modules/MugiIMDLedger.sol\";\nimport {MugiIMDV4Engine} from \"src/imd/modules/MugiIMDV4Engine.sol\";\nimport {MugiIMDGameHook} from \"src/imd/MugiIMDGameHook.sol\";\nimport {MugiIMDCrewFactory} from \"src/imd/MugiIMDCrewFactory.sol\";\nimport {MugiCrewToken} from \"src/game/MugiCrewToken.sol\";\nimport {MugiAirdrop} from \"src/game/MugiAirdrop.sol\";\nimport {MugiIMDBuybacks} from \"src/imd/modules/MugiIMDBuybacks.sol\";\nimport {MugiIMDPriceOracle} from \"src/imd/modules/MugiIMDPriceOracle.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {PoolSwapTest} from \"v4-core/src/test/PoolSwapTest.sol\";\n\ncontract ProofRandomness {\n    mapping(uint256 => address) public receivers;\n    mapping(uint256 => uint64) public fulfilledAt;\n    uint256 public requests;\n\n    function requestRandomness() external returns (uint256 request) {\n        request = ++requests;\n        receivers[request] = msg.sender;\n    }\n\n    function fulfill(uint256 request, uint256 word) external {\n        fulfilledAt[request] = uint64(block.timestamp);\n        MugiIMDGameHook(payable(receivers[request])).receiveRandomness(request, word);\n    }\n}\n\ncontract SettlementGuardWindowProof is Test {\n    uint256 internal constant SUPPLY = 1_000_000 ether;\n    address internal constant MALLORY = address(0xBADBAD);\n    MugiIMDGameHook internal game;\n    ProofRandomness internal randomness;\n    PoolSwapTest internal router;\n    address[10] internal crew;\n\n    receive() external payable {}\n\n    function setUp() public {\n        vm.warp(1_800_000_000);\n        IPoolManager manager = new PoolManager(address(this));\n        address hookAddress = address(uint160(0x1234000000) | uint160(0x2aec));\n        MugiIMDCrewFactory crews = new MugiIMDCrewFactory(address(this));\n        address[10] memory assets = crews.deployCrewSet(hookAddress, SUPPLY);\n        MugiAirdrop drop = new MugiAirdrop(hookAddress, vm.addr(0xA11CE123), SUPPLY, assets);\n        MugiIMDV4Engine engine = new MugiIMDV4Engine(hookAddress, manager);\n        MugiIMDLedger.Configuration memory lc = abi.decode(\n            abi.encode(hookAddress, assets, address(drop), address(engine), address(0x7EA0), address(0xC000), address(manager)),\n            (MugiIMDLedger.Configuration)\n        );\n        MugiIMDLedger ledger = new MugiIMDLedger(lc);\n        randomness = new ProofRandomness();\n        MugiIMDGameHook.Configuration memory c = MugiIMDGameHook.Configuration({\n            owner: address(this),\n            manager: address(manager),\n            team: address(0x7EA0),\n            community: address(0xC000),\n            v2MigrationTarget: address(this),\n            initialSupply: SUPPLY,\n            ledger: address(ledger),\n            engine: address(engine),\n            budgets: address(new MugiIMDBuybacks(hookAddress)),\n            prices: address(new MugiIMDPriceOracle(hookAddress)),\n            randomnessProvider: address(randomness),\n            imdVerifier: address(0),\n            airdrop: address(drop),\n            crewFactory: address(crews)\n        });\n        deployCodeTo(\"MugiIMDGameHook.sol:MugiIMDGameHook\", abi.encode(c), hookAddress);\n        game = MugiIMDGameHook(payable(hookAddress));\n        crew = assets;\n        vm.deal(address(this), 10_000 ether);\n        vm.warp(1_800_000_000 + 7 days);\n        for (uint8 i; i < 10; ++i) {\n            game.seedPool{value: 100 ether}(i);\n        }\n        game.launch();\n        router = new PoolSwapTest(manager);\n        vm.deal(MALLORY, 10_000 ether);\n    }\n\n    function _round() private {\n        vm.warp(game.nextCutoff());\n        game.requestElimination();\n        randomness.fulfill(game.pendingRequest(), 0);\n    }\n\n    function testPumpHeldFifteenMinutesBeforeCutoffIsNotRewardedBySettlement() public {\n        for (uint8 round; round < 8; ++round) {\n            _round();\n            game.settleRound(10);\n        }\n        // 16 minutes before the cutoff instead of 1 second before.\n        vm.warp(game.nextCutoff() - 16 minutes);\n        uint256 before = MALLORY.balance;\n        PoolKey memory key = game.poolKey(9);\n        vm.prank(MALLORY);\n        router.swap{value: 300 ether}(\n            key,\n            IPoolManager.SwapParams(true, -int256(300 ether), TickMath.MIN_SQRT_PRICE + 1),\n            PoolSwapTest.TestSettings(false, false),\n            bytes(\"\")\n        );\n        _round();\n        assertEq(game.defeatedCrew(), 8);\n        uint128 pumpedLiquidity = game.positionLiquidity(9);\n        game.settleRound(10);\n        // Matched ETH must not be deposited at a price nobody could arbitrage.\n        assertEq(game.positionLiquidity(9), pumpedLiquidity, \"matched liquidity deposited at pumped price\");\n\n        uint256 balance = MugiCrewToken(crew[9]).balanceOf(MALLORY);\n        vm.startPrank(MALLORY);\n        MugiCrewToken(crew[9]).approve(address(router), type(uint256).max);\n        router.swap(\n            key,\n            IPoolManager.SwapParams(false, -int256(balance), TickMath.MAX_SQRT_PRICE - 1),\n            PoolSwapTest.TestSettings(false, false),\n            bytes(\"\")\n        );\n        vm.stopPrank();\n        assertLt(MALLORY.balance, before, \"pump round trip is profitable\");\n    }\n}","reproduction":"test/scratch/Proof_9493fe6f99b8.t.sol (attached proof, copied from the tester) on a fresh PoolManager: ten pools seeded with 100 ETH each, SUPPLY 1,000,000 tokens, launch. Run eight rounds with VRF word 0 (crews 0..7 eliminated; crews 8 and 9 alive). vm.warp(nextCutoff - 16 minutes); MALLORY swaps exact-input 300 ETH into crew 9 through PoolSwapTest (beforeSwap/afterSwap write the pumped observation). warp to nextCutoff, requestElimination, fulfil word 0 (crew 8 defeated), settleRound(10), then MALLORY sells her whole crew-9 balance. Expected (what the fix claims and what happens with the same pump at cutoff - 1 s): crew-9 share emits LiquidityDeferred, positionLiquidity(9) stays 22898085733661968682982 and the round trip loses. Actual on this tree: positionLiquidity(9) becomes 27991789041817648579719 and MALLORY's ETH balance ends above its starting value (+19057074374016289333 wei). forge test --match-path test/scratch/Proof_9493fe6f99b8.t.sol fails with 'matched liquidity deposited at pumped price: 27991789041817648579719 != 22898085733661968682982'.","severity":"medium","snippet":"        uint64 cutoff = end - MIN_HISTORY;","title":"Settlement price guard only looks 15 minutes back from the cutoff; a pump held 16 minutes before the cutoff is accepted and the matched LP ETH is again extracted (fix for e1d28ad3 is incomplete)"}],"hash":"7e60a3630d747a82e588965412393a97afcaf919918100e5827c3b38b1a01652","nodeId":"f1c4c0a8-5151-45d2-9421-1028a640197f","outcome":"completed","summary":"The review is complete and written to `.imd-findings.json`. No tracked file was changed. My scratch copy of the proof under test/scratch is ignored by git.\n\n**Outcome: one blocking finding remains, at medium.** The settlement-pricing fix for my earlier medium is incomplete. Everything else I raised is settled.\n\n**What I confirmed this round**\n\n- **Settlement price guard (medium, finding 1).** The new oracle view compares spot with a TWAP that starts at the newest observation at least 15 minutes before the cutoff. A swap writes an observation at its own timestamp, so a pump placed 16 minutes before the cutoff becomes the start of the window and the TWAP equals the pumped tick. The tester's proof fails on this tree with the identical pre-fix numbers, so I merged their report into my original finding and attached that proof. The author's own test covers only a pump in the last 14.7 minutes.\n- **abortPrelaunch reserve retirement: fixed.** The abort path now zeroes every crew's unreleased reserve, burns all hook-held tokens and emits ReserveRetired. The airdrop's undistributed 5% stays, as the author disclosed.\n- **launch.json: fixed.** All four constructor arguments are now the static owner address from the brief.\n- **Cutoff schedule, module provenance, deployCrewSet pre-check, push-payment treasury, V2 residual exit and the three info items: settled as documented design or deployment-plan requirements.** The documentation changes are in the tree and match the author's answers. I dropped them from the findings rather than restate them.\n\n**Independent checks**\n\n- A whitespace-normalised, comment-stripped diff of src against the pre-fix commit shows semantic changes only in abortPrelaunch, the guard call in the matched-liquidity path, and the oracle. The rest of the hook diff is formatter output.\n- The full suite passes.\n\n| Suite | Result |\n| --- | --- |\n| forge test (excluding scratch) | 171 passed, 0 failed, 2 fork tests skipped |\n| Tester proof on this tree | fails as described |\n\n- I answered all 72 entry points in the coverage record, including the four verifier functions the economics specialist could not verify. They are plain onlyOwner pin and revoke with single-step Ownable, already disclosed.\n\n**What the author needs to do next.** Widen the settlement reference window beyond a 15-minute tail, for example the whole round from the previous settlement to the cutoff, and extend the existing settlement-pricing test with a pump placed before the window start. The raw hook creation-code pin and the accounting-factory bytecode will change again with that fix.","treeHash":null,"usage":{"cachedInputTokens":898642,"inputTokens":290,"model":"claude-fable-5-1","outputTokens":18847,"runtime":"claude","turns":21,"wallClockMs":748672}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"9b657b3675e34ec5","findings":[{"citation":"resolved","description":"settleRound -> _addMatchedLiquidity quotes the survivor's full-range reinforcement purely from the pool's current slot0 (MugiIMDV4Engine.quoteLiquidityForEth reads manager.getSlot0). Official-pool swaps are frozen by _requireLive from nextCutoff until the final settleRound batch, so the price used is whatever the last pre-cutoff trader left; nothing can arbitrage it before the protocol deposits at it. Unlike the buyback path (_buyAndBurn -> prices.quoteMinimum enforces MAX_SPOT_DEVIATION_TICKS against the 15-minute TWAP and a 3% slippage bound), the settlement path has no reference-price or deviation check. A holder who pumps a crew just before the cutoff, whose crew then survives the draw, sells into the deeper ETH side after reopen and takes part of the matched ETH (half of the eliminated pool's principal). The value comes out of protocol-owned LP, i.e. the ETH that later funds emergency recovery shares, the finale residual and the V2 handoff. Merged from audit_economics (medium, round-9 measurement) and audit_flow (low, round-1 measurement): same root cause, same fix. Severity medium because the attacker must hold across the VRF draw (crew survival risk 1/survivors) and pays 2.3% round-trip fees; in the final rounds the matched share is largest and the odds are best. Minimal fix preserving the design: quote the matched addition against prices.consult (TWAP ending before nextCutoff) and route through the existing LiquidityDeferred path when spot deviates beyond MAX_SPOT_DEVIATION_TICKS, as the buyback path already does.","line":369,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Reproduced in test/scratch/SettlementSpot.t.sol on MugiGameTestBase (PoolManager + PoolSwapTest, SUPPLY=1e6 ether, POOL_ETH=100 ether, ten pools seeded, Live). Run _round(0) eight times so crews 0..7 are eliminated and crews 8 and 9 survive. At block.timestamp = nextCutoff - 1, MALLORY (10,000 ETH) swaps exact-input 300 ETH into crew 9 through PoolSwapTest. Then _requestAndFulfill(0) (crew 8 eliminated), settleRound(10): settlementLiquidityEth = 117464701334635416041 wei is matched into crew 9 at the pumped price (positionLiquidity(9) 22898085733661968682982 -> 27991789041817648579719). MALLORY then sells her whole crew-9 balance. MALLORY ETH balance change: +19057074374016289333 wei (+19.06 ETH), ignoring her claimable treasure reward. Control (same base, _round(0) nine times, then the identical 300 ETH buy immediately followed by the sell, no settlement in between): -13215452388079516209 wei (-13.2 ETH of game + LP fees). Expected: a settlement deposit valued independently of the last pre-cutoff trade (or deferred when spot deviates from the TWAP), so the round trip is no better than the control. Actual: 32.3 ETH swing in the trader's favour, paid from the protocol's matched LP ETH.","severity":"medium","snippet":"        (uint128 liquidity,, uint256 needed) = engine.quoteLiquidityForEth(crew, ethAmount);","title":"Settlement matched liquidity is priced at the unprotected pre-cutoff spot price; a last-second pump extracts protocol LP ETH after reopen"},{"citation":"resolved","description":"The brief and ADAPTATION.md state that unused reserve is burned when its crew or the season closes. _retireReserve is reachable only from _beginSettlement, finalize and recoverStalledRandomness, none of which accept phase == Aborted, and every later hook entry point reverts InvalidState in Aborted. abortPrelaunch removes seeded LP and refunds ETH but leaves unreleasedReserve[i] (10I + 100*int128.max units per crew), the LP tokens returned by engine.removeLiquidity and the airdrop's 5% drop (retireRemaining requires launchedAt != 0, retireAirdrop requires launchedAt != 0) held by contracts with no code path to burn them. No holder funds are at risk; the disclosed reserve-retirement guarantee is not met for an aborted season and every crew token keeps a permanent misleading totalSupply.","line":251,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Reproduced in test/scratch/SettlementSpot.t.sol testAbortPrelaunchLeavesReserve: deploy a fresh graph with MugiGameTestBase._deployGameAt (test contract is owner), seedPool{value: 1 ether}(0), abortPrelaunch(). Observed: phase() == Aborted; unreleasedReserve(1) == MugiCrewToken(tokens(1)).reserveCap(); tokens(1).totalSupply() == reserveCap(); retireAirdrop() reverts InvalidState. Expected: unreleasedReserve(i) == 0 and token.totalSupply() reduced for every crew once the season is closed.","severity":"low","snippet":"        phase = Phase.Aborted;","title":"abortPrelaunch closes the season without retiring any crew reserve or the airdrop allocation; totalSupply stays at the full reserve forever"},{"citation":"resolved","description":"The two terminal branches of sweepExpiredFinalClaims are asymmetric. In EmergencyClosed the sweep pays the whole remaining balance minus teamEth to communityTreasury, so nothing can be stranded. In Finalized the sweep pays only ledger.reservedEth(); the survivor pool's removed LP principal, the survivor's undistributed treasure and ownBurnBudget, deferred-liquidity ETH, unspent buyback budgets and dust stay in the hook with the onlyOwner migrateToV2 as the only exit. If Configuration.v2MigrationTarget is pinned to an address that never receives code, migrateToV2 reverts InvalidState (target.code.length == 0) for the pin and InvalidState (pin mismatch) for any other target; the same happens if the owner key is lost. This is the largest ETH position in the game at season end. The requester records it as an open design decision (ADAPTATION.md line 91) and the shipped constants use a zero pin, so severity is low. Note that hook-constructor.json binds communityTreasury and teamTreasury to the owner wallet, so in the shipped tuple the emergency sweep and expired claims also go to the owner; that is disclosed there.","line":510,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Deploy the graph with Configuration.v2MigrationTarget = 0x000000000000000000000000000000000000dEaD (no code). Play nine rounds, finalize(), warp to claimsExpireAt, call sweepExpiredFinalClaims(): only ledger.reservedEth() leaves; address(hook).balance - teamEth > 0 (the survivor's LP principal). migrateToV2(0xdEaD) reverts InvalidState at `target.code.length == 0`; migrateToV2(anyOther) reverts InvalidState at `target != v2MigrationTarget`; no other function moves ETH. Expected: a terminal resolution like the EmergencyClosed branch. Actual: residual locked permanently. The zero-pin, owner-never-acts variant is asserted by testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver in test/imd/lifecycle/MugiCompatibilityHandoff.t.sol.","severity":"low","snippet":"        if (phase == Phase.EmergencyClosed) expiredEth = address(this).balance - teamEth;","title":"Finalized-phase residual ETH and survivor inventory have no permissionless or time-bounded exit; a nonzero pin to a code-less address or a lost owner key locks them forever"},{"citation":"resolved","description":"The comment above says 'No treasury call can block LP recovery', but _pay (line 607) reverts EthTransferFailed when the recipient call fails, and communityTreasury is an immutable constructor input with no code check and no pull-payment fallback. In EmergencyClosed the sweep pays address(this).balance - teamEth, so a reverting treasury locks every unallocated share, expired claim and dust forever: no other function can move ETH in that phase (migrateToV2 requires Finalized, claims are closed after claimsExpireAt). In Finalized the expired reservedEth is likewise locked and the escrow burn in the same call never happens. The shipped constants bind communityTreasury to the owner EOA, so the current tuple is unaffected; any contract treasury with a reverting receive (a safe module that rejects plain ETH) triggers it, and the encoding step cannot detect that because the constructor accepts any nonzero address.","line":511,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Deploy with Configuration.community = a contract whose receive() reverts (same address in MugiIMDLedger.Configuration.community so configurationHash matches). Seed, launch, let a round's randomnessDeadline pass, call recoverStalledRandomness(10) until phase == EmergencyClosed, warp to claimsExpireAt. sweepExpiredFinalClaims() reverts EthTransferFailed on every call; ledger.expireFinalClaims is rolled back; address(hook).balance - teamEth stays with no path to release it. Expected: the sweep clears liabilities and the ETH reaches the beneficiary or becomes claimable. Minimal fix: credit communityTreasury in a pull balance instead of pushing.","severity":"low","snippet":"        _pay(payable(communityTreasury), expiredEth);","title":"Terminal sweep pushes ETH to the immutable communityTreasury; a treasury that rejects ETH permanently blocks sweepExpiredFinalClaims and strands the whole EmergencyClosed balance"},{"citation":"resolved","description":"ADAPTATION.md ('fixed daily cutoffs'), the requestElimination comment ('Fixed clock cutoff applies even when nobody submits this transaction promptly') and the brief promise fixed daily cutoffs. Only the first cutoff (launch + 1 day) is fixed in advance. Every later cutoff is the block.timestamp of the final settleRound batch plus 24h, so it absorbs the delay before anyone calls requestElimination (up to 7 days), VRF latency (64 confirmations) and settlement latency. Players cannot know future cutoff times ahead, and the trading window, the 22-hour buyback window and the next randomness deadline all drift. Not a fund-loss issue; a broken published guarantee. If this is the intended semantics, the docs and launch notes ('scheduled daily cutoffs') should say the schedule is relative to settlement.","line":341,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Launch at T (nextCutoff == T + 1 day). At T + 1d + 3h call requestElimination(); fulfil at T + 1d + 3h15m; settleRound(10) at T + 1d + 4h. Expected under a fixed daily schedule: nextCutoff == T + 2d. Actual: nextCutoff == T + 2d + 4h (line 341). Repeating with a 4h delay each round puts the ninth cutoff 32h behind the fixed schedule.","severity":"low","snippet":"            nextCutoff = uint64(block.timestamp + 1 days); phase = Phase.Live;","title":"Round cutoffs are not a fixed daily schedule: each nextCutoff is settlement time + 1 day, so request, VRF and settlement latency shifts every later cutoff"},{"citation":"resolved","description":"deployHook pins the raw hook creation code, owner, manager, crew factory, supply, VRF adapter, verifier and airdrop, but for the four custody modules (ledger holds player accounting, engine holds every LP position, budgets and prices gate buybacks) it compares nothing with MugiIMDAccountingFactory.predictModules() or MugiIMDEngineFactory.predictEngine(). The four registry entries plus the pinned hook code therefore do not prove that the hook's custody modules are the audited MugiIMDLedger/MugiIMDV4Engine/MugiIMDBuybacks/MugiIMDPriceOracle children. The hook's first-use _validateConfiguration only checks return values (hook(), configurationHash(), manager()), which a purpose-built substitute can echo. Reachable only by the factory owner, and the tuple is committed publicly in deployModules, so this is a gap in the admission/provenance story rather than an outsider theft path. Fix: have deployModules commit (or the constructor take) the accounting and engine factory addresses and require each module to equal that factory's predicted child.","line":142,"path":"src/imd/MugiV1IMDDeploymentFactory.sol","reproduction":"Fixture test/imd/helpers/MugiIMDDeploymentFixture.sol. Build the hook Configuration with ledger = engine = budgets = prices = address(crewFactory) (any contract with code), mine a salt, deployModules(salt, hash, cfg), crewFactory.deployCrewSet(futureHook, SUPPLY) as OWNER, never call accountingFactory or engineFactory. Expected: deployHook(initCode) reverts InvalidConfiguration. Actual: deployHook succeeds and creates the hook at plannedHook while accountingFactory.predictModules().ledger and engineFactory.predictEngine() have no code.","severity":"low","snippet":"            || crewFactory.hook() != plannedHook || c.ledger.code.length == 0 || c.engine.code.length == 0","title":"deployHook does not bind ledger/engine/budgets/prices to the companion manifest factories' predicted children; it only checks that the addresses have code"},{"citation":"resolved","description":"deployModules commits plannedHook and binds the airdrop and token predictions to c.crewFactory. deployCrewSet is one-shot (hook != 0 reverts AlreadyDeployed) but accepts any nonzero futureHook and any initialSupply in range; only deployHook later checks crewFactory.hook() == plannedHook. If the owner passes a stale or mistyped futureHook (or a different initialSupply), the ten tokens are created with their entire reserve credited to the wrong address, deployCrewSet cannot be repeated, and deployHook reverts InvalidConfiguration forever because the main factory's crewFactory is fixed; the four admitted factories must be re-launched through IMD. No ETH exists yet, so no funds are at risk. Fix: let deployCrewSet take the main factory address and require futureHook == MugiV1IMDDeploymentFactory(mainFactory).plannedHook(), or list the pre-transaction check explicitly in docs/IMD_CONSTRUCTOR_DEPLOYMENT.md.","line":32,"path":"src/imd/MugiIMDCrewFactory.sol","reproduction":"Owner runs deployModules(salt, fullHash, c) committing plannedHook P. Owner calls crewFactory.deployCrewSet(Q, S) with Q != P. Then deployCrewSet(P, S) reverts AlreadyDeployed; deployHook(initCode) reverts InvalidConfiguration at `crewFactory.hook() != plannedHook` for every input; deployModules reverts ModulesUnavailable. Expected: the mistake is rejected at call time or recoverable. Actual: all four factories permanently unusable; ten tokens hold 10*S + 100*int128.max units each at code-less address Q.","severity":"low","snippet":"        if (futureHook == address(0)) revert InvalidConfiguration();","title":"deployCrewSet accepts any futureHook; one wrong owner argument permanently bricks all four one-shot factories"},{"citation":"resolved","description":"The brief's manifest gives constructorArgs [\"0x20714d50f4675c366de30b603728a90ddddb240f\"] for all four factories, and the launch rules say an owner address the brief itself states is written as that static address instead of $owner. launch.json uses \"$owner\" for all four entries and only the notes say it resolves to 0x2071...240f. $owner resolves to the paying wallet or the request's owner field; if the service resolves it to a payer wallet other than 0x2071...240f, all four immutable owner slots (and therefore control of every later descendant, the hook ownership and the prelaunch refund) go to that wallet with no way to change them. Packaging/manifest adjustments are allowed by the brief, so this is a manifest fix, not a source change.","line":7,"path":"launch.json","reproduction":"Compare launch.json contracts[*].constructorArgs[0] (\"$owner\", lines 7, 13, 19, 25) with the brief manifest (\"0x20714d50f4675c366de30b603728a90ddddb240f\" for each). Expected: the static address from the brief. Actual: the $owner placeholder, whose resolution depends on service state outside the manifest.","severity":"low","snippet":"        \"$owner\"","title":"launch.json writes $owner where the brief's manifest states the static owner address"},{"citation":"resolved","description":"migrateToV2 is onlyOwner and, with v2MigrationTarget == address(0) (hook-constructor.json), the only check on the receiver is target.code.length != 0. The amount moved is address(this).balance - teamEth - ledger.reservedEth() after finalize (survivor LP principal, survivor treasure and ownBurnBudget, deferred-liquidity ETH, unspent buyback budgets, dust) plus the survivor token inventory. A contract that forwards ETH to the owner satisfies the gate. The brief explicitly grants this discretion and ADAPTATION.md line 90 records it, so this is the owner-power trust assumption the Pashov adapter asks to document, not a permission bypass. The subsequent deployment plan should either pin a reviewed nonzero receiver in the hook tuple or state that the owner holds this discretion.","line":485,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Hook created with Configuration.v2MigrationTarget == address(0); season finalized. Owner deploys any contract S with payable receiveV1Finale(uint8,address,uint256) that forwards msg.value to the owner and calls migrateToV2(S): succeeds, S receives the whole residual ETH and survivor inventory. Shown by testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver in test/imd/lifecycle/MugiCompatibilityHandoff.t.sol.","severity":"info","snippet":"        if (phase != Phase.Finalized || migrated || target.code.length == 0","title":"Trust assumption: with the shipped zero V2 pin the hook owner alone chooses where all finale ETH and survivor inventory go"},{"citation":"resolved","description":"A single immutable attestor signature is the only gate on register() and claim(). allocation per claimer is min((initialSupply/20)/count, initialSupply/1000), so 50 attestor-signed sybil registrations per crew receive the entire 5% of every crew and each sybil is a non-excluded holder earning cutoff rewards. launchEligible returns true at 100 total registrations, so the attestor (not the owner) can make hook.launch() callable before the 7-day deadline once all pools are seeded. The brief says attestor settings need a reviewed subsequent deployment plan; this records the exact power that plan must cover.","line":63,"path":"src/game/MugiAirdrop.sol","reproduction":"Airdrop with attestor A; owner seeds all ten pools. A signs Registration for 50 fresh accounts per crew; each registers. total == 500 >= 100 so anyone's hook.launch() succeeds before configuredAt + 7 days. After launch allocation[c] = min((S/20)/50, S/1000) = S/1000; the 50 sybils per crew claim 50 * S/1000 = S/20, the full airdrop.","severity":"info","snippet":"        if (ECDSA.recover(digest, signature) != attestor) revert InvalidAirdrop();","title":"Trust assumption: the airdrop attestor key can capture the whole 5% airdrop with sybil registrations and can force an early permissionless launch"},{"citation":"resolved","description":"registerPool(crew, token, lpFee, tickSpacing, sqrtPriceX96) is external onlyHook and would let the hook register a pool with an arbitrary fee tier, spacing and starting price for any crew slot. The hook's only registration path is registerInitialPool (fixed 0.3%/60 with a price derived from the seed amounts) and no hook function references registerPool, so it is unreachable in this deployment. Removing it shrinks the audited surface; no behaviour changes.","line":107,"path":"src/imd/modules/MugiIMDV4Engine.sol","reproduction":"grep registerPool( across src: declared at src/imd/modules/MugiIMDV4Engine.sol:107 and never invoked by src/imd/MugiIMDGameHook.sol. Any non-hook caller: engine.registerPool(0, token, 3000, 60, 1<<96) reverts Unauthorized (test/imd/modules/MugiIMDEngineSecurity.t.sol).","severity":"info","snippet":"    function registerPool(","title":"MugiIMDV4Engine.registerPool is privileged dead code the hook never calls"},{"citation":"resolved","description":"The hook requires a replacement owner to acceptOwnership(); the verifier inherits OpenZeppelin Ownable with immediate transferOwnership and renounceOwnership. A mistyped transfer or a renounce permanently disables pinRequest/revokeRequest. Impact is bounded: with no active pin MugiIMDBuybacks.approve always fails and every round's buyback budget stays on the equal-share fallback; a previously pinned request stays active until its validUntil. No funds move. Operational note for the signer/verifier-owner part of the subsequent deployment plan.","line":14,"path":"src/game/MugiIMDVerifier.sol","reproduction":"Verifier owner calls renounceOwnership(). Afterwards pinRequest(...) reverts OwnableUnauthorizedAccount for everyone; hook.approvePlan(plan, proof) -> MugiIMDBuybacks.approve -> verify returns false (no active pin) -> InvalidPlan for every plan; budgets stay on _fallback allocations for the rest of the season.","severity":"info","snippet":"contract MugiIMDVerifier is Ownable {","title":"MugiIMDVerifier uses single-step Ownable transfer and renounce, unlike the hook's two-step ownership"}],"hash":"7edd376c1aa3db4ebe3d96d62ec7825964b5d1cbfa26678c8186621c9a33bad0","nodeId":"f1c4c0a8-5151-45d2-9421-1028a640197f","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds 12 findings plus a 75-row coverage record (65 holds, 10 finding, 0 unreached). Every snippet was verified against the tree and the JSON parses.\n\n**Outcome: not clean.** One medium defect reproduced against the code, seven lows, four documented trust assumptions. No critical or high finding, and nothing that blocks the factory deployment path itself: all four manifest constructors are nonpayable single-address constructors with no calls, and the largest initcode (the main factory, which embeds the hook creation code) is 45,836 bytes against the 49,152 limit, with the hook runtime at 22,663 bytes.\n\n**Medium, reproduced with a scratch test (settleRound, hook line 369).** Settlement reinforces survivors at whatever spot price the last pre-cutoff swap left, with no TWAP or deviation guard, while the pools are frozen so nobody can arbitrage it first. In the final round a 300 ETH pump of crew 9 one second before the cutoff, followed by a sell after settlement, nets the trader +19.06 ETH, where the identical round trip without settlement in between loses 13.2 ETH. The 32 ETH swing comes from protocol LP ETH. The economics and flow specialists reported the same root cause at different magnitudes and I merged them. Kept medium because the attacker carries elimination risk across the draw.\n\n**Lows kept after reproduction:**\n- abortPrelaunch leaves the full reserve and airdrop unburned forever (reproduced in the same scratch test).\n- Finalized residual has no exit besides the owner's one-shot migrateToV2; a nonzero pin to a code-less address locks it permanently.\n- The terminal sweep pushes ETH to the immutable community treasury via a reverting `_pay`, so a rejecting treasury strands the whole emergency balance. The shipped constants bind that treasury to the owner EOA, so the current tuple is unaffected.\n- Cutoffs drift by settlement latency each round despite the \"fixed daily cutoffs\" claim.\n- deployHook checks only `code.length` for the four custody modules rather than binding them to the companion factories' predicted children.\n- deployCrewSet accepts any futureHook, so one wrong owner argument bricks all four one-shot factories.\n- My own addition: launch.json writes `$owner` for all four factories where the brief's manifest states the static owner address.\n\n**Infos (trust assumptions, not bypasses):** zero V2 pin gives the owner free choice of the finale receiver; the attestor key can sybil the whole 5% airdrop and trigger early launch; `registerPool` is privileged dead code; the verifier uses single-step Ownable.\n\nThe unit suites pass (154 tests, fork and invariant suites excluded for time). No repository file was changed; the scratch test lives in `test/scratch/` only.","treeHash":null,"usage":{"cachedInputTokens":1915175,"inputTokens":482,"model":"claude-fable-5-1","outputTokens":50534,"runtime":"claude","turns":36,"wallClockMs":1083431}},{"artifacts":[],"attempt":1,"bundleHash":"3d635528fbc571ecb111b3c2dcef7215862e4eb7ee7b6349dc686740d3c9a723","device":"6f30d6341cbff249","findings":[],"hash":"8dd84fd9fd0aac050f7c530fac4bbb15b5b1cd010b80f99bf89c0a13fd8388d7","nodeId":"6625b2dc-66cb-426f-850e-ba921210b043","outcome":"completed","summary":"I fixed the medium finding. It needed a Solidity change, so the code has to be reviewed again before anything is deployed. Nothing was deployed, signed or submitted to an explorer, and `launch.json`, the compiler settings and the four factory constructors are unchanged.\n\n**Medium finding (settlement priced at a pumped spot): it reproduced exactly, and it's fixed.**\n- **Reproduction:** with the reviewer's own numbers, the 300 ETH pump one second before the cutoff netted the attacker +19.06 ETH, against −13.2 ETH for the same buy and sell with no settlement in between.\n- **Oracle change:** `MugiIMDPriceOracle.settlementPriceValid` checks the pool price against the 15-minute average price that ends at the round's cutoff. It ends at the cutoff, not at settlement time, because trading in the official pools stops at the cutoff; an average ending later would just match the pumped price. It never reverts.\n- **Hook change:** in `_addMatchedLiquidity`, if the price is more than 488 ticks (about 5%) from that average, the matched ETH is held back through the existing `LiquidityDeferred` path instead of being added to the pool. That ETH stays in the hook.\n- **Result:** the same attack now loses 13.13 ETH, about the same as the control, and crew 9's liquidity doesn't change. Ordinary rounds still add liquidity to every surviving crew.\n- **Remaining limits:** a last-second move under 5% is still accepted, and I didn't measure whether one can be profitable. Someone willing to pay the swap cost can also force a crew's share to be held back.\n\n**Low finding (cancelling before launch kept the reserve): it reproduced, and it's fixed.**\n- `abortPrelaunch` now burns all unused reserve and the LP tokens returned to the hook. I updated the existing abort test, which had asserted the old behaviour.\n- One gap remains, and it's disclosed: the airdrop's undistributed 5% stays in the airdrop contract, because fixing that would mean changing the airdrop contract too.\n\n**Changed pin:** the main factory's raw hook creation-code hash is now `0x1cd53e48…c38c626c` (24,923 B). Any full hook initcode hash or salt mined against the old source is no longer valid. The hook runtime is 23,121 B (limit 24,576) and the main factory initcode is 46,262 B (limit 49,152).\n\n**The other nine findings had no source change.**\n- **Cutoff schedule:** this is true as reported. Only the first cutoff is fixed at launch; each later one comes one day after the previous round's final settlement, so delays push it back. I corrected the docs to say this rather than changing the game timing.\n- **Owner-only finale exit and treasuries that reject ETH:** these follow from the brief's design and the owner wallet in the shipped settings. They're now written down as deployment-plan requirements.\n- **Factory input checks:** a wrong hook address passed to the crew factory, or modules from the wrong factories, can't be caught by the contracts. `docs/IMD_CONSTRUCTOR_DEPLOYMENT.md` now lists the exact checks to run before those transactions.\n- **Info items:** these are accurate trust notes, recorded in ADAPTATION.md.\n\n**Tests:** `forge build` passes, and `forge test` with the verifier's fuzz seed gives 146 passed and 0 failed, with the 2 fork suites skipped because no RPC is set. Pointed at this machine's mainnet endpoint, the 3 fork tests pass too. The new tests are in `test/imd/lifecycle/MugiSettlementPricing.t.sol`, plus an oracle unit test in `test/imd/modules/MugiIMDStateModules.t.sol`.\n\n**Files:**\n- **Records:** ADAPTATION.md has a new \"Revision of 2026-10-22\" section listing each change and the reason for it. README, `hook-constructor.json` and the inventory hashes are updated.\n- **Answers:** `.imd-responses.json` answers all 11 findings.\n- **Inventory caveat:** the hashes are for the files before the pipeline runs `forge fmt`, so the `.sol` entries will be stale after formatting.","treeHash":"69a7670d4cff04c0bfdd211c3127ede3687036e0","usage":{"cachedInputTokens":4687804,"inputTokens":76,"model":"claude-opus-5-5","outputTokens":38829,"runtime":"claude","turns":45,"wallClockMs":936980}},{"artifacts":[],"attempt":1,"bundleHash":"75e21806d542d8b6e5eac88f42f89cf8121a7c1e7cbbe9e613127f8c7ea535e6","device":"bf4c5b8707945096","findings":[],"hash":"999ef21d4e5d4cad7b2cd78fe1fdae810acc1dd749fc5603faf9acd88be1625c","nodeId":"6625b2dc-66cb-426f-850e-ba921210b043","outcome":"completed","summary":"I fixed the settlement-price finding (`cbd2b1fb…`) with a change to one source file, `MugiIMDPriceOracle.sol`. That file needs review before deployment: the brief says source fixes must be reported before anything deploys. Nothing was deployed, so there is no admission outcome, factory addresses or transaction receipts to report yet.\n\n**Reproduction.** The reviewer's proof failed on the starting tree with exactly the reported numbers: crew-9 liquidity went from 22898085733661968682982 to 27991789041817648579719 and the attacker gained 19.06 ETH. The cause is as they described. The guard averaged only from the newest observation at least 15 minutes before the cutoff, and a pump made 16 minutes before is that observation. So the \"average\" was just the pumped price.\n\n**Fix.** The settlement guard now compares the spot price with the average over the whole round ending at the cutoff, about one day. That average comes from hourly checkpoints recorded by the oracle, so it is exact, and swap spam can't push the start of the round out of storage. Buyback price protection still uses the 15-minute average and is unchanged.\n\n**What stays the same.** The hook source and its pinned creation code are byte-identical (`0x1cd53e48…c626c`, 24,923 B), and so are the main, crew and engine factories and `launch.json`. Only the oracle and `MugiIMDAccountingFactory`, which creates it, change. That factory is still well under the size limits. The four-factory launch estimate rises from about 14.67M to about 14.97M gas, still under 16,777,216.\n\n**Tests.**\n- The reviewer's proof now passes.\n- I added one game test: the same 300 ETH attack, with the pump held 16 minutes and 12 hours before the cutoff. Both are deferred and the attacker loses money.\n- I added three oracle unit tests with hand-computed averages and exact ±488-tick edges, including the swap-spam case.\n- All five new tests fail on the old oracle.\n- `forge build` passes, and `forge test` with the verifier's fuzz seed gives 150 passed, with 2 fork suites skipped without an RPC.\n- With the local mainnet RPC, all three fork tests pass. The first run of one fork suite reverted in setUp with no trace while it was still fetching fork state. The same command then passed twice.\n\n**Trade-offs, written up in ADAPTATION.md:**\n- A pump held for essentially the whole round still passes, as with any time-weighted average. The attacker is exposed to arbitrage the entire time.\n- Ordinary price moves of more than about 5% from the day's average will now also defer that crew's matched liquidity, which the old 15-minute check didn't do. The deferred ETH isn't lost: it stays in the hook for the finale or emergency recovery.\n- The guard costs up to about 67k gas per surviving crew in a quiet pool. Swaps cost at most one extra storage write per pool per hour.\n- I added three named constants to the oracle (also listed in the README): a 1-day settlement window, a 1-hour checkpoint interval and 32 checkpoint slots.\n\n**Files and docs.** The answer to the finding is in `.imd-responses.json`. ADAPTATION.md, the README and the gas figures in `docs/IMD_CONSTRUCTOR_DEPLOYMENT.md` are updated. Every hash in `inventory.json` now matches its file, including two the previous round had left stale. The earlier audit findings were already answered in ADAPTATION.md and are unchanged.","treeHash":"c4dd54ae02ad78e3b42de89a8067abd17f05bc8e","usage":{"cachedInputTokens":5308257,"inputTokens":94,"model":"claude-opus-5-5","outputTokens":66829,"runtime":"claude","turns":61,"wallClockMs":1016558}},{"artifacts":[],"attempt":1,"bundleHash":"23efdd6f31c7a6dd5f8abdc104f624c28fe3e71b80c8338dbab8cdbf8d011e68","device":"6d0f746f68a99ddf","findings":[],"hash":"a16d382bc8d3b9bb6905340f898c381f6748ba0190b97334668a7749cf2440f3","nodeId":"6625b2dc-66cb-426f-850e-ba921210b043","outcome":"completed","summary":"The packaging pass is complete and committed as `cf8d2fe`. No Solidity source changed, so the reviewed code, compiler settings, authorities, raw hook creation-code pin and the disclosed four-factory/nineteen-descendant graph are exactly as submitted.\n\n**Admission outcome from this pass:** ready to package. No code change was required under the launch rules or the brief, so I did not write a needs_input block. The four manifest entries in `launch.json` already match the request: four owner-bound factories in order, each with the single static owner argument. I left that file untouched.\n\n**Checks run locally**\n\n| Check | Result |\n| --- | --- |\n| forge build (0.8.26, Cancun, optimizer 200, via IR, bytecode hash none) | passes, lint warnings only |\n| forge test with the verifier fuzz seed | 142 passed, 0 failed, 2 fork suites skipped (no RPC) |\n| Protected opcode scan rehearsed over the four CREATE2-deployed factory runtimes | no reachable DELEGATECALL, CALLCODE or SELFDESTRUCT |\n| Estimated single launch transaction for the four factories | about 14.67M gas against the 16,777,216 cap |\n\n**Audit findings and what I did**\n\n- **Zero V2 pin lets the owner route finale ETH anywhere (medium).** Reproduces. Preserved because the brief specifies exactly this owner choice. Now proven by a disclosure test and listed as an owner trust assumption.\n- **Finale residual is owner-gated with no permissionless fallback (medium).** Reproduces. Preserved because the brief defines the finale handoff as owner-only and one-shot. The same test shows the residual survives the 30-day sweep and only the owner can move it. Adding a fallback would change the pinned hook code, so I flagged it as the one open design decision for the requester before the four-factory launch.\n- **Team, community and owner are the same wallet in the plan constants (medium).** Reproduces in the plan file only. The brief names no community wallet and the launch rules route unnamed treasuries to the owner, so I disclosed it in the plan file and ADAPTATION.md rather than inventing an address.\n- **PoolManager exclusion strips eligibility from third-party v4 LPs (low).** Reproduces by construction. Disclosed as a necessary trade-off of the singleton design.\n- **Gas-headroom test measured 26,942 gas (low).** Reproduces: forge does not meter creation cost for a `new` issued by the test contract. Fixed by metering the CREATE2 batch through a probe contract with an EVM cost floor assertion.\n- **Official-pool swap gate from cutoff to settlement (info).** Disclosed explicitly in ADAPTATION.md as a venue rule, distinct from ERC20 freezes.\n\n**Files changed:** ADAPTATION.md, README.md, docs/IMD_CONSTRUCTOR_DEPLOYMENT.md, hook-constructor.json, inventory.json, and the two test files. Inventory hashes were refreshed with Node, since this machine has no working Python, so the repository's Python artifact checker was not re-run here. That gap is recorded in the README.\n\n**Still open for the requester before the five child transactions:** whether to pin a nonzero, reviewed V2 receiver, whether a distinct community treasury should replace the owner wallet in the hook and ledger tuples, and whether a time-bounded fallback for the finale residual is wanted. Each would need a hook source change before the four-factory launch, because the main factory constructor pins the hook creation code.","treeHash":"f594827cefa26d15af2b6c909c9850448d422595","usage":{"cachedInputTokens":2327420,"inputTokens":578,"model":"claude-fable-5-1","outputTokens":37045,"runtime":"claude","turns":56,"wallClockMs":1397858}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"3f6a9bdd601cb99f","findings":[],"hash":"bcc2c7f0e65702844015ae996a88c3e6382cdfe7e8740abaa72dd50dc52db968","nodeId":"f1c4c0a8-5151-45d2-9421-1028a640197f","outcome":"completed","summary":"My medium finding cbd2b1fb is fixed, and I found nothing new, so `.imd-findings.json` has an empty findings list.\n\n**The finding:** the settlement price guard used to measure its reference price over only the last 15 minutes before the cutoff. A pump bought 16 minutes before the cutoff therefore passed the guard, and the attacker could take the protocol's matched LP ETH. The fix is in `MugiIMDPriceOracle.sol`.\n\n- **The old proof now passes:** I copied my attached proof (`Proof_cbd2b1fb7f6d.t.sol`) unchanged and ran it on the revised code. The crew-9 share is now deferred and the attacker's round trip no longer profits.\n- **The new reference covers the whole round:** `settlementPriceValid` now compares the spot price with an exact average tick over the whole round ending at the cutoff (`_roundMean`). `update()` records a checkpoint at the first hour boundary it crosses, using the tick that actually held across it. I checked these points:\n  - **Exact start point:** if no checkpoint exists in an hour, there was no oracle update in that hour, so projecting the earliest checkpoint back to the window start is exact.\n  - **Spam can't remove checkpoints:** there are 32 slots and a window has at most 26 hour boundaries.\n  - **Old slots are skipped**, and the guard returns \"not valid\" rather than reverting.\n  - **The cutoff is read before it changes:** in `settleRound`, `nextCutoff` is only reset after every deposit has been checked.\n- **Independent check:** I fuzzed the new average against a brute-force model for 3,000 runs, mixing frequent swaps with multi-hour gaps. It matched exactly: spot 488 ticks from the average was accepted and 489 ticks was rejected.\n- **Suite, sizes and manifest:**\n  - The full suite passes: 176 tests, with 2 fork suites skipped because there was no RPC.\n  - All contracts are within the size limits. The accounting factory's creation code is 20,476 B and the hook's is 24,923 B.\n  - `launch.json` is schema-valid: only `kind`, `contracts` and `notes`, with notes at 3,918 characters (limit 4,000) and four contracts, each taking the static owner address.\n\n**What remains is disclosed, not a defect.** A pump held for the whole round still passes, which is what my own suggested fix allowed for. Large legitimate price moves now defer that crew's matched share. The author documents both in ADAPTATION.md.\n\n**Coverage:** the record has 73 rows, all `holds`: the 72 listed entry points plus the settlement-guard invariant. Only the oracle changed this round, so I re-traced the settlement and oracle paths in detail. The other rows rest on my earlier trace of unchanged code and the passing suite, and each row's reason says which.\n\nI removed my scratch tests, and no tracked file was changed.","treeHash":null,"usage":{"cachedInputTokens":985139,"inputTokens":26,"model":"claude-opus-5-5","outputTokens":17315,"runtime":"claude","turns":15,"wallClockMs":457868}},{"artifacts":[],"attempt":1,"bundleHash":"4ebc13d6eb51f927f9109127fe2832d3d88dda804e1ae7d225a2bb069c74f436","device":"0eca5d6d7ad6ddb4","findings":[{"description":"settlementPriceValid averages from the newest observation at least MIN_HISTORY (15 min) before the round cutoff up to the cutoff (_meanBefore(series, cutoff)). A swap writes an observation at its own timestamp (beforeSwap -> _observe), so a pump executed 15 minutes or more before the cutoff becomes the start observation and the TWAP 'ending at the cutoff' equals the pumped tick: deviation 0, guard returns true, and MugiIMDGameHook._addMatchedLiquidity (src/imd/MugiIMDGameHook.sol:459) deposits the survivor's matched settlement ETH at the pumped price. The fix for the earlier medium finding (e1d28ad3) therefore only covers pumps made in roughly the last 14.7 minutes; the attacker only has to hold the position 15 minutes without being arbitraged, which on a thin game pool that charges a game fee on every swap is not guaranteed to happen. ADAPTATION.md discloses only sub-488-tick moves 'in the last seconds' as residual.","line":98,"path":"src/imd/modules/MugiIMDPriceOracle.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.26;\n\n// Proof: the settlement price guard (MugiIMDPriceOracle.settlementPriceValid)\n// only averages the newest observation at least MIN_HISTORY (15 min) before the\n// cutoff. A pump made 16 minutes before the cutoff becomes that observation, so\n// the \"TWAP ending at the cutoff\" equals the pumped tick and the guard accepts\n// it. Matched settlement ETH is deposited at the pumped price and the reviewer's\n// 300 ETH round trip is profitable again. Expected after a fix: the share defers\n// (crew-9 liquidity unchanged) and the attacker's round trip loses.\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {MugiIMDLedger} from \"src/imd/modules/MugiIMDLedger.sol\";\nimport {MugiIMDV4Engine} from \"src/imd/modules/MugiIMDV4Engine.sol\";\nimport {MugiIMDGameHook} from \"src/imd/MugiIMDGameHook.sol\";\nimport {MugiIMDCrewFactory} from \"src/imd/MugiIMDCrewFactory.sol\";\nimport {MugiCrewToken} from \"src/game/MugiCrewToken.sol\";\nimport {MugiAirdrop} from \"src/game/MugiAirdrop.sol\";\nimport {MugiIMDBuybacks} from \"src/imd/modules/MugiIMDBuybacks.sol\";\nimport {MugiIMDPriceOracle} from \"src/imd/modules/MugiIMDPriceOracle.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {TickMath} from \"v4-core/src/libraries/TickMath.sol\";\nimport {PoolSwapTest} from \"v4-core/src/test/PoolSwapTest.sol\";\n\ncontract ProofRandomness {\n    mapping(uint256 => address) public receivers;\n    mapping(uint256 => uint64) public fulfilledAt;\n    uint256 public requests;\n\n    function requestRandomness() external returns (uint256 request) {\n        request = ++requests;\n        receivers[request] = msg.sender;\n    }\n\n    function fulfill(uint256 request, uint256 word) external {\n        fulfilledAt[request] = uint64(block.timestamp);\n        MugiIMDGameHook(payable(receivers[request])).receiveRandomness(request, word);\n    }\n}\n\ncontract SettlementGuardWindowProof is Test {\n    uint256 internal constant SUPPLY = 1_000_000 ether;\n    address internal constant MALLORY = address(0xBADBAD);\n    MugiIMDGameHook internal game;\n    ProofRandomness internal randomness;\n    PoolSwapTest internal router;\n    address[10] internal crew;\n\n    receive() external payable {}\n\n    function setUp() public {\n        vm.warp(1_800_000_000);\n        IPoolManager manager = new PoolManager(address(this));\n        address hookAddress = address(uint160(0x1234000000) | uint160(0x2aec));\n        MugiIMDCrewFactory crews = new MugiIMDCrewFactory(address(this));\n        address[10] memory assets = crews.deployCrewSet(hookAddress, SUPPLY);\n        MugiAirdrop drop = new MugiAirdrop(hookAddress, vm.addr(0xA11CE123), SUPPLY, assets);\n        MugiIMDV4Engine engine = new MugiIMDV4Engine(hookAddress, manager);\n        MugiIMDLedger.Configuration memory lc = abi.decode(\n            abi.encode(hookAddress, assets, address(drop), address(engine), address(0x7EA0), address(0xC000), address(manager)),\n            (MugiIMDLedger.Configuration)\n        );\n        MugiIMDLedger ledger = new MugiIMDLedger(lc);\n        randomness = new ProofRandomness();\n        MugiIMDGameHook.Configuration memory c = MugiIMDGameHook.Configuration({\n            owner: address(this),\n            manager: address(manager),\n            team: address(0x7EA0),\n            community: address(0xC000),\n            v2MigrationTarget: address(this),\n            initialSupply: SUPPLY,\n            ledger: address(ledger),\n            engine: address(engine),\n            budgets: address(new MugiIMDBuybacks(hookAddress)),\n            prices: address(new MugiIMDPriceOracle(hookAddress)),\n            randomnessProvider: address(randomness),\n            imdVerifier: address(0),\n            airdrop: address(drop),\n            crewFactory: address(crews)\n        });\n        deployCodeTo(\"MugiIMDGameHook.sol:MugiIMDGameHook\", abi.encode(c), hookAddress);\n        game = MugiIMDGameHook(payable(hookAddress));\n        crew = assets;\n        vm.deal(address(this), 10_000 ether);\n        vm.warp(1_800_000_000 + 7 days);\n        for (uint8 i; i < 10; ++i) {\n            game.seedPool{value: 100 ether}(i);\n        }\n        game.launch();\n        router = new PoolSwapTest(manager);\n        vm.deal(MALLORY, 10_000 ether);\n    }\n\n    function _round() private {\n        vm.warp(game.nextCutoff());\n        game.requestElimination();\n        randomness.fulfill(game.pendingRequest(), 0);\n    }\n\n    function testPumpHeldFifteenMinutesBeforeCutoffIsNotRewardedBySettlement() public {\n        for (uint8 round; round < 8; ++round) {\n            _round();\n            game.settleRound(10);\n        }\n        // 16 minutes before the cutoff instead of 1 second before.\n        vm.warp(game.nextCutoff() - 16 minutes);\n        uint256 before = MALLORY.balance;\n        PoolKey memory key = game.poolKey(9);\n        vm.prank(MALLORY);\n        router.swap{value: 300 ether}(\n            key,\n            IPoolManager.SwapParams(true, -int256(300 ether), TickMath.MIN_SQRT_PRICE + 1),\n            PoolSwapTest.TestSettings(false, false),\n            bytes(\"\")\n        );\n        _round();\n        assertEq(game.defeatedCrew(), 8);\n        uint128 pumpedLiquidity = game.positionLiquidity(9);\n        game.settleRound(10);\n        // Matched ETH must not be deposited at a price nobody could arbitrage.\n        assertEq(game.positionLiquidity(9), pumpedLiquidity, \"matched liquidity deposited at pumped price\");\n\n        uint256 balance = MugiCrewToken(crew[9]).balanceOf(MALLORY);\n        vm.startPrank(MALLORY);\n        MugiCrewToken(crew[9]).approve(address(router), type(uint256).max);\n        router.swap(\n            key,\n            IPoolManager.SwapParams(false, -int256(balance), TickMath.MAX_SQRT_PRICE - 1),\n            PoolSwapTest.TestSettings(false, false),\n            bytes(\"\")\n        );\n        vm.stopPrank();\n        assertLt(MALLORY.balance, before, \"pump round trip is profitable\");\n    }\n}","reproduction":"Test fixture (10 pools seeded with 100 ETH, 1,000,000-token supply), crews 0..7 eliminated with word 0. Warp to nextCutoff - 16 minutes, MALLORY buys crew 9 with 300 ETH, warp to cutoff, request + fulfil word 0 (crew 8 defeated), settleRound(10), MALLORY sells all crew-9 tokens. Expected (as with the same pump at cutoff - 1 s): crew-9 matched share emits LiquidityDeferred, positionLiquidity(9) stays 22,898,085,733,661,968,682,982 and the round trip loses (-13,128,401,461,288,847,986 wei). Actual: positionLiquidity(9) grows to 27,991,789,041,817,648,579,719 and MALLORY ends +19,057,074,374,016,289,333 wei (identical to the pre-fix exploit). With a 1000 ETH pump at cutoff - 16 min the profit is +30.31 ETH; cutoff - 30 min gives the same +19.06 ETH. A remedy would measure the TWAP over a window the attacker cannot cheaply hold (e.g. the whole round since the previous settlement, or a much longer MIN_HISTORY for settlement), or price the matched deposit at that long TWAP instead of spot.","severity":"medium","title":"Settlement price guard is bypassed by a pump held 15 minutes before the cutoff; the reviewer's 300 ETH round trip is again +19.06 ETH"}],"hash":"c36fd6e3b2c3b4487e6cebb5ef0fb0682045d82d96f924aa708f3b2a1f18d099","nodeId":"1c377897-7d57-453d-ac44-4e9a893c96c6","outcome":"completed","summary":"The source fix from the last round is incomplete: a price pump made 15 minutes or more before a round's cutoff still gets past the new settlement price guard. The attack the earlier finding described makes the same +19.06 ETH it did before the fix. I reported it as a medium finding in `.imd-findings.json`, with a self-contained failing proof, and did not write a test asserting the broken behaviour.\n\n`forge test` with the verifier's seed: 171 passed, 0 failed, 2 skipped (both mainnet fork tests). My tests from the last round still pass unchanged against the revised source. Nothing outside `test/` was touched.\n\n**The finding.** The guard averages the pool price from the newest observation at least 15 minutes before the cutoff. A swap records an observation at its own time, so a pump made 16 minutes before the cutoff becomes the start of that average. The average then equals the pumped price, the guard accepts it, and the settlement ETH is added to the pool at that price. This assumes nobody trades against the pump during those 15 minutes.\n- **Same 300 ETH pump, 1 second before the cutoff:** the ETH is held back as intended and the attacker loses 13.13 ETH.\n- **16 or 30 minutes before:** the ETH is added and the attacker gains 19.06 ETH.\n- **1,000 ETH pump, 16 minutes before:** the attacker gains 30.31 ETH.\n\nSo the fix only covers pumps in roughly the last 14.7 minutes. `ADAPTATION.md` lists only small moves \"in the last seconds\" as the remaining risk. The likely remedy is to average over the whole round, or to price the deposit at the long-run average instead of the current price.\n\n**New tests**\n- **`test/imd/lifecycle/MugiSettlementGuardFuzz.t.sol`:** checks the window where the guard does work.\n  - A 100–1,000 ETH pump 1 second to 13 minutes before the cutoff is always held back, and the attacker always loses.\n  - Small pumps (0.01–1 ETH) still let the ETH go in, and the game stays solvent.\n  - Settling one pool per call still adds liquidity to each survivor exactly once.\n- **`test/imd/modules/MugiIMDPriceOracleGuard.t.sol`:** fuzz properties on random price histories.\n  - The guard never reverts on any input.\n  - With the cutoff set to now, it gives exactly the existing price check (`consult()`) plus the ±488-tick limit.\n  - The average stays within the prices seen.\n  - Any update after the cutoff makes it refuse.\n  - Plus exact boundary cases and the access checks on `update`.\n- **`test/imd/invariant/MugiPrelaunchAbortInvariant.t.sol`:** invariant suite for the new `abortPrelaunch` behaviour.\n  - Random seeding, stranger attempts, launch and abort, in any order.\n  - Seeded ETH is accounted for to the wei and refunded on abort.\n  - An aborted season burns all reserve and returned pool tokens, leaving only the airdrop's 5% plus at most 1 wei of rounding.\n  - Supply never grows, a closed season never reopens, strangers can do nothing, and abort is refused after launch.\n  - Two fixed sequences guarantee both the abort path and the launch path run.","treeHash":"7b0c0818e16b7ea5f70816f13c5f09d4281d88f6","usage":{"cachedInputTokens":2243040,"inputTokens":58,"model":"claude-opus-5-5","outputTokens":33671,"runtime":"claude","turns":29,"wallClockMs":676455}},{"artifacts":[],"attempt":1,"bundleHash":"1842892066cb96de8fa8d4774ea34b425f6bd468bc719074dcf2c4d948815f3d","device":"0b9c1289a6def0a1","findings":[],"hash":"c4e3738010ac51a187576511ab94bf07075dd223cbd6bc9d352c618946ab0a74","nodeId":"a019d455-9843-4b7b-bec6-9d5ba61810df","outcome":"completed","summary":"Updated only [launch.json](/root/.identitymd/work/0c8421fb-4f6d-4650-8c90-d9fd7d7a79c5/a019d455-9843-4b7b-bec6-9d5ba61810df/launch.json), preserving the four-factory order, using `$owner`, and expanding the required disclosures.\n\n- Local manifest and ABI checks passed.\n- `forge build` passed.\n- Seeded `forge test`: 143 passed, 0 failed, 2 fork checks skipped.\n- Unchanged source pin: `038ffc665b00229cd6794b48251e7eba71d84909`.\n\nAdmission outcome: local validation passed; remote admission remains unconfirmed. No deployment occurred, so the IMD launch record, four mainnet factory addresses, and receipts are unavailable. No explorer verification was submitted.","treeHash":"17047f4b389b5f33c41cb3a2bb46d2036eb13a6c","usage":{"cachedInputTokens":1840256,"inputTokens":130164,"model":"gpt-6-astra","outputTokens":11314,"runtime":"codex","turns":6,"wallClockMs":275586}},{"artifacts":[],"attempt":1,"bundleHash":"3fdd939ceb1424c8b60d84bf8416a6fbccaddab19bdeae33fc4f94c07ce98ef4","device":"dedc96e38388cb45","findings":[{"description":"deployHook pins the hook's raw creation code, owner, manager, crew factory, supply, VRF adapter, verifier and airdrop, but for the four accounting/execution modules it checks only `code.length != 0`. It never compares c.ledger/c.budgets/c.prices with MugiIMDAccountingFactory.predictModules() or c.engine with MugiIMDEngineFactory.predictEngine(). So the four-entry factory registry plus the pinned hook code do not prove that the hook's custody modules (which hold LP positions and player ETH/token accounting) are the audited MugiIMDLedger/MugiIMDV4Engine/MugiIMDBuybacks/MugiIMDPriceOracle children. The hook's first-use _validateConfiguration catches ordinary mistakes, but only through return values (hook(), configurationHash(), manager()), which a purpose-built substitute contract can echo. This is reachable only by the factory owner, and the full tuple is committed publicly in deployModules, so the impact is a gap in the admission and verification story, not a theft path open to outsiders. Docs (IMD_CONSTRUCTOR_DEPLOYMENT.md, step 5) describe the check as verifying 'the existence of the accounting/execution modules', which matches the code, but reviewers should not read it as provenance. Fix suggestion: have the main factory constructor take, or have deployModules commit, the accounting and engine factory addresses, then require that each module equals that factory's predicted child and that the child has code.","line":142,"path":"src/imd/MugiV1IMDDeploymentFactory.sol","reproduction":"Fixture from test/imd/helpers/MugiIMDDeploymentFixture.sol. Build the hook Configuration with ledger = engine = budgets = prices = address(crewFactory), which is any contract that has code. Mine a salt, call deployModules, then crewFactory.deployCrewSet(futureHook, SUPPLY) as OWNER, and never call the accounting or engine factory. Expected: deployHook reverts InvalidConfiguration because the modules are not the factory-created children. Actual: deployHook succeeds and creates the hook at plannedHook. accountingFactory.predictModules().ledger and engineFactory.predictEngine() still have no code.","severity":"low","title":"deployHook does not bind ledger/engine/budgets/prices to the companion manifest factories' children"}],"hash":"d3d45bc7980f55636bd4be537086bbbda7c4f0e55de1efca600bbdccd0b2b7a9","nodeId":"1c377897-7d57-453d-ac44-4e9a893c96c6","outcome":"completed","summary":"I added the tests, and the full suite passes with the verifier's fuzz seed: 156 passed, 0 failed, 2 skipped. The two skipped suites are the existing mainnet-fork tests, which need an RPC. The repository had no invariant tests before this.\n\n**What I added (all under `test/`)**\n- **`test/imd/invariant/MugiGameInvariant.t.sol`** drives the whole value-holding game with a random-sequence handler. It uses a real v4 PoolManager and the production `MugiIMDSwapRouter`. The handler calls buy, sell, wallet transfer, burn, claims, buybacks, team fees, airdrop retirement, rounds and partial settlement, stall recovery, the finale, the V2 handoff and expiry sweeps. After every call sequence these must hold:\n  - the hook's ETH covers player, team, treasure and buyback liabilities;\n  - the hook's tokens cover escrow, unused reserve and team fees;\n  - no crew's total supply ever grows, and every token is held inside the known graph;\n  - closed crews keep no reserve and no eligible supply;\n  - the season only moves forward, and the V2 handoff runs at most once and only after the ordinary finale;\n  - the router never keeps ETH or tokens.\n  \n  I added success counters to check the runs are not empty: sampled runs reach all nine eliminations, the finale and the V2 handoff.\n- **`test/imd/invariant/MugiCrewTokenInvariant.t.sol`** fuzzes one crew token. Balances always sum to total supply, supply falls only by burns from the fixed reserve, burns only touch the caller, and balances recorded before a past cutoff never change.\n- **`test/imd/MugiIMDManifestFactories.t.sol`** has 12 failure-path tests for the four manifest factories:\n  - With the exact manifest owner `0x2071…240f`, each factory creates no children in its constructor, and the pinned hook-code hash and length match.\n  - Every factory rejects a zero owner.\n  - A failed crew-set creation (zero hook, or supply outside the allowed range) rolls back completely.\n  - `deployModules` rejects each invalid input, including a fuzzed salt without the hook permission bits.\n  - `deployHook` rejects missing modules, a crew set bound to another hook, and a changed owner, manager, supply or airdrop.\n  - A mismatched crew supply or engine manager is caught at the first pool seed.\n  - Ownership transfer is two-step, and every economic entry point is closed before launch.\n\n**One low-severity finding, in `.imd-findings.json`.** `deployHook` (`src/imd/MugiV1IMDDeploymentFactory.sol:142`) only checks that the ledger, engine, budget and price modules have code. It does not check that the accounting and engine factories created them. I confirmed this with a scratch test: pointing all four at an unrelated contract and never using those two factories, the hook still deploys. So the four registry entries plus the pinned hook code do not prove the hook's custody modules are the audited ones. A purpose-built substitute could also pass the first-seed checks. Only the owner can do this, and the full configuration is published when the modules are created, so I rated it low. The fix is to require each module to be the matching factory's predicted child. No invariant failed.\n\nThe three new files are staged but not committed: git on this machine has no author identity, and I didn't change the git config. `.imd-findings.json` is in the repository root and not tracked by git.","treeHash":"06aa3696d70c345e8659540e5c0c9e0d610d00aa","usage":{"cachedInputTokens":2895657,"inputTokens":54,"model":"claude-opus-5-5","outputTokens":40378,"runtime":"claude","turns":32,"wallClockMs":1159795}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"c2e167266d13dcf4","findings":[{"citation":"resolved","description":"Access x economics seam. migrateToV2 is onlyOwner and, when the constructor field v2MigrationTarget is address(0) (the value the test fixture and the current deployment plan use), the only check on the receiver is target.code.length != 0. The amount moved is address(this).balance - teamEth - ledger.reservedEth(), which after finalize() contains the survivor pool's removed LP ETH principal, the survivor crew's undistributed treasure[survivor] and ownBurnBudget[survivor] game fees, deferred-liquidity ETH and ledger dust, plus the survivor token inventory. Nothing binds the receiver to a reviewed V2 implementation; a contract that forwards ETH to the owner satisfies the gate. The request explicitly asks for this discretion ('a zero constructor target allows the owner to choose a future receiver') and ADAPTATION.md line 90 records it, so this is reported as the owner-power trust assumption the Pashov adapter asks to document, not as a permission bypass. The deployment plan should pin a nonzero, reviewed V2 receiver in the hook tuple (deployHook accepts any c.v2MigrationTarget; the factory does not validate it) or the IMD admission record should state the owner holds this discretion.","line":485,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"State: hook created through MugiV1IMDDeploymentFactory.deployHook with Configuration.v2MigrationTarget == address(0); season played to finalize(). Owner deploys any contract S implementing receiveV1Finale(uint8,address,uint256) payable that forwards msg.value to the owner. Owner calls hook.migrateToV2(S). Expected under a continuity model: only a reviewed V2 receiver can receive. Actual: the call succeeds, S receives the whole residual ETH and survivor inventory. Demonstrated by the existing test testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver in test/imd/lifecycle/MugiCompatibilityHandoff.t.sol (migrateToV2(address(sink)) succeeds while migrateToV2(address(0xBAD)) reverts only because 0xBAD has no code).","severity":"info","snippet":"        if (phase != Phase.Finalized || migrated || target.code.length == 0\n            || (v2MigrationTarget != address(0) && target != v2MigrationTarget)) revert InvalidState();","title":"Trust assumption: with a zero V2 pin the hook owner alone chooses where all finale ETH and survivor inventory go"},{"citation":"resolved","description":"Asymmetry between the two terminal branches of sweepExpiredFinalClaims. In EmergencyClosed the sweep pays the whole remaining balance minus teamEth to the immutable community treasury, so no ETH can be stranded. In Finalized the sweep pays only ledger.reservedEth(); the survivor LP principal, survivor treasure/own-buyback budgets, deferred liquidity and dust stay in the hook with migrateToV2 (onlyOwner) as the only exit. After Finalized the only callable state changes are claimEth/claimToken(s) until expiry, withdrawTeamFees, sweepExpiredFinalClaims and migrateToV2; none of them can move that residual. Two concrete states make the residual permanently unrecoverable: (a) Configuration.v2MigrationTarget pinned to an address that never receives code (migrateToV2 reverts InvalidState on target.code.length == 0 and the pin forbids any other target); (b) the owner key is lost or the owner never acts. This is the largest ETH position in the game at the end of a season (half of every eliminated pool's principal was matched into survivors' pools round after round). The requester has accepted this as design (ADAPTATION.md line 91, 'open design decision'), so severity is set to low rather than medium; a minimal preserving fix is a permissionless fallback after claimsExpireAt plus a grace period that pays the residual to communityTreasury (or to survivor holders via a ledger finale round) when no migration has occurred, without removing the owner's one-shot handoff.","line":510,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Deploy the graph with Configuration.v2MigrationTarget = 0x000000000000000000000000000000000000dEaD (no code, never will have). Play to finalize(), warp past claimsExpireAt, call sweepExpiredFinalClaims(): only ledger.reservedEth() leaves. Then hook.balance - teamEth is still > 0 (survivor LP ETH). Owner calls migrateToV2(0xdEaD) -> reverts InvalidState (code.length == 0); migrateToV2(anyOther) -> reverts InvalidState (pin mismatch). No other function moves ETH. Expected: a terminal path that eventually resolves the residual as the emergency branch does. Actual: residual locked forever. The zero-pin variant of this state (owner never calls) is exercised by testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver in test/imd/lifecycle/MugiCompatibilityHandoff.t.sol, which asserts the residual remains after the sweep.","severity":"low","snippet":"        if (phase == Phase.EmergencyClosed) expiredEth = address(this).balance - teamEth;","title":"Finalized-phase residual ETH has no time-bounded or permissionless exit; asymmetric with the EmergencyClosed sweep"},{"citation":"resolved","description":"Access x economics seam. A single immutable attestor signature is the only gate on register() and claim(). Allocation per claimer is min((initialSupply/20)/count, initialSupply/1000) per crew, so 50 attestor-signed sybil registrations per crew (500 total) receive the entire 5% allocation of every crew, excluding real registrants, and each sybil account is a non-excluded holder that then earns cutoff rewards and conversions in the ledger. Separately, MugiAirdrop.launchEligible returns true once total registrations reach AUTOMATIC_LAUNCH_REGISTRATIONS (100), which lets anyone call hook.launch() as soon as seededMask == 1023, so the attestor (not the owner) decides whether the season launches before the 7-day deadline. The request says attestor settings need a reviewed subsequent deployment plan and mock values are forbidden; this entry records the exact power that plan must cover. No code change is required if the attestor is an accepted trusted role.","line":63,"path":"src/game/MugiAirdrop.sol","reproduction":"State: airdrop deployed with attestor A; owner has seeded all 10 pools. A signs Registration(account_k, crew c, socialId_k, deadline) for 50 fresh accounts per crew and each account calls register(). Immediately total registrations = 500 >= 100, so any caller's hook.launch() succeeds before configuredAt + 7 days. After launch, allocation[c] = min((S/20)/50, S/1000) = S/1000 for every crew; the 50 sybils per crew claim 50 * S/1000 = S/20, the full airdrop. Expected: airdrop reaches socially verified players; actual: distribution is entirely at the attestor's discretion.","severity":"info","snippet":"        if (ECDSA.recover(digest, signature) != attestor) revert InvalidAirdrop();","title":"Trust assumption: the airdrop attestor key can capture the full 5% airdrop and can force an early permissionless launch"},{"citation":"resolved","description":"Trust gap in the five-transaction creation sequence. MugiV1IMDDeploymentFactory.deployModules commits plannedHook and binds the airdrop and token predictions to c.crewFactory (one-shot, modulesDeployed). MugiIMDCrewFactory.deployCrewSet is also one-shot (hook != 0 reverts) but accepts any nonzero futureHook and any initialSupply in [1000, 1e36]. Only deployHook later checks crewFactory.hook() != plannedHook. If the owner passes a futureHook that differs from plannedHook (or an initialSupply different from the module configuration), the ten tokens are created with their entire reserve credited to the wrong address, deployCrewSet can never be repeated, and deployHook reverts InvalidConfiguration forever because the main factory's crewFactory is fixed; the four manifest factories then have to be re-admitted and re-launched through IMD at the owner's cost. No funds are at risk because no ETH exists yet, which is why this is low. The crew factory could take the main factory address (or the owner can be required to read MugiV1IMDDeploymentFactory.plannedHook() and MugiIMDCrewFactory.hook() in the reviewed plan before transaction 2); either way the deployment checklist in docs/IMD_CONSTRUCTOR_DEPLOYMENT.md should list this check explicitly.","line":32,"path":"src/imd/MugiIMDCrewFactory.sol","reproduction":"Owner runs deployModules(salt, fullHash, c) (commits plannedHook P). Owner then calls crewFactory.deployCrewSet(Q, S) with Q != P (any typo or stale prediction). Then deployCrewSet(P, S) -> reverts AlreadyDeployed; deployHook(initCode) -> reverts InvalidConfiguration at the crewFactory.hook() != plannedHook check for every input; deployModules -> reverts ModulesUnavailable. Expected: the graph is recoverable or the mistake is rejected at call time; actual: all four factories are permanently unusable and the ten tokens hold 10*S + 100*int128.max units each at code-less address Q.","severity":"low","snippet":"        if (futureHook == address(0)) revert InvalidConfiguration();\n        hook = futureHook;","title":"deployCrewSet does not cross-check futureHook against the main factory's committed hook, so one wrong owner argument bricks all four one-shot factories"},{"citation":"resolved","description":"Access-control inventory note. registerPool(crew, token, lpFee, tickSpacing, sqrtPriceX96) is external onlyHook and would let the hook register a pool with an arbitrary fee tier, tick spacing and starting price for any crew slot. The hook's only registration path is registerInitialPool (fixed 0.3%/60 and a price derived from the seed amounts), and no hook function invokes registerPool, so the surface is unreachable in this deployment (the only caller in the tree is test/imd/modules/MugiIMDEngineSecurity.t.sol:127 proving non-hook callers revert). It is dead privileged code: harmless today, but if the hook source ever grows a caller it would bypass the published 0.3%/full-range pool parameters. Removing it or making it private shrinks the audited surface; no behavior changes.","line":107,"path":"src/imd/modules/MugiIMDV4Engine.sol","reproduction":"grep shows registerPool( is referenced only in src/imd/modules/MugiIMDV4Engine.sol:107 (declaration) and the security test; MugiIMDGameHook.sol never calls it. Any non-hook caller: engine.registerPool(0, token, 3000, 60, 1<<96) -> reverts Unauthorized. Expected/actual match; recorded for inventory completeness.","severity":"info","snippet":"    function registerPool(","title":"MugiIMDV4Engine.registerPool is a privileged surface the hook never calls"},{"citation":"resolved","description":"Admin-variant asymmetry. The hook requires a replacement owner to acceptOwnership(); the verifier inherits OpenZeppelin Ownable with immediate transferOwnership(address) and renounceOwnership(). A mistyped transfer or a renounce permanently disables pinRequest/revokeRequest. Impact is bounded: with no pins, MugiIMDBuybacks.approve always fails and every round's buyback budget uses the equal-share fallback, and a previously pinned request stays active until its validUntil and cannot be revoked. No funds move. Recorded as a trust/operational note for the signer and verifier-owner part of the subsequent deployment plan.","line":14,"path":"src/game/MugiIMDVerifier.sol","reproduction":"Verifier owner calls renounceOwnership() (or transferOwnership(wrong)). Afterwards pinRequest(...) -> reverts OwnableUnauthorizedAccount for everyone; hook.approvePlan(plan, proof) -> MugiIMDBuybacks.approve -> verify returns false (no active pin) -> InvalidPlan for every plan, so budgets stay on _fallback equal allocations for the rest of the season. Expected under a two-step model: the mistake is recoverable before acceptance; actual: irreversible.","severity":"info","snippet":"contract MugiIMDVerifier is Ownable {","title":"MugiIMDVerifier uses single-step Ownable transfer and renounce, unlike the hook's two-step ownership"}],"hash":"f2993750d85039bb717ac74377d17e11a7909de6944a598eed061ac09272a98e","nodeId":"4d9babf4-44ee-40b4-ad65-cf0433f051a5","outcome":"completed","summary":"The review is complete. The findings file is written and validated, every one of the 72 listed entry points has a coverage row, all six snippets match the tree line-for-line, and no repository file was changed.\n\n**Outcome for the Access Control, Trust Gap and Asymmetry area: no exploitable permission defect found.** The permission model is tight. Every module (ledger, buybacks, oracle, engine) is `onlyHook` against an immutable address, every hook callback is `onlyManager` with the engine as the sole LP operator, all five creation functions are owner-only and one-shot, and the post-launch owner role is reduced to the two-step ownership transfer and the one-shot V2 handoff. There is no initializer, setter, proxy or delegatecall path anywhere in `src`.\n\n**What I recorded in `.imd-findings.json`** (six entries, none above low):\n\n- **Info, trust assumption.** With a zero V2 pin, `migrateToV2` lets the owner send all finale ETH and survivor inventory to any code-bearing receiver. Requested by the brief and already disclosed in ADAPTATION.md line 90. Recorded so the admission record states the owner holds this discretion or a reviewed nonzero pin is used.\n- **Low, asymmetry.** The Finalized branch of `sweepExpiredFinalClaims` pays out only reserved player ETH, while the EmergencyClosed branch sweeps the whole balance. A pinned target that never gets code, or a lost owner key, strands the survivor LP ETH forever. Disclosed at ADAPTATION.md line 91 as an open design decision, so kept at low.\n- **Info, trust assumption.** The airdrop attestor can capture the entire 5% allocation with 50 sybil registrations per crew and can trigger the permissionless launch before the 7-day deadline with 100 registrations.\n- **Low, deployment trust gap.** `deployCrewSet` accepts any future hook without checking the main factory's committed `plannedHook`. One wrong argument in transaction 2 permanently bricks all four one-shot factories, requiring a new IMD launch. No funds at risk.\n- **Info.** `MugiIMDV4Engine.registerPool` is a privileged surface the hook never calls.\n- **Info.** The IMD verifier uses single-step `Ownable` transfer and renounce, asymmetric with the hook's two-step model. Impact is bounded to losing plan pinning.\n\n**Coverage notes.** All 72 entry points are marked `holds` or `finding`, plus four invariant rows. I traced guards, state writes and failure paths for every entry point from my area. TWAP math, V4 delta math and the ledger's conversion arithmetic are outside my area and were not reviewed in depth. One economic lead I did not substantiate: `settleRound` adds matched liquidity at spot with no price check, which is permissionless in timing. I left it to the economics specialist since the 2% game fee each way makes a sandwich look unprofitable and I had no concrete delta.\n\n**Checks run.** `forge test` on the deployment factory, compatibility handoff and adversarial suites: 24 tests passed, 0 failed. The existing handoff test already demonstrates the finale-residual states cited in the first two entries, so I wrote no scratch tests.","treeHash":null,"usage":{"cachedInputTokens":1424980,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":53300,"runtime":"claude","turns":34,"wallClockMs":859137}}],"verification":[{"checks":[{"durationMs":145929,"exitCode":0,"name":"build","output":"Compiling 136 files with Solc 0.8.26\nSolc 0.8.26 finished in 145.79s\nCompiler run successful with warnings:\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:783:29:\n    |\n783 |     function previewAccount(address account) external view returns (uint256[10] memory, uint256, uint256[10] memory) {\n    |                             ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:787:29:\n    |\n787 |     function eligibleSupply(uint8 crew) external view returns (uint256) {\n    |                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:795:28:\n    |\n795 |     function escrowBacking(uint8 crew) external view returns (uint256) {\n    |                            ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:803:22:\n    |\n803 |     function poolKey(uint8 crew) external view returns (PoolKey memory) {\n    |                      ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:807:21:\n    |\n807 |     function poolId(uint8 crew) external view returns (PoolId) {\n    |                     ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:811:24:\n    |\n811 |     function poolState(uint8 crew) external view returns (uint160, int24, uint128) {\n    |                        ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:815:32:\n    |\n815 |     function positionLiquidity(uint8 crew) external view returns (uint128) {\n    |                                ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:26:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:61:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:73:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:93:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                                             ^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:827:26:\n    |\n827 |     function roundBudget(uint64 id) external view returns (MugiBuybacks.Budget memory) {\n    |                          ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/imd/MugiIMDCrewToken.t.sol:276:5:\n    |\n276 |     function testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256 initial, uint256 order) public view {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n  --> test/imd/modules/MugiIMDVerifier.t.sol:74:5:\n   |\n74 |     function testSignatureVerificationFitsCallbackStipend() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":8437,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/imd/MugiIMDProjectFactoryFork.t.sol:MugiIMDProjectFactoryForkTest\n[SKIP] testMainnetFactoryRecordsFourEntriesThenConstructorCompleteGraphSeedsTenPools() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 375.71µs (77.42µs CPU time)\n\nRan 1 test for test/imd/lifecycle/MugiGameHookMainnetFork.t.sol:MugiGameHookMainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 356.20µs (0.00ns CPU time)\n\nRan 4 tests for test/imd/modules/MugiIMDLedgerSeason.t.sol:MugiIMDLedgerSeasonTest\n[PASS] testConstructorFixesAllProtocolExclusionsWithoutInitialization() (gas: 2309714)\n[PASS] testConstructorRejectsZeroOrDuplicateTokensAndTokenProtocolRoleCollision() (gas: 26831)\n[PASS] testConstructorWorksBeforeAnyDependencyCodeExists() (gas: 16570)\n[PASS] testDuplicateTreasuryAddressesAreSubtractedOnlyOnce() (gas: 1141863)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 2.29ms (1.53ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDEngineSecurity.t.sol:MugiIMDEngineSecurityTest\n[PASS] testAllEconomicMutatorsRejectNonHookCaller() (gas: 150353)\n[PASS] testCallbackCannotBeInjectedEvenByManagerWithoutPendingUnlock() (gas: 62786)\n[PASS] testCounterfactualConstructorDoesNotCallDependencyAddresses() (gas: 13706)\n[PASS] testOnlyOwnerCanDeployPredictedEngineOnce() (gas: 6455846)\n[PASS] testPartialBuyPaysHookAndRefundsUnusedEth() (gas: 808775)\n[PASS] testRefundCallbackCannotReenterPositionOperations() (gas: 661418)\n[PASS] testRemovePaysHookAndLeavesNoPositionOrNewBalancesInEngine() (gas: 787517)\n[PASS] testSeedRefundsUnusedInputsAndPreservesPriorEngineBalances() (gas: 623887)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 4.32ms (3.37ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDLedgerSecurity.t.sol:MugiIMDLedgerSecurityTest\n[PASS] testAllRemainingLedgerMutatorsRejectOutsideCaller() (gas: 171999)\n[PASS] testCutoffCannotBeFutureRepeatedOrEarlierThanPriorAccountingEvent() (gas: 4908600)\n[PASS] testExcludedProtocolInventoryCannotCaptureEliminationRewards() (gas: 4078480)\n[PASS] testMaterializationAtOrAfterProposedCutoffCannotBeReusedAsAnEarlierVirtualSnapshot() (gas: 5210809)\n[PASS] testPremintedProtocolInventoryIsExcludedWithoutAnyTokenCallback() (gas: 1336129)\n[PASS] testRemovedInitializationReclassificationAndCallbackSelectorsAreUnavailableEvenToHook() (gas: 148153)\n[PASS] testZeroTokenClaimsAndEthSynchronizationDoNotChangeVirtualSnapshotTiming() (gas: 5446112)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 6.00ms (5.27ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 29944111)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127626)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 477993)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 26.46ms (19.81ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271053)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194348)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339207)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977419)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4417637)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11457644)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325174)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4875341)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221311)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 27.02ms (19.04ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6443127)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 30505960)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 39351528)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6389411)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1359329)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20403535)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5938085)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170491)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 69.16ms (60.09ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934426)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1630456)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6827950)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9965369)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294172)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 28337897)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439053)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 43951290)\nLogs:\n  Settlement and request gas: 5839856\n  Settlement and request gas: 5071920\n  Settlement and request gas: 4624286\n  Settlement and request gas: 4027105\n  Settlement and request gas: 3544496\n  Settlement and request gas: 3075560\n  Settlement and request gas: 2614087\n  Settlement and request gas: 2123896\n  Settlement and request gas: 1639076\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 375525)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1376759)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11668852)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5949828)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341595)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5840871)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 8060734)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1570879)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241599)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 83.71ms (81.03ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7664999)\n[PASS] testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver() (gas: 33786656)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 33547383)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 35221011)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 93.35ms (94.05ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiSettlementPricing.t.sol:MugiSettlementPricingTest\n[PASS] testLastSecondPumpDefersMatchedLiquidityAndRoundTripLoses() (gas: 27694909)\n[PASS] testOrdinaryTradingKeepsSettlementReinforcement() (gas: 5620216)\n[PASS] testPumpHeldBeforeFifteenMinuteTailStillDefers() (gas: 29779228)\n[PASS] testUnmovedSurvivorStillReceivesMatchedLiquidity() (gas: 27588338)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 119.62ms (70.20ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 106405037)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 75950776)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 18477719)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 96305602)\nLogs:\n  Four service module creations: 3693823\n  Ten crew token creations: 9091796\n  Engine creation: 2497921\n  Three accounting module creations: 4104378\n  Hook creation: 5909685\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 230320)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14470819)\nLogs:\n  Four factory runtime bytes: 61735\n  Four factory initcode bytes: 87521\n  Four factory CREATE2 execution gas: 12536210\n  Estimated launch transaction gas: 14967850\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 32313867)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 85205139)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 96370363)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 96370297)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 98363949)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 71611502)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 141.65ms (761.75ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 450918)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1043577)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 853500)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 623199)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1015496, ~: 1016359)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5592627)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 904038)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 810014)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 995696)\n[PASS] testSellMinimumOutputFailurePreservesAllowanceAndBalances() (gas: 440672)\n[PASS] testThirdPartyManagerUnlockCannotUseRouter() (gas: 396113)\n[PASS] testUnsolicitedCallbacksRejectedIncludingManagerWithoutPendingTrade() (gas: 71596)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 151.73ms (149.78ms CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDLedgerSnapshots.t.sol:MugiIMDLedgerSnapshotsTest\n[PASS] testCutoffTransfersBurnsAndKnownLoserSalesCannotMovePastRewardsOrConversion() (gas: 7006991)\n[PASS] testEmergencyUnwindUsesOriginalCutoffEvenAfterTransfersDuringLongRecoveryDelay() (gas: 7770266)\n[PASS] testFuzzAfterCutoffTransferCannotSellOrDuplicateConversion(uint96,uint96) (runs: 256, μ: 4060778, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 155.90ms (162.51ms CPU time)\n\nRan 11 tests for test/imd/modules/MugiIMDStateModules.t.sol:MugiIMDStateModulesTest\n[PASS] testAllBudgetMutatorsRequireHook() (gas: 103856)\n[PASS] testApprovalUsesHookHashDomainAndConsumerThroughOrdinaryCall() (gas: 523888)\n[PASS] testBudgetAuthorizesAccountsAndPreservesTradeCadence() (gas: 744739)\n[PASS] testConstructorsAcceptCounterfactualHookAndRejectZero() (gas: 2702387)\n[PASS] testOracleNegativeMeanRoundsDown() (gas: 164473)\n[PASS] testOracleOnlyHookCanUpdateButAnyoneCanRead() (gas: 150383)\n[PASS] testOracleRequiresHistoryAndRejectsSpotDeviation() (gas: 160932)\n[PASS] testSettlementGuardAveragesWholeRoundNotFifteenMinuteTail() (gas: 914826)\n[PASS] testSettlementGuardCheckpointsSurviveObservationSpam() (gas: 10281163)\n[PASS] testSettlementGuardRoundMeanIsExact() (gas: 851239)\n[PASS] testSettlementPriceGuardUsesTwapEndingAtCutoff() (gas: 608711)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 351.60ms (8.55ms CPU time)\n\nRan 12 tests for test/imd/MugiIMDManifestFactories.t.sol:MugiIMDManifestFactoriesTest\n[PASS] testCrewFactoryRejectsZeroHookAndOutOfRangeSupplyAtomically() (gas: 9403411)\n[PASS] testCrewSetBoundToAnotherHookBlocksHookCreation() (gas: 90926132)\n[PASS] testCrewSupplyMismatchIsCaughtAtFirstEconomicUse() (gas: 96407087)\n[PASS] testDeployModulesRejectsEveryInvalidStaticInput() (gas: 71108824)\n[PASS] testEngineBoundToAnotherManagerIsCaughtAtFirstEconomicUse() (gas: 100198461)\n[PASS] testEveryManifestFactoryRejectsZeroOwner() (gas: 4200)\n[PASS] testFuzzDeployModulesRejectsSaltWithoutHookPermissionBits(bytes32) (runs: 512, μ: 99630, ~: 99737)\n[PASS] testHookConfigurationCannotChangeOwnerManagerOrSupply() (gas: 490314096)\n[PASS] testHookOwnershipIsTwoStepAndOwnerOnly() (gas: 97865363)\n[PASS] testHookRequiresAccountingAndEngineModulesToExist() (gas: 97237029)\n[PASS] testManifestOrderFactoriesBindOnlyTheStaticOwnerAndCreateNoChildren() (gas: 155901)\n[PASS] testPrelaunchGatesRejectEveryEconomicEntryPoint() (gas: 98920883)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 351.71ms (833.02ms CPU time)\n\nRan 16 tests for test/imd/MugiIMDCrewToken.t.sol:MugiIMDCrewTokenTest\n[PASS] testBurnHistoryTracksMultipleTimestampsAndCoalescesSameTimestamp() (gas: 441690)\n[PASS] testConstructorAcceptsPredeterminedUndeployedHook() (gas: 16336)\n[PASS] testConstructorCreatesWholeFiniteReserveAndNoEarlierHistory() (gas: 100182)\n[PASS] testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256,uint256) (runs: 256, μ: 54361, ~: 54245)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3597541, ~: 3736076)\n[PASS] testInfiniteAllowanceAndFailedTransferPreserveHistory() (gas: 351050)\n[PASS] testInvalidConstructorConfigurationRejects() (gas: 4632)\n[PASS] testRejectsZeroTransferAndApprovalDestinations() (gas: 53819)\n[PASS] testRemovedMintInitializerAndArbitraryBurnSelectorsAreUnavailable() (gas: 219912)\n[PASS] testReserveHolderHasNoAuthorityOverOtherBalances() (gas: 223787)\n[PASS] testSameTimestampGenesisAndTransfersUseEndOfTimestampBalance() (gas: 313272)\n[PASS] testStaticConstructorPreservesAllCanonicalCrewNamesAndSymbols() (gas: 276675)\n[PASS] testStrictCutoffExcludesEveryExactCutoffTransferAndBurn() (gas: 568341)\n[PASS] testTransferFromCheckpointsBothWalletsAndFiniteAllowance() (gas: 367855)\n[PASS] testTransfersAndBurnDoNotCallRevertingOrBrokenHook() (gas: 539864)\n[PASS] testZeroAndSelfTransfersDoNotChangeHistoricalOwnership() (gas: 248761)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 442.79ms (517.15ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiSettlementGuardFuzz.t.sol:MugiSettlementGuardFuzzTest\n[PASS] testBatchedSettlementReinforcesEachSurvivorOnce() (gas: 5812062)\n[PASS] testFuzzLateLargePumpDefersAndLoses(uint256,uint256) (runs: 64, μ: 27752097, ~: 27752397)\n[PASS] testFuzzSmallPumpStillReinforcesAndStaysSolvent(uint256) (runs: 32, μ: 27520995, ~: 27521088)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.12s (1.64s CPU time)\n\nRan 3 tests for test/imd/invariant/MugiPrelaunchAbortInvariant.t.sol:MugiPrelaunchAbortInvariantTest\n[PASS]\nMugiPrelaunchAbortInvariantTest invariants:\n[PASS] invariant_abortRetiresReserveAndSupplyIsFinite\n[PASS] invariant_closedSeasonNeverReopensAndStrangersHaveNoPower\n[PASS] invariant_seededEthIsConservedAndRefundedOnAbort\n MugiPrelaunchAbortInvariantTest invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭----------------------+-----------------+-------+---------+----------╮\n| Contract             | Selector        | Calls | Reverts | Discards |\n+=====================================================================+\n| MugiPrelaunchHandler | abort           | 418   | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| MugiPrelaunchHandler | seed            | 459   | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| MugiPrelaunchHandler | seedAll         | 464   | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| MugiPrelaunchHandler | strangerActions | 402   | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| MugiPrelaunchHandler | tryLaunch       | 405   | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| MugiPrelaunchHandler | warp            | 412   | 0       | 0        |\n╰----------------------+-----------------+-------+---------+----------╯\n\nLogs:\n  seeds: 1\n  aborts: 1\n  launches: 0\n\n[PASS] testLaunchedSeasonCannotAbort() (gas: 8485781)\n[PASS] testPartialSeedAbortRetiresAndRefunds() (gas: 4325897)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.40s (1.44s CPU time)\n\nRan 1 test for test/imd/invariant/MugiCrewTokenInvariant.t.sol:MugiCrewTokenInvariantTest\n[PASS]\nMugiCrewTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToTotalSupply\n[PASS] invariant_burnOnlyAffectsCaller\n[PASS] invariant_genesisHasNoEarlierHistory\n[PASS] invariant_pastSnapshotsAreImmutable\n[PASS] invariant_supplyOnlyFallsByBurns\n MugiCrewTokenInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------------+--------------+-------+---------+----------╮\n| Contract             | Selector     | Calls | Reverts | Discards |\n+==================================================================+\n| MugiCrewTokenHandler | burn         | 1388  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | overspend    | 1333  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | snapshot     | 1352  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | transfer     | 1362  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | transferFrom | 1384  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | warp         | 1373  | 0       | 0        |\n╰----------------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.98s (1.98s CPU time)\n\nRan 1 test for test/imd/invariant/MugiGameInvariant.t.sol:MugiGameInvariantTest\n[PASS]\nMugiGameInvariantTest invariants:\n[PASS] invariant_closedCrewsRetainNoUnusedReserve\n[PASS] invariant_finiteSupplyNeverGrowsAndIsFullyHeld\n[PASS] invariant_hookEthCoversPlayerAndTeamLiabilities\n[PASS] invariant_hookTokensBackEscrowReserveAndTeamFees\n[PASS] invariant_routerNeverRetainsCustody\n[PASS] invariant_seasonOnlyMovesForward\n MugiGameInvariantTest invariants (runs: 48, calls: 4800, reverts: 0)\n\n╭-----------------+------------------+-------+---------+----------╮\n| Contract        | Selector         | Calls | Reverts | Discards |\n+=================================================================+\n| MugiGameHandler | advance          | 305   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | advanceRounds    | 311   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | burn             | 283   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | buy              | 309   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | claimEth         | 288   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | claimTokens      | 328   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | collectTeamFees  | 307   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | migrate          | 302   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | ownBuyback       | 302   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | retireAirdrop    | 324   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | sell             | 326   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | stall            | 299   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | sweep            | 259   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | transfer         | 266   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | warp             | 289   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | withdrawTeamFees | 302   | 0       | 0        |\n╰-----------------+------------------+-------+---------+----------╯\n\nLogs:\n  buy: 1\n  sell: 0\n  claimEth: 0\n  claimTokens: 1\n  ownBuyback: 1\n  round: 9\n  finalize: 1\n  migrate: 1\n  sweep: 0\n  emergency: 0\n  eliminations: 9\n  phase: 5\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.16s (5.14s CPU time)\n\nRan 13 tests for test/imd/modules/MugiIMDVerifier.t.sol:MugiIMDVerifierTest\n[PASS] testCanonicalIMDProtocolDigestAndSignatureVector() (gas: 14041)\n[PASS] testCrossChainReplayRejected() (gas: 32053)\n[PASS] testExpiryFutureIssueAndStaleAnswerRejected() (gas: 121424)\n[PASS] testMalformedAndFutureBlockMetadataRejected() (gas: 121394)\n[PASS] testOnlyOwnerCanPin() (gas: 34717)\n[PASS] testOwnerCannotRotateSignerOrWeakenEvidencePolicy() (gas: 107728)\n[PASS] testPanelPolicyRejectsMinorityAndImpossibleCounts() (gas: 151298)\n[PASS] testRevocationCannotBeRepinned() (gas: 98612)\n[PASS] testSignatureVerificationFitsCallbackStipend() (gas: 40767)\n[PASS] testTamperedSignatureRejected() (gas: 38804)\n[PASS] testUnpinnedAndWrongQuestionOrAnswerRejected() (gas: 118096)\n[PASS] testValidPinnedPlanAndConsumerReplayGuard() (gas: 161102)\n[PASS] testWrongConsumerAndDomainAreRejected() (gas: 139844)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 8.30s (4.94ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDLedgerTerminal.t.sol:MugiIMDLedgerTerminalTest\n[PASS] testEmergencyAfterPriorEthWithdrawalExpiresOnlyRemainingMixedRights() (gas: 6872513)\n[PASS] testEmergencyExpirationCannotResurrectSyncedOrLazyClaims() (gas: 10818557)\n[PASS] testEmergencyRejectsWrongMaskAndCannotRecordAnotherTerminalOrRound() (gas: 937792)\n[PASS] testEmergencyRewardsIncludeFrozenWalletAndVirtualBalancesAndEarlierEth() (gas: 8641692)\n[PASS] testEmergencyUnallocatedCrewSharesAndRemaindersNeverEnterPlayerReserve() (gas: 4862305)\n[PASS] testExpirationCannotResurrectSyncedOrLazyClaimsInEitherTerminalMode() (gas: 16635639)\n[PASS] testFuzzEagerMaterializationAndLateSyncHaveIdenticalEmergencyRights(uint8,uint96) (runs: 256, μ: 23002156, ~: 21690551)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 8.30s (510.02ms CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDPriceOracleGuard.t.sol:MugiIMDPriceOracleGuardTest\n[PASS] testFuzzGuardAtNowMatchesRoundMeanBand(int24[8],uint32[8],int24) (runs: 512, μ: 597936, ~: 605702)\n[PASS] testFuzzGuardNeverReverts(int24[8],uint32[8],uint8,uint64,int24) (runs: 512, μ: 543235, ~: 548570)\n[PASS] testFuzzPostCutoffUpdateAlwaysRefuses(int24[8],uint32[8],uint32,int24) (runs: 256, μ: 619670, ~: 632281)\n[PASS] testGuardRejectsEdgeInputsWithoutReverting() (gas: 532116)\n[PASS] testUpdateIsHookOnlyAndValidatesInputs() (gas: 100572)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 8.30s (16.94s CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 565920)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7343743)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 31708111)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 223240588, ~: 222802360)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 37064656)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 28105486)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 8.31s (8.34s CPU time)\n\nRan 25 test suites in 8.31s (44.90s CPU time): 175 tests passed, 0 failed, 2 skipped (177 total tests)\n","passed":true},{"durationMs":98,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MugiAirdrop.claim(uint64,bytes)\",\"MugiAirdrop.launch()\",\"MugiAirdrop.register(uint8,bytes32,uint64,bytes)\",\"MugiAirdrop.retireRemaining()\",\"MugiCrewToken.approve(address,uint256)\",\"MugiCrewToken.burn(uint256)\",\"MugiCrewToken.transfer(address,uint256)\",\"MugiCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDAccountingFactory.deployForHook((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address))\",\"MugiIMDBuybacks.account(uint64,uint8,uint256)\",\"MugiIMDBuybacks.approve((uint64,uint64,uint64,uint256[10]),address,bytes)\",\"MugiIMDBuybacks.authorize(uint64,uint8,uint256)\",\"MugiIMDBuybacks.create(uint64,uint256,uint16)\",\"MugiIMDCrewFactory.deployCrewSet(address,uint256)\",\"MugiIMDCrewToken.approve(address,uint256)\",\"MugiIMDCrewToken.burn(uint256)\",\"MugiIMDCrewToken.transfer(address,uint256)\",\"MugiIMDCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDEngineFactory.deployForHook(address,address)\",\"MugiIMDGameHook.abortPrelaunch()\",\"MugiIMDGameHook.acceptOwnership()\",\"MugiIMDGameHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MugiIMDGameHook.approvePlan((uint64,uint64,uint64,uint256[10]),bytes)\",\"MugiIMDGameHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MugiIMDGameHook.cancelOwnershipTransfer()\",\"MugiIMDGameHook.claimEth(address)\",\"MugiIMDGameHook.claimToken(uint8,uint256)\",\"MugiIMDGameHook.claimTokens()\",\"MugiIMDGameHook.collectTeamFees(uint8)\",\"MugiIMDGameHook.executeBuyback(uint64,uint8,uint256)\",\"MugiIMDGameHook.executeOwnBuyback(uint8,uint256)\",\"MugiIMDGameHook.finalize()\",\"MugiIMDGameHook.launch()\",\"MugiIMDGameHook.migrateToV2(address)\",\"MugiIMDGameHook.receive()\",\"MugiIMDGameHook.receiveRandomness(uint256,uint256)\",\"MugiIMDGameHook.recoverStalledRandomness(uint8)\",\"MugiIMDGameHook.requestElimination()\",\"MugiIMDGameHook.retireAirdrop()\",\"MugiIMDGameHook.seedPool(uint8)\",\"MugiIMDGameHook.settleRound(uint8)\",\"MugiIMDGameHook.sweepExpiredFinalClaims()\",\"MugiIMDGameHook.transferOwnership(address)\",\"MugiIMDGameHook.unlockCallback(bytes)\",\"MugiIMDGameHook.withdrawTeamFees()\",\"MugiIMDLedger.claimEth(address)\",\"MugiIMDLedger.claimToken(address,uint8,uint256)\",\"MugiIMDLedger.claimTokens(address)\",\"MugiIMDLedger.emergencyFinalize(uint16,uint256,uint64)\",\"MugiIMDLedger.expireFinalClaims()\",\"MugiIMDLedger.finalizeMigration(uint8,uint64)\",\"MugiIMDLedger.recordElimination(uint8,uint16,uint256,uint64)\",\"MugiIMDPriceOracle.update(uint8,int24)\",\"MugiIMDSwapRouter.buy(uint8,uint256,uint64)\",\"MugiIMDSwapRouter.sell(uint8,uint256,uint256,uint64)\",\"MugiIMDSwapRouter.unlockCallback(bytes)\",\"MugiIMDV4Engine.addLiquidity(uint8,uint128,uint256,uint256)\",\"MugiIMDV4Engine.buy(uint8,uint256,uint256,uint160)\",\"MugiIMDV4Engine.collectFees(uint8)\",\"MugiIMDV4Engine.registerInitialPool(uint8,address,uint256,uint256)\",\"MugiIMDV4Engine.registerPool(uint8,address,uint24,int24,uint160)\",\"MugiIMDV4Engine.removeLiquidity(uint8,uint256,uint256)\",\"MugiIMDV4Engine.unlockCallback(bytes)\",\"MugiIMDVerifier.pinRequest(bytes32,bytes32,bytes32,uint64)\",\"MugiIMDVerifier.renounceOwnership()\",\"MugiIMDVerifier.revokeRequest(bytes32)\",\"MugiIMDVerifier.transferOwnership(address)\",\"MugiV1IMDDeploymentFactory.deployHook(bytes)\",\"MugiV1IMDDeploymentFactory.deployModules(bytes32,bytes32,(address,address,bytes32,uint256,uint32,bool,address,address,uint16,uint16,uint64,address,address,uint256))\",\"MugiVRFAdapter.rawFulfillRandomWords(uint256,uint256[])\",\"MugiVRFAdapter.requestRandomness()\",\"MugiVRFAdapter.retryDelivery(uint256)\"],\"files\":{\".gitignore\":6,\"ADAPTATION.md\":265,\"README.md\":75,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":46,\"docs/IMD_FINDINGS_RESPONSE.md\":61,\"docs/IMD_FOLLOWUP_RESPONSE.md\":104,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":167,\"docs/validation/compatible/VALIDATION.md\":33,\"docs/validation/compatible/artifact-review.json\":966,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2606,\"docs/validation/compatible/full-suite.raw.log\":2,\"docs/validation/compatible/test-results.json\":1634,\"docs/validation/compatible/v2-integration-result.json\":32,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":56,\"docs/validation/followup/VALIDATION.md\":16,\"docs/validation/followup/full-suite.raw.json\":2,\"docs/validation/followup/ledger-targeted-summary.json\":170,\"docs/validation/followup/terminal-claim-baseline.log\":20,\"docs/validation/followup/test-results.json\":788,\"docs/validation/followup/validation-summary.json\":188,\"docs/validation/repaired-final/VALIDATION.md\":17,\"docs/validation/repaired-final/test-results.json\":788,\"docs/validation/repaired-final/validation-summary.json\":161,\"docs/validation/vrf-stall-repair/RECOVERY.md\":84,\"docs/validation/vrf-stall-repair/original-VrfStall.sol\":63,\"docs/validation/vrf-stall-repair/original-proof.log\":60,\"foundry.toml\":18,\"hook-constructor.json\":44,\"inventory.json\":642,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":115,\"src/game/MugiAirdrop.sol\":121,\"src/game/MugiCrewToken.sol\":170,\"src/game/MugiIMDVerifier.sol\":157,\"src/game/MugiReserveMath.sol\":27,\"src/game/MugiVRFAdapter.sol\":146,\"src/imd/MugiIMDAccountingFactory.sol\":49,\"src/imd/MugiIMDCrewFactory.sol\":43,\"src/imd/MugiIMDCrewToken.sol\":13,\"src/imd/MugiIMDEngineFactory.sol\":35,\"src/imd/MugiIMDGameHook.sol\":830,\"src/imd/MugiIMDSwapRouter.sol\":132,\"src/imd/MugiV1IMDDeploymentFactory.sol\":155,\"src/imd/libraries/MugiIMDDeploymentAddresses.sol\":15,\"src/imd/libraries/MugiIMDV4Fees.sol\":64,\"src/imd/modules/MugiIMDBuybacks.sol\":188,\"src/imd/modules/MugiIMDLedger.sol\":350,\"src/imd/modules/MugiIMDPriceOracle.sol\":264,\"src/imd/modules/MugiIMDV4Engine.sol\":408,\"test/imd/MugiIMDCrewToken.t.sol\":308,\"test/imd/MugiIMDManifestFactories.t.sol\":287,\"test/imd/MugiIMDProjectFactoryFork.t.sol\":141,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":266,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/invariant/MugiCrewTokenInvariant.t.sol\":188,\"test/imd/invariant/MugiGameInvariant.t.sol\":447,\"test/imd/invariant/MugiPrelaunchAbortInvariant.t.sol\":233,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":205,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":620,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiSettlementGuardFuzz.t.sol\":125,\"test/imd/lifecycle/MugiSettlementPricing.t.sol\":139,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":279,\"test/imd/lifecycle/MugiSwapRouter.t.sol\":288,\"test/imd/modules/MugiIMDEngineSecurity.t.sol\":216,\"test/imd/modules/MugiIMDLedgerFixture.sol\":115,\"test/imd/modules/MugiIMDLedgerSeason.t.sol\":68,\"test/imd/modules/MugiIMDLedgerSecurity.t.sol\":117,\"test/imd/modules/MugiIMDLedgerSnapshots.t.sol\":144,\"test/imd/modules/MugiIMDLedgerTerminal.t.sol\":258,\"test/imd/modules/MugiIMDPriceOracleGuard.t.sol\":121,\"test/imd/modules/MugiIMDStateModules.t.sol\":251,\"test/imd/modules/MugiIMDVerifier.t.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"2e709afce4669909e00d09e7d2fd589e14a61c7619e4db6036c7435edaf62918","verifiedTreeHash":"bf92727fdab1b6965da67ae000ea6a4c57dc3e79","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":117696,"exitCode":0,"name":"build","output":"Compiling 130 files with Solc 0.8.26\nSolc 0.8.26 finished in 117.57s\nCompiler run successful with warnings:\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:783:29:\n    |\n783 |     function previewAccount(address account) external view returns (uint256[10] memory, uint256, uint256[10] memory) {\n    |                             ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:787:29:\n    |\n787 |     function eligibleSupply(uint8 crew) external view returns (uint256) {\n    |                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:795:28:\n    |\n795 |     function escrowBacking(uint8 crew) external view returns (uint256) {\n    |                            ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:803:22:\n    |\n803 |     function poolKey(uint8 crew) external view returns (PoolKey memory) {\n    |                      ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:807:21:\n    |\n807 |     function poolId(uint8 crew) external view returns (PoolId) {\n    |                     ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:811:24:\n    |\n811 |     function poolState(uint8 crew) external view returns (uint160, int24, uint128) {\n    |                        ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:815:32:\n    |\n815 |     function positionLiquidity(uint8 crew) external view returns (uint128) {\n    |                                ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:26:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:61:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:73:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:93:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                                             ^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:827:26:\n    |\n827 |     function roundBudget(uint64 id) external view returns (MugiBuybacks.Budget memory) {\n    |                          ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/imd/MugiIMDCrewToken.t.sol:276:5:\n    |\n276 |     function testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256 initial, uint256 order) public view {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n  --> test/imd/modules/MugiIMDVerifier.t.sol:74:5:\n   |\n74 |     function testSignatureVerificationFitsCallbackStipend() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":8087,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/imd/MugiIMDProjectFactoryFork.t.sol:MugiIMDProjectFactoryForkTest\n[SKIP] testMainnetFactoryRecordsFourEntriesThenConstructorCompleteGraphSeedsTenPools() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 389.10µs (58.03µs CPU time)\n\nRan 1 test for test/imd/lifecycle/MugiGameHookMainnetFork.t.sol:MugiGameHookMainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 379.00µs (0.00ns CPU time)\n\nRan 4 tests for test/imd/modules/MugiIMDLedgerSeason.t.sol:MugiIMDLedgerSeasonTest\n[PASS] testConstructorFixesAllProtocolExclusionsWithoutInitialization() (gas: 2309714)\n[PASS] testConstructorRejectsZeroOrDuplicateTokensAndTokenProtocolRoleCollision() (gas: 26831)\n[PASS] testConstructorWorksBeforeAnyDependencyCodeExists() (gas: 16570)\n[PASS] testDuplicateTreasuryAddressesAreSubtractedOnlyOnce() (gas: 1141863)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.78ms (2.19ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 29077213)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127626)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 476627)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 47.32ms (31.35ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiSettlementPricing.t.sol:MugiSettlementPricingTest\n[PASS] testLastSecondPumpDefersMatchedLiquidityAndRoundTripLoses() (gas: 26804540)\n[PASS] testOrdinaryTradingKeepsSettlementReinforcement() (gas: 5376310)\n[PASS] testUnmovedSurvivorStillReceivesMatchedLiquidity() (gas: 26696162)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 79.01ms (39.67ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 449552)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1042211)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 852134)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 620467)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1012796, ~: 1013627)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5348711)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 902672)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 807282)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 994330)\n[PASS] testSellMinimumOutputFailurePreservesAllowanceAndBalances() (gas: 439306)\n[PASS] testThirdPartyManagerUnlockCannotUseRouter() (gas: 396113)\n[PASS] testUnsolicitedCallbacksRejectedIncludingManagerWithoutPendingTrade() (gas: 71596)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 79.91ms (76.45ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271053)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194348)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339207)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977419)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4175087)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11213728)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325174)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4875341)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221311)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 80.12ms (66.51ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7421083)\n[PASS] testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver() (gas: 32909507)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 32670234)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 34343862)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 81.49ms (75.81ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDEngineSecurity.t.sol:MugiIMDEngineSecurityTest\n[PASS] testAllEconomicMutatorsRejectNonHookCaller() (gas: 150353)\n[PASS] testCallbackCannotBeInjectedEvenByManagerWithoutPendingUnlock() (gas: 62786)\n[PASS] testCounterfactualConstructorDoesNotCallDependencyAddresses() (gas: 13706)\n[PASS] testOnlyOwnerCanDeployPredictedEngineOnce() (gas: 6455846)\n[PASS] testPartialBuyPaysHookAndRefundsUnusedEth() (gas: 808775)\n[PASS] testRefundCallbackCannotReenterPositionOperations() (gas: 661418)\n[PASS] testRemovePaysHookAndLeavesNoPositionOrNewBalancesInEngine() (gas: 787517)\n[PASS] testSeedRefundsUnusedInputsAndPreservesPriorEngineBalances() (gas: 623887)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 108.68ms (4.12ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 105979468)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 75950776)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 18477719)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 96114655)\nLogs:\n  Four service module creations: 3693823\n  Ten crew token creations: 9091796\n  Engine creation: 2497921\n  Three accounting module creations: 3913431\n  Hook creation: 5909685\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 228028)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14258298)\nLogs:\n  Four factory runtime bytes: 60782\n  Four factory initcode bytes: 86568\n  Four factory CREATE2 execution gas: 12345124\n  Estimated launch transaction gas: 14761516\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 32122920)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 85205139)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 96179416)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 96179350)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 98172980)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 71611502)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 152.23ms (868.95ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDLedgerTerminal.t.sol:MugiIMDLedgerTerminalTest\n[PASS] testEmergencyAfterPriorEthWithdrawalExpiresOnlyRemainingMixedRights() (gas: 6872513)\n[PASS] testEmergencyExpirationCannotResurrectSyncedOrLazyClaims() (gas: 10818557)\n[PASS] testEmergencyRejectsWrongMaskAndCannotRecordAnotherTerminalOrRound() (gas: 937792)\n[PASS] testEmergencyRewardsIncludeFrozenWalletAndVirtualBalancesAndEarlierEth() (gas: 8641692)\n[PASS] testEmergencyUnallocatedCrewSharesAndRemaindersNeverEnterPlayerReserve() (gas: 4862305)\n[PASS] testExpirationCannotResurrectSyncedOrLazyClaimsInEitherTerminalMode() (gas: 16635639)\n[PASS] testFuzzEagerMaterializationAndLateSyncHaveIdenticalEmergencyRights(uint8,uint96) (runs: 256, μ: 23175291, ~: 21691368)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 440.78ms (470.40ms CPU time)\n\nRan 13 tests for test/imd/modules/MugiIMDVerifier.t.sol:MugiIMDVerifierTest\n[PASS] testCanonicalIMDProtocolDigestAndSignatureVector() (gas: 14041)\n[PASS] testCrossChainReplayRejected() (gas: 32053)\n[PASS] testExpiryFutureIssueAndStaleAnswerRejected() (gas: 121424)\n[PASS] testMalformedAndFutureBlockMetadataRejected() (gas: 121394)\n[PASS] testOnlyOwnerCanPin() (gas: 34717)\n[PASS] testOwnerCannotRotateSignerOrWeakenEvidencePolicy() (gas: 107728)\n[PASS] testPanelPolicyRejectsMinorityAndImpossibleCounts() (gas: 151298)\n[PASS] testRevocationCannotBeRepinned() (gas: 98612)\n[PASS] testSignatureVerificationFitsCallbackStipend() (gas: 40767)\n[PASS] testTamperedSignatureRejected() (gas: 38804)\n[PASS] testUnpinnedAndWrongQuestionOrAnswerRejected() (gas: 118096)\n[PASS] testValidPinnedPlanAndConsumerReplayGuard() (gas: 161102)\n[PASS] testWrongConsumerAndDomainAreRejected() (gas: 139844)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 441.25ms (5.36ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDStateModules.t.sol:MugiIMDStateModulesTest\n[PASS] testAllBudgetMutatorsRequireHook() (gas: 103800)\n[PASS] testApprovalUsesHookHashDomainAndConsumerThroughOrdinaryCall() (gas: 523832)\n[PASS] testBudgetAuthorizesAccountsAndPreservesTradeCadence() (gas: 744683)\n[PASS] testConstructorsAcceptCounterfactualHookAndRejectZero() (gas: 2480317)\n[PASS] testOracleNegativeMeanRoundsDown() (gas: 139986)\n[PASS] testOracleOnlyHookCanUpdateButAnyoneCanRead() (gas: 126667)\n[PASS] testOracleRequiresHistoryAndRejectsSpotDeviation() (gas: 136584)\n[PASS] testSettlementPriceGuardUsesTwapEndingAtCutoff() (gas: 275805)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 441.30ms (2.00ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6199211)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 29637696)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 38474379)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6145495)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1355576)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20168935)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5695535)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170491)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 7.67s (80.25ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934426)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1624992)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6581205)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9502909)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294172)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 27469633)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439053)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 43074141)\nLogs:\n  Settlement and request gas: 5597306\n  Settlement and request gas: 4853376\n  Settlement and request gas: 4433060\n  Settlement and request gas: 3965797\n  Settlement and request gas: 3493406\n  Settlement and request gas: 3034688\n  Settlement and request gas: 2583433\n  Settlement and request gas: 2103460\n  Settlement and request gas: 1628858\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 375525)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1373297)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11645392)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5705912)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341595)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5596855)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 7816818)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1568147)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241599)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 7.67s (98.31ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDLedgerSecurity.t.sol:MugiIMDLedgerSecurityTest\n[PASS] testAllRemainingLedgerMutatorsRejectOutsideCaller() (gas: 171999)\n[PASS] testCutoffCannotBeFutureRepeatedOrEarlierThanPriorAccountingEvent() (gas: 4908600)\n[PASS] testExcludedProtocolInventoryCannotCaptureEliminationRewards() (gas: 4078480)\n[PASS] testMaterializationAtOrAfterProposedCutoffCannotBeReusedAsAnEarlierVirtualSnapshot() (gas: 5210809)\n[PASS] testPremintedProtocolInventoryIsExcludedWithoutAnyTokenCallback() (gas: 1336129)\n[PASS] testRemovedInitializationReclassificationAndCallbackSelectorsAreUnavailableEvenToHook() (gas: 148153)\n[PASS] testZeroTokenClaimsAndEthSynchronizationDoNotChangeVirtualSnapshotTiming() (gas: 5446112)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 7.97s (6.59ms CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDLedgerSnapshots.t.sol:MugiIMDLedgerSnapshotsTest\n[PASS] testCutoffTransfersBurnsAndKnownLoserSalesCannotMovePastRewardsOrConversion() (gas: 7006991)\n[PASS] testEmergencyUnwindUsesOriginalCutoffEvenAfterTransfersDuringLongRecoveryDelay() (gas: 7770266)\n[PASS] testFuzzAfterCutoffTransferCannotSellOrDuplicateConversion(uint96,uint96) (runs: 256, μ: 4060778, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.97s (7.98s CPU time)\n\nRan 16 tests for test/imd/MugiIMDCrewToken.t.sol:MugiIMDCrewTokenTest\n[PASS] testBurnHistoryTracksMultipleTimestampsAndCoalescesSameTimestamp() (gas: 441690)\n[PASS] testConstructorAcceptsPredeterminedUndeployedHook() (gas: 16336)\n[PASS] testConstructorCreatesWholeFiniteReserveAndNoEarlierHistory() (gas: 100182)\n[PASS] testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256,uint256) (runs: 256, μ: 54361, ~: 54245)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3606968, ~: 3736452)\n[PASS] testInfiniteAllowanceAndFailedTransferPreserveHistory() (gas: 351050)\n[PASS] testInvalidConstructorConfigurationRejects() (gas: 4632)\n[PASS] testRejectsZeroTransferAndApprovalDestinations() (gas: 53819)\n[PASS] testRemovedMintInitializerAndArbitraryBurnSelectorsAreUnavailable() (gas: 219912)\n[PASS] testReserveHolderHasNoAuthorityOverOtherBalances() (gas: 223787)\n[PASS] testSameTimestampGenesisAndTransfersUseEndOfTimestampBalance() (gas: 313272)\n[PASS] testStaticConstructorPreservesAllCanonicalCrewNamesAndSymbols() (gas: 276675)\n[PASS] testStrictCutoffExcludesEveryExactCutoffTransferAndBurn() (gas: 568341)\n[PASS] testTransferFromCheckpointsBothWalletsAndFiniteAllowance() (gas: 367855)\n[PASS] testTransfersAndBurnDoNotCallRevertingOrBrokenHook() (gas: 539864)\n[PASS] testZeroAndSelfTransfersDoNotChangeHistoricalOwnership() (gas: 248761)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 7.97s (136.93ms CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 564045)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7097095)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 30837115)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 222184310, ~: 222114921)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 36196392)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 27237222)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.97s (8.05s CPU time)\n\nRan 19 test suites in 7.97s (49.17s CPU time): 146 tests passed, 0 failed, 2 skipped (148 total tests)\n","passed":true},{"durationMs":63,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MugiAirdrop.claim(uint64,bytes)\",\"MugiAirdrop.launch()\",\"MugiAirdrop.register(uint8,bytes32,uint64,bytes)\",\"MugiAirdrop.retireRemaining()\",\"MugiCrewToken.approve(address,uint256)\",\"MugiCrewToken.burn(uint256)\",\"MugiCrewToken.transfer(address,uint256)\",\"MugiCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDAccountingFactory.deployForHook((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address))\",\"MugiIMDBuybacks.account(uint64,uint8,uint256)\",\"MugiIMDBuybacks.approve((uint64,uint64,uint64,uint256[10]),address,bytes)\",\"MugiIMDBuybacks.authorize(uint64,uint8,uint256)\",\"MugiIMDBuybacks.create(uint64,uint256,uint16)\",\"MugiIMDCrewFactory.deployCrewSet(address,uint256)\",\"MugiIMDCrewToken.approve(address,uint256)\",\"MugiIMDCrewToken.burn(uint256)\",\"MugiIMDCrewToken.transfer(address,uint256)\",\"MugiIMDCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDEngineFactory.deployForHook(address,address)\",\"MugiIMDGameHook.abortPrelaunch()\",\"MugiIMDGameHook.acceptOwnership()\",\"MugiIMDGameHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MugiIMDGameHook.approvePlan((uint64,uint64,uint64,uint256[10]),bytes)\",\"MugiIMDGameHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MugiIMDGameHook.cancelOwnershipTransfer()\",\"MugiIMDGameHook.claimEth(address)\",\"MugiIMDGameHook.claimToken(uint8,uint256)\",\"MugiIMDGameHook.claimTokens()\",\"MugiIMDGameHook.collectTeamFees(uint8)\",\"MugiIMDGameHook.executeBuyback(uint64,uint8,uint256)\",\"MugiIMDGameHook.executeOwnBuyback(uint8,uint256)\",\"MugiIMDGameHook.finalize()\",\"MugiIMDGameHook.launch()\",\"MugiIMDGameHook.migrateToV2(address)\",\"MugiIMDGameHook.receive()\",\"MugiIMDGameHook.receiveRandomness(uint256,uint256)\",\"MugiIMDGameHook.recoverStalledRandomness(uint8)\",\"MugiIMDGameHook.requestElimination()\",\"MugiIMDGameHook.retireAirdrop()\",\"MugiIMDGameHook.seedPool(uint8)\",\"MugiIMDGameHook.settleRound(uint8)\",\"MugiIMDGameHook.sweepExpiredFinalClaims()\",\"MugiIMDGameHook.transferOwnership(address)\",\"MugiIMDGameHook.unlockCallback(bytes)\",\"MugiIMDGameHook.withdrawTeamFees()\",\"MugiIMDLedger.claimEth(address)\",\"MugiIMDLedger.claimToken(address,uint8,uint256)\",\"MugiIMDLedger.claimTokens(address)\",\"MugiIMDLedger.emergencyFinalize(uint16,uint256,uint64)\",\"MugiIMDLedger.expireFinalClaims()\",\"MugiIMDLedger.finalizeMigration(uint8,uint64)\",\"MugiIMDLedger.recordElimination(uint8,uint16,uint256,uint64)\",\"MugiIMDPriceOracle.update(uint8,int24)\",\"MugiIMDSwapRouter.buy(uint8,uint256,uint64)\",\"MugiIMDSwapRouter.sell(uint8,uint256,uint256,uint64)\",\"MugiIMDSwapRouter.unlockCallback(bytes)\",\"MugiIMDV4Engine.addLiquidity(uint8,uint128,uint256,uint256)\",\"MugiIMDV4Engine.buy(uint8,uint256,uint256,uint160)\",\"MugiIMDV4Engine.collectFees(uint8)\",\"MugiIMDV4Engine.registerInitialPool(uint8,address,uint256,uint256)\",\"MugiIMDV4Engine.registerPool(uint8,address,uint24,int24,uint160)\",\"MugiIMDV4Engine.removeLiquidity(uint8,uint256,uint256)\",\"MugiIMDV4Engine.unlockCallback(bytes)\",\"MugiIMDVerifier.pinRequest(bytes32,bytes32,bytes32,uint64)\",\"MugiIMDVerifier.renounceOwnership()\",\"MugiIMDVerifier.revokeRequest(bytes32)\",\"MugiIMDVerifier.transferOwnership(address)\",\"MugiV1IMDDeploymentFactory.deployHook(bytes)\",\"MugiV1IMDDeploymentFactory.deployModules(bytes32,bytes32,(address,address,bytes32,uint256,uint32,bool,address,address,uint16,uint16,uint64,address,address,uint256))\",\"MugiVRFAdapter.rawFulfillRandomWords(uint256,uint256[])\",\"MugiVRFAdapter.requestRandomness()\",\"MugiVRFAdapter.retryDelivery(uint256)\"],\"files\":{\".gitignore\":6,\"ADAPTATION.md\":202,\"README.md\":59,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":46,\"docs/IMD_FINDINGS_RESPONSE.md\":61,\"docs/IMD_FOLLOWUP_RESPONSE.md\":104,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":167,\"docs/validation/compatible/VALIDATION.md\":33,\"docs/validation/compatible/artifact-review.json\":966,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2606,\"docs/validation/compatible/full-suite.raw.log\":2,\"docs/validation/compatible/test-results.json\":1634,\"docs/validation/compatible/v2-integration-result.json\":32,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":56,\"docs/validation/followup/VALIDATION.md\":16,\"docs/validation/followup/full-suite.raw.json\":2,\"docs/validation/followup/ledger-targeted-summary.json\":170,\"docs/validation/followup/terminal-claim-baseline.log\":20,\"docs/validation/followup/test-results.json\":788,\"docs/validation/followup/validation-summary.json\":188,\"docs/validation/repaired-final/VALIDATION.md\":17,\"docs/validation/repaired-final/test-results.json\":788,\"docs/validation/repaired-final/validation-summary.json\":161,\"docs/validation/vrf-stall-repair/RECOVERY.md\":84,\"docs/validation/vrf-stall-repair/original-VrfStall.sol\":63,\"docs/validation/vrf-stall-repair/original-proof.log\":60,\"foundry.toml\":18,\"hook-constructor.json\":44,\"inventory.json\":642,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":115,\"src/game/MugiAirdrop.sol\":121,\"src/game/MugiCrewToken.sol\":170,\"src/game/MugiIMDVerifier.sol\":157,\"src/game/MugiReserveMath.sol\":27,\"src/game/MugiVRFAdapter.sol\":146,\"src/imd/MugiIMDAccountingFactory.sol\":49,\"src/imd/MugiIMDCrewFactory.sol\":43,\"src/imd/MugiIMDCrewToken.sol\":13,\"src/imd/MugiIMDEngineFactory.sol\":35,\"src/imd/MugiIMDGameHook.sol\":830,\"src/imd/MugiIMDSwapRouter.sol\":132,\"src/imd/MugiV1IMDDeploymentFactory.sol\":155,\"src/imd/libraries/MugiIMDDeploymentAddresses.sol\":15,\"src/imd/libraries/MugiIMDV4Fees.sol\":64,\"src/imd/modules/MugiIMDBuybacks.sol\":188,\"src/imd/modules/MugiIMDLedger.sol\":350,\"src/imd/modules/MugiIMDPriceOracle.sol\":194,\"src/imd/modules/MugiIMDV4Engine.sol\":408,\"test/imd/MugiIMDCrewToken.t.sol\":308,\"test/imd/MugiIMDProjectFactoryFork.t.sol\":141,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":266,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":205,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":620,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiSettlementPricing.t.sol\":108,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":279,\"test/imd/lifecycle/MugiSwapRouter.t.sol\":288,\"test/imd/modules/MugiIMDEngineSecurity.t.sol\":216,\"test/imd/modules/MugiIMDLedgerFixture.sol\":115,\"test/imd/modules/MugiIMDLedgerSeason.t.sol\":68,\"test/imd/modules/MugiIMDLedgerSecurity.t.sol\":117,\"test/imd/modules/MugiIMDLedgerSnapshots.t.sol\":144,\"test/imd/modules/MugiIMDLedgerTerminal.t.sol\":258,\"test/imd/modules/MugiIMDStateModules.t.sol\":171,\"test/imd/modules/MugiIMDVerifier.t.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"3ccde9f146bbb4b0d63d13ea5c24561e7717d0e4f8bd51b69879291a3b4c3465","verifiedTreeHash":"dcd127809a68139302e5df2378f134aeabdb7d8e","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":102876,"exitCode":0,"name":"build","output":"Compiling 130 files with Solc 0.8.26\nSolc 0.8.26 finished in 102.77s\nCompiler run successful with warnings:\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:783:29:\n    |\n783 |     function previewAccount(address account) external view returns (uint256[10] memory, uint256, uint256[10] memory) {\n    |                             ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:787:29:\n    |\n787 |     function eligibleSupply(uint8 crew) external view returns (uint256) {\n    |                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:795:28:\n    |\n795 |     function escrowBacking(uint8 crew) external view returns (uint256) {\n    |                            ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:803:22:\n    |\n803 |     function poolKey(uint8 crew) external view returns (PoolKey memory) {\n    |                      ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:807:21:\n    |\n807 |     function poolId(uint8 crew) external view returns (PoolId) {\n    |                     ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:811:24:\n    |\n811 |     function poolState(uint8 crew) external view returns (uint160, int24, uint128) {\n    |                        ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:815:32:\n    |\n815 |     function positionLiquidity(uint8 crew) external view returns (uint128) {\n    |                                ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:26:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:61:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:73:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:93:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                                             ^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:827:26:\n    |\n827 |     function roundBudget(uint64 id) external view returns (MugiBuybacks.Budget memory) {\n    |                          ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/imd/MugiIMDCrewToken.t.sol:276:5:\n    |\n276 |     function testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256 initial, uint256 order) public view {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n  --> test/imd/modules/MugiIMDVerifier.t.sol:74:5:\n   |\n74 |     function testSignatureVerificationFitsCallbackStipend() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":7439,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/imd/lifecycle/MugiGameHookMainnetFork.t.sol:MugiGameHookMainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 421.56µs (0.00ns CPU time)\n\nRan 1 test for test/imd/MugiIMDProjectFactoryFork.t.sol:MugiIMDProjectFactoryForkTest\n[SKIP] testMainnetFactoryRecordsFourEntriesThenConstructorCompleteGraphSeedsTenPools() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 513.16µs (57.39µs CPU time)\n\nRan 4 tests for test/imd/modules/MugiIMDLedgerSeason.t.sol:MugiIMDLedgerSeasonTest\n[PASS] testConstructorFixesAllProtocolExclusionsWithoutInitialization() (gas: 2309714)\n[PASS] testConstructorRejectsZeroOrDuplicateTokensAndTokenProtocolRoleCollision() (gas: 26831)\n[PASS] testConstructorWorksBeforeAnyDependencyCodeExists() (gas: 16570)\n[PASS] testDuplicateTreasuryAddressesAreSubtractedOnlyOnce() (gas: 1141863)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.77ms (1.18ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 29944111)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127626)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 477993)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 23.17ms (17.51ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiSettlementPricing.t.sol:MugiSettlementPricingTest\n[PASS] testLastSecondPumpDefersMatchedLiquidityAndRoundTripLoses() (gas: 27694909)\n[PASS] testOrdinaryTradingKeepsSettlementReinforcement() (gas: 5620216)\n[PASS] testPumpHeldBeforeFifteenMinuteTailStillDefers() (gas: 29779228)\n[PASS] testUnmovedSurvivorStillReceivesMatchedLiquidity() (gas: 27588338)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 80.57ms (74.15ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7664999)\n[PASS] testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver() (gas: 33786656)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 33547383)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 35221011)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 80.67ms (81.41ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDLedgerSecurity.t.sol:MugiIMDLedgerSecurityTest\n[PASS] testAllRemainingLedgerMutatorsRejectOutsideCaller() (gas: 171999)\n[PASS] testCutoffCannotBeFutureRepeatedOrEarlierThanPriorAccountingEvent() (gas: 4908600)\n[PASS] testExcludedProtocolInventoryCannotCaptureEliminationRewards() (gas: 4078480)\n[PASS] testMaterializationAtOrAfterProposedCutoffCannotBeReusedAsAnEarlierVirtualSnapshot() (gas: 5210809)\n[PASS] testPremintedProtocolInventoryIsExcludedWithoutAnyTokenCallback() (gas: 1336129)\n[PASS] testRemovedInitializationReclassificationAndCallbackSelectorsAreUnavailableEvenToHook() (gas: 148153)\n[PASS] testZeroTokenClaimsAndEthSynchronizationDoNotChangeVirtualSnapshotTiming() (gas: 5446112)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 85.87ms (6.48ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 450918)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1043577)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 853500)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 623199)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1015496, ~: 1016359)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5592627)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 904038)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 810014)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 995696)\n[PASS] testSellMinimumOutputFailurePreservesAllowanceAndBalances() (gas: 440672)\n[PASS] testThirdPartyManagerUnlockCannotUseRouter() (gas: 396113)\n[PASS] testUnsolicitedCallbacksRejectedIncludingManagerWithoutPendingTrade() (gas: 71596)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 102.66ms (95.47ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDEngineSecurity.t.sol:MugiIMDEngineSecurityTest\n[PASS] testAllEconomicMutatorsRejectNonHookCaller() (gas: 150353)\n[PASS] testCallbackCannotBeInjectedEvenByManagerWithoutPendingUnlock() (gas: 62786)\n[PASS] testCounterfactualConstructorDoesNotCallDependencyAddresses() (gas: 13706)\n[PASS] testOnlyOwnerCanDeployPredictedEngineOnce() (gas: 6455846)\n[PASS] testPartialBuyPaysHookAndRefundsUnusedEth() (gas: 808775)\n[PASS] testRefundCallbackCannotReenterPositionOperations() (gas: 661418)\n[PASS] testRemovePaysHookAndLeavesNoPositionOrNewBalancesInEngine() (gas: 787517)\n[PASS] testSeedRefundsUnusedInputsAndPreservesPriorEngineBalances() (gas: 623887)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 108.59ms (3.54ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 106405037)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 75950776)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 18477719)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 96305602)\nLogs:\n  Four service module creations: 3693823\n  Ten crew token creations: 9091796\n  Engine creation: 2497921\n  Three accounting module creations: 4104378\n  Hook creation: 5909685\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 230320)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14470819)\nLogs:\n  Four factory runtime bytes: 61735\n  Four factory initcode bytes: 87521\n  Four factory CREATE2 execution gas: 12536210\n  Estimated launch transaction gas: 14967850\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 32313867)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 85205139)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 96370363)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 96370297)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 98363949)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 71611502)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 110.05ms (802.63ms CPU time)\n\nRan 16 tests for test/imd/MugiIMDCrewToken.t.sol:MugiIMDCrewTokenTest\n[PASS] testBurnHistoryTracksMultipleTimestampsAndCoalescesSameTimestamp() (gas: 441690)\n[PASS] testConstructorAcceptsPredeterminedUndeployedHook() (gas: 16336)\n[PASS] testConstructorCreatesWholeFiniteReserveAndNoEarlierHistory() (gas: 100182)\n[PASS] testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256,uint256) (runs: 256, μ: 54393, ~: 54346)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3602735, ~: 3740200)\n[PASS] testInfiniteAllowanceAndFailedTransferPreserveHistory() (gas: 351050)\n[PASS] testInvalidConstructorConfigurationRejects() (gas: 4632)\n[PASS] testRejectsZeroTransferAndApprovalDestinations() (gas: 53819)\n[PASS] testRemovedMintInitializerAndArbitraryBurnSelectorsAreUnavailable() (gas: 219912)\n[PASS] testReserveHolderHasNoAuthorityOverOtherBalances() (gas: 223787)\n[PASS] testSameTimestampGenesisAndTransfersUseEndOfTimestampBalance() (gas: 313272)\n[PASS] testStaticConstructorPreservesAllCanonicalCrewNamesAndSymbols() (gas: 276675)\n[PASS] testStrictCutoffExcludesEveryExactCutoffTransferAndBurn() (gas: 568341)\n[PASS] testTransferFromCheckpointsBothWalletsAndFiniteAllowance() (gas: 367855)\n[PASS] testTransfersAndBurnDoNotCallRevertingOrBrokenHook() (gas: 539864)\n[PASS] testZeroAndSelfTransfersDoNotChangeHistoricalOwnership() (gas: 248761)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 400.64ms (524.04ms CPU time)\n\nRan 11 tests for test/imd/modules/MugiIMDStateModules.t.sol:MugiIMDStateModulesTest\n[PASS] testAllBudgetMutatorsRequireHook() (gas: 103856)\n[PASS] testApprovalUsesHookHashDomainAndConsumerThroughOrdinaryCall() (gas: 523888)\n[PASS] testBudgetAuthorizesAccountsAndPreservesTradeCadence() (gas: 744739)\n[PASS] testConstructorsAcceptCounterfactualHookAndRejectZero() (gas: 2702387)\n[PASS] testOracleNegativeMeanRoundsDown() (gas: 164473)\n[PASS] testOracleOnlyHookCanUpdateButAnyoneCanRead() (gas: 150383)\n[PASS] testOracleRequiresHistoryAndRejectsSpotDeviation() (gas: 160932)\n[PASS] testSettlementGuardAveragesWholeRoundNotFifteenMinuteTail() (gas: 914826)\n[PASS] testSettlementGuardCheckpointsSurviveObservationSpam() (gas: 10281163)\n[PASS] testSettlementGuardRoundMeanIsExact() (gas: 851239)\n[PASS] testSettlementPriceGuardUsesTwapEndingAtCutoff() (gas: 608711)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 427.44ms (9.62ms CPU time)\n\nRan 13 tests for test/imd/modules/MugiIMDVerifier.t.sol:MugiIMDVerifierTest\n[PASS] testCanonicalIMDProtocolDigestAndSignatureVector() (gas: 14041)\n[PASS] testCrossChainReplayRejected() (gas: 32053)\n[PASS] testExpiryFutureIssueAndStaleAnswerRejected() (gas: 121424)\n[PASS] testMalformedAndFutureBlockMetadataRejected() (gas: 121394)\n[PASS] testOnlyOwnerCanPin() (gas: 34717)\n[PASS] testOwnerCannotRotateSignerOrWeakenEvidencePolicy() (gas: 107728)\n[PASS] testPanelPolicyRejectsMinorityAndImpossibleCounts() (gas: 151298)\n[PASS] testRevocationCannotBeRepinned() (gas: 98612)\n[PASS] testSignatureVerificationFitsCallbackStipend() (gas: 40767)\n[PASS] testTamperedSignatureRejected() (gas: 38804)\n[PASS] testUnpinnedAndWrongQuestionOrAnswerRejected() (gas: 118096)\n[PASS] testValidPinnedPlanAndConsumerReplayGuard() (gas: 161102)\n[PASS] testWrongConsumerAndDomainAreRejected() (gas: 139844)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 7.31s (4.49ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6443127)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 30505960)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 39351528)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6389411)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1359329)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20403535)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5938085)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170491)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 7.31s (87.66ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDLedgerTerminal.t.sol:MugiIMDLedgerTerminalTest\n[PASS] testEmergencyAfterPriorEthWithdrawalExpiresOnlyRemainingMixedRights() (gas: 6872513)\n[PASS] testEmergencyExpirationCannotResurrectSyncedOrLazyClaims() (gas: 10818557)\n[PASS] testEmergencyRejectsWrongMaskAndCannotRecordAnotherTerminalOrRound() (gas: 937792)\n[PASS] testEmergencyRewardsIncludeFrozenWalletAndVirtualBalancesAndEarlierEth() (gas: 8641692)\n[PASS] testEmergencyUnallocatedCrewSharesAndRemaindersNeverEnterPlayerReserve() (gas: 4862305)\n[PASS] testExpirationCannotResurrectSyncedOrLazyClaimsInEitherTerminalMode() (gas: 16635639)\n[PASS] testFuzzEagerMaterializationAndLateSyncHaveIdenticalEmergencyRights(uint8,uint96) (runs: 256, μ: 22972531, ~: 21690983)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 7.31s (455.01ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934426)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1630456)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6827950)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9965369)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294172)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 28337897)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439053)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 43951290)\nLogs:\n  Settlement and request gas: 5839856\n  Settlement and request gas: 5071920\n  Settlement and request gas: 4624286\n  Settlement and request gas: 4027105\n  Settlement and request gas: 3544496\n  Settlement and request gas: 3075560\n  Settlement and request gas: 2614087\n  Settlement and request gas: 2123896\n  Settlement and request gas: 1639076\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 375525)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1376759)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11668852)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5949828)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341595)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5840871)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 8060734)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1570879)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241599)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 7.31s (77.95ms CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDLedgerSnapshots.t.sol:MugiIMDLedgerSnapshotsTest\n[PASS] testCutoffTransfersBurnsAndKnownLoserSalesCannotMovePastRewardsOrConversion() (gas: 7006991)\n[PASS] testEmergencyUnwindUsesOriginalCutoffEvenAfterTransfersDuringLongRecoveryDelay() (gas: 7770266)\n[PASS] testFuzzAfterCutoffTransferCannotSellOrDuplicateConversion(uint96,uint96) (runs: 256, μ: 4060778, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.31s (7.31s CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271053)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194348)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339207)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977419)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4417637)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11457644)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325174)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4875341)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221311)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 7.33s (25.18ms CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 565920)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7343743)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 31708111)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 222806341, ~: 222205257)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 37064656)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 28105486)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.33s (7.39s CPU time)\n\nRan 19 test suites in 7.33s (52.62s CPU time): 150 tests passed, 0 failed, 2 skipped (152 total tests)\n","passed":true},{"durationMs":63,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MugiAirdrop.claim(uint64,bytes)\",\"MugiAirdrop.launch()\",\"MugiAirdrop.register(uint8,bytes32,uint64,bytes)\",\"MugiAirdrop.retireRemaining()\",\"MugiCrewToken.approve(address,uint256)\",\"MugiCrewToken.burn(uint256)\",\"MugiCrewToken.transfer(address,uint256)\",\"MugiCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDAccountingFactory.deployForHook((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address))\",\"MugiIMDBuybacks.account(uint64,uint8,uint256)\",\"MugiIMDBuybacks.approve((uint64,uint64,uint64,uint256[10]),address,bytes)\",\"MugiIMDBuybacks.authorize(uint64,uint8,uint256)\",\"MugiIMDBuybacks.create(uint64,uint256,uint16)\",\"MugiIMDCrewFactory.deployCrewSet(address,uint256)\",\"MugiIMDCrewToken.approve(address,uint256)\",\"MugiIMDCrewToken.burn(uint256)\",\"MugiIMDCrewToken.transfer(address,uint256)\",\"MugiIMDCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDEngineFactory.deployForHook(address,address)\",\"MugiIMDGameHook.abortPrelaunch()\",\"MugiIMDGameHook.acceptOwnership()\",\"MugiIMDGameHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MugiIMDGameHook.approvePlan((uint64,uint64,uint64,uint256[10]),bytes)\",\"MugiIMDGameHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MugiIMDGameHook.cancelOwnershipTransfer()\",\"MugiIMDGameHook.claimEth(address)\",\"MugiIMDGameHook.claimToken(uint8,uint256)\",\"MugiIMDGameHook.claimTokens()\",\"MugiIMDGameHook.collectTeamFees(uint8)\",\"MugiIMDGameHook.executeBuyback(uint64,uint8,uint256)\",\"MugiIMDGameHook.executeOwnBuyback(uint8,uint256)\",\"MugiIMDGameHook.finalize()\",\"MugiIMDGameHook.launch()\",\"MugiIMDGameHook.migrateToV2(address)\",\"MugiIMDGameHook.receive()\",\"MugiIMDGameHook.receiveRandomness(uint256,uint256)\",\"MugiIMDGameHook.recoverStalledRandomness(uint8)\",\"MugiIMDGameHook.requestElimination()\",\"MugiIMDGameHook.retireAirdrop()\",\"MugiIMDGameHook.seedPool(uint8)\",\"MugiIMDGameHook.settleRound(uint8)\",\"MugiIMDGameHook.sweepExpiredFinalClaims()\",\"MugiIMDGameHook.transferOwnership(address)\",\"MugiIMDGameHook.unlockCallback(bytes)\",\"MugiIMDGameHook.withdrawTeamFees()\",\"MugiIMDLedger.claimEth(address)\",\"MugiIMDLedger.claimToken(address,uint8,uint256)\",\"MugiIMDLedger.claimTokens(address)\",\"MugiIMDLedger.emergencyFinalize(uint16,uint256,uint64)\",\"MugiIMDLedger.expireFinalClaims()\",\"MugiIMDLedger.finalizeMigration(uint8,uint64)\",\"MugiIMDLedger.recordElimination(uint8,uint16,uint256,uint64)\",\"MugiIMDPriceOracle.update(uint8,int24)\",\"MugiIMDSwapRouter.buy(uint8,uint256,uint64)\",\"MugiIMDSwapRouter.sell(uint8,uint256,uint256,uint64)\",\"MugiIMDSwapRouter.unlockCallback(bytes)\",\"MugiIMDV4Engine.addLiquidity(uint8,uint128,uint256,uint256)\",\"MugiIMDV4Engine.buy(uint8,uint256,uint256,uint160)\",\"MugiIMDV4Engine.collectFees(uint8)\",\"MugiIMDV4Engine.registerInitialPool(uint8,address,uint256,uint256)\",\"MugiIMDV4Engine.registerPool(uint8,address,uint24,int24,uint160)\",\"MugiIMDV4Engine.removeLiquidity(uint8,uint256,uint256)\",\"MugiIMDV4Engine.unlockCallback(bytes)\",\"MugiIMDVerifier.pinRequest(bytes32,bytes32,bytes32,uint64)\",\"MugiIMDVerifier.renounceOwnership()\",\"MugiIMDVerifier.revokeRequest(bytes32)\",\"MugiIMDVerifier.transferOwnership(address)\",\"MugiV1IMDDeploymentFactory.deployHook(bytes)\",\"MugiV1IMDDeploymentFactory.deployModules(bytes32,bytes32,(address,address,bytes32,uint256,uint32,bool,address,address,uint16,uint16,uint64,address,address,uint256))\",\"MugiVRFAdapter.rawFulfillRandomWords(uint256,uint256[])\",\"MugiVRFAdapter.requestRandomness()\",\"MugiVRFAdapter.retryDelivery(uint256)\"],\"files\":{\".gitignore\":6,\"ADAPTATION.md\":265,\"README.md\":75,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":46,\"docs/IMD_FINDINGS_RESPONSE.md\":61,\"docs/IMD_FOLLOWUP_RESPONSE.md\":104,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":167,\"docs/validation/compatible/VALIDATION.md\":33,\"docs/validation/compatible/artifact-review.json\":966,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2606,\"docs/validation/compatible/full-suite.raw.log\":2,\"docs/validation/compatible/test-results.json\":1634,\"docs/validation/compatible/v2-integration-result.json\":32,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":56,\"docs/validation/followup/VALIDATION.md\":16,\"docs/validation/followup/full-suite.raw.json\":2,\"docs/validation/followup/ledger-targeted-summary.json\":170,\"docs/validation/followup/terminal-claim-baseline.log\":20,\"docs/validation/followup/test-results.json\":788,\"docs/validation/followup/validation-summary.json\":188,\"docs/validation/repaired-final/VALIDATION.md\":17,\"docs/validation/repaired-final/test-results.json\":788,\"docs/validation/repaired-final/validation-summary.json\":161,\"docs/validation/vrf-stall-repair/RECOVERY.md\":84,\"docs/validation/vrf-stall-repair/original-VrfStall.sol\":63,\"docs/validation/vrf-stall-repair/original-proof.log\":60,\"foundry.toml\":18,\"hook-constructor.json\":44,\"inventory.json\":642,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":115,\"src/game/MugiAirdrop.sol\":121,\"src/game/MugiCrewToken.sol\":170,\"src/game/MugiIMDVerifier.sol\":157,\"src/game/MugiReserveMath.sol\":27,\"src/game/MugiVRFAdapter.sol\":146,\"src/imd/MugiIMDAccountingFactory.sol\":49,\"src/imd/MugiIMDCrewFactory.sol\":43,\"src/imd/MugiIMDCrewToken.sol\":13,\"src/imd/MugiIMDEngineFactory.sol\":35,\"src/imd/MugiIMDGameHook.sol\":830,\"src/imd/MugiIMDSwapRouter.sol\":132,\"src/imd/MugiV1IMDDeploymentFactory.sol\":155,\"src/imd/libraries/MugiIMDDeploymentAddresses.sol\":15,\"src/imd/libraries/MugiIMDV4Fees.sol\":64,\"src/imd/modules/MugiIMDBuybacks.sol\":188,\"src/imd/modules/MugiIMDLedger.sol\":350,\"src/imd/modules/MugiIMDPriceOracle.sol\":264,\"src/imd/modules/MugiIMDV4Engine.sol\":408,\"test/imd/MugiIMDCrewToken.t.sol\":308,\"test/imd/MugiIMDProjectFactoryFork.t.sol\":141,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":266,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":205,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":620,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiSettlementPricing.t.sol\":139,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":279,\"test/imd/lifecycle/MugiSwapRouter.t.sol\":288,\"test/imd/modules/MugiIMDEngineSecurity.t.sol\":216,\"test/imd/modules/MugiIMDLedgerFixture.sol\":115,\"test/imd/modules/MugiIMDLedgerSeason.t.sol\":68,\"test/imd/modules/MugiIMDLedgerSecurity.t.sol\":117,\"test/imd/modules/MugiIMDLedgerSnapshots.t.sol\":144,\"test/imd/modules/MugiIMDLedgerTerminal.t.sol\":258,\"test/imd/modules/MugiIMDStateModules.t.sol\":251,\"test/imd/modules/MugiIMDVerifier.t.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"62017509fad038fc14ec8244d879910b11188b3ac12b4c17cb08f6df30620d1c","verifiedTreeHash":"0fb197c5e8cc94cc3222f6a500c30c75cb3ada51","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":262690,"exitCode":0,"name":"build","output":"Compiling 130 files with Solc 0.8.26\nSolc 0.8.26 finished in 262.44s\nCompiler run successful with warnings:\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:783:29:\n    |\n783 |     function previewAccount(address account) external view returns (uint256[10] memory, uint256, uint256[10] memory) {\n    |                             ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:787:29:\n    |\n787 |     function eligibleSupply(uint8 crew) external view returns (uint256) {\n    |                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:795:28:\n    |\n795 |     function escrowBacking(uint8 crew) external view returns (uint256) {\n    |                            ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:803:22:\n    |\n803 |     function poolKey(uint8 crew) external view returns (PoolKey memory) {\n    |                      ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:807:21:\n    |\n807 |     function poolId(uint8 crew) external view returns (PoolId) {\n    |                     ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:811:24:\n    |\n811 |     function poolState(uint8 crew) external view returns (uint160, int24, uint128) {\n    |                        ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:815:32:\n    |\n815 |     function positionLiquidity(uint8 crew) external view returns (uint128) {\n    |                                ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:26:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:61:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:73:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:93:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                                             ^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:827:26:\n    |\n827 |     function roundBudget(uint64 id) external view returns (MugiBuybacks.Budget memory) {\n    |                          ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/imd/MugiIMDCrewToken.t.sol:276:5:\n    |\n276 |     function testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256 initial, uint256 order) public view {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n  --> test/imd/modules/MugiIMDVerifier.t.sol:74:5:\n   |\n74 |     function testSignatureVerificationFitsCallbackStipend() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":16068,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/imd/lifecycle/MugiGameHookMainnetFork.t.sol:MugiGameHookMainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 893.24µs (0.00ns CPU time)\n\nRan 1 test for test/imd/MugiIMDProjectFactoryFork.t.sol:MugiIMDProjectFactoryForkTest\n[SKIP] testMainnetFactoryRecordsFourEntriesThenConstructorCompleteGraphSeedsTenPools() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 880.85µs (68.25µs CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDStateModules.t.sol:MugiIMDStateModulesTest\n[PASS] testAllBudgetMutatorsRequireHook() (gas: 103800)\n[PASS] testApprovalUsesHookHashDomainAndConsumerThroughOrdinaryCall() (gas: 523832)\n[PASS] testBudgetAuthorizesAccountsAndPreservesTradeCadence() (gas: 744683)\n[PASS] testConstructorsAcceptCounterfactualHookAndRejectZero() (gas: 2480317)\n[PASS] testOracleNegativeMeanRoundsDown() (gas: 139986)\n[PASS] testOracleOnlyHookCanUpdateButAnyoneCanRead() (gas: 126667)\n[PASS] testOracleRequiresHistoryAndRejectsSpotDeviation() (gas: 136584)\n[PASS] testSettlementPriceGuardUsesTwapEndingAtCutoff() (gas: 275805)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 3.68ms (3.70ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 29077213)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127626)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 476627)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 62.88ms (40.81ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271053)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194348)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339207)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977419)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4175087)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11213728)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325174)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4875341)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221311)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 91.78ms (40.93ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6199211)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 29637696)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 38474379)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6145495)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1355576)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20168935)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5695535)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170491)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 165.41ms (134.71ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 449552)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1042211)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 852134)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 620467)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1012796, ~: 1013627)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5348711)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 902672)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 807282)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 994330)\n[PASS] testSellMinimumOutputFailurePreservesAllowanceAndBalances() (gas: 439306)\n[PASS] testThirdPartyManagerUnlockCannotUseRouter() (gas: 396113)\n[PASS] testUnsolicitedCallbacksRejectedIncludingManagerWithoutPendingTrade() (gas: 71596)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 167.04ms (162.55ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934426)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1624992)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6581205)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9502909)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294172)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 27469633)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439053)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 43074141)\nLogs:\n  Settlement and request gas: 5597306\n  Settlement and request gas: 4853376\n  Settlement and request gas: 4433060\n  Settlement and request gas: 3965797\n  Settlement and request gas: 3493406\n  Settlement and request gas: 3034688\n  Settlement and request gas: 2583433\n  Settlement and request gas: 2103460\n  Settlement and request gas: 1628858\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 375525)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1373297)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11645392)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5705912)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341595)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5596855)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 7816818)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1568147)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241599)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 166.96ms (163.59ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDLedgerSecurity.t.sol:MugiIMDLedgerSecurityTest\n[PASS] testAllRemainingLedgerMutatorsRejectOutsideCaller() (gas: 171999)\n[PASS] testCutoffCannotBeFutureRepeatedOrEarlierThanPriorAccountingEvent() (gas: 4908600)\n[PASS] testExcludedProtocolInventoryCannotCaptureEliminationRewards() (gas: 4078480)\n[PASS] testMaterializationAtOrAfterProposedCutoffCannotBeReusedAsAnEarlierVirtualSnapshot() (gas: 5210809)\n[PASS] testPremintedProtocolInventoryIsExcludedWithoutAnyTokenCallback() (gas: 1336129)\n[PASS] testRemovedInitializationReclassificationAndCallbackSelectorsAreUnavailableEvenToHook() (gas: 148153)\n[PASS] testZeroTokenClaimsAndEthSynchronizationDoNotChangeVirtualSnapshotTiming() (gas: 5446112)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 216.45ms (10.37ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7421083)\n[PASS] testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver() (gas: 32909507)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 32670234)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 34343862)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 275.47ms (140.23ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 105979468)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 75950776)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 18477719)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 96114655)\nLogs:\n  Four service module creations: 3693823\n  Ten crew token creations: 9091796\n  Engine creation: 2497921\n  Three accounting module creations: 3913431\n  Hook creation: 5909685\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 228028)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14258298)\nLogs:\n  Four factory runtime bytes: 60782\n  Four factory initcode bytes: 86568\n  Four factory CREATE2 execution gas: 12345124\n  Estimated launch transaction gas: 14761516\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 32122920)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 85205139)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 96179416)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 96179350)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 98172980)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 71611502)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 275.77ms (1.74s CPU time)\n\nRan 4 tests for test/imd/modules/MugiIMDLedgerSeason.t.sol:MugiIMDLedgerSeasonTest\n[PASS] testConstructorFixesAllProtocolExclusionsWithoutInitialization() (gas: 2309714)\n[PASS] testConstructorRejectsZeroOrDuplicateTokensAndTokenProtocolRoleCollision() (gas: 26831)\n[PASS] testConstructorWorksBeforeAnyDependencyCodeExists() (gas: 16570)\n[PASS] testDuplicateTreasuryAddressesAreSubtractedOnlyOnce() (gas: 1141863)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 744.68ms (4.03ms CPU time)\n\nRan 13 tests for test/imd/modules/MugiIMDVerifier.t.sol:MugiIMDVerifierTest\n[PASS] testCanonicalIMDProtocolDigestAndSignatureVector() (gas: 14041)\n[PASS] testCrossChainReplayRejected() (gas: 32053)\n[PASS] testExpiryFutureIssueAndStaleAnswerRejected() (gas: 121424)\n[PASS] testMalformedAndFutureBlockMetadataRejected() (gas: 121394)\n[PASS] testOnlyOwnerCanPin() (gas: 34717)\n[PASS] testOwnerCannotRotateSignerOrWeakenEvidencePolicy() (gas: 107728)\n[PASS] testPanelPolicyRejectsMinorityAndImpossibleCounts() (gas: 151298)\n[PASS] testRevocationCannotBeRepinned() (gas: 98612)\n[PASS] testSignatureVerificationFitsCallbackStipend() (gas: 40767)\n[PASS] testTamperedSignatureRejected() (gas: 38804)\n[PASS] testUnpinnedAndWrongQuestionOrAnswerRejected() (gas: 118096)\n[PASS] testValidPinnedPlanAndConsumerReplayGuard() (gas: 161102)\n[PASS] testWrongConsumerAndDomainAreRejected() (gas: 139844)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 782.26ms (8.39ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDEngineSecurity.t.sol:MugiIMDEngineSecurityTest\n[PASS] testAllEconomicMutatorsRejectNonHookCaller() (gas: 150353)\n[PASS] testCallbackCannotBeInjectedEvenByManagerWithoutPendingUnlock() (gas: 62786)\n[PASS] testCounterfactualConstructorDoesNotCallDependencyAddresses() (gas: 13706)\n[PASS] testOnlyOwnerCanDeployPredictedEngineOnce() (gas: 6455846)\n[PASS] testPartialBuyPaysHookAndRefundsUnusedEth() (gas: 808775)\n[PASS] testRefundCallbackCannotReenterPositionOperations() (gas: 661418)\n[PASS] testRemovePaysHookAndLeavesNoPositionOrNewBalancesInEngine() (gas: 787517)\n[PASS] testSeedRefundsUnusedInputsAndPreservesPriorEngineBalances() (gas: 623887)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 782.39ms (6.03ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDLedgerTerminal.t.sol:MugiIMDLedgerTerminalTest\n[PASS] testEmergencyAfterPriorEthWithdrawalExpiresOnlyRemainingMixedRights() (gas: 6872513)\n[PASS] testEmergencyExpirationCannotResurrectSyncedOrLazyClaims() (gas: 10818557)\n[PASS] testEmergencyRejectsWrongMaskAndCannotRecordAnotherTerminalOrRound() (gas: 937792)\n[PASS] testEmergencyRewardsIncludeFrozenWalletAndVirtualBalancesAndEarlierEth() (gas: 8641692)\n[PASS] testEmergencyUnallocatedCrewSharesAndRemaindersNeverEnterPlayerReserve() (gas: 4862305)\n[PASS] testExpirationCannotResurrectSyncedOrLazyClaimsInEitherTerminalMode() (gas: 16635639)\n[PASS] testFuzzEagerMaterializationAndLateSyncHaveIdenticalEmergencyRights(uint8,uint96) (runs: 256, μ: 23175291, ~: 21691368)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 782.75ms (824.09ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiSettlementPricing.t.sol:MugiSettlementPricingTest\n[PASS] testLastSecondPumpDefersMatchedLiquidityAndRoundTripLoses() (gas: 26804540)\n[PASS] testOrdinaryTradingKeepsSettlementReinforcement() (gas: 5376310)\n[PASS] testUnmovedSurvivorStillReceivesMatchedLiquidity() (gas: 26696162)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 14.32s (79.20ms CPU time)\n\nRan 16 tests for test/imd/MugiIMDCrewToken.t.sol:MugiIMDCrewTokenTest\n[PASS] testBurnHistoryTracksMultipleTimestampsAndCoalescesSameTimestamp() (gas: 441690)\n[PASS] testConstructorAcceptsPredeterminedUndeployedHook() (gas: 16336)\n[PASS] testConstructorCreatesWholeFiniteReserveAndNoEarlierHistory() (gas: 100182)\n[PASS] testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256,uint256) (runs: 256, μ: 54361, ~: 54245)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3606968, ~: 3736452)\n[PASS] testInfiniteAllowanceAndFailedTransferPreserveHistory() (gas: 351050)\n[PASS] testInvalidConstructorConfigurationRejects() (gas: 4632)\n[PASS] testRejectsZeroTransferAndApprovalDestinations() (gas: 53819)\n[PASS] testRemovedMintInitializerAndArbitraryBurnSelectorsAreUnavailable() (gas: 219912)\n[PASS] testReserveHolderHasNoAuthorityOverOtherBalances() (gas: 223787)\n[PASS] testSameTimestampGenesisAndTransfersUseEndOfTimestampBalance() (gas: 313272)\n[PASS] testStaticConstructorPreservesAllCanonicalCrewNamesAndSymbols() (gas: 276675)\n[PASS] testStrictCutoffExcludesEveryExactCutoffTransferAndBurn() (gas: 568341)\n[PASS] testTransferFromCheckpointsBothWalletsAndFiniteAllowance() (gas: 367855)\n[PASS] testTransfersAndBurnDoNotCallRevertingOrBrokenHook() (gas: 539864)\n[PASS] testZeroAndSelfTransfersDoNotChangeHistoricalOwnership() (gas: 248761)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 15.76s (513.09ms CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDLedgerSnapshots.t.sol:MugiIMDLedgerSnapshotsTest\n[PASS] testCutoffTransfersBurnsAndKnownLoserSalesCannotMovePastRewardsOrConversion() (gas: 7006991)\n[PASS] testEmergencyUnwindUsesOriginalCutoffEvenAfterTransfersDuringLongRecoveryDelay() (gas: 7770266)\n[PASS] testFuzzAfterCutoffTransferCannotSellOrDuplicateConversion(uint96,uint96) (runs: 256, μ: 4060778, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 15.76s (142.54ms CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 564045)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7097095)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 30837115)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 222184310, ~: 222114921)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 36196392)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 27237222)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 15.76s (15.87s CPU time)\n\nRan 19 test suites in 15.76s (66.13s CPU time): 146 tests passed, 0 failed, 2 skipped (148 total tests)\n","passed":true},{"durationMs":175,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MugiAirdrop.claim(uint64,bytes)\",\"MugiAirdrop.launch()\",\"MugiAirdrop.register(uint8,bytes32,uint64,bytes)\",\"MugiAirdrop.retireRemaining()\",\"MugiCrewToken.approve(address,uint256)\",\"MugiCrewToken.burn(uint256)\",\"MugiCrewToken.transfer(address,uint256)\",\"MugiCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDAccountingFactory.deployForHook((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address))\",\"MugiIMDBuybacks.account(uint64,uint8,uint256)\",\"MugiIMDBuybacks.approve((uint64,uint64,uint64,uint256[10]),address,bytes)\",\"MugiIMDBuybacks.authorize(uint64,uint8,uint256)\",\"MugiIMDBuybacks.create(uint64,uint256,uint16)\",\"MugiIMDCrewFactory.deployCrewSet(address,uint256)\",\"MugiIMDCrewToken.approve(address,uint256)\",\"MugiIMDCrewToken.burn(uint256)\",\"MugiIMDCrewToken.transfer(address,uint256)\",\"MugiIMDCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDEngineFactory.deployForHook(address,address)\",\"MugiIMDGameHook.abortPrelaunch()\",\"MugiIMDGameHook.acceptOwnership()\",\"MugiIMDGameHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MugiIMDGameHook.approvePlan((uint64,uint64,uint64,uint256[10]),bytes)\",\"MugiIMDGameHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MugiIMDGameHook.cancelOwnershipTransfer()\",\"MugiIMDGameHook.claimEth(address)\",\"MugiIMDGameHook.claimToken(uint8,uint256)\",\"MugiIMDGameHook.claimTokens()\",\"MugiIMDGameHook.collectTeamFees(uint8)\",\"MugiIMDGameHook.executeBuyback(uint64,uint8,uint256)\",\"MugiIMDGameHook.executeOwnBuyback(uint8,uint256)\",\"MugiIMDGameHook.finalize()\",\"MugiIMDGameHook.launch()\",\"MugiIMDGameHook.migrateToV2(address)\",\"MugiIMDGameHook.receive()\",\"MugiIMDGameHook.receiveRandomness(uint256,uint256)\",\"MugiIMDGameHook.recoverStalledRandomness(uint8)\",\"MugiIMDGameHook.requestElimination()\",\"MugiIMDGameHook.retireAirdrop()\",\"MugiIMDGameHook.seedPool(uint8)\",\"MugiIMDGameHook.settleRound(uint8)\",\"MugiIMDGameHook.sweepExpiredFinalClaims()\",\"MugiIMDGameHook.transferOwnership(address)\",\"MugiIMDGameHook.unlockCallback(bytes)\",\"MugiIMDGameHook.withdrawTeamFees()\",\"MugiIMDLedger.claimEth(address)\",\"MugiIMDLedger.claimToken(address,uint8,uint256)\",\"MugiIMDLedger.claimTokens(address)\",\"MugiIMDLedger.emergencyFinalize(uint16,uint256,uint64)\",\"MugiIMDLedger.expireFinalClaims()\",\"MugiIMDLedger.finalizeMigration(uint8,uint64)\",\"MugiIMDLedger.recordElimination(uint8,uint16,uint256,uint64)\",\"MugiIMDPriceOracle.update(uint8,int24)\",\"MugiIMDSwapRouter.buy(uint8,uint256,uint64)\",\"MugiIMDSwapRouter.sell(uint8,uint256,uint256,uint64)\",\"MugiIMDSwapRouter.unlockCallback(bytes)\",\"MugiIMDV4Engine.addLiquidity(uint8,uint128,uint256,uint256)\",\"MugiIMDV4Engine.buy(uint8,uint256,uint256,uint160)\",\"MugiIMDV4Engine.collectFees(uint8)\",\"MugiIMDV4Engine.registerInitialPool(uint8,address,uint256,uint256)\",\"MugiIMDV4Engine.registerPool(uint8,address,uint24,int24,uint160)\",\"MugiIMDV4Engine.removeLiquidity(uint8,uint256,uint256)\",\"MugiIMDV4Engine.unlockCallback(bytes)\",\"MugiIMDVerifier.pinRequest(bytes32,bytes32,bytes32,uint64)\",\"MugiIMDVerifier.renounceOwnership()\",\"MugiIMDVerifier.revokeRequest(bytes32)\",\"MugiIMDVerifier.transferOwnership(address)\",\"MugiV1IMDDeploymentFactory.deployHook(bytes)\",\"MugiV1IMDDeploymentFactory.deployModules(bytes32,bytes32,(address,address,bytes32,uint256,uint32,bool,address,address,uint16,uint16,uint64,address,address,uint256))\",\"MugiVRFAdapter.rawFulfillRandomWords(uint256,uint256[])\",\"MugiVRFAdapter.requestRandomness()\",\"MugiVRFAdapter.retryDelivery(uint256)\"],\"files\":{\".gitignore\":6,\"ADAPTATION.md\":202,\"README.md\":59,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":46,\"docs/IMD_FINDINGS_RESPONSE.md\":61,\"docs/IMD_FOLLOWUP_RESPONSE.md\":104,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":167,\"docs/validation/compatible/VALIDATION.md\":33,\"docs/validation/compatible/artifact-review.json\":966,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2606,\"docs/validation/compatible/full-suite.raw.log\":2,\"docs/validation/compatible/test-results.json\":1634,\"docs/validation/compatible/v2-integration-result.json\":32,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":56,\"docs/validation/followup/VALIDATION.md\":16,\"docs/validation/followup/full-suite.raw.json\":2,\"docs/validation/followup/ledger-targeted-summary.json\":170,\"docs/validation/followup/terminal-claim-baseline.log\":20,\"docs/validation/followup/test-results.json\":788,\"docs/validation/followup/validation-summary.json\":188,\"docs/validation/repaired-final/VALIDATION.md\":17,\"docs/validation/repaired-final/test-results.json\":788,\"docs/validation/repaired-final/validation-summary.json\":161,\"docs/validation/vrf-stall-repair/RECOVERY.md\":84,\"docs/validation/vrf-stall-repair/original-VrfStall.sol\":63,\"docs/validation/vrf-stall-repair/original-proof.log\":60,\"foundry.toml\":18,\"hook-constructor.json\":44,\"inventory.json\":642,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":115,\"src/game/MugiAirdrop.sol\":121,\"src/game/MugiCrewToken.sol\":170,\"src/game/MugiIMDVerifier.sol\":157,\"src/game/MugiReserveMath.sol\":27,\"src/game/MugiVRFAdapter.sol\":146,\"src/imd/MugiIMDAccountingFactory.sol\":49,\"src/imd/MugiIMDCrewFactory.sol\":43,\"src/imd/MugiIMDCrewToken.sol\":13,\"src/imd/MugiIMDEngineFactory.sol\":35,\"src/imd/MugiIMDGameHook.sol\":830,\"src/imd/MugiIMDSwapRouter.sol\":132,\"src/imd/MugiV1IMDDeploymentFactory.sol\":155,\"src/imd/libraries/MugiIMDDeploymentAddresses.sol\":15,\"src/imd/libraries/MugiIMDV4Fees.sol\":64,\"src/imd/modules/MugiIMDBuybacks.sol\":188,\"src/imd/modules/MugiIMDLedger.sol\":350,\"src/imd/modules/MugiIMDPriceOracle.sol\":194,\"src/imd/modules/MugiIMDV4Engine.sol\":408,\"test/imd/MugiIMDCrewToken.t.sol\":308,\"test/imd/MugiIMDProjectFactoryFork.t.sol\":141,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":266,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":205,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":620,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiSettlementPricing.t.sol\":108,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":279,\"test/imd/lifecycle/MugiSwapRouter.t.sol\":288,\"test/imd/modules/MugiIMDEngineSecurity.t.sol\":216,\"test/imd/modules/MugiIMDLedgerFixture.sol\":115,\"test/imd/modules/MugiIMDLedgerSeason.t.sol\":68,\"test/imd/modules/MugiIMDLedgerSecurity.t.sol\":117,\"test/imd/modules/MugiIMDLedgerSnapshots.t.sol\":144,\"test/imd/modules/MugiIMDLedgerTerminal.t.sol\":258,\"test/imd/modules/MugiIMDStateModules.t.sol\":171,\"test/imd/modules/MugiIMDVerifier.t.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":45623,"exitCode":0,"name":"slither","output":"Slither crashed on this tree, an analyser bug and not a finding, so its rejecting detectors did not run; Aderyn's report below stands in. slither produced no report: ^^^^^^^^^^^^\n  File \"/opt/slither/lib/python3.11/site-packages/slither/slithir/operations/member.py\", line 33, in __init__\n    assert is_valid_rvalue(variable_left) or isinstance(\nAssertionError\n'forge clean' running (wd: /tmp/imd-verify-P5iwkA/repo)\n'forge config --json' running\n'forge build --build-info --deny never --skip ./test/** ./script/** --force' running (wd: /tmp/imd-verify-P5iwkA/repo)\n","passed":true},{"durationMs":2526,"exitCode":0,"name":"aderyn","output":"[high] eth-send-unchecked-address at src/imd/MugiIMDGameHook.sol:562: ETH transferred without address checks (3 places)\n[high] reentrancy-state-change at src/game/MugiVRFAdapter.sol:91: Reentrancy: State change after external call (21 places)\n[high] unsafe-casting at src/imd/modules/MugiIMDPriceOracle.sol:133: Unsafe Casting of integers\n[high] yul-return at src/imd/MugiIMDGameHook.sol:779: Yul block contains `return`\n[low] centralization-risk at src/game/MugiIMDVerifier.sol:14: Centralization Risk (10 places)\n[low] costly-loop at src/game/MugiAirdrop.sol:74: Costly operations inside loop (14 places)\n[low] internal-function-used-once at src/imd/libraries/MugiIMDDeploymentAddresses.sol:7: Internal Function Used Only Once (2 places)\n[low] large-numeric-literal at src/game/MugiVRFAdapter.sol:74: Large Numeric Literal (10 places)\n[low] literal-instead-of-constant at src/game/MugiAirdrop.sol:32: Literal Instead of Constant (88 places)\n[low] local-variable-shadowing at src/imd/MugiIMDGameHook.sol:132: Local Variable Shadows State Variable (17 places)\n[low] missing-inheritance at src/game/MugiVRFAdapter.sol:25: Missing Inheritance (3 places)\n[low] modifier-used-only-once at src/imd/modules/MugiIMDPriceOracle.sol:50: Modifier Invoked Only Once\n[low] push-zero-opcode at src/game/MugiAirdrop.sol:2: PUSH0 Opcode (18 places)\n[low] require-revert-in-loop at src/imd/MugiIMDCrewFactory.sol:34: Loop Contains `require`/`revert` (8 places)\n[low] state-change-without-event at src/game/MugiAirdrop.sol:71: State Change Without Event (21 places)\n[low] state-variable-could-be-immutable at src/game/MugiAirdrop.sol:15: State Variable Could Be Immutable (12 places)\n[low] unchecked-return at src/imd/MugiIMDGameHook.sol:280: Unchecked Return (13 places)\n[low] uninitialized-local-variable at src/game/MugiAirdrop.sol:36: Uninitialized Local Variable (7 places)\n[low] unsafe-erc20-operation at src/game/MugiAirdrop.sol:118: Unsafe ERC20 Operation (11 places)\n[low] unspecific-solidity-pragma at src/game/MugiAirdrop.sol:2: Unspecific Solidity Pragma (15 places)\n[low] unused-public-function at src/imd/MugiIMDCrewFactory.sol:25: Public Function Not Used Internally (16 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"8dd84fd9fd0aac050f7c530fac4bbb15b5b1cd010b80f99bf89c0a13fd8388d7","verifiedTreeHash":"69a7670d4cff04c0bfdd211c3127ede3687036e0","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":263893,"exitCode":0,"name":"build","output":"Compiling 130 files with Solc 0.8.26\nSolc 0.8.26 finished in 263.64s\nCompiler run successful with warnings:\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:783:29:\n    |\n783 |     function previewAccount(address account) external view returns (uint256[10] memory, uint256, uint256[10] memory) {\n    |                             ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:787:29:\n    |\n787 |     function eligibleSupply(uint8 crew) external view returns (uint256) {\n    |                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:795:28:\n    |\n795 |     function escrowBacking(uint8 crew) external view returns (uint256) {\n    |                            ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:803:22:\n    |\n803 |     function poolKey(uint8 crew) external view returns (PoolKey memory) {\n    |                      ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:807:21:\n    |\n807 |     function poolId(uint8 crew) external view returns (PoolId) {\n    |                     ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:811:24:\n    |\n811 |     function poolState(uint8 crew) external view returns (uint160, int24, uint128) {\n    |                        ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:815:32:\n    |\n815 |     function positionLiquidity(uint8 crew) external view returns (uint128) {\n    |                                ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:26:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:61:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:73:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:93:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                                             ^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:827:26:\n    |\n827 |     function roundBudget(uint64 id) external view returns (MugiBuybacks.Budget memory) {\n    |                          ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/imd/MugiIMDCrewToken.t.sol:276:5:\n    |\n276 |     function testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256 initial, uint256 order) public view {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n  --> test/imd/modules/MugiIMDVerifier.t.sol:74:5:\n   |\n74 |     function testSignatureVerificationFitsCallbackStipend() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":14992,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/imd/MugiIMDProjectFactoryFork.t.sol:MugiIMDProjectFactoryForkTest\n[SKIP] testMainnetFactoryRecordsFourEntriesThenConstructorCompleteGraphSeedsTenPools() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 962.97µs (144.70µs CPU time)\n\nRan 1 test for test/imd/lifecycle/MugiGameHookMainnetFork.t.sol:MugiGameHookMainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 628.44µs (0.00ns CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDEngineSecurity.t.sol:MugiIMDEngineSecurityTest\n[PASS] testAllEconomicMutatorsRejectNonHookCaller() (gas: 150353)\n[PASS] testCallbackCannotBeInjectedEvenByManagerWithoutPendingUnlock() (gas: 62786)\n[PASS] testCounterfactualConstructorDoesNotCallDependencyAddresses() (gas: 13706)\n[PASS] testOnlyOwnerCanDeployPredictedEngineOnce() (gas: 6455846)\n[PASS] testPartialBuyPaysHookAndRefundsUnusedEth() (gas: 808775)\n[PASS] testRefundCallbackCannotReenterPositionOperations() (gas: 661418)\n[PASS] testRemovePaysHookAndLeavesNoPositionOrNewBalancesInEngine() (gas: 787517)\n[PASS] testSeedRefundsUnusedInputsAndPreservesPriorEngineBalances() (gas: 623887)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 14.55ms (10.77ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 29944111)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127626)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 477993)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 47.51ms (35.04ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiSettlementPricing.t.sol:MugiSettlementPricingTest\n[PASS] testLastSecondPumpDefersMatchedLiquidityAndRoundTripLoses() (gas: 27694909)\n[PASS] testOrdinaryTradingKeepsSettlementReinforcement() (gas: 5620216)\n[PASS] testPumpHeldBeforeFifteenMinuteTailStillDefers() (gas: 29779228)\n[PASS] testUnmovedSurvivorStillReceivesMatchedLiquidity() (gas: 27588338)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 121.66ms (142.10ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7664999)\n[PASS] testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver() (gas: 33786656)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 33547383)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 35221011)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 130.49ms (148.23ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934426)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1630456)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6827950)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9965369)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294172)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 28337897)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439053)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 43951290)\nLogs:\n  Settlement and request gas: 5839856\n  Settlement and request gas: 5071920\n  Settlement and request gas: 4624286\n  Settlement and request gas: 4027105\n  Settlement and request gas: 3544496\n  Settlement and request gas: 3075560\n  Settlement and request gas: 2614087\n  Settlement and request gas: 2123896\n  Settlement and request gas: 1639076\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 375525)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1376759)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11668852)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5949828)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341595)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5840871)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 8060734)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1570879)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241599)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 136.07ms (189.58ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6443127)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 30505960)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 39351528)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6389411)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1359329)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20403535)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5938085)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170491)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 184.62ms (161.56ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 450918)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1043577)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 853500)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 623199)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1015496, ~: 1016359)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5592627)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 904038)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 810014)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 995696)\n[PASS] testSellMinimumOutputFailurePreservesAllowanceAndBalances() (gas: 440672)\n[PASS] testThirdPartyManagerUnlockCannotUseRouter() (gas: 396113)\n[PASS] testUnsolicitedCallbacksRejectedIncludingManagerWithoutPendingTrade() (gas: 71596)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 184.53ms (186.15ms CPU time)\n\nRan 4 tests for test/imd/modules/MugiIMDLedgerSeason.t.sol:MugiIMDLedgerSeasonTest\n[PASS] testConstructorFixesAllProtocolExclusionsWithoutInitialization() (gas: 2309714)\n[PASS] testConstructorRejectsZeroOrDuplicateTokensAndTokenProtocolRoleCollision() (gas: 26831)\n[PASS] testConstructorWorksBeforeAnyDependencyCodeExists() (gas: 16570)\n[PASS] testDuplicateTreasuryAddressesAreSubtractedOnlyOnce() (gas: 1141863)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 261.41ms (3.45ms CPU time)\n\nRan 11 tests for test/imd/modules/MugiIMDStateModules.t.sol:MugiIMDStateModulesTest\n[PASS] testAllBudgetMutatorsRequireHook() (gas: 103856)\n[PASS] testApprovalUsesHookHashDomainAndConsumerThroughOrdinaryCall() (gas: 523888)\n[PASS] testBudgetAuthorizesAccountsAndPreservesTradeCadence() (gas: 744739)\n[PASS] testConstructorsAcceptCounterfactualHookAndRejectZero() (gas: 2702387)\n[PASS] testOracleNegativeMeanRoundsDown() (gas: 164473)\n[PASS] testOracleOnlyHookCanUpdateButAnyoneCanRead() (gas: 150383)\n[PASS] testOracleRequiresHistoryAndRejectsSpotDeviation() (gas: 160932)\n[PASS] testSettlementGuardAveragesWholeRoundNotFifteenMinuteTail() (gas: 914826)\n[PASS] testSettlementGuardCheckpointsSurviveObservationSpam() (gas: 10281163)\n[PASS] testSettlementGuardRoundMeanIsExact() (gas: 851239)\n[PASS] testSettlementPriceGuardUsesTwapEndingAtCutoff() (gas: 608711)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 268.55ms (12.32ms CPU time)\n\nRan 16 tests for test/imd/MugiIMDCrewToken.t.sol:MugiIMDCrewTokenTest\n[PASS] testBurnHistoryTracksMultipleTimestampsAndCoalescesSameTimestamp() (gas: 441690)\n[PASS] testConstructorAcceptsPredeterminedUndeployedHook() (gas: 16336)\n[PASS] testConstructorCreatesWholeFiniteReserveAndNoEarlierHistory() (gas: 100182)\n[PASS] testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256,uint256) (runs: 256, μ: 54393, ~: 54346)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3602735, ~: 3740200)\n[PASS] testInfiniteAllowanceAndFailedTransferPreserveHistory() (gas: 351050)\n[PASS] testInvalidConstructorConfigurationRejects() (gas: 4632)\n[PASS] testRejectsZeroTransferAndApprovalDestinations() (gas: 53819)\n[PASS] testRemovedMintInitializerAndArbitraryBurnSelectorsAreUnavailable() (gas: 219912)\n[PASS] testReserveHolderHasNoAuthorityOverOtherBalances() (gas: 223787)\n[PASS] testSameTimestampGenesisAndTransfersUseEndOfTimestampBalance() (gas: 313272)\n[PASS] testStaticConstructorPreservesAllCanonicalCrewNamesAndSymbols() (gas: 276675)\n[PASS] testStrictCutoffExcludesEveryExactCutoffTransferAndBurn() (gas: 568341)\n[PASS] testTransferFromCheckpointsBothWalletsAndFiniteAllowance() (gas: 367855)\n[PASS] testTransfersAndBurnDoNotCallRevertingOrBrokenHook() (gas: 539864)\n[PASS] testZeroAndSelfTransfersDoNotChangeHistoricalOwnership() (gas: 248761)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 267.83ms (261.88ms CPU time)\n\nRan 13 tests for test/imd/modules/MugiIMDVerifier.t.sol:MugiIMDVerifierTest\n[PASS] testCanonicalIMDProtocolDigestAndSignatureVector() (gas: 14041)\n[PASS] testCrossChainReplayRejected() (gas: 32053)\n[PASS] testExpiryFutureIssueAndStaleAnswerRejected() (gas: 121424)\n[PASS] testMalformedAndFutureBlockMetadataRejected() (gas: 121394)\n[PASS] testOnlyOwnerCanPin() (gas: 34717)\n[PASS] testOwnerCannotRotateSignerOrWeakenEvidencePolicy() (gas: 107728)\n[PASS] testPanelPolicyRejectsMinorityAndImpossibleCounts() (gas: 151298)\n[PASS] testRevocationCannotBeRepinned() (gas: 98612)\n[PASS] testSignatureVerificationFitsCallbackStipend() (gas: 40767)\n[PASS] testTamperedSignatureRejected() (gas: 38804)\n[PASS] testUnpinnedAndWrongQuestionOrAnswerRejected() (gas: 118096)\n[PASS] testValidPinnedPlanAndConsumerReplayGuard() (gas: 161102)\n[PASS] testWrongConsumerAndDomainAreRejected() (gas: 139844)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 268.61ms (11.43ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271053)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194348)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339207)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977419)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4417637)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11457644)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325174)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4875341)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221311)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 1.04s (64.02ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDLedgerTerminal.t.sol:MugiIMDLedgerTerminalTest\n[PASS] testEmergencyAfterPriorEthWithdrawalExpiresOnlyRemainingMixedRights() (gas: 6872513)\n[PASS] testEmergencyExpirationCannotResurrectSyncedOrLazyClaims() (gas: 10818557)\n[PASS] testEmergencyRejectsWrongMaskAndCannotRecordAnotherTerminalOrRound() (gas: 937792)\n[PASS] testEmergencyRewardsIncludeFrozenWalletAndVirtualBalancesAndEarlierEth() (gas: 8641692)\n[PASS] testEmergencyUnallocatedCrewSharesAndRemaindersNeverEnterPlayerReserve() (gas: 4862305)\n[PASS] testExpirationCannotResurrectSyncedOrLazyClaimsInEitherTerminalMode() (gas: 16635639)\n[PASS] testFuzzEagerMaterializationAndLateSyncHaveIdenticalEmergencyRights(uint8,uint96) (runs: 256, μ: 22972531, ~: 21690983)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 1.04s (1.08s CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDLedgerSecurity.t.sol:MugiIMDLedgerSecurityTest\n[PASS] testAllRemainingLedgerMutatorsRejectOutsideCaller() (gas: 171999)\n[PASS] testCutoffCannotBeFutureRepeatedOrEarlierThanPriorAccountingEvent() (gas: 4908600)\n[PASS] testExcludedProtocolInventoryCannotCaptureEliminationRewards() (gas: 4078480)\n[PASS] testMaterializationAtOrAfterProposedCutoffCannotBeReusedAsAnEarlierVirtualSnapshot() (gas: 5210809)\n[PASS] testPremintedProtocolInventoryIsExcludedWithoutAnyTokenCallback() (gas: 1336129)\n[PASS] testRemovedInitializationReclassificationAndCallbackSelectorsAreUnavailableEvenToHook() (gas: 148153)\n[PASS] testZeroTokenClaimsAndEthSynchronizationDoNotChangeVirtualSnapshotTiming() (gas: 5446112)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 13.86s (8.06ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 106405037)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 75950776)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 18477719)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 96305602)\nLogs:\n  Four service module creations: 3693823\n  Ten crew token creations: 9091796\n  Engine creation: 2497921\n  Three accounting module creations: 4104378\n  Hook creation: 5909685\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 230320)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14470819)\nLogs:\n  Four factory runtime bytes: 61735\n  Four factory initcode bytes: 87521\n  Four factory CREATE2 execution gas: 12536210\n  Estimated launch transaction gas: 14967850\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 32313867)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 85205139)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 96370363)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 96370297)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 98363949)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 71611502)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 14.13s (2.07s CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDLedgerSnapshots.t.sol:MugiIMDLedgerSnapshotsTest\n[PASS] testCutoffTransfersBurnsAndKnownLoserSalesCannotMovePastRewardsOrConversion() (gas: 7006991)\n[PASS] testEmergencyUnwindUsesOriginalCutoffEvenAfterTransfersDuringLongRecoveryDelay() (gas: 7770266)\n[PASS] testFuzzAfterCutoffTransferCannotSellOrDuplicateConversion(uint96,uint96) (runs: 256, μ: 4060778, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 14.71s (13.88s CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 565920)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7343743)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 31708111)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 222806341, ~: 222205257)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 37064656)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 28105486)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 14.71s (14.82s CPU time)\n\nRan 19 test suites in 14.71s (61.39s CPU time): 150 tests passed, 0 failed, 2 skipped (152 total tests)\n","passed":true},{"durationMs":170,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MugiAirdrop.claim(uint64,bytes)\",\"MugiAirdrop.launch()\",\"MugiAirdrop.register(uint8,bytes32,uint64,bytes)\",\"MugiAirdrop.retireRemaining()\",\"MugiCrewToken.approve(address,uint256)\",\"MugiCrewToken.burn(uint256)\",\"MugiCrewToken.transfer(address,uint256)\",\"MugiCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDAccountingFactory.deployForHook((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address))\",\"MugiIMDBuybacks.account(uint64,uint8,uint256)\",\"MugiIMDBuybacks.approve((uint64,uint64,uint64,uint256[10]),address,bytes)\",\"MugiIMDBuybacks.authorize(uint64,uint8,uint256)\",\"MugiIMDBuybacks.create(uint64,uint256,uint16)\",\"MugiIMDCrewFactory.deployCrewSet(address,uint256)\",\"MugiIMDCrewToken.approve(address,uint256)\",\"MugiIMDCrewToken.burn(uint256)\",\"MugiIMDCrewToken.transfer(address,uint256)\",\"MugiIMDCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDEngineFactory.deployForHook(address,address)\",\"MugiIMDGameHook.abortPrelaunch()\",\"MugiIMDGameHook.acceptOwnership()\",\"MugiIMDGameHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MugiIMDGameHook.approvePlan((uint64,uint64,uint64,uint256[10]),bytes)\",\"MugiIMDGameHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MugiIMDGameHook.cancelOwnershipTransfer()\",\"MugiIMDGameHook.claimEth(address)\",\"MugiIMDGameHook.claimToken(uint8,uint256)\",\"MugiIMDGameHook.claimTokens()\",\"MugiIMDGameHook.collectTeamFees(uint8)\",\"MugiIMDGameHook.executeBuyback(uint64,uint8,uint256)\",\"MugiIMDGameHook.executeOwnBuyback(uint8,uint256)\",\"MugiIMDGameHook.finalize()\",\"MugiIMDGameHook.launch()\",\"MugiIMDGameHook.migrateToV2(address)\",\"MugiIMDGameHook.receive()\",\"MugiIMDGameHook.receiveRandomness(uint256,uint256)\",\"MugiIMDGameHook.recoverStalledRandomness(uint8)\",\"MugiIMDGameHook.requestElimination()\",\"MugiIMDGameHook.retireAirdrop()\",\"MugiIMDGameHook.seedPool(uint8)\",\"MugiIMDGameHook.settleRound(uint8)\",\"MugiIMDGameHook.sweepExpiredFinalClaims()\",\"MugiIMDGameHook.transferOwnership(address)\",\"MugiIMDGameHook.unlockCallback(bytes)\",\"MugiIMDGameHook.withdrawTeamFees()\",\"MugiIMDLedger.claimEth(address)\",\"MugiIMDLedger.claimToken(address,uint8,uint256)\",\"MugiIMDLedger.claimTokens(address)\",\"MugiIMDLedger.emergencyFinalize(uint16,uint256,uint64)\",\"MugiIMDLedger.expireFinalClaims()\",\"MugiIMDLedger.finalizeMigration(uint8,uint64)\",\"MugiIMDLedger.recordElimination(uint8,uint16,uint256,uint64)\",\"MugiIMDPriceOracle.update(uint8,int24)\",\"MugiIMDSwapRouter.buy(uint8,uint256,uint64)\",\"MugiIMDSwapRouter.sell(uint8,uint256,uint256,uint64)\",\"MugiIMDSwapRouter.unlockCallback(bytes)\",\"MugiIMDV4Engine.addLiquidity(uint8,uint128,uint256,uint256)\",\"MugiIMDV4Engine.buy(uint8,uint256,uint256,uint160)\",\"MugiIMDV4Engine.collectFees(uint8)\",\"MugiIMDV4Engine.registerInitialPool(uint8,address,uint256,uint256)\",\"MugiIMDV4Engine.registerPool(uint8,address,uint24,int24,uint160)\",\"MugiIMDV4Engine.removeLiquidity(uint8,uint256,uint256)\",\"MugiIMDV4Engine.unlockCallback(bytes)\",\"MugiIMDVerifier.pinRequest(bytes32,bytes32,bytes32,uint64)\",\"MugiIMDVerifier.renounceOwnership()\",\"MugiIMDVerifier.revokeRequest(bytes32)\",\"MugiIMDVerifier.transferOwnership(address)\",\"MugiV1IMDDeploymentFactory.deployHook(bytes)\",\"MugiV1IMDDeploymentFactory.deployModules(bytes32,bytes32,(address,address,bytes32,uint256,uint32,bool,address,address,uint16,uint16,uint64,address,address,uint256))\",\"MugiVRFAdapter.rawFulfillRandomWords(uint256,uint256[])\",\"MugiVRFAdapter.requestRandomness()\",\"MugiVRFAdapter.retryDelivery(uint256)\"],\"files\":{\".gitignore\":6,\"ADAPTATION.md\":265,\"README.md\":75,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":46,\"docs/IMD_FINDINGS_RESPONSE.md\":61,\"docs/IMD_FOLLOWUP_RESPONSE.md\":104,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":167,\"docs/validation/compatible/VALIDATION.md\":33,\"docs/validation/compatible/artifact-review.json\":966,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2606,\"docs/validation/compatible/full-suite.raw.log\":2,\"docs/validation/compatible/test-results.json\":1634,\"docs/validation/compatible/v2-integration-result.json\":32,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":56,\"docs/validation/followup/VALIDATION.md\":16,\"docs/validation/followup/full-suite.raw.json\":2,\"docs/validation/followup/ledger-targeted-summary.json\":170,\"docs/validation/followup/terminal-claim-baseline.log\":20,\"docs/validation/followup/test-results.json\":788,\"docs/validation/followup/validation-summary.json\":188,\"docs/validation/repaired-final/VALIDATION.md\":17,\"docs/validation/repaired-final/test-results.json\":788,\"docs/validation/repaired-final/validation-summary.json\":161,\"docs/validation/vrf-stall-repair/RECOVERY.md\":84,\"docs/validation/vrf-stall-repair/original-VrfStall.sol\":63,\"docs/validation/vrf-stall-repair/original-proof.log\":60,\"foundry.toml\":18,\"hook-constructor.json\":44,\"inventory.json\":642,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":115,\"src/game/MugiAirdrop.sol\":121,\"src/game/MugiCrewToken.sol\":170,\"src/game/MugiIMDVerifier.sol\":157,\"src/game/MugiReserveMath.sol\":27,\"src/game/MugiVRFAdapter.sol\":146,\"src/imd/MugiIMDAccountingFactory.sol\":49,\"src/imd/MugiIMDCrewFactory.sol\":43,\"src/imd/MugiIMDCrewToken.sol\":13,\"src/imd/MugiIMDEngineFactory.sol\":35,\"src/imd/MugiIMDGameHook.sol\":830,\"src/imd/MugiIMDSwapRouter.sol\":132,\"src/imd/MugiV1IMDDeploymentFactory.sol\":155,\"src/imd/libraries/MugiIMDDeploymentAddresses.sol\":15,\"src/imd/libraries/MugiIMDV4Fees.sol\":64,\"src/imd/modules/MugiIMDBuybacks.sol\":188,\"src/imd/modules/MugiIMDLedger.sol\":350,\"src/imd/modules/MugiIMDPriceOracle.sol\":264,\"src/imd/modules/MugiIMDV4Engine.sol\":408,\"test/imd/MugiIMDCrewToken.t.sol\":308,\"test/imd/MugiIMDProjectFactoryFork.t.sol\":141,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":266,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":205,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":620,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiSettlementPricing.t.sol\":139,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":279,\"test/imd/lifecycle/MugiSwapRouter.t.sol\":288,\"test/imd/modules/MugiIMDEngineSecurity.t.sol\":216,\"test/imd/modules/MugiIMDLedgerFixture.sol\":115,\"test/imd/modules/MugiIMDLedgerSeason.t.sol\":68,\"test/imd/modules/MugiIMDLedgerSecurity.t.sol\":117,\"test/imd/modules/MugiIMDLedgerSnapshots.t.sol\":144,\"test/imd/modules/MugiIMDLedgerTerminal.t.sol\":258,\"test/imd/modules/MugiIMDStateModules.t.sol\":251,\"test/imd/modules/MugiIMDVerifier.t.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":44118,"exitCode":0,"name":"slither","output":"Slither crashed on this tree, an analyser bug and not a finding, so its rejecting detectors did not run; Aderyn's report below stands in. slither produced no report: ^^^^^^^^^^^^\n  File \"/opt/slither/lib/python3.11/site-packages/slither/slithir/operations/member.py\", line 33, in __init__\n    assert is_valid_rvalue(variable_left) or isinstance(\nAssertionError\n'forge clean' running (wd: /tmp/imd-verify-gZ6uRo/repo)\n'forge config --json' running\n'forge build --build-info --deny never --skip ./test/** ./script/** --force' running (wd: /tmp/imd-verify-gZ6uRo/repo)\n","passed":true},{"durationMs":2296,"exitCode":0,"name":"aderyn","output":"[high] eth-send-unchecked-address at src/imd/MugiIMDGameHook.sol:562: ETH transferred without address checks (3 places)\n[high] reentrancy-state-change at src/game/MugiVRFAdapter.sol:91: Reentrancy: State change after external call (21 places)\n[high] unsafe-casting at src/imd/modules/MugiIMDPriceOracle.sol:201: Unsafe Casting of integers\n[high] yul-return at src/imd/MugiIMDGameHook.sol:779: Yul block contains `return`\n[low] centralization-risk at src/game/MugiIMDVerifier.sol:14: Centralization Risk (10 places)\n[low] costly-loop at src/game/MugiAirdrop.sol:74: Costly operations inside loop (14 places)\n[low] internal-function-used-once at src/imd/libraries/MugiIMDDeploymentAddresses.sol:7: Internal Function Used Only Once (2 places)\n[low] large-numeric-literal at src/game/MugiVRFAdapter.sol:74: Large Numeric Literal (10 places)\n[low] literal-instead-of-constant at src/game/MugiAirdrop.sol:32: Literal Instead of Constant (88 places)\n[low] local-variable-shadowing at src/imd/MugiIMDGameHook.sol:132: Local Variable Shadows State Variable (17 places)\n[low] missing-inheritance at src/game/MugiVRFAdapter.sol:25: Missing Inheritance (3 places)\n[low] modifier-used-only-once at src/imd/modules/MugiIMDPriceOracle.sol:68: Modifier Invoked Only Once\n[low] push-zero-opcode at src/game/MugiAirdrop.sol:2: PUSH0 Opcode (18 places)\n[low] require-revert-in-loop at src/imd/MugiIMDCrewFactory.sol:34: Loop Contains `require`/`revert` (8 places)\n[low] state-change-without-event at src/game/MugiAirdrop.sol:71: State Change Without Event (21 places)\n[low] state-variable-could-be-immutable at src/game/MugiAirdrop.sol:15: State Variable Could Be Immutable (12 places)\n[low] unchecked-return at src/imd/MugiIMDGameHook.sol:280: Unchecked Return (13 places)\n[low] uninitialized-local-variable at src/game/MugiAirdrop.sol:36: Uninitialized Local Variable (7 places)\n[low] unsafe-erc20-operation at src/game/MugiAirdrop.sol:118: Unsafe ERC20 Operation (11 places)\n[low] unspecific-solidity-pragma at src/game/MugiAirdrop.sol:2: Unspecific Solidity Pragma (15 places)\n[low] unused-public-function at src/imd/MugiIMDCrewFactory.sol:25: Public Function Not Used Internally (16 places)","passed":true},{"durationMs":56160,"exitCode":0,"name":"proof cbd2b1fb7f6d","output":"Compiling 112 files with Solc 0.8.26\nSolc 0.8.26 finished in 54.75s\nCompiler run successful with warnings:\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:783:29:\n    |\n783 |     function previewAccount(address account) external view returns (uint256[10] memory, uint256, uint256[10] memory) {\n    |                             ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:787:29:\n    |\n787 |     function eligibleSupply(uint8 crew) external view returns (uint256) {\n    |                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:795:28:\n    |\n795 |     function escrowBacking(uint8 crew) external view returns (uint256) {\n    |                            ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:803:22:\n    |\n803 |     function poolKey(uint8 crew) external view returns (PoolKey memory) {\n    |                      ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:807:21:\n    |\n807 |     function poolId(uint8 crew) external view returns (PoolId) {\n    |                     ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:811:24:\n    |\n811 |     function poolState(uint8 crew) external view returns (uint160, int24, uint128) {\n    |                        ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:815:32:\n    |\n815 |     function positionLiquidity(uint8 crew) external view returns (uint128) {\n    |                                ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:26:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:61:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:73:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:93:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                                             ^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:827:26:\n    |\n827 |     function roundBudget(uint64 id) external view returns (MugiBuybacks.Budget memory) {\n    |                          ^^^^^^^^^\n\n\nRan 1 test for test/imd-proof-d3215fe0/Proof_cbd2b1fb7f6d.t.sol:SettlementGuardWindowProof\n[PASS] testPumpHeldFifteenMinutesBeforeCutoffIsNotRewardedBySettlement() (gas: 23346119)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 33.50ms (23.84ms CPU time)\n\nRan 1 test suite in 34.33ms (33.50ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"999ef21d4e5d4cad7b2cd78fe1fdae810acc1dd749fc5603faf9acd88be1625c","verifiedTreeHash":"c4dd54ae02ad78e3b42de89a8067abd17f05bc8e","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":98099,"exitCode":0,"name":"build","output":"Compiling 129 files with Solc 0.8.26\nSolc 0.8.26 finished in 97.97s\nCompiler run successful with warnings:\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:625:29:\n    |\n625 |     function previewAccount(address account) external view returns (uint256[10 ...\n    |                             ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:626:29:\n    |\n626 |     function eligibleSupply(uint8 crew) external view returns (uint256) { _forwardView(address(ledger)); }\n    |                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:628:28:\n    |\n628 |     function escrowBacking(uint8 crew) external view returns (uint256) { _forwardView(address(ledger)); }\n    |                            ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:630:22:\n    |\n630 |     function poolKey(uint8 crew) external view returns (PoolKey memory) { _forwardView(address(engine)); }\n    |                      ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:631:21:\n    |\n631 |     function poolId(uint8 crew) external view returns (PoolId) { _forwardView(address(engine)); }\n    |                     ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:632:24:\n    |\n632 |     function poolState(uint8 crew) external view returns (uint160, int24, uint128) { _forwardView(address(engine)); }\n    |                        ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:633:32:\n    |\n633 |     function positionLiquidity(uint8 crew) external view returns (uint128) { _forwardView(address(engine)); }\n    |                                ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:26:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:61:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:73:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:93:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                                             ^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:638:26:\n    |\n638 |     function roundBudget(uint64 id) external view returns (MugiBuybacks.Budget memory) { _forwardView(address(budgets)); }\n    |                          ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/imd/MugiIMDCrewToken.t.sol:276:5:\n    |\n276 |     function testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256 initial, uint256 order) public view {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n  --> test/imd/modules/MugiIMDVerifier.t.sol:74:5:\n   |\n74 |     function testSignatureVerificationFitsCallbackStipend() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":7341,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/imd/lifecycle/MugiGameHookMainnetFork.t.sol:MugiGameHookMainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 351.62µs (0.00ns CPU time)\n\nRan 1 test for test/imd/MugiIMDProjectFactoryFork.t.sol:MugiIMDProjectFactoryForkTest\n[SKIP] testMainnetFactoryRecordsFourEntriesThenConstructorCompleteGraphSeedsTenPools() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 353.64µs (36.07µs CPU time)\n\nRan 4 tests for test/imd/modules/MugiIMDLedgerSeason.t.sol:MugiIMDLedgerSeasonTest\n[PASS] testConstructorFixesAllProtocolExclusionsWithoutInitialization() (gas: 2309714)\n[PASS] testConstructorRejectsZeroOrDuplicateTokensAndTokenProtocolRoleCollision() (gas: 26831)\n[PASS] testConstructorWorksBeforeAnyDependencyCodeExists() (gas: 16570)\n[PASS] testDuplicateTreasuryAddressesAreSubtractedOnlyOnce() (gas: 1141863)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.77ms (1.19ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 28708864)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127626)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 476583)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 25.09ms (17.28ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6125490)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 29269303)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 38107268)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6071774)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1355084)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20108725)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5621858)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170491)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 46.00ms (64.03ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDLedgerSecurity.t.sol:MugiIMDLedgerSecurityTest\n[PASS] testAllRemainingLedgerMutatorsRejectOutsideCaller() (gas: 171999)\n[PASS] testCutoffCannotBeFutureRepeatedOrEarlierThanPriorAccountingEvent() (gas: 4908600)\n[PASS] testExcludedProtocolInventoryCannotCaptureEliminationRewards() (gas: 4078480)\n[PASS] testMaterializationAtOrAfterProposedCutoffCannotBeReusedAsAnEarlierVirtualSnapshot() (gas: 5210809)\n[PASS] testPremintedProtocolInventoryIsExcludedWithoutAnyTokenCallback() (gas: 1336129)\n[PASS] testRemovedInitializationReclassificationAndCallbackSelectorsAreUnavailableEvenToHook() (gas: 148153)\n[PASS] testZeroTokenClaimsAndEthSynchronizationDoNotChangeVirtualSnapshotTiming() (gas: 5446112)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 58.49ms (4.98ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271053)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194348)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339207)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977419)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4101410)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11140007)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325174)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4875341)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221311)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 71.39ms (20.35ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7347371)\n[PASS] testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver() (gas: 32542396)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 32303123)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 33976751)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 72.46ms (85.40ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 449508)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1042167)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 852090)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 620379)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1012701, ~: 1013539)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5274990)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 902628)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 807194)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 994286)\n[PASS] testSellMinimumOutputFailurePreservesAllowanceAndBalances() (gas: 439262)\n[PASS] testThirdPartyManagerUnlockCannotUseRouter() (gas: 396113)\n[PASS] testUnsolicitedCallbacksRejectedIncludingManagerWithoutPendingTrade() (gas: 71596)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 76.48ms (73.70ms CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDLedgerSnapshots.t.sol:MugiIMDLedgerSnapshotsTest\n[PASS] testCutoffTransfersBurnsAndKnownLoserSalesCannotMovePastRewardsOrConversion() (gas: 7006991)\n[PASS] testEmergencyUnwindUsesOriginalCutoffEvenAfterTransfersDuringLongRecoveryDelay() (gas: 7770266)\n[PASS] testFuzzAfterCutoffTransferCannotSellOrDuplicateConversion(uint96,uint96) (runs: 256, μ: 4060778, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 106.69ms (80.78ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDStateModules.t.sol:MugiIMDStateModulesTest\n[PASS] testAllBudgetMutatorsRequireHook() (gas: 103800)\n[PASS] testApprovalUsesHookHashDomainAndConsumerThroughOrdinaryCall() (gas: 523802)\n[PASS] testBudgetAuthorizesAccountsAndPreservesTradeCadence() (gas: 744543)\n[PASS] testConstructorsAcceptCounterfactualHookAndRejectZero() (gas: 2385626)\n[PASS] testOracleNegativeMeanRoundsDown() (gas: 139608)\n[PASS] testOracleOnlyHookCanUpdateButAnyoneCanRead() (gas: 126199)\n[PASS] testOracleRequiresHistoryAndRejectsSpotDeviation() (gas: 135910)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 113.57ms (1.52ms CPU time)\n\nRan 16 tests for test/imd/MugiIMDCrewToken.t.sol:MugiIMDCrewTokenTest\n[PASS] testBurnHistoryTracksMultipleTimestampsAndCoalescesSameTimestamp() (gas: 441690)\n[PASS] testConstructorAcceptsPredeterminedUndeployedHook() (gas: 16336)\n[PASS] testConstructorCreatesWholeFiniteReserveAndNoEarlierHistory() (gas: 100182)\n[PASS] testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256,uint256) (runs: 256, μ: 54366, ~: 54289)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3587133, ~: 3710216)\n[PASS] testInfiniteAllowanceAndFailedTransferPreserveHistory() (gas: 351050)\n[PASS] testInvalidConstructorConfigurationRejects() (gas: 4632)\n[PASS] testRejectsZeroTransferAndApprovalDestinations() (gas: 53819)\n[PASS] testRemovedMintInitializerAndArbitraryBurnSelectorsAreUnavailable() (gas: 219912)\n[PASS] testReserveHolderHasNoAuthorityOverOtherBalances() (gas: 223787)\n[PASS] testSameTimestampGenesisAndTransfersUseEndOfTimestampBalance() (gas: 313272)\n[PASS] testStaticConstructorPreservesAllCanonicalCrewNamesAndSymbols() (gas: 276675)\n[PASS] testStrictCutoffExcludesEveryExactCutoffTransferAndBurn() (gas: 568341)\n[PASS] testTransferFromCheckpointsBothWalletsAndFiniteAllowance() (gas: 367855)\n[PASS] testTransfersAndBurnDoNotCallRevertingOrBrokenHook() (gas: 539864)\n[PASS] testZeroAndSelfTransfersDoNotChangeHistoricalOwnership() (gas: 248761)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 113.56ms (230.58ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934426)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1624816)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6506717)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9363700)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294172)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 27101240)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439053)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 42707030)\nLogs:\n  Settlement and request gas: 5523629\n  Settlement and request gas: 4787887\n  Settlement and request gas: 4375760\n  Settlement and request gas: 3916684\n  Settlement and request gas: 3452480\n  Settlement and request gas: 3001948\n  Settlement and request gas: 2558879\n  Settlement and request gas: 2087091\n  Settlement and request gas: 1620674\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 375525)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1372533)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11155742)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5632191)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341595)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5522752)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 7743106)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1568059)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241599)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 113.55ms (74.86ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDLedgerTerminal.t.sol:MugiIMDLedgerTerminalTest\n[PASS] testEmergencyAfterPriorEthWithdrawalExpiresOnlyRemainingMixedRights() (gas: 6872513)\n[PASS] testEmergencyExpirationCannotResurrectSyncedOrLazyClaims() (gas: 10818557)\n[PASS] testEmergencyRejectsWrongMaskAndCannotRecordAnotherTerminalOrRound() (gas: 937792)\n[PASS] testEmergencyRewardsIncludeFrozenWalletAndVirtualBalancesAndEarlierEth() (gas: 8641692)\n[PASS] testEmergencyUnallocatedCrewSharesAndRemaindersNeverEnterPlayerReserve() (gas: 4862305)\n[PASS] testExpirationCannotResurrectSyncedOrLazyClaimsInEitherTerminalMode() (gas: 16635639)\n[PASS] testFuzzEagerMaterializationAndLateSyncHaveIdenticalEmergencyRights(uint8,uint96) (runs: 256, μ: 23009153, ~: 21690551)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 413.89ms (434.20ms CPU time)\n\nRan 13 tests for test/imd/modules/MugiIMDVerifier.t.sol:MugiIMDVerifierTest\n[PASS] testCanonicalIMDProtocolDigestAndSignatureVector() (gas: 14041)\n[PASS] testCrossChainReplayRejected() (gas: 32053)\n[PASS] testExpiryFutureIssueAndStaleAnswerRejected() (gas: 121424)\n[PASS] testMalformedAndFutureBlockMetadataRejected() (gas: 121394)\n[PASS] testOnlyOwnerCanPin() (gas: 34717)\n[PASS] testOwnerCannotRotateSignerOrWeakenEvidencePolicy() (gas: 107728)\n[PASS] testPanelPolicyRejectsMinorityAndImpossibleCounts() (gas: 151298)\n[PASS] testRevocationCannotBeRepinned() (gas: 98612)\n[PASS] testSignatureVerificationFitsCallbackStipend() (gas: 40767)\n[PASS] testTamperedSignatureRejected() (gas: 38804)\n[PASS] testUnpinnedAndWrongQuestionOrAnswerRejected() (gas: 118096)\n[PASS] testValidPinnedPlanAndConsumerReplayGuard() (gas: 161102)\n[PASS] testWrongConsumerAndDomainAreRejected() (gas: 139844)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 7.04s (3.89ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDEngineSecurity.t.sol:MugiIMDEngineSecurityTest\n[PASS] testAllEconomicMutatorsRejectNonHookCaller() (gas: 150353)\n[PASS] testCallbackCannotBeInjectedEvenByManagerWithoutPendingUnlock() (gas: 62786)\n[PASS] testCounterfactualConstructorDoesNotCallDependencyAddresses() (gas: 13706)\n[PASS] testOnlyOwnerCanDeployPredictedEngineOnce() (gas: 6455846)\n[PASS] testPartialBuyPaysHookAndRefundsUnusedEth() (gas: 808775)\n[PASS] testRefundCallbackCannotReenterPositionOperations() (gas: 661418)\n[PASS] testRemovePaysHookAndLeavesNoPositionOrNewBalancesInEngine() (gas: 787517)\n[PASS] testSeedRefundsUnusedInputsAndPreservesPriorEngineBalances() (gas: 623887)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 7.07s (2.69ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 69993263)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 40179916)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 143450616)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 60128436)\nLogs:\n  Four service module creations: 3693167\n  Ten crew token creations: 9091601\n  Engine creation: 2497921\n  Three accounting module creations: 3831414\n  Hook creation: 5778342\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 223633)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14156646)\nLogs:\n  Four factory runtime bytes: 60375\n  Four factory initcode bytes: 85703\n  Four factory CREATE2 execution gas: 12262905\n  Estimated launch transaction gas: 14665457\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 25147600)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 49349293)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 60193548)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 60193482)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 62102607)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 35799830)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 7.07s (556.74ms CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 563187)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7023286)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 30468634)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 219966492, ~: 219235119)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 35827999)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 26868829)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.23s (7.26s CPU time)\n\nRan 18 test suites in 7.23s (29.62s CPU time): 142 tests passed, 0 failed, 2 skipped (144 total tests)\n","passed":true},{"durationMs":70,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MugiAirdrop.claim(uint64,bytes)\",\"MugiAirdrop.launch()\",\"MugiAirdrop.register(uint8,bytes32,uint64,bytes)\",\"MugiAirdrop.retireRemaining()\",\"MugiCrewToken.approve(address,uint256)\",\"MugiCrewToken.burn(uint256)\",\"MugiCrewToken.transfer(address,uint256)\",\"MugiCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDAccountingFactory.deployForHook((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address))\",\"MugiIMDBuybacks.account(uint64,uint8,uint256)\",\"MugiIMDBuybacks.approve((uint64,uint64,uint64,uint256[10]),address,bytes)\",\"MugiIMDBuybacks.authorize(uint64,uint8,uint256)\",\"MugiIMDBuybacks.create(uint64,uint256,uint16)\",\"MugiIMDCrewFactory.deployCrewSet(address,uint256)\",\"MugiIMDCrewToken.approve(address,uint256)\",\"MugiIMDCrewToken.burn(uint256)\",\"MugiIMDCrewToken.transfer(address,uint256)\",\"MugiIMDCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDEngineFactory.deployForHook(address,address)\",\"MugiIMDGameHook.abortPrelaunch()\",\"MugiIMDGameHook.acceptOwnership()\",\"MugiIMDGameHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MugiIMDGameHook.approvePlan((uint64,uint64,uint64,uint256[10]),bytes)\",\"MugiIMDGameHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MugiIMDGameHook.cancelOwnershipTransfer()\",\"MugiIMDGameHook.claimEth(address)\",\"MugiIMDGameHook.claimToken(uint8,uint256)\",\"MugiIMDGameHook.claimTokens()\",\"MugiIMDGameHook.collectTeamFees(uint8)\",\"MugiIMDGameHook.executeBuyback(uint64,uint8,uint256)\",\"MugiIMDGameHook.executeOwnBuyback(uint8,uint256)\",\"MugiIMDGameHook.finalize()\",\"MugiIMDGameHook.launch()\",\"MugiIMDGameHook.migrateToV2(address)\",\"MugiIMDGameHook.receive()\",\"MugiIMDGameHook.receiveRandomness(uint256,uint256)\",\"MugiIMDGameHook.recoverStalledRandomness(uint8)\",\"MugiIMDGameHook.requestElimination()\",\"MugiIMDGameHook.retireAirdrop()\",\"MugiIMDGameHook.seedPool(uint8)\",\"MugiIMDGameHook.settleRound(uint8)\",\"MugiIMDGameHook.sweepExpiredFinalClaims()\",\"MugiIMDGameHook.transferOwnership(address)\",\"MugiIMDGameHook.unlockCallback(bytes)\",\"MugiIMDGameHook.withdrawTeamFees()\",\"MugiIMDLedger.claimEth(address)\",\"MugiIMDLedger.claimToken(address,uint8,uint256)\",\"MugiIMDLedger.claimTokens(address)\",\"MugiIMDLedger.emergencyFinalize(uint16,uint256,uint64)\",\"MugiIMDLedger.expireFinalClaims()\",\"MugiIMDLedger.finalizeMigration(uint8,uint64)\",\"MugiIMDLedger.recordElimination(uint8,uint16,uint256,uint64)\",\"MugiIMDPriceOracle.update(uint8,int24)\",\"MugiIMDSwapRouter.buy(uint8,uint256,uint64)\",\"MugiIMDSwapRouter.sell(uint8,uint256,uint256,uint64)\",\"MugiIMDSwapRouter.unlockCallback(bytes)\",\"MugiIMDV4Engine.addLiquidity(uint8,uint128,uint256,uint256)\",\"MugiIMDV4Engine.buy(uint8,uint256,uint256,uint160)\",\"MugiIMDV4Engine.collectFees(uint8)\",\"MugiIMDV4Engine.registerInitialPool(uint8,address,uint256,uint256)\",\"MugiIMDV4Engine.registerPool(uint8,address,uint24,int24,uint160)\",\"MugiIMDV4Engine.removeLiquidity(uint8,uint256,uint256)\",\"MugiIMDV4Engine.unlockCallback(bytes)\",\"MugiIMDVerifier.pinRequest(bytes32,bytes32,bytes32,uint64)\",\"MugiIMDVerifier.renounceOwnership()\",\"MugiIMDVerifier.revokeRequest(bytes32)\",\"MugiIMDVerifier.transferOwnership(address)\",\"MugiV1IMDDeploymentFactory.deployHook(bytes)\",\"MugiV1IMDDeploymentFactory.deployModules(bytes32,bytes32,(address,address,bytes32,uint256,uint32,bool,address,address,uint16,uint16,uint64,address,address,uint256))\",\"MugiVRFAdapter.rawFulfillRandomWords(uint256,uint256[])\",\"MugiVRFAdapter.requestRandomness()\",\"MugiVRFAdapter.retryDelivery(uint256)\"],\"files\":{\".gitignore\":6,\"ADAPTATION.md\":131,\"README.md\":47,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":42,\"docs/IMD_FINDINGS_RESPONSE.md\":61,\"docs/IMD_FOLLOWUP_RESPONSE.md\":104,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":167,\"docs/validation/compatible/VALIDATION.md\":33,\"docs/validation/compatible/artifact-review.json\":966,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2606,\"docs/validation/compatible/full-suite.raw.log\":2,\"docs/validation/compatible/test-results.json\":1634,\"docs/validation/compatible/v2-integration-result.json\":32,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":56,\"docs/validation/followup/VALIDATION.md\":16,\"docs/validation/followup/full-suite.raw.json\":2,\"docs/validation/followup/ledger-targeted-summary.json\":170,\"docs/validation/followup/terminal-claim-baseline.log\":20,\"docs/validation/followup/test-results.json\":788,\"docs/validation/followup/validation-summary.json\":188,\"docs/validation/repaired-final/VALIDATION.md\":17,\"docs/validation/repaired-final/test-results.json\":788,\"docs/validation/repaired-final/validation-summary.json\":161,\"docs/validation/vrf-stall-repair/RECOVERY.md\":84,\"docs/validation/vrf-stall-repair/original-VrfStall.sol\":63,\"docs/validation/vrf-stall-repair/original-proof.log\":60,\"foundry.toml\":18,\"hook-constructor.json\":43,\"inventory.json\":641,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":115,\"src/game/MugiAirdrop.sol\":121,\"src/game/MugiCrewToken.sol\":170,\"src/game/MugiIMDVerifier.sol\":157,\"src/game/MugiReserveMath.sol\":27,\"src/game/MugiVRFAdapter.sol\":146,\"src/imd/MugiIMDAccountingFactory.sol\":49,\"src/imd/MugiIMDCrewFactory.sol\":43,\"src/imd/MugiIMDCrewToken.sol\":13,\"src/imd/MugiIMDEngineFactory.sol\":35,\"src/imd/MugiIMDGameHook.sol\":639,\"src/imd/MugiIMDSwapRouter.sol\":132,\"src/imd/MugiV1IMDDeploymentFactory.sol\":155,\"src/imd/libraries/MugiIMDDeploymentAddresses.sol\":15,\"src/imd/libraries/MugiIMDV4Fees.sol\":64,\"src/imd/modules/MugiIMDBuybacks.sol\":188,\"src/imd/modules/MugiIMDLedger.sol\":350,\"src/imd/modules/MugiIMDPriceOracle.sol\":170,\"src/imd/modules/MugiIMDV4Engine.sol\":408,\"test/imd/MugiIMDCrewToken.t.sol\":308,\"test/imd/MugiIMDProjectFactoryFork.t.sol\":141,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":266,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":205,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":568,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":279,\"test/imd/lifecycle/MugiSwapRouter.t.sol\":288,\"test/imd/modules/MugiIMDEngineSecurity.t.sol\":216,\"test/imd/modules/MugiIMDLedgerFixture.sol\":115,\"test/imd/modules/MugiIMDLedgerSeason.t.sol\":68,\"test/imd/modules/MugiIMDLedgerSecurity.t.sol\":117,\"test/imd/modules/MugiIMDLedgerSnapshots.t.sol\":144,\"test/imd/modules/MugiIMDLedgerTerminal.t.sol\":258,\"test/imd/modules/MugiIMDStateModules.t.sol\":144,\"test/imd/modules/MugiIMDVerifier.t.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"a16d382bc8d3b9bb6905340f898c381f6748ba0190b97334668a7749cf2440f3","verifiedTreeHash":"f594827cefa26d15af2b6c909c9850448d422595","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":141650,"exitCode":0,"name":"build","output":"Compiling 136 files with Solc 0.8.26\nSolc 0.8.26 finished in 141.53s\nCompiler run successful with warnings:\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:783:29:\n    |\n783 |     function previewAccount(address account) external view returns (uint256[10] memory, uint256, uint256[10] memory) {\n    |                             ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:787:29:\n    |\n787 |     function eligibleSupply(uint8 crew) external view returns (uint256) {\n    |                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:795:28:\n    |\n795 |     function escrowBacking(uint8 crew) external view returns (uint256) {\n    |                            ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:803:22:\n    |\n803 |     function poolKey(uint8 crew) external view returns (PoolKey memory) {\n    |                      ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:807:21:\n    |\n807 |     function poolId(uint8 crew) external view returns (PoolId) {\n    |                     ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:811:24:\n    |\n811 |     function poolState(uint8 crew) external view returns (uint160, int24, uint128) {\n    |                        ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:815:32:\n    |\n815 |     function positionLiquidity(uint8 crew) external view returns (uint128) {\n    |                                ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:26:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:61:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:73:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:819:93:\n    |\n819 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                                             ^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:827:26:\n    |\n827 |     function roundBudget(uint64 id) external view returns (MugiBuybacks.Budget memory) {\n    |                          ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/imd/MugiIMDCrewToken.t.sol:276:5:\n    |\n276 |     function testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256 initial, uint256 order) public view {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n  --> test/imd/modules/MugiIMDVerifier.t.sol:74:5:\n   |\n74 |     function testSignatureVerificationFitsCallbackStipend() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":7867,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/imd/lifecycle/MugiGameHookMainnetFork.t.sol:MugiGameHookMainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 374.00µs (0.00ns CPU time)\n\nRan 1 test for test/imd/MugiIMDProjectFactoryFork.t.sol:MugiIMDProjectFactoryForkTest\n[SKIP] testMainnetFactoryRecordsFourEntriesThenConstructorCompleteGraphSeedsTenPools() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 474.90µs (130.93µs CPU time)\n\nRan 4 tests for test/imd/modules/MugiIMDLedgerSeason.t.sol:MugiIMDLedgerSeasonTest\n[PASS] testConstructorFixesAllProtocolExclusionsWithoutInitialization() (gas: 2309714)\n[PASS] testConstructorRejectsZeroOrDuplicateTokensAndTokenProtocolRoleCollision() (gas: 26831)\n[PASS] testConstructorWorksBeforeAnyDependencyCodeExists() (gas: 16570)\n[PASS] testDuplicateTreasuryAddressesAreSubtractedOnlyOnce() (gas: 1141863)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 4.43ms (3.27ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDEngineSecurity.t.sol:MugiIMDEngineSecurityTest\n[PASS] testAllEconomicMutatorsRejectNonHookCaller() (gas: 150353)\n[PASS] testCallbackCannotBeInjectedEvenByManagerWithoutPendingUnlock() (gas: 62786)\n[PASS] testCounterfactualConstructorDoesNotCallDependencyAddresses() (gas: 13706)\n[PASS] testOnlyOwnerCanDeployPredictedEngineOnce() (gas: 6455846)\n[PASS] testPartialBuyPaysHookAndRefundsUnusedEth() (gas: 808775)\n[PASS] testRefundCallbackCannotReenterPositionOperations() (gas: 661418)\n[PASS] testRemovePaysHookAndLeavesNoPositionOrNewBalancesInEngine() (gas: 787517)\n[PASS] testSeedRefundsUnusedInputsAndPreservesPriorEngineBalances() (gas: 623887)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 5.53ms (4.37ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDLedgerSecurity.t.sol:MugiIMDLedgerSecurityTest\n[PASS] testAllRemainingLedgerMutatorsRejectOutsideCaller() (gas: 171999)\n[PASS] testCutoffCannotBeFutureRepeatedOrEarlierThanPriorAccountingEvent() (gas: 4908600)\n[PASS] testExcludedProtocolInventoryCannotCaptureEliminationRewards() (gas: 4078480)\n[PASS] testMaterializationAtOrAfterProposedCutoffCannotBeReusedAsAnEarlierVirtualSnapshot() (gas: 5210809)\n[PASS] testPremintedProtocolInventoryIsExcludedWithoutAnyTokenCallback() (gas: 1336129)\n[PASS] testRemovedInitializationReclassificationAndCallbackSelectorsAreUnavailableEvenToHook() (gas: 148153)\n[PASS] testZeroTokenClaimsAndEthSynchronizationDoNotChangeVirtualSnapshotTiming() (gas: 5446112)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 8.80ms (7.53ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271053)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194348)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339207)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977419)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4175087)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11213728)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325174)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4875341)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221311)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 37.61ms (29.58ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 29077213)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127626)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 476627)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 40.07ms (28.34ms CPU time)\n\nRan 13 tests for test/imd/modules/MugiIMDVerifier.t.sol:MugiIMDVerifierTest\n[PASS] testCanonicalIMDProtocolDigestAndSignatureVector() (gas: 14041)\n[PASS] testCrossChainReplayRejected() (gas: 32053)\n[PASS] testExpiryFutureIssueAndStaleAnswerRejected() (gas: 121424)\n[PASS] testMalformedAndFutureBlockMetadataRejected() (gas: 121394)\n[PASS] testOnlyOwnerCanPin() (gas: 34717)\n[PASS] testOwnerCannotRotateSignerOrWeakenEvidencePolicy() (gas: 107728)\n[PASS] testPanelPolicyRejectsMinorityAndImpossibleCounts() (gas: 151298)\n[PASS] testRevocationCannotBeRepinned() (gas: 98612)\n[PASS] testSignatureVerificationFitsCallbackStipend() (gas: 40767)\n[PASS] testTamperedSignatureRejected() (gas: 38804)\n[PASS] testUnpinnedAndWrongQuestionOrAnswerRejected() (gas: 118096)\n[PASS] testValidPinnedPlanAndConsumerReplayGuard() (gas: 161102)\n[PASS] testWrongConsumerAndDomainAreRejected() (gas: 139844)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 51.75ms (5.88ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiSettlementPricing.t.sol:MugiSettlementPricingTest\n[PASS] testLastSecondPumpDefersMatchedLiquidityAndRoundTripLoses() (gas: 26804540)\n[PASS] testOrdinaryTradingKeepsSettlementReinforcement() (gas: 5376310)\n[PASS] testUnmovedSurvivorStillReceivesMatchedLiquidity() (gas: 26696162)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 147.49ms (48.38ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 449552)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1042211)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 852134)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 620467)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1012796, ~: 1013627)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5348711)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 902672)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 807282)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 994330)\n[PASS] testSellMinimumOutputFailurePreservesAllowanceAndBalances() (gas: 439306)\n[PASS] testThirdPartyManagerUnlockCannotUseRouter() (gas: 396113)\n[PASS] testUnsolicitedCallbacksRejectedIncludingManagerWithoutPendingTrade() (gas: 71596)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 166.55ms (161.82ms CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDLedgerSnapshots.t.sol:MugiIMDLedgerSnapshotsTest\n[PASS] testCutoffTransfersBurnsAndKnownLoserSalesCannotMovePastRewardsOrConversion() (gas: 7006991)\n[PASS] testEmergencyUnwindUsesOriginalCutoffEvenAfterTransfersDuringLongRecoveryDelay() (gas: 7770266)\n[PASS] testFuzzAfterCutoffTransferCannotSellOrDuplicateConversion(uint96,uint96) (runs: 256, μ: 4060778, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 183.22ms (171.16ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7421083)\n[PASS] testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver() (gas: 32909507)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 32670234)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 34343862)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 201.59ms (72.26ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 105979468)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 75950776)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 18477719)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 96114655)\nLogs:\n  Four service module creations: 3693823\n  Ten crew token creations: 9091796\n  Engine creation: 2497921\n  Three accounting module creations: 3913431\n  Hook creation: 5909685\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 228028)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14258298)\nLogs:\n  Four factory runtime bytes: 60782\n  Four factory initcode bytes: 86568\n  Four factory CREATE2 execution gas: 12345124\n  Estimated launch transaction gas: 14761516\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 32122920)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 85205139)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 96179416)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 96179350)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 98172980)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 71611502)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 201.63ms (722.63ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6199211)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 29637696)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 38474379)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6145495)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1355576)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20168935)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5695535)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170491)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 536.81ms (91.94ms CPU time)\n\nRan 12 tests for test/imd/MugiIMDManifestFactories.t.sol:MugiIMDManifestFactoriesTest\n[PASS] testCrewFactoryRejectsZeroHookAndOutOfRangeSupplyAtomically() (gas: 9403411)\n[PASS] testCrewSetBoundToAnotherHookBlocksHookCreation() (gas: 90735185)\n[PASS] testCrewSupplyMismatchIsCaughtAtFirstEconomicUse() (gas: 96216118)\n[PASS] testDeployModulesRejectsEveryInvalidStaticInput() (gas: 71108824)\n[PASS] testEngineBoundToAnotherManagerIsCaughtAtFirstEconomicUse() (gas: 100007492)\n[PASS] testEveryManifestFactoryRejectsZeroOwner() (gas: 4200)\n[PASS] testFuzzDeployModulesRejectsSaltWithoutHookPermissionBits(bytes32) (runs: 512, μ: 99635, ~: 99737)\n[PASS] testHookConfigurationCannotChangeOwnerManagerOrSupply() (gas: 489550308)\n[PASS] testHookOwnershipIsTwoStepAndOwnerOnly() (gas: 97674394)\n[PASS] testHookRequiresAccountingAndEngineModulesToExist() (gas: 97046082)\n[PASS] testManifestOrderFactoriesBindOnlyTheStaticOwnerAndCreateNoChildren() (gas: 155901)\n[PASS] testPrelaunchGatesRejectEveryEconomicEntryPoint() (gas: 98706454)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 536.84ms (900.48ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDStateModules.t.sol:MugiIMDStateModulesTest\n[PASS] testAllBudgetMutatorsRequireHook() (gas: 103800)\n[PASS] testApprovalUsesHookHashDomainAndConsumerThroughOrdinaryCall() (gas: 523832)\n[PASS] testBudgetAuthorizesAccountsAndPreservesTradeCadence() (gas: 744683)\n[PASS] testConstructorsAcceptCounterfactualHookAndRejectZero() (gas: 2480317)\n[PASS] testOracleNegativeMeanRoundsDown() (gas: 139986)\n[PASS] testOracleOnlyHookCanUpdateButAnyoneCanRead() (gas: 126667)\n[PASS] testOracleRequiresHistoryAndRejectsSpotDeviation() (gas: 136584)\n[PASS] testSettlementPriceGuardUsesTwapEndingAtCutoff() (gas: 275805)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 536.84ms (2.08ms CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDPriceOracleGuard.t.sol:MugiIMDPriceOracleGuardTest\n[PASS] testFuzzGuardAtNowMatchesConsultBand(int24[8],uint32[8],int24) (runs: 512, μ: 456013, ~: 463326)\n[PASS] testFuzzGuardNeverReverts(int24[8],uint32[8],uint8,uint64,int24) (runs: 512, μ: 439212, ~: 447060)\n[PASS] testFuzzPostCutoffUpdateAlwaysRefuses(int24[8],uint32[8],uint32,int24) (runs: 256, μ: 498313, ~: 506974)\n[PASS] testGuardRejectsEdgeInputsWithoutReverting() (gas: 163561)\n[PASS] testUpdateIsHookOnlyAndValidatesInputs() (gas: 100387)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 541.03ms (1.16s CPU time)\n\nRan 16 tests for test/imd/MugiIMDCrewToken.t.sol:MugiIMDCrewTokenTest\n[PASS] testBurnHistoryTracksMultipleTimestampsAndCoalescesSameTimestamp() (gas: 441690)\n[PASS] testConstructorAcceptsPredeterminedUndeployedHook() (gas: 16336)\n[PASS] testConstructorCreatesWholeFiniteReserveAndNoEarlierHistory() (gas: 100182)\n[PASS] testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256,uint256) (runs: 256, μ: 54369, ~: 54245)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3596858, ~: 3714725)\n[PASS] testInfiniteAllowanceAndFailedTransferPreserveHistory() (gas: 351050)\n[PASS] testInvalidConstructorConfigurationRejects() (gas: 4632)\n[PASS] testRejectsZeroTransferAndApprovalDestinations() (gas: 53819)\n[PASS] testRemovedMintInitializerAndArbitraryBurnSelectorsAreUnavailable() (gas: 219912)\n[PASS] testReserveHolderHasNoAuthorityOverOtherBalances() (gas: 223787)\n[PASS] testSameTimestampGenesisAndTransfersUseEndOfTimestampBalance() (gas: 313272)\n[PASS] testStaticConstructorPreservesAllCanonicalCrewNamesAndSymbols() (gas: 276675)\n[PASS] testStrictCutoffExcludesEveryExactCutoffTransferAndBurn() (gas: 568341)\n[PASS] testTransferFromCheckpointsBothWalletsAndFiniteAllowance() (gas: 367855)\n[PASS] testTransfersAndBurnDoNotCallRevertingOrBrokenHook() (gas: 539864)\n[PASS] testZeroAndSelfTransfersDoNotChangeHistoricalOwnership() (gas: 248761)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 541.02ms (256.41ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDLedgerTerminal.t.sol:MugiIMDLedgerTerminalTest\n[PASS] testEmergencyAfterPriorEthWithdrawalExpiresOnlyRemainingMixedRights() (gas: 6872513)\n[PASS] testEmergencyExpirationCannotResurrectSyncedOrLazyClaims() (gas: 10818557)\n[PASS] testEmergencyRejectsWrongMaskAndCannotRecordAnotherTerminalOrRound() (gas: 937792)\n[PASS] testEmergencyRewardsIncludeFrozenWalletAndVirtualBalancesAndEarlierEth() (gas: 8641692)\n[PASS] testEmergencyUnallocatedCrewSharesAndRemaindersNeverEnterPlayerReserve() (gas: 4862305)\n[PASS] testExpirationCannotResurrectSyncedOrLazyClaimsInEitherTerminalMode() (gas: 16635639)\n[PASS] testFuzzEagerMaterializationAndLateSyncHaveIdenticalEmergencyRights(uint8,uint96) (runs: 256, μ: 23296516, ~: 21691922)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 541.15ms (581.40ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiSettlementGuardFuzz.t.sol:MugiSettlementGuardFuzzTest\n[PASS] testBatchedSettlementReinforcesEachSurvivorOnce() (gas: 5569512)\n[PASS] testFuzzLateLargePumpDefersAndLoses(uint256,uint256) (runs: 64, μ: 26865430, ~: 26869472)\n[PASS] testFuzzSmallPumpStillReinforcesAndStaysSolvent(uint256) (runs: 32, μ: 26631518, ~: 26631639)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.02s (1.59s CPU time)\n\nRan 3 tests for test/imd/invariant/MugiPrelaunchAbortInvariant.t.sol:MugiPrelaunchAbortInvariantTest\n[PASS]\nMugiPrelaunchAbortInvariantTest invariants:\n[PASS] invariant_abortRetiresReserveAndSupplyIsFinite\n[PASS] invariant_closedSeasonNeverReopensAndStrangersHaveNoPower\n[PASS] invariant_seededEthIsConservedAndRefundedOnAbort\n MugiPrelaunchAbortInvariantTest invariants (runs: 64, calls: 2560, reverts: 0)\n\n╭----------------------+-----------------+-------+---------+----------╮\n| Contract             | Selector        | Calls | Reverts | Discards |\n+=====================================================================+\n| MugiPrelaunchHandler | abort           | 418   | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| MugiPrelaunchHandler | seed            | 459   | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| MugiPrelaunchHandler | seedAll         | 464   | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| MugiPrelaunchHandler | strangerActions | 402   | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| MugiPrelaunchHandler | tryLaunch       | 405   | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| MugiPrelaunchHandler | warp            | 412   | 0       | 0        |\n╰----------------------+-----------------+-------+---------+----------╯\n\nLogs:\n  seeds: 0\n  aborts: 1\n  launches: 0\n\n[PASS] testLaunchedSeasonCannotAbort() (gas: 8251181)\n[PASS] testPartialSeedAbortRetiresAndRefunds() (gas: 4278977)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.37s (1.38s CPU time)\n\nRan 1 test for test/imd/invariant/MugiCrewTokenInvariant.t.sol:MugiCrewTokenInvariantTest\n[PASS]\nMugiCrewTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToTotalSupply\n[PASS] invariant_burnOnlyAffectsCaller\n[PASS] invariant_genesisHasNoEarlierHistory\n[PASS] invariant_pastSnapshotsAreImmutable\n[PASS] invariant_supplyOnlyFallsByBurns\n MugiCrewTokenInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------------+--------------+-------+---------+----------╮\n| Contract             | Selector     | Calls | Reverts | Discards |\n+==================================================================+\n| MugiCrewTokenHandler | burn         | 1388  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | overspend    | 1333  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | snapshot     | 1352  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | transfer     | 1362  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | transferFrom | 1384  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | warp         | 1373  | 0       | 0        |\n╰----------------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.95s (1.95s CPU time)\n\nRan 1 test for test/imd/invariant/MugiGameInvariant.t.sol:MugiGameInvariantTest\n[PASS]\nMugiGameInvariantTest invariants:\n[PASS] invariant_closedCrewsRetainNoUnusedReserve\n[PASS] invariant_finiteSupplyNeverGrowsAndIsFullyHeld\n[PASS] invariant_hookEthCoversPlayerAndTeamLiabilities\n[PASS] invariant_hookTokensBackEscrowReserveAndTeamFees\n[PASS] invariant_routerNeverRetainsCustody\n[PASS] invariant_seasonOnlyMovesForward\n MugiGameInvariantTest invariants (runs: 48, calls: 4800, reverts: 0)\n\n╭-----------------+------------------+-------+---------+----------╮\n| Contract        | Selector         | Calls | Reverts | Discards |\n+=================================================================+\n| MugiGameHandler | advance          | 305   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | advanceRounds    | 311   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | burn             | 283   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | buy              | 309   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | claimEth         | 288   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | claimTokens      | 328   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | collectTeamFees  | 307   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | migrate          | 302   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | ownBuyback       | 302   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | retireAirdrop    | 324   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | sell             | 326   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | stall            | 299   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | sweep            | 259   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | transfer         | 266   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | warp             | 289   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | withdrawTeamFees | 302   | 0       | 0        |\n╰-----------------+------------------+-------+---------+----------╯\n\nLogs:\n  buy: 2\n  sell: 0\n  claimEth: 2\n  claimTokens: 6\n  ownBuyback: 0\n  round: 9\n  finalize: 1\n  migrate: 1\n  sweep: 0\n  emergency: 0\n  eliminations: 9\n  phase: 5\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.11s (5.08s CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934426)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1624992)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6581205)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9502909)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294172)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 27469633)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439053)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 43074141)\nLogs:\n  Settlement and request gas: 5597306\n  Settlement and request gas: 4853376\n  Settlement and request gas: 4433060\n  Settlement and request gas: 3965797\n  Settlement and request gas: 3493406\n  Settlement and request gas: 3034688\n  Settlement and request gas: 2583433\n  Settlement and request gas: 2103460\n  Settlement and request gas: 1628858\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 375525)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1373297)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11645392)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5705912)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341595)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5596855)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 7816818)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1568147)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241599)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 7.68s (74.82ms CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 564045)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7097095)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 30837115)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 222003965, ~: 221210526)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 36196392)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 27237222)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.73s (7.78s CPU time)\n\nRan 25 test suites in 7.73s (29.15s CPU time): 171 tests passed, 0 failed, 2 skipped (173 total tests)\n","passed":true},{"durationMs":101,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MugiAirdrop.claim(uint64,bytes)\",\"MugiAirdrop.launch()\",\"MugiAirdrop.register(uint8,bytes32,uint64,bytes)\",\"MugiAirdrop.retireRemaining()\",\"MugiCrewToken.approve(address,uint256)\",\"MugiCrewToken.burn(uint256)\",\"MugiCrewToken.transfer(address,uint256)\",\"MugiCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDAccountingFactory.deployForHook((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address))\",\"MugiIMDBuybacks.account(uint64,uint8,uint256)\",\"MugiIMDBuybacks.approve((uint64,uint64,uint64,uint256[10]),address,bytes)\",\"MugiIMDBuybacks.authorize(uint64,uint8,uint256)\",\"MugiIMDBuybacks.create(uint64,uint256,uint16)\",\"MugiIMDCrewFactory.deployCrewSet(address,uint256)\",\"MugiIMDCrewToken.approve(address,uint256)\",\"MugiIMDCrewToken.burn(uint256)\",\"MugiIMDCrewToken.transfer(address,uint256)\",\"MugiIMDCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDEngineFactory.deployForHook(address,address)\",\"MugiIMDGameHook.abortPrelaunch()\",\"MugiIMDGameHook.acceptOwnership()\",\"MugiIMDGameHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MugiIMDGameHook.approvePlan((uint64,uint64,uint64,uint256[10]),bytes)\",\"MugiIMDGameHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MugiIMDGameHook.cancelOwnershipTransfer()\",\"MugiIMDGameHook.claimEth(address)\",\"MugiIMDGameHook.claimToken(uint8,uint256)\",\"MugiIMDGameHook.claimTokens()\",\"MugiIMDGameHook.collectTeamFees(uint8)\",\"MugiIMDGameHook.executeBuyback(uint64,uint8,uint256)\",\"MugiIMDGameHook.executeOwnBuyback(uint8,uint256)\",\"MugiIMDGameHook.finalize()\",\"MugiIMDGameHook.launch()\",\"MugiIMDGameHook.migrateToV2(address)\",\"MugiIMDGameHook.receive()\",\"MugiIMDGameHook.receiveRandomness(uint256,uint256)\",\"MugiIMDGameHook.recoverStalledRandomness(uint8)\",\"MugiIMDGameHook.requestElimination()\",\"MugiIMDGameHook.retireAirdrop()\",\"MugiIMDGameHook.seedPool(uint8)\",\"MugiIMDGameHook.settleRound(uint8)\",\"MugiIMDGameHook.sweepExpiredFinalClaims()\",\"MugiIMDGameHook.transferOwnership(address)\",\"MugiIMDGameHook.unlockCallback(bytes)\",\"MugiIMDGameHook.withdrawTeamFees()\",\"MugiIMDLedger.claimEth(address)\",\"MugiIMDLedger.claimToken(address,uint8,uint256)\",\"MugiIMDLedger.claimTokens(address)\",\"MugiIMDLedger.emergencyFinalize(uint16,uint256,uint64)\",\"MugiIMDLedger.expireFinalClaims()\",\"MugiIMDLedger.finalizeMigration(uint8,uint64)\",\"MugiIMDLedger.recordElimination(uint8,uint16,uint256,uint64)\",\"MugiIMDPriceOracle.update(uint8,int24)\",\"MugiIMDSwapRouter.buy(uint8,uint256,uint64)\",\"MugiIMDSwapRouter.sell(uint8,uint256,uint256,uint64)\",\"MugiIMDSwapRouter.unlockCallback(bytes)\",\"MugiIMDV4Engine.addLiquidity(uint8,uint128,uint256,uint256)\",\"MugiIMDV4Engine.buy(uint8,uint256,uint256,uint160)\",\"MugiIMDV4Engine.collectFees(uint8)\",\"MugiIMDV4Engine.registerInitialPool(uint8,address,uint256,uint256)\",\"MugiIMDV4Engine.registerPool(uint8,address,uint24,int24,uint160)\",\"MugiIMDV4Engine.removeLiquidity(uint8,uint256,uint256)\",\"MugiIMDV4Engine.unlockCallback(bytes)\",\"MugiIMDVerifier.pinRequest(bytes32,bytes32,bytes32,uint64)\",\"MugiIMDVerifier.renounceOwnership()\",\"MugiIMDVerifier.revokeRequest(bytes32)\",\"MugiIMDVerifier.transferOwnership(address)\",\"MugiV1IMDDeploymentFactory.deployHook(bytes)\",\"MugiV1IMDDeploymentFactory.deployModules(bytes32,bytes32,(address,address,bytes32,uint256,uint32,bool,address,address,uint16,uint16,uint64,address,address,uint256))\",\"MugiVRFAdapter.rawFulfillRandomWords(uint256,uint256[])\",\"MugiVRFAdapter.requestRandomness()\",\"MugiVRFAdapter.retryDelivery(uint256)\"],\"files\":{\".gitignore\":6,\"ADAPTATION.md\":202,\"README.md\":59,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":46,\"docs/IMD_FINDINGS_RESPONSE.md\":61,\"docs/IMD_FOLLOWUP_RESPONSE.md\":104,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":167,\"docs/validation/compatible/VALIDATION.md\":33,\"docs/validation/compatible/artifact-review.json\":966,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2606,\"docs/validation/compatible/full-suite.raw.log\":2,\"docs/validation/compatible/test-results.json\":1634,\"docs/validation/compatible/v2-integration-result.json\":32,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":56,\"docs/validation/followup/VALIDATION.md\":16,\"docs/validation/followup/full-suite.raw.json\":2,\"docs/validation/followup/ledger-targeted-summary.json\":170,\"docs/validation/followup/terminal-claim-baseline.log\":20,\"docs/validation/followup/test-results.json\":788,\"docs/validation/followup/validation-summary.json\":188,\"docs/validation/repaired-final/VALIDATION.md\":17,\"docs/validation/repaired-final/test-results.json\":788,\"docs/validation/repaired-final/validation-summary.json\":161,\"docs/validation/vrf-stall-repair/RECOVERY.md\":84,\"docs/validation/vrf-stall-repair/original-VrfStall.sol\":63,\"docs/validation/vrf-stall-repair/original-proof.log\":60,\"foundry.toml\":18,\"hook-constructor.json\":44,\"inventory.json\":642,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":115,\"src/game/MugiAirdrop.sol\":121,\"src/game/MugiCrewToken.sol\":170,\"src/game/MugiIMDVerifier.sol\":157,\"src/game/MugiReserveMath.sol\":27,\"src/game/MugiVRFAdapter.sol\":146,\"src/imd/MugiIMDAccountingFactory.sol\":49,\"src/imd/MugiIMDCrewFactory.sol\":43,\"src/imd/MugiIMDCrewToken.sol\":13,\"src/imd/MugiIMDEngineFactory.sol\":35,\"src/imd/MugiIMDGameHook.sol\":830,\"src/imd/MugiIMDSwapRouter.sol\":132,\"src/imd/MugiV1IMDDeploymentFactory.sol\":155,\"src/imd/libraries/MugiIMDDeploymentAddresses.sol\":15,\"src/imd/libraries/MugiIMDV4Fees.sol\":64,\"src/imd/modules/MugiIMDBuybacks.sol\":188,\"src/imd/modules/MugiIMDLedger.sol\":350,\"src/imd/modules/MugiIMDPriceOracle.sol\":194,\"src/imd/modules/MugiIMDV4Engine.sol\":408,\"test/imd/MugiIMDCrewToken.t.sol\":308,\"test/imd/MugiIMDManifestFactories.t.sol\":287,\"test/imd/MugiIMDProjectFactoryFork.t.sol\":141,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":266,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/invariant/MugiCrewTokenInvariant.t.sol\":188,\"test/imd/invariant/MugiGameInvariant.t.sol\":447,\"test/imd/invariant/MugiPrelaunchAbortInvariant.t.sol\":233,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":205,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":620,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiSettlementGuardFuzz.t.sol\":125,\"test/imd/lifecycle/MugiSettlementPricing.t.sol\":108,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":279,\"test/imd/lifecycle/MugiSwapRouter.t.sol\":288,\"test/imd/modules/MugiIMDEngineSecurity.t.sol\":216,\"test/imd/modules/MugiIMDLedgerFixture.sol\":115,\"test/imd/modules/MugiIMDLedgerSeason.t.sol\":68,\"test/imd/modules/MugiIMDLedgerSecurity.t.sol\":117,\"test/imd/modules/MugiIMDLedgerSnapshots.t.sol\":144,\"test/imd/modules/MugiIMDLedgerTerminal.t.sol\":258,\"test/imd/modules/MugiIMDPriceOracleGuard.t.sol\":108,\"test/imd/modules/MugiIMDStateModules.t.sol\":171,\"test/imd/modules/MugiIMDVerifier.t.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c36fd6e3b2c3b4487e6cebb5ef0fb0682045d82d96f924aa708f3b2a1f18d099","verifiedTreeHash":"7b0c0818e16b7ea5f70816f13c5f09d4281d88f6","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":109103,"exitCode":0,"name":"build","output":"Compiling 129 files with Solc 0.8.26\nSolc 0.8.26 finished in 108.97s\nCompiler run successful with warnings:\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:625:29:\n    |\n625 |     function previewAccount(address account) external view returns (uint256[10 ...\n    |                             ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:626:29:\n    |\n626 |     function eligibleSupply(uint8 crew) external view returns (uint256) { _forwardView(address(ledger)); }\n    |                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:628:28:\n    |\n628 |     function escrowBacking(uint8 crew) external view returns (uint256) { _forwardView(address(ledger)); }\n    |                            ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:630:22:\n    |\n630 |     function poolKey(uint8 crew) external view returns (PoolKey memory) { _forwardView(address(engine)); }\n    |                      ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:631:21:\n    |\n631 |     function poolId(uint8 crew) external view returns (PoolId) { _forwardView(address(engine)); }\n    |                     ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:632:24:\n    |\n632 |     function poolState(uint8 crew) external view returns (uint160, int24, uint128) { _forwardView(address(engine)); }\n    |                        ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:633:32:\n    |\n633 |     function positionLiquidity(uint8 crew) external view returns (uint128) { _forwardView(address(engine)); }\n    |                                ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:26:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:61:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:73:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:93:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                                             ^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:638:26:\n    |\n638 |     function roundBudget(uint64 id) external view returns (MugiBuybacks.Budget memory) { _forwardView(address(budgets)); }\n    |                          ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/imd/MugiIMDCrewToken.t.sol:276:5:\n    |\n276 |     function testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256 initial, uint256 order) public view {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n  --> test/imd/modules/MugiIMDVerifier.t.sol:74:5:\n   |\n74 |     function testSignatureVerificationFitsCallbackStipend() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":7865,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/imd/lifecycle/MugiGameHookMainnetFork.t.sol:MugiGameHookMainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 419.08µs (0.00ns CPU time)\n\nRan 1 test for test/imd/MugiIMDProjectFactoryFork.t.sol:MugiIMDProjectFactoryForkTest\n[SKIP] testMainnetFactoryRecordsFourEntriesThenConstructorCompleteGraphSeedsTenPools() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 637.89µs (58.79µs CPU time)\n\nRan 4 tests for test/imd/modules/MugiIMDLedgerSeason.t.sol:MugiIMDLedgerSeasonTest\n[PASS] testConstructorFixesAllProtocolExclusionsWithoutInitialization() (gas: 2309714)\n[PASS] testConstructorRejectsZeroOrDuplicateTokensAndTokenProtocolRoleCollision() (gas: 26831)\n[PASS] testConstructorWorksBeforeAnyDependencyCodeExists() (gas: 16570)\n[PASS] testDuplicateTreasuryAddressesAreSubtractedOnlyOnce() (gas: 1141863)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 9.90ms (2.83ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271053)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194348)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339207)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977419)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4101410)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11140007)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325174)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4875341)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221311)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 43.48ms (28.95ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 28708864)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127626)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 476583)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 46.29ms (32.32ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7347371)\n[PASS] testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver() (gas: 32542396)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 32303123)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 33976751)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 79.40ms (83.32ms CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDLedgerSnapshots.t.sol:MugiIMDLedgerSnapshotsTest\n[PASS] testCutoffTransfersBurnsAndKnownLoserSalesCannotMovePastRewardsOrConversion() (gas: 7006991)\n[PASS] testEmergencyUnwindUsesOriginalCutoffEvenAfterTransfersDuringLongRecoveryDelay() (gas: 7770266)\n[PASS] testFuzzAfterCutoffTransferCannotSellOrDuplicateConversion(uint96,uint96) (runs: 256, μ: 4060778, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 79.74ms (91.64ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934426)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1624816)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6506717)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9363700)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294172)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 27101240)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439053)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 42707030)\nLogs:\n  Settlement and request gas: 5523629\n  Settlement and request gas: 4787887\n  Settlement and request gas: 4375760\n  Settlement and request gas: 3916684\n  Settlement and request gas: 3452480\n  Settlement and request gas: 3001948\n  Settlement and request gas: 2558879\n  Settlement and request gas: 2087091\n  Settlement and request gas: 1620674\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 375525)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1372533)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11155742)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5632191)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341595)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5522752)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 7743106)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1568059)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241599)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 80.74ms (82.85ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 449508)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1042167)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 852090)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 620379)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1012701, ~: 1013539)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5274990)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 902628)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 807194)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 994286)\n[PASS] testSellMinimumOutputFailurePreservesAllowanceAndBalances() (gas: 439262)\n[PASS] testThirdPartyManagerUnlockCannotUseRouter() (gas: 396113)\n[PASS] testUnsolicitedCallbacksRejectedIncludingManagerWithoutPendingTrade() (gas: 71596)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 106.34ms (104.79ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDStateModules.t.sol:MugiIMDStateModulesTest\n[PASS] testAllBudgetMutatorsRequireHook() (gas: 103800)\n[PASS] testApprovalUsesHookHashDomainAndConsumerThroughOrdinaryCall() (gas: 523802)\n[PASS] testBudgetAuthorizesAccountsAndPreservesTradeCadence() (gas: 744543)\n[PASS] testConstructorsAcceptCounterfactualHookAndRejectZero() (gas: 2385626)\n[PASS] testOracleNegativeMeanRoundsDown() (gas: 139608)\n[PASS] testOracleOnlyHookCanUpdateButAnyoneCanRead() (gas: 126199)\n[PASS] testOracleRequiresHistoryAndRejectsSpotDeviation() (gas: 135910)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 130.14ms (1.94ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 69993263)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 40179916)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 143450616)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 60128436)\nLogs:\n  Four service module creations: 3693167\n  Ten crew token creations: 9091601\n  Engine creation: 2497921\n  Three accounting module creations: 3831414\n  Hook creation: 5778342\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 223633)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14156646)\nLogs:\n  Four factory runtime bytes: 60375\n  Four factory initcode bytes: 85703\n  Four factory CREATE2 execution gas: 12262905\n  Estimated launch transaction gas: 14665457\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 25147600)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 49349293)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 60193548)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 60193482)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 62102607)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 35799830)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 155.13ms (662.24ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDLedgerSecurity.t.sol:MugiIMDLedgerSecurityTest\n[PASS] testAllRemainingLedgerMutatorsRejectOutsideCaller() (gas: 171999)\n[PASS] testCutoffCannotBeFutureRepeatedOrEarlierThanPriorAccountingEvent() (gas: 4908600)\n[PASS] testExcludedProtocolInventoryCannotCaptureEliminationRewards() (gas: 4078480)\n[PASS] testMaterializationAtOrAfterProposedCutoffCannotBeReusedAsAnEarlierVirtualSnapshot() (gas: 5210809)\n[PASS] testPremintedProtocolInventoryIsExcludedWithoutAnyTokenCallback() (gas: 1336129)\n[PASS] testRemovedInitializationReclassificationAndCallbackSelectorsAreUnavailableEvenToHook() (gas: 148153)\n[PASS] testZeroTokenClaimsAndEthSynchronizationDoNotChangeVirtualSnapshotTiming() (gas: 5446112)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 422.50ms (11.36ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDEngineSecurity.t.sol:MugiIMDEngineSecurityTest\n[PASS] testAllEconomicMutatorsRejectNonHookCaller() (gas: 150353)\n[PASS] testCallbackCannotBeInjectedEvenByManagerWithoutPendingUnlock() (gas: 62786)\n[PASS] testCounterfactualConstructorDoesNotCallDependencyAddresses() (gas: 13706)\n[PASS] testOnlyOwnerCanDeployPredictedEngineOnce() (gas: 6455846)\n[PASS] testPartialBuyPaysHookAndRefundsUnusedEth() (gas: 808775)\n[PASS] testRefundCallbackCannotReenterPositionOperations() (gas: 661418)\n[PASS] testRemovePaysHookAndLeavesNoPositionOrNewBalancesInEngine() (gas: 787517)\n[PASS] testSeedRefundsUnusedInputsAndPreservesPriorEngineBalances() (gas: 623887)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 480.86ms (2.60ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDLedgerTerminal.t.sol:MugiIMDLedgerTerminalTest\n[PASS] testEmergencyAfterPriorEthWithdrawalExpiresOnlyRemainingMixedRights() (gas: 6872513)\n[PASS] testEmergencyExpirationCannotResurrectSyncedOrLazyClaims() (gas: 10818557)\n[PASS] testEmergencyRejectsWrongMaskAndCannotRecordAnotherTerminalOrRound() (gas: 937792)\n[PASS] testEmergencyRewardsIncludeFrozenWalletAndVirtualBalancesAndEarlierEth() (gas: 8641692)\n[PASS] testEmergencyUnallocatedCrewSharesAndRemaindersNeverEnterPlayerReserve() (gas: 4862305)\n[PASS] testExpirationCannotResurrectSyncedOrLazyClaimsInEitherTerminalMode() (gas: 16635639)\n[PASS] testFuzzEagerMaterializationAndLateSyncHaveIdenticalEmergencyRights(uint8,uint96) (runs: 256, μ: 23009153, ~: 21690551)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 481.01ms (506.24ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6125490)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 29269303)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 38107268)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6071774)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1355084)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20108725)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5621858)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170491)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 7.52s (68.78ms CPU time)\n\nRan 13 tests for test/imd/modules/MugiIMDVerifier.t.sol:MugiIMDVerifierTest\n[PASS] testCanonicalIMDProtocolDigestAndSignatureVector() (gas: 14041)\n[PASS] testCrossChainReplayRejected() (gas: 32053)\n[PASS] testExpiryFutureIssueAndStaleAnswerRejected() (gas: 121424)\n[PASS] testMalformedAndFutureBlockMetadataRejected() (gas: 121394)\n[PASS] testOnlyOwnerCanPin() (gas: 34717)\n[PASS] testOwnerCannotRotateSignerOrWeakenEvidencePolicy() (gas: 107728)\n[PASS] testPanelPolicyRejectsMinorityAndImpossibleCounts() (gas: 151298)\n[PASS] testRevocationCannotBeRepinned() (gas: 98612)\n[PASS] testSignatureVerificationFitsCallbackStipend() (gas: 40767)\n[PASS] testTamperedSignatureRejected() (gas: 38804)\n[PASS] testUnpinnedAndWrongQuestionOrAnswerRejected() (gas: 118096)\n[PASS] testValidPinnedPlanAndConsumerReplayGuard() (gas: 161102)\n[PASS] testWrongConsumerAndDomainAreRejected() (gas: 139844)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 7.63s (7.54ms CPU time)\n\nRan 16 tests for test/imd/MugiIMDCrewToken.t.sol:MugiIMDCrewTokenTest\n[PASS] testBurnHistoryTracksMultipleTimestampsAndCoalescesSameTimestamp() (gas: 441690)\n[PASS] testConstructorAcceptsPredeterminedUndeployedHook() (gas: 16336)\n[PASS] testConstructorCreatesWholeFiniteReserveAndNoEarlierHistory() (gas: 100182)\n[PASS] testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256,uint256) (runs: 256, μ: 54366, ~: 54289)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3587133, ~: 3710216)\n[PASS] testInfiniteAllowanceAndFailedTransferPreserveHistory() (gas: 351050)\n[PASS] testInvalidConstructorConfigurationRejects() (gas: 4632)\n[PASS] testRejectsZeroTransferAndApprovalDestinations() (gas: 53819)\n[PASS] testRemovedMintInitializerAndArbitraryBurnSelectorsAreUnavailable() (gas: 219912)\n[PASS] testReserveHolderHasNoAuthorityOverOtherBalances() (gas: 223787)\n[PASS] testSameTimestampGenesisAndTransfersUseEndOfTimestampBalance() (gas: 313272)\n[PASS] testStaticConstructorPreservesAllCanonicalCrewNamesAndSymbols() (gas: 276675)\n[PASS] testStrictCutoffExcludesEveryExactCutoffTransferAndBurn() (gas: 568341)\n[PASS] testTransferFromCheckpointsBothWalletsAndFiniteAllowance() (gas: 367855)\n[PASS] testTransfersAndBurnDoNotCallRevertingOrBrokenHook() (gas: 539864)\n[PASS] testZeroAndSelfTransfersDoNotChangeHistoricalOwnership() (gas: 248761)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 7.73s (7.77s CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 563187)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7023286)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 30468634)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 219966492, ~: 219235119)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 35827999)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 26868829)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.73s (7.81s CPU time)\n\nRan 18 test suites in 7.74s (32.74s CPU time): 142 tests passed, 0 failed, 2 skipped (144 total tests)\n","passed":true},{"durationMs":83,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MugiAirdrop.claim(uint64,bytes)\",\"MugiAirdrop.launch()\",\"MugiAirdrop.register(uint8,bytes32,uint64,bytes)\",\"MugiAirdrop.retireRemaining()\",\"MugiCrewToken.approve(address,uint256)\",\"MugiCrewToken.burn(uint256)\",\"MugiCrewToken.transfer(address,uint256)\",\"MugiCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDAccountingFactory.deployForHook((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address))\",\"MugiIMDBuybacks.account(uint64,uint8,uint256)\",\"MugiIMDBuybacks.approve((uint64,uint64,uint64,uint256[10]),address,bytes)\",\"MugiIMDBuybacks.authorize(uint64,uint8,uint256)\",\"MugiIMDBuybacks.create(uint64,uint256,uint16)\",\"MugiIMDCrewFactory.deployCrewSet(address,uint256)\",\"MugiIMDCrewToken.approve(address,uint256)\",\"MugiIMDCrewToken.burn(uint256)\",\"MugiIMDCrewToken.transfer(address,uint256)\",\"MugiIMDCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDEngineFactory.deployForHook(address,address)\",\"MugiIMDGameHook.abortPrelaunch()\",\"MugiIMDGameHook.acceptOwnership()\",\"MugiIMDGameHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MugiIMDGameHook.approvePlan((uint64,uint64,uint64,uint256[10]),bytes)\",\"MugiIMDGameHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MugiIMDGameHook.cancelOwnershipTransfer()\",\"MugiIMDGameHook.claimEth(address)\",\"MugiIMDGameHook.claimToken(uint8,uint256)\",\"MugiIMDGameHook.claimTokens()\",\"MugiIMDGameHook.collectTeamFees(uint8)\",\"MugiIMDGameHook.executeBuyback(uint64,uint8,uint256)\",\"MugiIMDGameHook.executeOwnBuyback(uint8,uint256)\",\"MugiIMDGameHook.finalize()\",\"MugiIMDGameHook.launch()\",\"MugiIMDGameHook.migrateToV2(address)\",\"MugiIMDGameHook.receive()\",\"MugiIMDGameHook.receiveRandomness(uint256,uint256)\",\"MugiIMDGameHook.recoverStalledRandomness(uint8)\",\"MugiIMDGameHook.requestElimination()\",\"MugiIMDGameHook.retireAirdrop()\",\"MugiIMDGameHook.seedPool(uint8)\",\"MugiIMDGameHook.settleRound(uint8)\",\"MugiIMDGameHook.sweepExpiredFinalClaims()\",\"MugiIMDGameHook.transferOwnership(address)\",\"MugiIMDGameHook.unlockCallback(bytes)\",\"MugiIMDGameHook.withdrawTeamFees()\",\"MugiIMDLedger.claimEth(address)\",\"MugiIMDLedger.claimToken(address,uint8,uint256)\",\"MugiIMDLedger.claimTokens(address)\",\"MugiIMDLedger.emergencyFinalize(uint16,uint256,uint64)\",\"MugiIMDLedger.expireFinalClaims()\",\"MugiIMDLedger.finalizeMigration(uint8,uint64)\",\"MugiIMDLedger.recordElimination(uint8,uint16,uint256,uint64)\",\"MugiIMDPriceOracle.update(uint8,int24)\",\"MugiIMDSwapRouter.buy(uint8,uint256,uint64)\",\"MugiIMDSwapRouter.sell(uint8,uint256,uint256,uint64)\",\"MugiIMDSwapRouter.unlockCallback(bytes)\",\"MugiIMDV4Engine.addLiquidity(uint8,uint128,uint256,uint256)\",\"MugiIMDV4Engine.buy(uint8,uint256,uint256,uint160)\",\"MugiIMDV4Engine.collectFees(uint8)\",\"MugiIMDV4Engine.registerInitialPool(uint8,address,uint256,uint256)\",\"MugiIMDV4Engine.registerPool(uint8,address,uint24,int24,uint160)\",\"MugiIMDV4Engine.removeLiquidity(uint8,uint256,uint256)\",\"MugiIMDV4Engine.unlockCallback(bytes)\",\"MugiIMDVerifier.pinRequest(bytes32,bytes32,bytes32,uint64)\",\"MugiIMDVerifier.renounceOwnership()\",\"MugiIMDVerifier.revokeRequest(bytes32)\",\"MugiIMDVerifier.transferOwnership(address)\",\"MugiV1IMDDeploymentFactory.deployHook(bytes)\",\"MugiV1IMDDeploymentFactory.deployModules(bytes32,bytes32,(address,address,bytes32,uint256,uint32,bool,address,address,uint16,uint16,uint64,address,address,uint256))\",\"MugiVRFAdapter.rawFulfillRandomWords(uint256,uint256[])\",\"MugiVRFAdapter.requestRandomness()\",\"MugiVRFAdapter.retryDelivery(uint256)\"],\"files\":{\".gitignore\":6,\"ADAPTATION.md\":131,\"README.md\":47,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":42,\"docs/IMD_FINDINGS_RESPONSE.md\":61,\"docs/IMD_FOLLOWUP_RESPONSE.md\":104,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":167,\"docs/validation/compatible/VALIDATION.md\":33,\"docs/validation/compatible/artifact-review.json\":966,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2606,\"docs/validation/compatible/full-suite.raw.log\":2,\"docs/validation/compatible/test-results.json\":1634,\"docs/validation/compatible/v2-integration-result.json\":32,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":56,\"docs/validation/followup/VALIDATION.md\":16,\"docs/validation/followup/full-suite.raw.json\":2,\"docs/validation/followup/ledger-targeted-summary.json\":170,\"docs/validation/followup/terminal-claim-baseline.log\":20,\"docs/validation/followup/test-results.json\":788,\"docs/validation/followup/validation-summary.json\":188,\"docs/validation/repaired-final/VALIDATION.md\":17,\"docs/validation/repaired-final/test-results.json\":788,\"docs/validation/repaired-final/validation-summary.json\":161,\"docs/validation/vrf-stall-repair/RECOVERY.md\":84,\"docs/validation/vrf-stall-repair/original-VrfStall.sol\":63,\"docs/validation/vrf-stall-repair/original-proof.log\":60,\"foundry.toml\":18,\"hook-constructor.json\":43,\"inventory.json\":641,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":115,\"src/game/MugiAirdrop.sol\":121,\"src/game/MugiCrewToken.sol\":170,\"src/game/MugiIMDVerifier.sol\":157,\"src/game/MugiReserveMath.sol\":27,\"src/game/MugiVRFAdapter.sol\":146,\"src/imd/MugiIMDAccountingFactory.sol\":49,\"src/imd/MugiIMDCrewFactory.sol\":43,\"src/imd/MugiIMDCrewToken.sol\":13,\"src/imd/MugiIMDEngineFactory.sol\":35,\"src/imd/MugiIMDGameHook.sol\":639,\"src/imd/MugiIMDSwapRouter.sol\":132,\"src/imd/MugiV1IMDDeploymentFactory.sol\":155,\"src/imd/libraries/MugiIMDDeploymentAddresses.sol\":15,\"src/imd/libraries/MugiIMDV4Fees.sol\":64,\"src/imd/modules/MugiIMDBuybacks.sol\":188,\"src/imd/modules/MugiIMDLedger.sol\":350,\"src/imd/modules/MugiIMDPriceOracle.sol\":170,\"src/imd/modules/MugiIMDV4Engine.sol\":408,\"test/imd/MugiIMDCrewToken.t.sol\":308,\"test/imd/MugiIMDProjectFactoryFork.t.sol\":141,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":266,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":205,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":568,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":279,\"test/imd/lifecycle/MugiSwapRouter.t.sol\":288,\"test/imd/modules/MugiIMDEngineSecurity.t.sol\":216,\"test/imd/modules/MugiIMDLedgerFixture.sol\":115,\"test/imd/modules/MugiIMDLedgerSeason.t.sol\":68,\"test/imd/modules/MugiIMDLedgerSecurity.t.sol\":117,\"test/imd/modules/MugiIMDLedgerSnapshots.t.sol\":144,\"test/imd/modules/MugiIMDLedgerTerminal.t.sol\":258,\"test/imd/modules/MugiIMDStateModules.t.sol\":144,\"test/imd/modules/MugiIMDVerifier.t.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"c4e3738010ac51a187576511ab94bf07075dd223cbd6bc9d352c618946ab0a74","verifiedTreeHash":"17047f4b389b5f33c41cb3a2bb46d2036eb13a6c","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":121600,"exitCode":0,"name":"build","output":"Compiling 132 files with Solc 0.8.26\nSolc 0.8.26 finished in 121.48s\nCompiler run successful with warnings:\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:625:29:\n    |\n625 |     function previewAccount(address account) external view returns (uint256[10 ...\n    |                             ^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:626:29:\n    |\n626 |     function eligibleSupply(uint8 crew) external view returns (uint256) { _forwardView(address(ledger)); }\n    |                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:628:28:\n    |\n628 |     function escrowBacking(uint8 crew) external view returns (uint256) { _forwardView(address(ledger)); }\n    |                            ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:630:22:\n    |\n630 |     function poolKey(uint8 crew) external view returns (PoolKey memory) { _forwardView(address(engine)); }\n    |                      ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:631:21:\n    |\n631 |     function poolId(uint8 crew) external view returns (PoolId) { _forwardView(address(engine)); }\n    |                     ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:632:24:\n    |\n632 |     function poolState(uint8 crew) external view returns (uint160, int24, uint128) { _forwardView(address(engine)); }\n    |                        ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:633:32:\n    |\n633 |     function positionLiquidity(uint8 crew) external view returns (uint128) { _forwardView(address(engine)); }\n    |                                ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:26:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                          ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:61:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                             ^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:73:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                         ^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:634:93:\n    |\n634 |     function buybackTwap(uint8 crew) external view returns (int24 tick, uint32 secondsUsed, uint16 observations) {\n    |                                                                                             ^^^^^^^^^^^^^^^^^^^\n\nWarning (5667): Unused function parameter. Remove or comment out the variable name to silence this warning.\n   --> src/imd/MugiIMDGameHook.sol:638:26:\n    |\n638 |     function roundBudget(uint64 id) external view returns (MugiBuybacks.Budget memory) { _forwardView(address(budgets)); }\n    |                          ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/imd/MugiIMDCrewToken.t.sol:276:5:\n    |\n276 |     function testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256 initial, uint256 order) public view {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to view\n  --> test/imd/modules/MugiIMDVerifier.t.sol:74:5:\n   |\n74 |     function testSignatureVerificationFitsCallbackStipend() public {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":7552,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/imd/lifecycle/MugiGameHookMainnetFork.t.sol:MugiGameHookMainnetForkTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 532.82µs (0.00ns CPU time)\n\nRan 1 test for test/imd/MugiIMDProjectFactoryFork.t.sol:MugiIMDProjectFactoryForkTest\n[SKIP] testMainnetFactoryRecordsFourEntriesThenConstructorCompleteGraphSeedsTenPools() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 586.36µs (89.49µs CPU time)\n\nRan 4 tests for test/imd/modules/MugiIMDLedgerSeason.t.sol:MugiIMDLedgerSeasonTest\n[PASS] testConstructorFixesAllProtocolExclusionsWithoutInitialization() (gas: 2309714)\n[PASS] testConstructorRejectsZeroOrDuplicateTokensAndTokenProtocolRoleCollision() (gas: 26831)\n[PASS] testConstructorWorksBeforeAnyDependencyCodeExists() (gas: 16570)\n[PASS] testDuplicateTreasuryAddressesAreSubtractedOnlyOnce() (gas: 1141863)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 3.12ms (2.31ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDStateModules.t.sol:MugiIMDStateModulesTest\n[PASS] testAllBudgetMutatorsRequireHook() (gas: 103800)\n[PASS] testApprovalUsesHookHashDomainAndConsumerThroughOrdinaryCall() (gas: 523802)\n[PASS] testBudgetAuthorizesAccountsAndPreservesTradeCadence() (gas: 744543)\n[PASS] testConstructorsAcceptCounterfactualHookAndRejectZero() (gas: 2385626)\n[PASS] testOracleNegativeMeanRoundsDown() (gas: 139608)\n[PASS] testOracleOnlyHookCanUpdateButAnyoneCanRead() (gas: 126199)\n[PASS] testOracleRequiresHistoryAndRejectsSpotDeviation() (gas: 135910)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 8.02ms (1.45ms CPU time)\n\nRan 7 tests for test/imd/modules/MugiIMDLedgerSecurity.t.sol:MugiIMDLedgerSecurityTest\n[PASS] testAllRemainingLedgerMutatorsRejectOutsideCaller() (gas: 171999)\n[PASS] testCutoffCannotBeFutureRepeatedOrEarlierThanPriorAccountingEvent() (gas: 4908600)\n[PASS] testExcludedProtocolInventoryCannotCaptureEliminationRewards() (gas: 4078480)\n[PASS] testMaterializationAtOrAfterProposedCutoffCannotBeReusedAsAnEarlierVirtualSnapshot() (gas: 5210809)\n[PASS] testPremintedProtocolInventoryIsExcludedWithoutAnyTokenCallback() (gas: 1336129)\n[PASS] testRemovedInitializationReclassificationAndCallbackSelectorsAreUnavailableEvenToHook() (gas: 148153)\n[PASS] testZeroTokenClaimsAndEthSynchronizationDoNotChangeVirtualSnapshotTiming() (gas: 5446112)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 11.04ms (5.79ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 28708864)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127626)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 476583)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 23.83ms (17.13ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271053)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194348)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339207)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977419)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4101410)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11140007)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325174)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4875341)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221311)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 44.32ms (27.02ms CPU time)\n\nRan 4 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7347371)\n[PASS] testOrdinaryFinaleResidualStaysOwnerGatedAndZeroPinAcceptsAnyReceiver() (gas: 32542396)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 32303123)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 33976751)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 70.98ms (84.97ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934426)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1624816)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6506717)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9363700)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294172)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 27101240)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439053)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 42707030)\nLogs:\n  Settlement and request gas: 5523629\n  Settlement and request gas: 4787887\n  Settlement and request gas: 4375760\n  Settlement and request gas: 3916684\n  Settlement and request gas: 3452480\n  Settlement and request gas: 3001948\n  Settlement and request gas: 2558879\n  Settlement and request gas: 2087091\n  Settlement and request gas: 1620674\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 375525)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1372533)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11155742)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5632191)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341595)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5522752)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 7743106)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1568059)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241599)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 73.28ms (77.66ms CPU time)\n\nRan 5 tests for test/imd/modules/MugiIMDLedgerSnapshots.t.sol:MugiIMDLedgerSnapshotsTest\n[PASS] testCutoffTransfersBurnsAndKnownLoserSalesCannotMovePastRewardsOrConversion() (gas: 7006991)\n[PASS] testEmergencyUnwindUsesOriginalCutoffEvenAfterTransfersDuringLongRecoveryDelay() (gas: 7770266)\n[PASS] testFuzzAfterCutoffTransferCannotSellOrDuplicateConversion(uint96,uint96) (runs: 256, μ: 4060778, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 81.76ms (93.71ms CPU time)\n\nRan 13 tests for test/imd/modules/MugiIMDVerifier.t.sol:MugiIMDVerifierTest\n[PASS] testCanonicalIMDProtocolDigestAndSignatureVector() (gas: 14041)\n[PASS] testCrossChainReplayRejected() (gas: 32053)\n[PASS] testExpiryFutureIssueAndStaleAnswerRejected() (gas: 121424)\n[PASS] testMalformedAndFutureBlockMetadataRejected() (gas: 121394)\n[PASS] testOnlyOwnerCanPin() (gas: 34717)\n[PASS] testOwnerCannotRotateSignerOrWeakenEvidencePolicy() (gas: 107728)\n[PASS] testPanelPolicyRejectsMinorityAndImpossibleCounts() (gas: 151298)\n[PASS] testRevocationCannotBeRepinned() (gas: 98612)\n[PASS] testSignatureVerificationFitsCallbackStipend() (gas: 40767)\n[PASS] testTamperedSignatureRejected() (gas: 38804)\n[PASS] testUnpinnedAndWrongQuestionOrAnswerRejected() (gas: 118096)\n[PASS] testValidPinnedPlanAndConsumerReplayGuard() (gas: 161102)\n[PASS] testWrongConsumerAndDomainAreRejected() (gas: 139844)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 94.60ms (6.45ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDEngineSecurity.t.sol:MugiIMDEngineSecurityTest\n[PASS] testAllEconomicMutatorsRejectNonHookCaller() (gas: 150353)\n[PASS] testCallbackCannotBeInjectedEvenByManagerWithoutPendingUnlock() (gas: 62786)\n[PASS] testCounterfactualConstructorDoesNotCallDependencyAddresses() (gas: 13706)\n[PASS] testOnlyOwnerCanDeployPredictedEngineOnce() (gas: 6455846)\n[PASS] testPartialBuyPaysHookAndRefundsUnusedEth() (gas: 808775)\n[PASS] testRefundCallbackCannotReenterPositionOperations() (gas: 661418)\n[PASS] testRemovePaysHookAndLeavesNoPositionOrNewBalancesInEngine() (gas: 787517)\n[PASS] testSeedRefundsUnusedInputsAndPreservesPriorEngineBalances() (gas: 623887)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 116.76ms (2.21ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 69993263)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 40179916)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 143450616)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 60128436)\nLogs:\n  Four service module creations: 3693167\n  Ten crew token creations: 9091601\n  Engine creation: 2497921\n  Three accounting module creations: 3831414\n  Hook creation: 5778342\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 223633)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14156646)\nLogs:\n  Four factory runtime bytes: 60375\n  Four factory initcode bytes: 85703\n  Four factory CREATE2 execution gas: 12262905\n  Estimated launch transaction gas: 14665457\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 25147600)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 49349293)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 60193548)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 60193482)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 62102607)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 35799830)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 129.28ms (375.48ms CPU time)\n\nRan 16 tests for test/imd/MugiIMDCrewToken.t.sol:MugiIMDCrewTokenTest\n[PASS] testBurnHistoryTracksMultipleTimestampsAndCoalescesSameTimestamp() (gas: 441690)\n[PASS] testConstructorAcceptsPredeterminedUndeployedHook() (gas: 16336)\n[PASS] testConstructorCreatesWholeFiniteReserveAndNoEarlierHistory() (gas: 100182)\n[PASS] testFuzzFiniteReserveCoversMaxReinforcementsAndConversions(uint256,uint256) (runs: 256, μ: 54362, ~: 54312)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3598844, ~: 3724538)\n[PASS] testInfiniteAllowanceAndFailedTransferPreserveHistory() (gas: 351050)\n[PASS] testInvalidConstructorConfigurationRejects() (gas: 4632)\n[PASS] testRejectsZeroTransferAndApprovalDestinations() (gas: 53819)\n[PASS] testRemovedMintInitializerAndArbitraryBurnSelectorsAreUnavailable() (gas: 219912)\n[PASS] testReserveHolderHasNoAuthorityOverOtherBalances() (gas: 223787)\n[PASS] testSameTimestampGenesisAndTransfersUseEndOfTimestampBalance() (gas: 313272)\n[PASS] testStaticConstructorPreservesAllCanonicalCrewNamesAndSymbols() (gas: 276675)\n[PASS] testStrictCutoffExcludesEveryExactCutoffTransferAndBurn() (gas: 568341)\n[PASS] testTransferFromCheckpointsBothWalletsAndFiniteAllowance() (gas: 367855)\n[PASS] testTransfersAndBurnDoNotCallRevertingOrBrokenHook() (gas: 539864)\n[PASS] testZeroAndSelfTransfersDoNotChangeHistoricalOwnership() (gas: 248761)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 241.19ms (363.14ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 449508)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1042167)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 852090)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 620379)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1012701, ~: 1013539)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5274990)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 902628)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 807194)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 994286)\n[PASS] testSellMinimumOutputFailurePreservesAllowanceAndBalances() (gas: 439262)\n[PASS] testThirdPartyManagerUnlockCannotUseRouter() (gas: 396113)\n[PASS] testUnsolicitedCallbacksRejectedIncludingManagerWithoutPendingTrade() (gas: 71596)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 420.87ms (418.42ms CPU time)\n\nRan 8 tests for test/imd/modules/MugiIMDLedgerTerminal.t.sol:MugiIMDLedgerTerminalTest\n[PASS] testEmergencyAfterPriorEthWithdrawalExpiresOnlyRemainingMixedRights() (gas: 6872513)\n[PASS] testEmergencyExpirationCannotResurrectSyncedOrLazyClaims() (gas: 10818557)\n[PASS] testEmergencyRejectsWrongMaskAndCannotRecordAnotherTerminalOrRound() (gas: 937792)\n[PASS] testEmergencyRewardsIncludeFrozenWalletAndVirtualBalancesAndEarlierEth() (gas: 8641692)\n[PASS] testEmergencyUnallocatedCrewSharesAndRemaindersNeverEnterPlayerReserve() (gas: 4862305)\n[PASS] testExpirationCannotResurrectSyncedOrLazyClaimsInEitherTerminalMode() (gas: 16635639)\n[PASS] testFuzzEagerMaterializationAndLateSyncHaveIdenticalEmergencyRights(uint8,uint96) (runs: 256, μ: 23098957, ~: 21691368)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 449.97ms (465.18ms CPU time)\n\nRan 1 test for test/imd/invariant/MugiCrewTokenInvariant.t.sol:MugiCrewTokenInvariantTest\n[PASS]\nMugiCrewTokenInvariantTest invariants:\n[PASS] invariant_balancesSumToTotalSupply\n[PASS] invariant_burnOnlyAffectsCaller\n[PASS] invariant_genesisHasNoEarlierHistory\n[PASS] invariant_pastSnapshotsAreImmutable\n[PASS] invariant_supplyOnlyFallsByBurns\n MugiCrewTokenInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------------+--------------+-------+---------+----------╮\n| Contract             | Selector     | Calls | Reverts | Discards |\n+==================================================================+\n| MugiCrewTokenHandler | burn         | 1388  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | overspend    | 1333  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | snapshot     | 1352  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | transfer     | 1362  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | transferFrom | 1384  | 0       | 0        |\n|----------------------+--------------+-------+---------+----------|\n| MugiCrewTokenHandler | warp         | 1373  | 0       | 0        |\n╰----------------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.83s (1.82s CPU time)\n\nRan 1 test for test/imd/invariant/MugiGameInvariant.t.sol:MugiGameInvariantTest\n[PASS]\nMugiGameInvariantTest invariants:\n[PASS] invariant_closedCrewsRetainNoUnusedReserve\n[PASS] invariant_finiteSupplyNeverGrowsAndIsFullyHeld\n[PASS] invariant_hookEthCoversPlayerAndTeamLiabilities\n[PASS] invariant_hookTokensBackEscrowReserveAndTeamFees\n[PASS] invariant_routerNeverRetainsCustody\n[PASS] invariant_seasonOnlyMovesForward\n MugiGameInvariantTest invariants (runs: 48, calls: 4800, reverts: 0)\n\n╭-----------------+------------------+-------+---------+----------╮\n| Contract        | Selector         | Calls | Reverts | Discards |\n+=================================================================+\n| MugiGameHandler | advance          | 305   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | advanceRounds    | 311   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | burn             | 283   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | buy              | 309   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | claimEth         | 288   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | claimTokens      | 328   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | collectTeamFees  | 307   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | migrate          | 302   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | ownBuyback       | 302   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | retireAirdrop    | 324   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | sell             | 326   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | stall            | 299   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | sweep            | 259   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | transfer         | 266   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | warp             | 289   | 0       | 0        |\n|-----------------+------------------+-------+---------+----------|\n| MugiGameHandler | withdrawTeamFees | 302   | 0       | 0        |\n╰-----------------+------------------+-------+---------+----------╯\n\nLogs:\n  buy: 3\n  sell: 0\n  claimEth: 1\n  claimTokens: 2\n  ownBuyback: 0\n  round: 9\n  finalize: 1\n  migrate: 1\n  sweep: 0\n  emergency: 0\n  eliminations: 9\n  phase: 5\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.44s (4.43s CPU time)\n\nRan 12 tests for test/imd/MugiIMDManifestFactories.t.sol:MugiIMDManifestFactoriesTest\n[PASS] testCrewFactoryRejectsZeroHookAndOutOfRangeSupplyAtomically() (gas: 9403411)\n[PASS] testCrewSetBoundToAnotherHookBlocksHookCreation() (gas: 54841454)\n[PASS] testCrewSupplyMismatchIsCaughtAtFirstEconomicUse() (gas: 60230250)\n[PASS] testDeployModulesRejectsEveryInvalidStaticInput() (gas: 35338078)\n[PASS] testEngineBoundToAnotherManagerIsCaughtAtFirstEconomicUse() (gas: 64021624)\n[PASS] testEveryManifestFactoryRejectsZeroOwner() (gas: 4200)\n[PASS] testFuzzDeployModulesRejectsSaltWithoutHookPermissionBits(bytes32) (runs: 512, μ: 99209, ~: 99316)\n[PASS] testHookConfigurationCannotChangeOwnerManagerOrSupply() (gas: 394747127)\n[PASS] testHookOwnershipIsTwoStepAndOwnerOnly() (gas: 61688409)\n[PASS] testHookRequiresAccountingAndEngineModulesToExist() (gas: 61044578)\n[PASS] testManifestOrderFactoriesBindOnlyTheStaticOwnerAndCreateNoChildren() (gas: 154789)\n[PASS] testPrelaunchGatesRejectEveryEconomicEntryPoint() (gas: 62720447)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 7.23s (953.32ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6125490)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 29269303)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 38107268)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6071774)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1355084)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20108725)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5621858)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170491)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 7.26s (56.70ms CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 563187)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7023286)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 30468634)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 221535353, ~: 220950094)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 35827999)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 26868829)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.44s (7.46s CPU time)\n\nRan 21 test suites in 7.44s (29.97s CPU time): 156 tests passed, 0 failed, 2 skipped (158 total tests)\n","passed":true},{"durationMs":71,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"MugiAirdrop.claim(uint64,bytes)\",\"MugiAirdrop.launch()\",\"MugiAirdrop.register(uint8,bytes32,uint64,bytes)\",\"MugiAirdrop.retireRemaining()\",\"MugiCrewToken.approve(address,uint256)\",\"MugiCrewToken.burn(uint256)\",\"MugiCrewToken.transfer(address,uint256)\",\"MugiCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDAccountingFactory.deployForHook((address,address,address,address,address,address,address,address,address,address,address,address,address,address,address,address))\",\"MugiIMDBuybacks.account(uint64,uint8,uint256)\",\"MugiIMDBuybacks.approve((uint64,uint64,uint64,uint256[10]),address,bytes)\",\"MugiIMDBuybacks.authorize(uint64,uint8,uint256)\",\"MugiIMDBuybacks.create(uint64,uint256,uint16)\",\"MugiIMDCrewFactory.deployCrewSet(address,uint256)\",\"MugiIMDCrewToken.approve(address,uint256)\",\"MugiIMDCrewToken.burn(uint256)\",\"MugiIMDCrewToken.transfer(address,uint256)\",\"MugiIMDCrewToken.transferFrom(address,address,uint256)\",\"MugiIMDEngineFactory.deployForHook(address,address)\",\"MugiIMDGameHook.abortPrelaunch()\",\"MugiIMDGameHook.acceptOwnership()\",\"MugiIMDGameHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MugiIMDGameHook.approvePlan((uint64,uint64,uint64,uint256[10]),bytes)\",\"MugiIMDGameHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MugiIMDGameHook.cancelOwnershipTransfer()\",\"MugiIMDGameHook.claimEth(address)\",\"MugiIMDGameHook.claimToken(uint8,uint256)\",\"MugiIMDGameHook.claimTokens()\",\"MugiIMDGameHook.collectTeamFees(uint8)\",\"MugiIMDGameHook.executeBuyback(uint64,uint8,uint256)\",\"MugiIMDGameHook.executeOwnBuyback(uint8,uint256)\",\"MugiIMDGameHook.finalize()\",\"MugiIMDGameHook.launch()\",\"MugiIMDGameHook.migrateToV2(address)\",\"MugiIMDGameHook.receive()\",\"MugiIMDGameHook.receiveRandomness(uint256,uint256)\",\"MugiIMDGameHook.recoverStalledRandomness(uint8)\",\"MugiIMDGameHook.requestElimination()\",\"MugiIMDGameHook.retireAirdrop()\",\"MugiIMDGameHook.seedPool(uint8)\",\"MugiIMDGameHook.settleRound(uint8)\",\"MugiIMDGameHook.sweepExpiredFinalClaims()\",\"MugiIMDGameHook.transferOwnership(address)\",\"MugiIMDGameHook.unlockCallback(bytes)\",\"MugiIMDGameHook.withdrawTeamFees()\",\"MugiIMDLedger.claimEth(address)\",\"MugiIMDLedger.claimToken(address,uint8,uint256)\",\"MugiIMDLedger.claimTokens(address)\",\"MugiIMDLedger.emergencyFinalize(uint16,uint256,uint64)\",\"MugiIMDLedger.expireFinalClaims()\",\"MugiIMDLedger.finalizeMigration(uint8,uint64)\",\"MugiIMDLedger.recordElimination(uint8,uint16,uint256,uint64)\",\"MugiIMDPriceOracle.update(uint8,int24)\",\"MugiIMDSwapRouter.buy(uint8,uint256,uint64)\",\"MugiIMDSwapRouter.sell(uint8,uint256,uint256,uint64)\",\"MugiIMDSwapRouter.unlockCallback(bytes)\",\"MugiIMDV4Engine.addLiquidity(uint8,uint128,uint256,uint256)\",\"MugiIMDV4Engine.buy(uint8,uint256,uint256,uint160)\",\"MugiIMDV4Engine.collectFees(uint8)\",\"MugiIMDV4Engine.registerInitialPool(uint8,address,uint256,uint256)\",\"MugiIMDV4Engine.registerPool(uint8,address,uint24,int24,uint160)\",\"MugiIMDV4Engine.removeLiquidity(uint8,uint256,uint256)\",\"MugiIMDV4Engine.unlockCallback(bytes)\",\"MugiIMDVerifier.pinRequest(bytes32,bytes32,bytes32,uint64)\",\"MugiIMDVerifier.renounceOwnership()\",\"MugiIMDVerifier.revokeRequest(bytes32)\",\"MugiIMDVerifier.transferOwnership(address)\",\"MugiV1IMDDeploymentFactory.deployHook(bytes)\",\"MugiV1IMDDeploymentFactory.deployModules(bytes32,bytes32,(address,address,bytes32,uint256,uint32,bool,address,address,uint16,uint16,uint64,address,address,uint256))\",\"MugiVRFAdapter.rawFulfillRandomWords(uint256,uint256[])\",\"MugiVRFAdapter.requestRandomness()\",\"MugiVRFAdapter.retryDelivery(uint256)\"],\"files\":{\".gitignore\":6,\"ADAPTATION.md\":131,\"README.md\":47,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":42,\"docs/IMD_FINDINGS_RESPONSE.md\":61,\"docs/IMD_FOLLOWUP_RESPONSE.md\":104,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":167,\"docs/validation/compatible/VALIDATION.md\":33,\"docs/validation/compatible/artifact-review.json\":966,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2606,\"docs/validation/compatible/full-suite.raw.log\":2,\"docs/validation/compatible/test-results.json\":1634,\"docs/validation/compatible/v2-integration-result.json\":32,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":56,\"docs/validation/followup/VALIDATION.md\":16,\"docs/validation/followup/full-suite.raw.json\":2,\"docs/validation/followup/ledger-targeted-summary.json\":170,\"docs/validation/followup/terminal-claim-baseline.log\":20,\"docs/validation/followup/test-results.json\":788,\"docs/validation/followup/validation-summary.json\":188,\"docs/validation/repaired-final/VALIDATION.md\":17,\"docs/validation/repaired-final/test-results.json\":788,\"docs/validation/repaired-final/validation-summary.json\":161,\"docs/validation/vrf-stall-repair/RECOVERY.md\":84,\"docs/validation/vrf-stall-repair/original-VrfStall.sol\":63,\"docs/validation/vrf-stall-repair/original-proof.log\":60,\"foundry.toml\":18,\"hook-constructor.json\":43,\"inventory.json\":641,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":115,\"src/game/MugiAirdrop.sol\":121,\"src/game/MugiCrewToken.sol\":170,\"src/game/MugiIMDVerifier.sol\":157,\"src/game/MugiReserveMath.sol\":27,\"src/game/MugiVRFAdapter.sol\":146,\"src/imd/MugiIMDAccountingFactory.sol\":49,\"src/imd/MugiIMDCrewFactory.sol\":43,\"src/imd/MugiIMDCrewToken.sol\":13,\"src/imd/MugiIMDEngineFactory.sol\":35,\"src/imd/MugiIMDGameHook.sol\":639,\"src/imd/MugiIMDSwapRouter.sol\":132,\"src/imd/MugiV1IMDDeploymentFactory.sol\":155,\"src/imd/libraries/MugiIMDDeploymentAddresses.sol\":15,\"src/imd/libraries/MugiIMDV4Fees.sol\":64,\"src/imd/modules/MugiIMDBuybacks.sol\":188,\"src/imd/modules/MugiIMDLedger.sol\":350,\"src/imd/modules/MugiIMDPriceOracle.sol\":170,\"src/imd/modules/MugiIMDV4Engine.sol\":408,\"test/imd/MugiIMDCrewToken.t.sol\":308,\"test/imd/MugiIMDManifestFactories.t.sol\":287,\"test/imd/MugiIMDProjectFactoryFork.t.sol\":141,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":266,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/invariant/MugiCrewTokenInvariant.t.sol\":188,\"test/imd/invariant/MugiGameInvariant.t.sol\":447,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":205,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":568,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":279,\"test/imd/lifecycle/MugiSwapRouter.t.sol\":288,\"test/imd/modules/MugiIMDEngineSecurity.t.sol\":216,\"test/imd/modules/MugiIMDLedgerFixture.sol\":115,\"test/imd/modules/MugiIMDLedgerSeason.t.sol\":68,\"test/imd/modules/MugiIMDLedgerSecurity.t.sol\":117,\"test/imd/modules/MugiIMDLedgerSnapshots.t.sol\":144,\"test/imd/modules/MugiIMDLedgerTerminal.t.sol\":258,\"test/imd/modules/MugiIMDStateModules.t.sol\":144,\"test/imd/modules/MugiIMDVerifier.t.sol\":230},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"d3d45bc7980f55636bd4be537086bbbda7c4f0e55de1efca600bbdccd0b2b7a9","verifiedTreeHash":"06aa3696d70c345e8659540e5c0c9e0d610d00aa","verifierVersion":"0.1.0+560ab6a2"}]}