{"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":"9b411387-9c65-4aac-83b7-8d40e4ff1e88","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"640474213b13f278256ecd5117ce9e5670f1fd7e22716dc19c5556dfaa9775f4","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":"aab6199f0c4d4f091ae70318447a7ed276cc117875a85d1a7c4e85f308f2a689","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":"e9d4c26ce8dfb47de575dc8724d27e470965d625a6c97add2cecaec4a192c800","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":"1019a18c4bbe563d45663b964cdef3927ff38808876953301ea04b9cae06e81d","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":"e71eb970552d966392cea27f4f7b9fd50d6517e475ed2b8976dbd790500f6ce7","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":"625173f0766c8f0fc5f56d076cb2e9560c01c753410dd5d8994d44c07828d0ee","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":"49c2c6da549d512dd36f84826242e9682985541e0d75e6a09723ea3d63594cf2","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":"65c4c2c640f939f6faf37b1eca64958f4bc1bb315ba56168c1c2245d229b034e","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"981bcbf528573ffe1bb6a2ac97f5daeed742ec8f037cdd1bc463088164783c63","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 narrowly repaired IMD-compatible MUGI V1 source, starting at this exact submitted source pin, on Ethereum mainnet through the contracts-only path. Inspect ADAPTATION.md, README.md, docs/IMD_CONSTRUCTOR_DEPLOYMENT.md, all docs/validation, inventory.json, launch.json, src and all tests. FOLLOW-UP: compare the delta from previously audited commit 9901dc71030df5818e4b307df1c5c43506346c12 and audit job 0c8421fb-4f6d-4650-8c90-d9fd7d7a79c5, accepted report hash 573ea9d5650bafcdc892589b64157aecbe9239f7efb89fa37b3d9bed699654f2. That report identified three blocking medium findings concerning owner-selected V2 destination, finale-fund liveness and owner/community treasury aliasing; report acceptance is not a clean audit. This source targets those findings with immutable receiver binding, permissionless bounded handoff and deadline fallback, and treasury separation. Expedite the focused regression review where possible for the requested 2026-10-22 00:00 UTC deadline, while retaining full admission, independent audit and security checks over the whole application. No policy exception is requested. Preserve Solidity 0.8.26, Cancun, optimizer 200, viaIR and bytecode_hash none. Prefer the exact submitted source. Necessary minimal source fixes and packaging adjustments are authorized through the normal audited pipeline, with regression tests and renewed independent review; preserve all explicit game, claims, reserve, immutable-V2 and community protections below. Do not stop merely because a safe focused fix is needed. Stop with needs_input if satisfying a finding would change those economic rules or requires unknown live child settings. Return the exact final source pin, diff and validation evidence for any adapted code; do not present adapted code as identical to the submitted commit. 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 static 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 AND REMEDIES: V2 remains separate future work. A nonzero immutable V2 receiver must be configured before hook creation. Anyone may trigger the one-shot atomic handoff to that exact target only during the thirty-day ordinary-finale window. Retire unused reserve first; retain earned player token backing and reserved player/team ETH. Receiver failure must roll everything back. At the deadline a permissionless community fallback handles only unallocated protocol inventory/ETH while protecting claim liabilities under their published expiry rules. Preserve the surviving holders thirty-day claim window and prohibit emergency migration. The community treasury must differ from owner and team, including after ownership transfer; expired claims must not be redirected to owner through treasury aliasing. Audit these exact code-enforced remedies and their regression tests. The planned community recipient is 0x973d5993Be7021882f72da0babCF884e77F76bBb, a distinct wallet under the same operator, not an independent DAO. It differs from the owner/team wallet; do not claim independent community governance or custody. The V2 receiver remains null in the hook-constructor plan, explicitly unresolved required child configuration. Its real address must be reviewed before hook creation/activation, outside this four-factory request. Do not invent it or confuse pending child settings with the four factories owner-only constructor arguments. Handoff is protocol-fund continuity, not automatic wallet-level V2 allocation. Check actual V2 receiver integration and current low/informational findings, including third-party PoolManager custody exclusions and deployment gas including code deposit. Return explicit admission outcome, final source pin, IMD launch record, four factory addresses and transaction receipts, and distinguish local proof from deployed state. 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. Initial deployment entries: {\"contracts\":[{\"constructorArgs\":[\"0x20714d50f4675c366de30b603728a90ddddb240f\"],\"contract\":\"MugiIMDCrewFactory\"},{\"constructorArgs\":[\"0x20714d50f4675c366de30b603728a90ddddb240f\"],\"contract\":\"MugiV1IMDDeploymentFactory\"},{\"constructorArgs\":[\"0x20714d50f4675c366de30b603728a90ddddb240f\"],\"contract\":\"MugiIMDAccountingFactory\"},{\"constructorArgs\":[\"0x20714d50f4675c366de30b603728a90ddddb240f\"],\"contract\":\"MugiIMDEngineFactory\"}],\"kind\":\"evm_contracts\"}","parentJobId":null,"planHash":"dfe7ddf77ed9e9b2f56570a58c8047edacdc1a46e4f678785415e4523399948e","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"9b411387-9c65-4aac-83b7-8d40e4ff1e88","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2439-mugiimdcrewfactory-mugiv1imddeploymentfa"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52178","feedbackHash":"0bf2643f9c69cbc0bc086b02f2269eee99fd6a42e4e1155596546b3236bcd395","nodeKey":"adapt_contract_project","submissionHash":"640474213b13f278256ecd5117ce9e5670f1fd7e22716dc19c5556dfaa9775f4","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52120","feedbackHash":"f9f65333b78b4fb78a582295bd307946c069c001a73b0ec18ec56b3eac645c26","nodeKey":"audit_economics","submissionHash":"aab6199f0c4d4f091ae70318447a7ed276cc117875a85d1a7c4e85f308f2a689","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52666","feedbackHash":"e99a2d5b0940cf622f83d170fd28673ce679dd361c87d8ce9ca31335a72c5da4","nodeKey":"audit_flow","submissionHash":"e9d4c26ce8dfb47de575dc8724d27e470965d625a6c97add2cecaec4a192c800","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51474","feedbackHash":"62e43e562207f5d1447bad849edb4f0df199112447d5ca7a3718157ff9029246","nodeKey":"audit_imported_code","submissionHash":"1019a18c4bbe563d45663b964cdef3927ff38808876953301ea04b9cae06e81d","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51537","feedbackHash":"9b1a17aab84865b08e2231dd77e79038cae7700971c6162d1a139bfe8593dc54","nodeKey":"audit_judge","submissionHash":"e71eb970552d966392cea27f4f7b9fd50d6517e475ed2b8976dbd790500f6ce7","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52468","feedbackHash":"51cc76150d0a3316a46d4289b97aa61cf17fc350c1d21c11290bc8e3f3864ed8","nodeKey":"audit_math","submissionHash":"625173f0766c8f0fc5f56d076cb2e9560c01c753410dd5d8994d44c07828d0ee","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50974","feedbackHash":"184429227b67b64ae59f9f6e824929088644cec9acb9092612b47fbd926e90d9","nodeKey":"audit_permissions","submissionHash":"49c2c6da549d512dd36f84826242e9682985541e0d75e6a09723ea3d63594cf2","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51527","feedbackHash":"d674877db59cedbce816a6f793ccfa07a27aefc62deeb53c82e86dff063769fb","nodeKey":"manifest","submissionHash":"65c4c2c640f939f6faf37b1eca64958f4bc1bb315ba56168c1c2245d229b034e","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"50979","feedbackHash":"cd85c548c27bb9eaab846314144940be8a142ec93be3761aa047d63372cf7ea8","nodeKey":"write_foundry_tests","submissionHash":"981bcbf528573ffe1bb6a2ac97f5daeed742ec8f037cdd1bc463088164783c63","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"d98bc1d9215b832f4f763ff09a03138995ff9dec813114d2a499a098296ba975","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"0e3b71e2ffcd200b","findings":[{"citation":"resolved","description":"The repaired constructor enforces community != owner and community != team, and transferOwnership rejects the community address, but no equivalent gate exists for v2MigrationTarget. It may equal teamTreasury, owner or communityTreasury. Because migrateToV2 is now permissionless and only requires target == v2MigrationTarget with code present, a hook created with v2MigrationTarget set to a contract-wallet team/owner lets anyone route the entire unreserved finale ETH and survivor inventory to the owner/team at finale, which is exactly the owner-selected-sink outcome the prior report asked to remove. The request text says the V2 receiver is a reviewed child setting, so this is an off-chain review gate today; the code gate that was added for community is simply absent for the V2 pin. MugiV1IMDDeploymentFactory.deployHook also does not compare c.v2MigrationTarget against c.team/c.owner/c.community.","line":132,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"test/scratch/V2TargetAlias.t.sol (uses the repo fixture): build _hookConfiguration(), set c.v2MigrationTarget = TEAM (or OWNER, or COMMUNITY), mine the salt, run deployModules/deployCrewSet/deployForHook, then factory.deployHook(code). Expected: InvalidConfiguration (as for c.community == c.team). Actual: deployment succeeds and game.v2MigrationTarget() == game.teamTreasury(); all three variants pass on this source. Fix: add c.v2MigrationTarget == c.owner || c.v2MigrationTarget == c.team || c.v2MigrationTarget == c.community to the constructor revert condition (and optionally mirror it in deployHook), with a regression test next to testTeamCannotBeCommunityDestination.","severity":"low","snippet":"            || c.v2MigrationTarget == address(0) || c.community == c.owner || c.community == c.team","title":"Hook constructor accepts a V2 receiver aliased to team, owner or community"},{"citation":"resolved","description":"docs/validation/compatible/VALIDATION.md, validation-summary.json and README.md state 152 tests passed with zero failures on Foundry 1.5.1-stable. On the Foundry shipped in this review environment (forge 1.8.5, same solc 0.8.26/cancun/viaIR/200 runs, identical bytecode hashes) the full suite gives 148 passed, 1 failed, 2 fork tests skipped. The failure is this gasleft()-based creation meter, which intentionally aborts when the runner's CREATE instrumentation omits the 200 gas/byte code-deposit component. It is a test-harness portability issue, not a contract defect, and the independent Anvil receipt (14,187,986 gas) still substantiates the gas claim. But any reviewer or admission pipeline that runs forge test on a current toolchain sees a red suite, and the committed evidence does not disclose the toolchain sensitivity.","line":101,"path":"test/imd/MugiV1IMDDeploymentFactory.t.sol","reproduction":"forge --version (1.8.5) ; forge test --match-test testFactoryCreationBatchHasConservativeGasHeadroom. Expected (per docs): PASS. Actual: [FAIL: creation meter omitted runtime code-deposit gas: 26942 < 12075000]. Remedy options: measure via a deployer helper contract and record receipt gas (vm.lastCallGas / vm.getGasUsed style) or compute the bound from code.length rather than gasleft(); update VALIDATION.md to state the forge version the meter depends on.","severity":"low","snippet":"        assertGe(execution, codeDeposit, \"creation meter omitted runtime code-deposit gas\");","title":"Factory gas-headroom regression fails under Foundry 1.8.5; validation evidence is pinned to 1.5.1"},{"citation":"resolved","description":"The three medium remedies reproduce as described: the V2 pin is immutable and nonzero, migrateToV2 is permissionless and bounded to [finalize, finalize+30d), receiver revert rolls back both transfers (verified by the repo's handoff tests and read of the code), fallbackFinaleToCommunity is permissionless at/after the deadline and leaves teamEth, ledger.reservedEth and escrowBacking untouched, and the community address is code-separated from owner/team and barred from becoming owner. What the code cannot enforce, and the requester discloses, is that 0x973d5993Be7021882f72da0babCF884e77F76bBb is a second wallet of the same operator. The V2 receiver can be pinned to an address that has no code yet (testNonzeroFutureV2ContractCanBePinnedBeforeItsDeployment). If the operator never deploys code there, migrateToV2 reverts for 30 days on target.code.length == 0 and the fallback then sends all unreserved protocol ETH and survivor inventory to the operator-controlled community wallet, and sweepExpiredFinalClaims later sends expired player ETH to the same wallet. Address inequality therefore proves owner/community separation only at the key level. Admission should treat the pinned V2 receiver and the community wallet as operator-trust assumptions, not as independent custody, and should require the V2 receiver to exist (or be a committed CREATE2 of reviewed code) before hook creation.","line":490,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"State: hook created with v2MigrationTarget = X where X.code.length == 0 forever; season finalizes at T. For any t in [T, T+30d): migrateToV2(X) reverts InvalidState (line 490). At t >= T+30d: anyone calls fallbackFinaleToCommunity(); communityTreasury receives balance - teamEth - reservedEth and survivor inventory (lines 511-514). At t >= claimsExpireAt: sweepExpiredFinalClaims() sends remaining reservedEth to communityTreasury. The repo test testFinaleFallbackHasHardDeadlineAndPreservesReservedAssets shows the same flow with COMMUNITY as the sink. No code change is required by the brief; this is a disclosure/admission note.","severity":"info","snippet":"        if (phase != Phase.Finalized || migrated || target.code.length == 0","title":"Deadline fallback makes operator inaction route finale funds to the operator's own second wallet"},{"citation":"resolved","description":"The constructor now reverts on a zero V2 receiver (src/imd/MugiIMDGameHook.sol:132), so the committed child plan cannot create the hook until a reviewed nonzero address is chosen; the plan file itself is marked partial-season-constants-not-deployable. This is consistent with the brief (receiver reviewed outside this four-factory request) and is not a defect, but it is an explicit admission precondition for the 19 descendants: nothing in this request yields a live game, and the four registry entries index factories only. Other unresolved live settings (VRF coordinator/subscription/keyHash, airdrop attestor, IMD verifier owner/signer/panel) are also absent from the manifest and must come from a reviewed subsequent plan; mock values from the test fixture must not be reused.","line":9,"path":"hook-constructor.json","reproduction":"Encode Configuration from hook-constructor.json as-is (v2MigrationTarget = 0): MugiV1IMDDeploymentFactory.deployHook(code) reverts DeploymentFailed because the hook constructor reverts InvalidConfiguration (repo test testZeroV2ReceiverCannotCreateHook). Deploying only launch.json's four factories therefore leaves tokens, hook, ledger, engine, budgets, prices, VRF adapter, verifier, airdrop and router non-existent.","severity":"info","snippet":"  \"v2MigrationTarget\": null,","title":"Hook creation is blocked on an unresolved V2 receiver; four-factory launch does not deploy or activate the game"},{"citation":"resolved","description":"Read in full: all 18 files under src (MugiIMDGameHook, MugiV1IMDDeploymentFactory, MugiIMDCrewFactory, MugiIMDCrewToken, MugiIMDAccountingFactory, MugiIMDEngineFactory, modules MugiIMDLedger/MugiIMDV4Engine/MugiIMDBuybacks/MugiIMDPriceOracle, libraries MugiIMDDeploymentAddresses/MugiIMDV4Fees, game MugiCrewToken/MugiAirdrop/MugiVRFAdapter/MugiIMDVerifier/MugiReserveMath), the full source delta from 9901dc7 (only MugiIMDGameHook.sol changed: nonzero/alias constructor gates, permissionless deadline-bound migrateToV2, fallbackFinaleToCommunity, community barred from ownership), launch.json, inventory.json, hook-constructor.json, ADAPTATION.md, README.md, docs/IMD_CONSTRUCTOR_DEPLOYMENT.md, docs/IMD_COMPATIBLE_R2_RESPONSE.md, docs/validation/compatible, and the regression tests MugiCompatibilityHandoff.t.sol, MugiTerminalConfiguration.t.sol, MugiV1IMDDeploymentFactory.t.sol and the deployment fixture. Independently reproduced: (1) protected floor on the four factories - one-transaction CREATE2 deployment on an empty chain with the manifest owner argument, runtimes 7180/21064/18963/13168 bytes, initcodes 7366/46853/19148/13353 bytes, no reachable DELEGATECALL/CALLCODE/SELFDESTRUCT, owner() == 0x20714d50...240f for all four; (2) compiled raw creation-code hashes equal the documented ones (hook 0x7161ccaa..., factories 0xbdea60ad..., 0x4cd5521c..., 0xa0a571f7..., 0x0d97ebac...), so the main factory pins the hook code compiled from this exact pin; (3) 148/149 non-fork tests pass. Checked by reading: constructor-only reserve 10I+100M with no mint selector; free transfers with no hook callback, pause, blacklist or confiscation; burn limited to msg.sender balance; strictly-before-cutoff checkpoint reads; 75% conversion exactness (SCALE = 4^9*9! keeps every round's divisor exact for synced and lazy accounts); excluded custodians hook/ledger/airdrop/engine/team/community/PoolManager; no post-deployment initializer or dependency setter; CREATE-nonce graph and CREATE2 hook commitment checks in deployHook; migrate/fallback/sweep leave teamEth, reservedEth and escrowBacking intact and are mutually exclusive via migrated; EmergencyClosed has no migration path. Not reached: the two mainnet-fork tests (no RPC; skipped), the external V2 receiver source (only a .txt test transcript is in the bundle, so actual receiveV1Finale behaviour is unverified here), the IMD floor OwnerChecks base and the live IMD factory/registry, and any Anvil receipt replay. No deployment, explorer verification or launch record exists yet; all evidence is local proof, not deployed state.","line":31,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"forge test --no-match-path '*Fork*' (148 passed, 1 failed as reported above); forge test --match-path test/scratch/ProtectedProbe.t.sol -vv (opcode/size probe passes); cast keccak over out/*/*.json bytecode objects matches docs/validation/compatible/artifact-review.json.","severity":"info","snippet":"contract MugiIMDGameHook {","title":"Coverage statement: contracts read, checks reproduced, and what could not be reached"}],"hash":"1019a18c4bbe563d45663b964cdef3927ff38808876953301ea04b9cae06e81d","nodeId":"03e50071-b1fc-4d78-b41a-326860f205c1","outcome":"completed","summary":"The findings file is written and validated. All five entries anchor to lines that exist in the tree, and no tracked file was changed.\n\n## Review outcome\n\n**No blocking defect found in the repaired source.** The delta from the previously audited commit 9901dc7 touches only `src/imd/MugiIMDGameHook.sol`, and the three medium remedies reproduce as claimed:\n\n- **Immutable V2 target.** The constructor rejects a zero receiver, and `migrateToV2` accepts only the pinned address with code present.\n- **Permissionless bounded handoff and fallback.** Anyone may hand off during the 30-day window after finale. At the deadline anyone may send only unreserved ETH and survivor inventory to the community treasury. Team ETH, reserved player ETH and token escrow stay untouched in both paths, the two paths are mutually exclusive, and emergency closure has no migration path.\n- **Treasury separation.** The constructor rejects community equal to owner or team, and ownership can never transfer to the community address.\n\n**Independent checks that passed.** I rebuilt the protected floor locally: the four factories deploy on an empty chain in one CREATE2 transaction with the manifest owner, every runtime is under EIP-170, no DELEGATECALL, CALLCODE or SELFDESTRUCT is reachable, and `owner()` is the stated wallet for all four. Compiled creation-code hashes match the documented ones exactly, so the main factory pins the hook compiled from this pin. Constructor-only reserve, free transfers, own-balance-only burn, strictly-before-cutoff snapshots, exact 75% conversion divisibility, excluded custodians, and the absence of pause or post-deployment initializers all hold on read. The manifest is schema-valid.\n\n**Findings written** (`.imd-findings.json`):\n\n- **Low.** The constructor gates community against owner and team but never gates the V2 receiver, so a hook can be created with the receiver equal to team, owner or community. My scratch test deploys all three variants successfully. With a contract-wallet team this re-creates the owner-selected sink via a permissionless call.\n- **Low.** The factory gas-headroom regression fails on forge 1.8.5 because of how `gasleft()` meters CREATE, so the committed \"152 passed, zero failures\" claim holds only on Foundry 1.5.1. Contract bytecode is identical across both.\n- **Info.** The fallback and expired-claim sink is the operator's own second wallet. If the operator never deploys code at the pinned receiver, the finale funds flow to that wallet after 30 days. This is disclosed and not enforceable in code.\n- **Info.** The child plan leaves the V2 receiver null, so the hook cannot be created from this bundle. The four-factory launch deploys and activates nothing beyond the factories.\n- **Info.** Coverage statement listing all 18 source files read, the regression tests and docs read, and what could not be reached.\n\n**Not reached.** The two mainnet-fork tests skipped without an RPC. The V2 receiver source is outside this bundle, so actual `receiveV1Finale` behaviour is unverified here. No deployment, launch record, factory addresses or receipts exist yet. Everything above is local proof, not deployed state.\n\n**Admission position.** The source is admissible for the four-factory contracts-only launch as submitted. The low finding on the V2 receiver gate is a one-line constructor fix with a regression test, and it should be resolved before hook creation rather than before factory deployment, since the receiver is a reviewed child setting.","treeHash":null,"usage":{"cachedInputTokens":1439144,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":47046,"runtime":"claude","turns":34,"wallClockMs":1418450}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"98b4506bef931d13","findings":[{"citation":"resolved","description":"Asymmetry between the three season-closing paths. _beginSettlement (crew close), finalize() and recoverStalledRandomness() all call _retireReserve/burn so that unused reserve leaves totalSupply, and retireAirdrop() burns the airdrop's unclaimed 5% after launch. abortPrelaunch() is also a terminal close (Phase.Aborted) but only refunds ETH: it leaves unreleasedReserve[i] at reserveCap for every crew, leaves the returned 95% LP tokens plus the 5% already transferred to MugiAirdrop in place, and no later path can burn them: retireAirdrop() requires launchedAt != 0, sweepExpiredFinalClaims() requires Finalized/EmergencyClosed, and the hook has no other burn entry. ADAPTATION.md and launch.json notes state that 'Unused reserve is excluded from eligibility and burned when its crew or season closes'; for the Aborted close this is not code-enforced. No ETH is lost (the only ETH refunded is the owner's own seed), so impact is limited to a permanently wrong on-chain supply picture (totalSupply ~1.7e40 per crew of which ~0 is circulating) and the airdrop contract holding tokens of a dead season forever, which a later V2 or explorer could misread as live supply.","line":257,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Deploy the graph through the four factories (test/imd/helpers/MugiIMDDeploymentFixture.sol _deployGraph), initialSupply 1e24. Owner: seedPool{value:1 ether}(0); abortPrelaunch(). Observed (test/scratch/AbortStrand.t.sol): phase == Aborted; crew0 totalSupply 17014118346046933173168730371588410572700; airdrop balance 50000000000000000000000 (the 5% drop); hook balance 17014118346046933123168730371588410572699; unreleasedReserve(0) 17014118346046932173168730371588410572700; unreleasedReserve(1) and hook balance of crew1 still the full reserveCap. retireAirdrop() reverts InvalidState; sweepExpiredFinalClaims() reverts InvalidState. Expected under the documented rule: the Aborted close burns the hook-held reserve (and the airdrop's unclaimed allocation) exactly as the other closes do. Minimal fix that preserves all game economics: in abortPrelaunch, after removing liquidity, call _retireReserve(i) for all ten crews, burn the hook's returned crew-token balances, and allow airdrop.retireRemaining()/retireAirdrop() in Phase.Aborted (or have abort call it); add a regression test asserting totalSupply == 0 for every crew after abort.","severity":"low","snippet":"        phase = Phase.Aborted;\n        uint256 refund = address(this).balance;\n        _pay(payable(owner), refund);","title":"Aborted season never retires unreleased reserve or the 5% airdrop allocation (stated 'burned when season closes' rule not enforced on the Aborted close)"},{"citation":"resolved","description":"The brief asks for the immutable-receiver remedy and its regression tests to be audited. The code is correct: migrateToV2 reverts while v2MigrationTarget has no code (src/imd/MugiIMDGameHook.sol:493-494) and fallbackFinaleToCommunity becomes available at migrationDeadline. However every lifecycle fixture pins a receiver that already has code (HandoffReceiver / ForwardingV2Receiver), and MugiTerminalConfiguration.t.sol only asserts that a code-less address can be pinned, not what happens at finale. The realistic production path (receiver pinned before V2 exists, V2 never deployed or deployed late) is therefore untested in the committed suite; a future edit that drops the code check or lets any code-bearing address through would not be caught.","line":39,"path":"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol","reproduction":"Override _migrationTarget() to return 0xABC123 (no code) in MugiGameTestBase, run nine rounds and finalize (test/scratch/CodelessReceiver.t.sol). Observed: protocol ETH awaiting handoff 1008891317777777777777 wei; migrateToV2(0xABC123) by BOB reverts InvalidState; fallbackFinaleToCommunity() at migrationDeadline-1 reverts InvalidState; at migrationDeadline it succeeds and COMMUNITY receives exactly that protocol ETH with migrated()==true. This is the intended behaviour; the gap is that no test in test/imd asserts it. Suggested fix: add this scenario to MugiCompatibilityHandoff.t.sol (and a variant where code appears at the pinned address at day 29 and migrateToV2 then succeeds).","severity":"info","snippet":"    function _migrationTarget() internal view override returns (address) { return address(receiver); }","title":"No committed regression test covers the code-less pinned V2 receiver: handoff must stay blocked until the deadline fallback"},{"citation":"resolved","description":"Entry-point inventory: the hook registers pools only through registerInitialPool (src/imd/MugiIMDGameHook.sol:228). registerPool(crew, token, lpFee, tickSpacing, sqrtPriceX96) with caller-chosen fee, spacing and starting price is reachable only by the hook, and the hook contains no call to it, so it is unreachable in production and exists only for test/imd/modules/MugiIMDEngineSecurity.t.sol. It is not exploitable (onlyHook, and the hook is immutable with no arbitrary-call path), but it is privileged code shipped in the mainnet runtime that the verifier lists as a state-changing entry point and that the launch disclosure does not mention. Removing it (or documenting it as unreachable) shrinks the audited surface and the code-deposit gas.","line":107,"path":"src/imd/modules/MugiIMDV4Engine.sol","reproduction":"grep -rn 'registerPool(' src/ returns only the definition and the private _registerPool; the hook has no caller. Any EOA calling engine.registerPool(0, token, 3000, 60, 1<<96) reverts Unauthorized(); the hook cannot be made to call it. State: unreachable in production, so no failing economic state; reported as inventory/disclosure only.","severity":"info","snippet":"    function registerPool(\n        uint8 crew,\n        address token,\n        uint24 lpFee,\n        int24 tickSpacing,\n        uint160 sqrtPriceX96\n    ) external onlyHook returns (PoolId id) {\n        return _registerPool(crew, token, lpFee, tickSpacing, sqrtPriceX96);\n    }","title":"MugiIMDV4Engine.registerPool is an onlyHook entry point the hook never calls (dead privileged surface in the audited ABI)"}],"hash":"49c2c6da549d512dd36f84826242e9682985541e0d75e6a09723ea3d63594cf2","nodeId":"3cc84c6f-ff41-4a24-a936-695b9692d2e7","outcome":"completed","summary":"Review complete. The findings file is written and validated, all 73 listed entry points have coverage rows, and the working tree contains only the allowed outputs (the other untracked dotfiles are sandbox character devices, not files).\n\n**Outcome for the assigned area (Access Control, Trust Gap, Asymmetry): no blocking defect.** The three remedies this source was built for are enforced in code and covered by regression tests:\n\n- **Immutable receiver binding.** The hook constructor rejects a zero receiver and any receiver equal to owner, team or community. `migrateToV2` is permissionless, accepts only that exact address, requires code, and is one-shot and atomic. A receiver revert rolls back both transfers.\n- **Finale-fund liveness.** `fallbackFinaleToCommunity` opens exactly when the handoff window closes, pays only balance minus team ETH minus reserved ETH plus inventory minus escrow, and uses the same exclusions as the handoff. Sweeping expired claims first does not erase the migration deadline.\n- **Treasury separation.** Community must differ from owner and team at construction, and `transferOwnership` rejects both the community treasury and the V2 receiver, so expired claims and fallback ETH can never be aliased to the owner after a transfer. The ledger excludes team, community, hook, airdrop, engine and PoolManager from eligibility, and the hook binds that tuple through the configuration hash.\n\nBeyond the delta, the permission model is tight: the owner's only post-construction powers are `seedPool` and `abortPrelaunch`, both prelaunch; every module is hook-only with reentrancy and unlock-commitment guards; removals with zero minimums only run while trading is closed by the cutoff, so they cannot be sandwiched.\n\n**Reported findings (in `.imd-findings.json`):**\n\n1. **Low.** An aborted season never retires the unreleased reserve or the 5% airdrop allocation. The scratch test shows crew token total supply stays at about 1.7e40 with the reserve held by the hook and the drop in the airdrop forever, and no path can burn them. This contradicts the stated \"burned when the season closes\" rule, though no ETH is at risk.\n2. **Info.** No committed test covers the code-less pinned receiver path. The code behaves correctly (handoff blocked, fallback pays the community at the deadline), but only my scratch test exercises it.\n3. **Info.** `MugiIMDV4Engine.registerPool` is a hook-only function the hook never calls, so it is dead privileged code in the mainnet runtime.\n\n**Trust assumptions the judge should carry forward, not defects:** owner and team treasury are the same wallet, the community recipient is a second wallet of the same operator, and the verifier owner, attestor key, VRF subscription and the real V2 receiver remain unresolved child settings that must be reviewed before hook creation. The survivor crew's final-round treasure and unspent budgets flow to the V2 receiver or community rather than to holders; the docs disclose this.\n\n**Checks run:** full suite offline with a clean environment, 153 tests passed, fork tests excluded. Two scratch tests under `test/scratch/` reproduced findings 1 and 2. Slither did not run on the verifier side; the Aderyn leads in my area (unchecked ETH sends, reentrancy after external calls) traced to guarded or commitment-protected paths and were not promoted.","treeHash":null,"usage":{"cachedInputTokens":2108224,"inputTokens":482,"model":"claude-fable-5-1","outputTokens":56155,"runtime":"claude","turns":33,"wallClockMs":1121674}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"c9743cd9807c4c3a","findings":[{"citation":"resolved","description":"Seam: boundary (sqrtPriceLimit at currentTick-303) x precision (minTokens computed on the whole budget). MugiIMDGameHook._buyAndBurn (src/imd/MugiIMDGameHook.sol:427-428) asks MugiIMDPriceOracle.quoteMinimum for `minimum` on the FULL `ethAmount` (quote * 0.97, src/imd/modules/MugiIMDPriceOracle.sol:146) and a price limit 303 ticks (~3%) below spot, then calls engine.buy(crew, ethAmount, minimum, limit). The engine natspec (line 282: 'Partial fills are allowed here; the budget must be charged by actual ethSpent') and MugiIMDBuybacks.account's actualSpent accounting assume a partial fill can succeed. But _buy requires `received >= action.amount1` where amount1 is the full-budget minimum. A full-range constant-product position moves 3% in price once roughly 1.53% of the pool's ETH reserve has been swapped in (X/(X+s) = sqrt(0.97)), so a swap larger than that is cut by the limit and returns far fewer tokens than the full-budget minimum, and the whole executeBuyback / executeOwnBuyback reverts. Because MugiIMDBuybacks.authorize rejects any amount below _minimumTrade (ceil(allocation/100)) and executeOwnBuyback rejects amounts below ceil(ownBurnBudget/100), there is no admissible amount for a crew whose 1% minimum trade exceeds ~1.53% of its pool ETH, so that crew's round allocation (and its own-burn budget) is unspendable for the entire 22-hour window. Partial-fill handling in `account` is dead code except in the narrow band where spot is >~3% cheaper than the TWAP so a >=91% fill still clears the minimum. The ETH is not lost: the unspent budget stays in the hook and flows to the finale handoff / community fallback / emergency recovery, but the published 'bounded buybacks that burn loser proceeds into survivor supply' rule is silently not executed for thin pools, and plan allocations the verifier approved cannot be honoured. Minimal fix preserving the bounded-buyback design: let the oracle return a minimum per unit of ETH (or price-limit only) and have the hook check `burned >= minimum * spent / ethAmount` after the swap, or compute `minimum` on the smaller of ethAmount and the ETH needed to reach the limit; keep MugiIMDBuybacks.account charging `spent`.","line":369,"path":"src/imd/modules/MugiIMDV4Engine.sol","reproduction":"State after a settlement: survivor crew C pool has ETH reserve X = 1e17 wei (0.1 ETH; reachable because seedPool takes any owner msg.value per crew and holder sells drain ETH from a pool), the loser's LP removal returned 8e18 wei so settlementBuybackEth = 4e18 wei, 8 survivors, so MugiIMDBuybacks._fallback allocation[C] = 5e17 wei and _minimumTrade = ceil(5e17/100) = 5e15 wei; chunk = (4e18+19)/20 = 2e17. Oracle has >=15 min history and spot == TWAP (deviation 0). Call MugiIMDGameHook.executeBuyback(roundId, C, 5e15) (any amount in [5e15, 2e17] behaves the same). Expected per the engine natspec and MugiIMDBuybacks.account: the swap fills up to the 3% limit, spent ~1.534e15 wei is charged, tokens are burned. Actual: quoteMinimum returns minTokens = 5e15 * 0.997 * P * 0.97 = 4.835e15*P; the swap is stopped by sqrtPriceLimit after spending s where 1e17/(1e17+s) = sqrt(0.97) -> s = 1.534e15 wei, yielding received ~ 1.534e15*0.997*P*(1-0.015) = 1.506e15*P < 4.835e15*P, so _buy reverts SlippageExceeded and the whole executeBuyback reverts. Amounts below 5e15 revert in authorize (amount < _minimumTrade). An approved plan can only lower allocation[C] to total*3/(4n) = 3.75e17 (minimum trade 3.75e15), still > 1.534e15, so crew C's buyback budget cannot be spent at all this round; after the 22h deadline it is left in the hook as unreserved ETH. The same arithmetic applies to executeOwnBuyback with ownBurnBudget[C] >= 1.534e17 wei (minimum ceil(budget/100) > 1.534e15).","severity":"low","snippet":"        if (spent > action.amount0 || received < action.amount1 || received == 0) revert SlippageExceeded();","title":"Buyback minimum output is sized for the full ethAmount, so any fill that stops at the 303-tick price limit reverts; crews whose 1% minimum trade exceeds ~1.5% of their pool ETH cannot spend their allo"}],"hash":"625173f0766c8f0fc5f56d076cb2e9560c01c753410dd5d8994d44c07828d0ee","nodeId":"4010ef63-80f6-4668-9347-ff0678864b4c","outcome":"completed","summary":"The review is complete. The findings file is valid, its snippet matches the tree, and all 73 listed entry points have a coverage row. No repository file was changed.\n\n**Outcome: no critical, high or medium math defect found. One low finding.**\n\n**What I audited in depth (Math Precision, Boundary, Numerical Gap guides)**\n\n- **Ledger conversion chain.** SCALE = 4⁹·9! makes every 75% conversion `x·3/(4n)` exact for any sequence of distinct survivor counts, so the global eager update and the per-account lazy replay agree bit for bit and `InexactConversion` is unreachable. Escrow ceilings stay consistent through claims, and escrow release never underflows.\n- **Reserve sufficiency.** Each matched-LP addition is capped at int128.max or deferred, and total releases are bounded by 11I + 54M + 9, well inside the 10I + 100M reserve, so `_releaseReserve` cannot brick settlement.\n- **V4 liquidity quoting.** The engine's floor-rounded liquidity and the PoolManager's round-up amounts were traced. `ethUsed ≤ budget` holds, so the SlippageExceeded path in matched liquidity is unreachable and the Settling phase cannot get stuck.\n- **Fee library.** All four swap branches were checked against v4's hook-delta plumbing, including the 2%-of-gross gross-up and int128 bounds.\n- **Terminal paths.** V2 handoff, community fallback and expiry sweep use the same subtractions, cannot underflow, and the shared 30-day deadline means expired liabilities can never reach the V2 receiver in any call order.\n- **ETH backing.** Reserved player ETH and team ETH are always physically backed after fee materialization.\n\n**The one finding (low).** The buyback minimum output is computed for the whole requested ETH amount while the swap is bounded by a 3% price limit. Any fill cut by the limit returns fewer tokens than that minimum and reverts, so the engine's \"partial fills are allowed\" path is dead. For a crew whose 1% minimum trade exceeds roughly 1.5% of its pool's ETH reserve, no admissible amount exists and its round allocation cannot be spent. Funds are not lost. The ETH stays in the hook and reaches the finale paths. The reproduction with concrete numbers is in the file, with a minimal fix that keeps the bounded-buyback design.\n\n**Not reached.** No proof test was written, which is only required for critical or high findings. Fuzzing beyond the existing suite was not run in the budget.","treeHash":null,"usage":{"cachedInputTokens":1200177,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":60689,"runtime":"claude","turns":22,"wallClockMs":939275}},{"artifacts":[],"attempt":1,"bundleHash":"7a5f7741c79ea5d68730bc3c559d64cbe9fabe1ffbc6d8d218cbd1e60a06dc40","device":"f768e94767a9dde3","findings":[],"hash":"640474213b13f278256ecd5117ce9e5670f1fd7e22716dc19c5556dfaa9775f4","nodeId":"79d3b15c-d5e0-4b38-b8ba-de046bf860d2","outcome":"completed","summary":"Work is complete and committed. Final source pin: `0a1286b75de4b36392dfd777b93d984809029e32`, on top of the submitted pin `b553ba7`.\n\n**Admission outcome from this step:** the adapted source builds and tests green with the project's own configuration, but nothing is deployed. There is no launch record, no factory addresses and no receipts. Those come from IMD's deployer after the manifest step and audit, and I did not call the factory, sign anything or submit explorer verification. The four-factory manifest arguments remain exactly the single owner address per factory.\n\n**What reproduced and what changed**\n\n- **V2 receiver alias (low, reproduced).** A hook with the V2 receiver set to team, owner or community deployed successfully on `b553ba7`. The constructor in `src/imd/MugiIMDGameHook.sol` now rejects those three aliases, mirroring the existing community gate. `transferOwnership` also rejects the immutable V2 receiver as a new owner, so the separation holds after an ownership transfer. Four regression tests cover every variant.\n- **Gas-headroom test (low, reproduced on Forge 1.8.3).** The old meter saw 26,942 gas for four creations because Forge 1.8 does not meter `new` of a project artifact from a test-directory contract. The test now deploys the exact four initcodes in manifest order through raw CREATE2 in a test-only helper, which is what the IMD factory itself executes. Measured 12,296,955 gas including code deposit, conservative bound 14,824,595, consistent with the earlier Anvil receipt of 14,187,986.\n- **Fixture consequence.** The lifecycle base fixture used the test contract as both owner and V2 receiver, which the new gate rejects. It now uses a small forwarding receiver with its own address. All pre-existing balance and counter assertions pass unchanged.\n- **Three informational findings** needed no code change and are restated as trust assumptions in ADAPTATION.md and the new validation document: the community wallet and future V2 receiver are operator-controlled addresses, hook creation stays blocked until a reviewed nonzero receiver exists, and the four factories activate nothing.\n\n**Evidence**\n\n| Check | Result |\n| --- | --- |\n| forge test, verifier fuzz seed | 153 passed, 0 failed, 2 fork tests skipped (no RPC) |\n| Project artifact checker | all 75 sources match, constructors static and nonpayable, no forbidden selectors |\n| Raw hook creation code hash | `0x53dae9dd…8852b64` (changed from `b553ba7`, as the hook source changed) |\n\nOnly one production file changed. The full `git diff b553ba7 -- src test` is saved at `docs/validation/v2-alias-gate/src-test-diff.patch`, with the suite JSON, parsed results, summary and VALIDATION.md alongside. ADAPTATION.md lists each change, its file and the finding that required it. Compiler settings, dependencies, launch.json, economic rules, claims rules, the raw hook code pin and the constructor-complete child graph are untouched.\n\n**Open for later steps:** the real V2 receiver address, VRF, attestor and verifier settings still need a reviewed child deployment plan before any hook creation, and the independent audit should re-read the constructor gate and the forwarding receiver fixture.","treeHash":"5007a9048fe37d1e9713df444d1228b183dc89c6","usage":{"cachedInputTokens":2237312,"inputTokens":738,"model":"claude-fable-5-1","outputTokens":42498,"runtime":"claude","turns":49,"wallClockMs":1058075}},{"artifacts":[],"attempt":1,"bundleHash":"38eeea8e94ecd6bca021479c11b72ed56cf72948d3ab7995c0441143a8636e73","device":"29393b39cd68a88a","findings":[],"hash":"65c4c2c640f939f6faf37b1eca64958f4bc1bb315ba56168c1c2245d229b034e","nodeId":"22907b76-1428-4615-92ed-fe864716cb41","outcome":"completed","summary":"Updated only [launch.json](/home/imd-worker/.identitymd/work/9b411387-9c65-4aac-83b7-8d40e4ff1e88/22907b76-1428-4615-92ed-fe864716cb41/launch.json): preserved factory order, changed all owner arguments to `$owner`, and expanded disclosures within the 4,000-character limit.\n\nImplementation source remains `2907a8fec35bd79bde8f699ec8502bb5d644a3a4`.\n\nValidation passed:\n\n- Manifest structure, constructor ABI, bytecode limits and source-hash checks.\n- `forge build`.\n- Required-seed `forge test`: **153 passed, 0 failed, 2 fork tests skipped** without RPC configuration.\n\nAdmission and renewed independent audit remain pending. No mainnet deployment or explorer verification was performed; no production launch record, factory addresses or receipts are available.","treeHash":"5c64a3df5154a896c4454a2e7e0a9bc42e194ca4","usage":{"cachedInputTokens":2056448,"inputTokens":166170,"model":"gpt-6-astra","outputTokens":12249,"runtime":"codex","turns":6,"wallClockMs":350054}},{"artifacts":[],"attempt":1,"bundleHash":"d8b9ca1696170beb00370a416d99363a04b6a453839b780c4e90c44d71e3f951","device":"eaa98ad0794d4f76","findings":[],"hash":"981bcbf528573ffe1bb6a2ac97f5daeed742ec8f037cdd1bc463088164783c63","nodeId":"636ebb9d-2203-4dc9-b0a1-bdfb6b9aa963","outcome":"completed","summary":"Added 19 tests under `test/`, including five invariant campaigns covering 49,152 randomized calls.\n\nOffline build and seeded tests passed: **172 passed, 0 failed, 2 fork suites skipped**.\n\nProduction source remains unchanged at `2907a8fec35bd79bde8f699ec8502bb5d644a3a4`.\n\n[Review, source diff and validation evidence](/home/imd/.identitymd/work/9b411387-9c65-4aac-83b7-8d40e4ff1e88/636ebb9d-2203-4dc9-b0a1-bdfb6b9aa963/test/imd/REGRESSION_REVIEW.md). Admission remains unestablished; no deployment, launch record, factory addresses or receipts were produced.","treeHash":"c98f9ef1ebe49484647f292a9529040e219768ad","usage":{"cachedInputTokens":7863552,"inputTokens":218442,"model":"gpt-6-astra","outputTokens":44648,"runtime":"codex","turns":9,"wallClockMs":1116674}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"a5c5e95a2ed07117","findings":[{"citation":"resolved","description":"The repair for the prior blocking finding (owner-selected V2 destination) pins `v2MigrationTarget` in the hook constructor and makes `migrateToV2` permissionless to exactly that address (src/imd/MugiIMDGameHook.sol:493-494). The deployment plan (ADAPTATION.md 'The address can be planned before the V2 contract is deployed'; hook-constructor.json leaves it null) explicitly allows the pinned address to have no code when the hook is created. `deployHook` checks that ledger/engine/budgets/prices have code but never checks `c.v2MigrationTarget.code.length`, and the hook only checks `target.code.length != 0` at migration time. Consequently, if the receiver is a CREATE2/CREATE address controlled by the operator (the only way to 'plan' an undeployed address), the economic guarantee is address-fixed but code-free: after `finalize()` the operator deploys any contract there, including a plain forwarder to its own wallet, and anyone (or the operator) calls `migrateToV2` to send all unreserved finale ETH plus survivor inventory to that code. This is functionally the same outcome as the owner-selected sink the prior audit asked to remove; the owner/team/community inequality gates do not constrain it because the forwarder is a fresh address. On mainnet after Pectra an EOA receiver can also satisfy the `code.length != 0` check through EIP-7702 delegation. ADAPTATION.md discloses 'V2 receiver code governs its later use of protocol funds' as a trust assumption, so this is reported as low (trust assumption, disclosed) rather than medium, but the code-enforced remedy is weaker than the brief's 'immutable receiver binding' reads. Minimal fix preserving all game rules: in `deployHook` add `|| c.v2MigrationTarget.code.length == 0` to the InvalidConfiguration gate (a runtime factory check, not a constructor check, so the empty-chain constructor rule is untouched), which forces the actual receiver contract to exist and be reviewable before hook creation; optionally also reject a receiver whose code is an EIP-7702 delegation prefix (0xef0100).","line":142,"path":"src/imd/MugiV1IMDDeploymentFactory.sol","reproduction":"State: hook created with v2MigrationTarget = CREATE2 address P that has no code (deployHook accepts it; hook constructor accepts it). Run a full season and call finalize(). Step 1: migrateToV2(P) reverts InvalidState (code.length == 0). Step 2: operator deploys OperatorForwarder{salt}(operatorWallet) at P. Step 3: any caller (BOB) calls migrateToV2(P): succeeds, migrated == true, operatorWallet receives exactly address(game).balance - teamEth - reservedPlayerEth and MugiCrewToken(survivor).balanceOf(game) - escrowBacking(survivor). Expected per brief: receiver bound before hook creation so that the finale sink is reviewed and not operator-chosen later. Actual: pinned address only; code chosen post-finale. Verified locally with test/scratch/ReviewEconomics.t.sol::testUndeployedReceiverAddressLetsOperatorChooseCodeAfterFinale (passes on current code, demonstrating the behaviour).","severity":"low","snippet":"            || crewFactory.hook() != plannedHook || c.ledger.code.length == 0 || c.engine.code.length == 0\n            || c.budgets.code.length == 0 || c.prices.code.length == 0) revert InvalidConfiguration();","title":"Immutable V2 receiver binds an address, not code: a codeless precommitted receiver leaves the operator free to choose the finale sink after finalize"},{"citation":"resolved","description":"In `recoverStalledRandomness` the final batch removes every live crew's V4 position; the token side of each removal (`removed.tokenPrincipal`) lands in the hook as released inventory. Only `unreleasedReserve` is burned (`_retireReserve`), `sweepExpiredFinalClaims` later burns only `escrowBacking`, and `fallbackFinaleToCommunity`/`migrateToV2` are gated to `Phase.Finalized`, so no path ever burns or forwards these tokens. Normal finale, by contrast, forwards the survivor's released inventory to V2/community. The brief's stated rule that unused supply is burned when the season closes therefore holds only for reserve, not for the re-acquired LP principal; the tokens remain counted in totalSupply forever and the hook becomes a permanent dead holder (excluded from eligibility, so no reward effect). No ETH or player claim is affected, hence informational. Minimal fix: in the `settlementCursor == 10` branch of `recoverStalledRandomness`, after `_retireReserve(i)`, burn `balanceOf(hook) - escrowBacking(i) - teamTokens[i]` for each live crew (or burn it in `sweepExpiredFinalClaims` when phase is EmergencyClosed).","line":325,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"State: season launched, one round settled, second round's requestElimination called then warped to randomnessDeadline(); recoverStalledRandomness(10) -> EmergencyClosed. Warp to claimsExpireAt, call sweepExpiredFinalClaims() then withdrawTeamFees(). For each live crew i: escrowBacking(i) == 0, unreleasedReserve(i) == 0, teamTokens(i) == 0, yet sum of MugiCrewToken(crew[i]).balanceOf(hook) == 9,029,641,035,000,000,000,004,182 base units (SUPPLY 1e24, POOL_ETH 100 ether fixture). fallbackFinaleToCommunity() reverts InvalidState. Expected: season-close burns or forwards all protocol inventory; actual: tokens stranded. Verified with test/scratch/ReviewEconomics.t.sol::testEmergencyClosureStrandsLiveCrewLpTokensInHook.","severity":"info","snippet":"            for (uint8 i; i < 10; ++i) if ((aliveMask & (uint16(1) << i)) != 0) _retireReserve(i);","title":"Emergency closure never retires or forwards live-crew LP principal tokens; they stay in the hook after sweep and team withdrawal"}],"hash":"aab6199f0c4d4f091ae70318447a7ed276cc117875a85d1a7c4e85f308f2a689","nodeId":"2b18bf31-33e0-494c-9eea-fb018cda6e06","outcome":"completed","summary":"The review is complete. Both findings are anchored to lines that match the tree, the JSON parses, and no tracked file changed. Nothing remains that needs another tool call.\n\n**Outcome.** No critical, high or medium defect in the Economic Security, Invariant and Flow Gap areas of the submitted source. The three repaired blocking findings from the prior audit are code-enforced and regression-tested as described. All 153 non-fork tests pass locally on Forge 1.8.3. The two fork suites were not run.\n\n**Findings written to `.imd-findings.json`:**\n\n- **Low, receiver binding is address-only.** The hook pins the V2 receiver address, and `migrateToV2` is permissionless to exactly that address with atomic rollback. But `deployHook` never requires the receiver to have code, and the plan explicitly allows an undeployed address. My scratch test shows the operator deploying a forwarder at the codeless precommitted address after finale, after which anyone's `migrateToV2` sends all unreserved finale ETH and survivor inventory to the operator wallet. This is the prior \"owner-selected sink\" outcome by another route. ADAPTATION.md discloses receiver code as a trust assumption, so I rated it low. The minimal fix is a runtime code-presence check on the receiver in `deployHook`, which keeps every game rule intact.\n- **Info, emergency closure strands tokens.** After `recoverStalledRandomness`, the live crews' LP principal tokens return to the hook and no path ever burns or forwards them. The sweep burns only escrow, and the community fallback is gated to the normal finale. Reproduced: about 9.03M base units remain in the hook after sweep and team withdrawal in the fixture. No ETH or claim is affected.\n\n**Coverage.** All 76 listed entry points have a row, plus solvency, deadline-ordering, treasury-separation, deployment-size and manifest rows. Verified invariants include ETH solvency against team and reserved player ETH, token solvency against escrow, reserve and team tokens, mutual exclusion of handoff versus fallback at the shared deadline in both call orders, and the community/owner/team/V2 inequality gates surviving ownership transfer. The four verifier entry points are marked holds on the basis that they only gate plan approval, which the buyback module bounds regardless.\n\n**Deployment evidence.** Local Anvil receipt shows 14.19M gas including code deposit against a 16.78M cap. Hook runtime has 941 bytes of EIP-170 headroom and the deployment factory initcode has 2,182 bytes of EIP-3860 headroom. This is local proof only; nothing is deployed, the policy gas ceiling is not in the tree, and the V2 receiver remains unresolved in the child plan.","treeHash":null,"usage":{"cachedInputTokens":1499560,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":48281,"runtime":"claude","turns":32,"wallClockMs":1114200}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"1da032f42d59f73b","findings":[{"citation":"resolved","description":"MugiIMDGameHook._buyAndBurn (src/imd/MugiIMDGameHook.sol:427-428) asks the oracle for minTokens on the WHOLE ethAmount (TWAP quote x 0.997 x 0.97) together with a sqrtPriceLimit 303 ticks (~3%) below spot, and engine._buy then requires received >= that full-budget minimum. A full-range position reaches the 3% limit after roughly 1.53% of the pool's ETH is swapped in, so any ethAmount above ~1.56% of pool ETH is partially filled and always reverts SlippageExceeded. The engine natspec ('Partial fills are allowed here; the budget must be charged by actual ethSpent') and MugiIMDBuybacks.account(actualSpent) / executeOwnBuyback's `spent < minimum` check assume partial fills succeed; they cannot. Because executeOwnBuyback requires ethAmount >= ceil(ownBurnBudget/100) and MugiIMDBuybacks.authorize requires amount >= ceil(allocation/100), a crew whose own-burn budget exceeds ~1.56x its pool ETH (or whose round allocation exceeds ~1.56x pool ETH, e.g. after holder sells drain a thin pool) has no admissible amount at all. ownBurnBudget only grows from swap fees until spent, so once stuck it stays stuck until the crew is eliminated. ETH is not lost (it stays in the hook and later flows to the loser settlement budget, finale handoff/fallback or emergency recovery), but the published 'bounded buybacks' rule silently stops executing for high-volume/thin-liquidity crews. Specialist audit_math reported the round-budget variant; reproduced here through the own-burn path. Fix: check output against minimum scaled by actual spend (burned >= minimum * spent / ethAmount) or size the minimum to the ETH that can fill before the limit, keeping budgets charged by spent.","line":369,"path":"src/imd/modules/MugiIMDV4Engine.sol","reproduction":"Lifecycle fixture MugiGameTestBase (SUPPLY 1e24, POOL_ETH 100 ether per crew, launched). Through PoolSwapTest, 90 round trips on crew 0 of buy 100 ETH exact-in then sell the whole bought balance, 61 s apart, then warp +2 h (TWAP settles, deviation < 488 ticks). State: ownBurnBudget(0) = 177797514266584282887 wei, pool-0 liquidity 9.7468e21 (~100 ETH). executeOwnBuyback(0, 1777975142665842829) (exact minimum = ceil(budget/100)) reverts MugiIMDV4Engine.SlippageExceeded; executeOwnBuyback(0, budget/20) (maximum) also reverts SlippageExceeded; executeOwnBuyback(0, minimum-1) reverts InvalidState. Expected: a partial fill up to the price limit (~1.55 ETH) is executed, charged by spent and burned. Actual: no amount in the admissible range can execute. Ran test/scratch/Review.t.sol::testOwnBuybackMinimumOnFullBudget (passes, demonstrating the behaviour).","severity":"low","snippet":"        if (spent > action.amount0 || received < action.amount1 || received == 0) revert SlippageExceeded();","title":"Bounded buyback minimum is quoted on the full budget, so any fill stopped by the 303-tick price limit reverts; own-burn and round budgets become unspendable once their 1% minimum exceeds ~1.5% of pool"},{"citation":"resolved","description":"recoverStalledRandomness removes each live crew's full-range position; MugiIMDV4Engine._settle takes the token principal to the hook. At close only unreleasedReserve is burned (_retireReserve). sweepExpiredFinalClaims later burns only the ledger escrow backing (expireFinalClaims) and pays ETH; fallbackFinaleToCommunity and migrateToV2 require Phase.Finalized; no other path moves or burns hook-held crew tokens. In the ordinary finale the same released inventory is handed to V2 or the community; in the EmergencyClosed path it is stranded and permanently counted in totalSupply, contrary to the stated rule that protocol inventory/unused supply is retired at season close. No ETH or player claim is affected (the hook is an excluded account). Merged duplicate of audit_flow (low) and audit_economics (info). Fix: in the settlementCursor==10 branch burn balanceOf(hook) - escrowBacking(i) - teamTokens[i] for each live crew (or burn it in sweepExpiredFinalClaims when EmergencyClosed), re-checking the 941-byte runtime headroom.","line":325,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Lifecycle fixture, launched, no request made. warp(randomnessDeadline()); recoverStalledRandomness(10) -> EmergencyClosed; warp(claimsExpireAt()); sweepExpiredFinalClaims(); withdrawTeamFees(). For every crew i: balanceOf(hook) = 949999999999999999999999, escrowBacking(i) = 0, unreleasedReserve(i) = 0; fallbackFinaleToCommunity() reverts InvalidState. Expected: hook balance == escrowBacking + teamTokens (0) after season close. Ran test/scratch/Review.t.sol::testEmergencyStrandsLp.","severity":"low","snippet":"            for (uint8 i; i < 10; ++i) if ((aliveMask & (uint16(1) << i)) != 0) _retireReserve(i);","title":"Emergency closure leaves every live crew's withdrawn LP principal tokens in the hook forever; they are neither burned nor forwarded"},{"citation":"resolved","description":"Aborted is terminal, but abortPrelaunch only removes seeded positions and refunds ETH. unreleasedReserve stays at reserveCap for every crew (minus initialSupply for seeded crews), the returned 95% LP tokens stay in the hook and the 5% drop stays in MugiAirdrop. retireAirdrop requires launchedAt != 0 and sweepExpiredFinalClaims requires Finalized/EmergencyClosed, so nothing can ever burn them. The documented rule 'Unused reserve is excluded from eligibility and burned when its crew or season closes' (ADAPTATION.md, launch.json notes) is not enforced on this close. No ETH loss (only the owner's own seed is refunded); impact is a permanently misleading supply picture for a dead season that a later V2 or explorer could read as live. Reported by audit_permissions. Fix: in abortPrelaunch call _retireReserve(i) for all crews, burn the hook's returned crew balances, and allow retireAirdrop in Phase.Aborted.","line":257,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Fresh hook from _deployGameAt(0x1235...2aec, 1e24): seedPool{value:1 ether}(0); abortPrelaunch(). Observed: crew0 totalSupply 17014118346046933173168730371588410572700, hook balance 17014118346046933123168730371588410572699, airdrop balance 50000000000000000000000, unreleasedReserve(0) 17014118346046932173168730371588410572700; crew1 totalSupply unchanged at reserveCap; retireAirdrop() and sweepExpiredFinalClaims() revert InvalidState. Expected: reserve and returned inventory burned at the Aborted close. Ran test/scratch/Review.t.sol::testAbortKeepsReserve.","severity":"low","snippet":"        phase = Phase.Aborted;","title":"abortPrelaunch closes the season without retiring unreleased reserve, returned LP tokens or the airdrop's 5%, and no later path can"},{"citation":"resolved","description":"The repair for the prior 'owner-selected V2 destination' finding pins v2MigrationTarget in the hook constructor and lets anyone hand off to exactly that address. Neither the hook constructor nor MugiV1IMDDeploymentFactory.deployHook (src/imd/MugiV1IMDDeploymentFactory.sol:139-143, which checks code only for ledger/engine/budgets/prices) requires the receiver to have code, and the repository test testNonzeroFutureV2ContractCanBePinnedBeforeItsDeployment confirms a codeless address is accepted. Code is only checked at migration time. If the pinned address is a CREATE/CREATE2 address the operator controls (the only way to plan an undeployed address), the operator chooses the receiver code after finalize, e.g. a forwarder to its own wallet, and every unreserved finale ETH and survivor-inventory unit reaches it; the owner/team/community inequality checks do not constrain a fresh address. On mainnet an EOA receiver can also pass code.length != 0 through an EIP-7702 delegation. ADAPTATION.md discloses that V2 receiver code governs later use of funds and the plan keeps the receiver unresolved, so this is low (trust assumption made code-enforceable), not a reopening of the medium. Merged duplicate of audit_economics (low) and audit_flow (info). Fix preserving the game rules: in deployHook reject c.v2MigrationTarget.code.length == 0 (a runtime factory check, not a constructor check) and optionally reject a 0xef0100 delegation prefix, so the reviewed receiver code exists before the hook is committed.","line":493,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Configuration.v2MigrationTarget = address(0xABC123) (no code): deployHook succeeds (test/imd/MugiTerminalConfiguration.t.sol:63-68). Run nine rounds and finalize(): migrateToV2(0xABC123) reverts InvalidState. The address's controller then deploys at it a contract whose receiveV1Finale forwards msg.value and the survivor tokens to the owner wallet; any caller's migrateToV2(0xABC123) before migrationDeadline succeeds and the owner wallet receives address(hook).balance - teamEth - reservedEth and balanceOf(hook) - escrowBacking(survivor). Expected per the brief: receiver reviewed and fixed before hook creation. Actual: only its address is fixed; its code is chosen later.","severity":"low","snippet":"        if (phase != Phase.Finalized || migrated || target.code.length == 0\n            || target != v2MigrationTarget || block.timestamp >= migrationDeadline) revert InvalidState();","title":"Immutable V2 receiver binds only an address: a codeless pinned receiver lets its deployer choose the finale sink's code after finalize"}],"hash":"e71eb970552d966392cea27f4f7b9fd50d6517e475ed2b8976dbd790500f6ce7","nodeId":"d80445a5-fec1-479d-9c22-2a385f2a5453","outcome":"completed","summary":"I found no critical, high or medium defects. Four low findings survived reproduction, so the three medium findings from the earlier audit (job 0c8421fb) don't reopen. Admission still requires none of my findings to be outstanding, though, so these four lows have to be fixed before the launch can be admitted. The results and a 75-row coverage record are in `.imd-findings.json`: all 73 listed entry points plus two invariant rows. Every snippet in it matches the tree.\n\nThe source under review is identical to the submitted pin `2907a8f`; the commits after it change only tests and evidence. I deployed nothing, have no launch record, factory addresses or receipts, and changed no files. The scratch tests I used have been deleted.\n\n**Findings (all low):**\n1. **Buybacks can become impossible to execute** (`MugiIMDV4Engine.sol:369`). The minimum token output is worked out for the whole ETH amount, but the swap stops at a price limit about 3% away. So any buyback larger than about 1.56% of the pool's ETH always reverts. I reproduced it through the crew's own burn budget: 177.8 ETH against a ~100 ETH pool. Both the smallest allowed amount (1.78 ETH) and the largest (budget/20) revert `SlippageExceeded`, and anything below the minimum reverts `InvalidState`. The ETH isn't lost: it stays in the hook and goes to later settlement or the finale. This merges the math specialist's round-budget version of the same problem.\n2. **Emergency closure leaves LP tokens stuck in the hook** (`MugiIMDGameHook.sol:325`). After `recoverStalledRandomness`, the claims sweep and the team withdrawal, the hook still holds 949,999.99… tokens per crew. Escrow and reserve are both 0, and no function can burn or move these tokens. This merges two specialists' reports of the same issue.\n3. **`abortPrelaunch` burns no reserve** (`:257`). The reserve, the returned LP tokens and the airdrop's 5% all stay. `retireAirdrop` and `sweepExpiredFinalClaims` revert in the Aborted state, so this breaks the stated rule that unused reserve is burned when the season closes.\n4. **The V2 receiver is fixed by address only, not by code** (`:493`). `deployHook` accepts an address with no code (the repo's own test confirms it), so whoever controls that address can choose the receiver's code after `finalize`. An EOA with an EIP-7702 delegation would also pass the code check. The suggested fix is to require receiver code in `deployHook`. This merges two specialists' reports.\n\n**What holds:**\n- **Receiver repair:** the handoff goes only to the exact pinned target, only inside the 30-day window, and rolls back entirely if the receiver fails.\n- **Community fallback:** it pays only unallocated ETH and tokens, and works whether it runs before or after the claims sweep.\n- **Treasury separation:** the community treasury can't equal the owner or team, including after an ownership transfer, and the V2 receiver can never become owner.\n- **Deployment sizes:** the hook's runtime is 23,635 B (941 B under the 24,576 B limit). The main factory's creation code is 46,970 B plus the 32 B owner word (under 49,152 B).\n\n**Dropped findings:**\n- Thin size headroom: true, but not a defect.\n- The final survivor's treasure going to V2 rather than holders: a documented design choice.\n- Missing test for a code-less receiver: a test gap only.\n- `registerPool`: the hook never calls it, so it is unreachable.\n\nI didn't read the verifier and router line by line. I checked their guards, so those coverage rows are based on lighter tracing than the hook, ledger, engine, buyback, oracle, factory, airdrop and VRF rows.","treeHash":null,"usage":{"cachedInputTokens":2001169,"inputTokens":42,"model":"claude-opus-5-5","outputTokens":31096,"runtime":"claude","turns":24,"wallClockMs":1189781}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"30bcdea6dcb9ee40","findings":[{"citation":"resolved","description":"recoverStalledRandomness removes every alive crew's full-range position, which returns the LP token principal to the hook (engine _settle takes to hook). At close it only burns unreleasedReserve[i] via _retireReserve. sweepExpiredFinalClaims later burns only the ledger escrow backing (expiredTokens[i]) and pays ETH as balance - teamEth to the community. No path ever burns or moves the returned LP principal tokens: fallbackFinaleToCommunity and migrateToV2 require Phase.Finalized, claims are expired, and the hook has no other token sink. In the ordinary finale the same inventory is handed to V2 or the community; in the emergency path it is simply stranded. Impact is no fund loss (the hook is an excluded account so eligibility is unaffected) but each crew's totalSupply permanently overstates circulating supply by the stranded amount, contrary to the published rule that season closure retires protocol inventory, and the asymmetry between the two terminal paths is undocumented. Minimal fix: in recoverStalledRandomness, after _retireReserve(i), burn the hook-held balance of alive crew i that exceeds ledger escrowBacking(i) + teamTokens[i] (or route it to communityTreasury in sweepExpiredFinalClaims for the EmergencyClosed branch, mirroring the ETH treatment).","line":325,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"State: launched season from the lifecycle fixture (MugiGameTestBase, initialSupply 1e24 per crew, silent VRF coordinator). Sequence: warp to nextCutoff; requestElimination(); warp to randomnessDeadline(); recoverStalledRandomness(10) -> phase EmergencyClosed; warp to claimsExpireAt(); sweepExpiredFinalClaims(). Observed (test/scratch/EmergencyLeftover.t.sol, logs): for every crew i, MugiCrewToken(tokens[i]).balanceOf(hook) == 949999999999999999999999 while escrowBacking(i) == 0, unreleasedReserve(i) == 0, teamTokens(i) == 0; fallbackFinaleToCommunity() and migrateToV2(target) both revert InvalidState. Expected: at season close every hook-held unit that backs no liability is burned (as the ordinary finale and the reserve rule do), leaving balanceOf(hook) == escrowBacking + teamTokens.","severity":"low","snippet":"            for (uint8 i; i < 10; ++i) if ((aliveMask & (uint16(1) << i)) != 0) _retireReserve(i);","title":"Emergency closure retires only unreleased reserve; withdrawn LP tokens of every alive crew stay in the hook forever and remain in totalSupply"},{"citation":"resolved","description":"The constructor rejects v2MigrationTarget equal to owner, team or community and the handoff only accepts that exact address, but the address may be pinned before any code exists there (testNonzeroFutureV2ContractCanBePinnedBeforeItsDeployment). The operator therefore chooses the receiver's code later. The repository's own lifecycle fixture demonstrates the consequence: ForwardingV2Receiver (test/imd/lifecycle/MugiGameHook.t.sol:44) is constructed with the owner test contract as sink and forwards all received ETH and survivor tokens to it, and every handoff test passes with it. This is a trust assumption the task already states (handoff is protocol-fund continuity, receiver must be reviewed before hook creation); it is recorded here so the admission decision does not treat the alias gate as custody separation. No code change is proposed; the required control is the off-chain review of the actual receiver source and deployment address before deployModules commits the hook initcode hash.","line":493,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"Input: Configuration.v2MigrationTarget = CREATE2/CREATE-predicted address A with no code; deploy hook; later deploy at A a contract whose receiveV1Finale(uint8,address,uint256) payable forwards msg.value and the token balance to the owner wallet. After finalize(), any caller runs migrateToV2(A): all ETH except teamEth + reservedEth and all survivor inventory except escrow arrive at the owner. The alias gate (line 131-134) does not fire because A != owner. Expected per the prior report's intent: the finale destination is not owner-controlled; actual: it is, unless the receiver is independently reviewed.","severity":"info","snippet":"        if (phase != Phase.Finalized || migrated || target.code.length == 0\n            || target != v2MigrationTarget || block.timestamp >= migrationDeadline) revert InvalidState();","title":"Immutable V2 receiver binding is address-level only: the operator deploys whatever code lands at the pinned address, so a receiver that forwards to the owner passes every gate"},{"citation":"resolved","description":"Because the main factory embeds the complete hook creation code in its own initcode to pin the hash, the factory's initcode (46,970 B + 32 B owner word = 47,002 B) sits 2,150 B below the 49,152 B initcode limit, and the hook runtime (23,635 B) sits 941 B below the 24,576 B runtime limit. The validation record (docs/validation/v2-alias-gate/VALIDATION.md) measures the four creations at 12,296,955 gas with a conservative bound of 14,824,595 against the 16,777,216 transaction cap. These numbers hold for this exact pin (forge build --sizes on Forge 1.8.3, solc 0.8.26, viaIR, 200 runs, bytecode_hash none) but leave little room: a repair of the low finding above, if applied, must be checked against both limits before re-pinning. No defect in the current tree.","line":79,"path":"src/imd/MugiV1IMDDeploymentFactory.sol","reproduction":"Run forge build --sizes at this pin: MugiIMDGameHook runtime 23,635 B (margin 941), MugiV1IMDDeploymentFactory initcode 46,970 B (margin 2,182 before the constructor argument). Adding roughly 1 KB of runtime to the hook makes deployHook's CREATE2 fail on mainnet (EIP-170) even though forge tests with code_size_limit unset also enforce it; adding ~2.2 KB to the hook creation code makes the factory's own creation exceed EIP-3860 and the IMD launch transaction reverts.","severity":"info","snippet":"        hookCreationCodeHash = keccak256(type(MugiGameHook).creationCode);\n        hookCreationCodeLength = type(MugiGameHook).creationCode.length;","title":"Deployment headroom is thin: hook runtime is 941 bytes under EIP-170 and the main factory initcode is 2,150 bytes under EIP-3860; any further hook fix of that size blocks the four-factory launch"},{"citation":"resolved","description":"treasure[crew] is only converted into holder rewards when that crew is the loser (_beginSettlement -> ledger.recordElimination(loser, aliveMask, treasure[loser], ...)). The last survivor is never a loser, so its treasure, the unspent part of the round-9 buyback budget and its ownBurnBudget stay as plain hook ETH and are included in ethAmount at migrateToV2/fallbackFinaleToCommunity. This matches the documented handoff ('protocol-fund continuity') and the historical response (docs/IMD_FOLLOWUP_RESPONSE.md:71) but the current ADAPTATION.md and README do not state that survivor-pool game fees collected during the final round are not a holder reward. Disclosed here as a gate/assumption per the assignment, not as a code defect.","line":499,"path":"src/imd/MugiIMDGameHook.sol","reproduction":"State: Live season with eliminations == 9, survivor crew S. Input: a player buys on pool S via MugiIMDSwapRouter.buy(S, 0, deadline) with 10 ether; _gameFee books 0.1 ether as treasure[S] and ownBurnBudget[S]. After finalize() and migrateToV2(v2MigrationTarget): previewAccount(player).earnedEth is unchanged by that fee and the receiver's msg.value includes it. Expected under a reading of 'pro-rata treasures' as holder rewards: the fee reaches S holders; actual: it reaches the V2 receiver or, after the deadline, the community wallet.","severity":"info","snippet":"        uint256 ethAmount = address(this).balance - teamEth - ledger.reservedEth();","title":"Final survivor's accrued treasure, unspent round budgets and own-burn budget are never distributed to holders; they are handed to V2 or the community as unreserved ETH"}],"hash":"e9d4c26ce8dfb47de575dc8724d27e470965d625a6c97add2cecaec4a192c800","nodeId":"a53b19e3-373a-44e0-a74a-52ddb815c5d1","outcome":"completed","summary":"Review complete. The findings file is written and validated: all four snippets match the tree at their cited lines, and all 73 listed entry points have a coverage row (plus manifest and three invariant rows).\n\n**Outcome**\n\nNo critical, high or medium defects found in the assigned area (Execution Trace, Periphery, First Principles) at pin `2907a8f`. The three remedies the follow-up targeted hold as code-enforced:\n\n- **Immutable receiver binding**: the constructor rejects a zero target and any alias of owner, team or community. The handoff accepts only that exact address, strictly before the deadline, one-shot, with full rollback on receiver revert.\n- **Finale liveness**: at the deadline anyone can route only unreserved ETH and survivor inventory to the immutable community wallet. Both orderings with the expired-claims sweep pay the community exactly once and keep team ETH and claim reserves.\n- **Treasury separation**: constructor and ownership-transfer gates hold, and the ledger's configuration hash binds the same team and community addresses.\n\nThe existing suite passes (153 tests, fork suites excluded for lack of RPC). Build is clean on Forge 1.8.3, solc 0.8.26, Cancun, viaIR, 200 runs, bytecode hash none.\n\n**Findings written to `.imd-findings.json`**\n\n1. **Low.** Emergency closure strands every alive crew's withdrawn LP token principal in the hook. After `recoverStalledRandomness` and `sweepExpiredFinalClaims`, each crew token shows about 950k units held by the hook with zero escrow, reserve or team liability, and no path can burn or move them. No fund loss, but totalSupply permanently overstates circulating supply and the behavior differs from the ordinary finale, which hands that inventory off. Reproduced in `test/scratch/EmergencyLeftover.t.sol`.\n2. **Info.** The receiver binding is address-level only. The address may be pinned before code exists, so the operator chooses the receiver code later. The project's own lifecycle fixture uses a receiver that forwards everything to the owner and passes all gates. This confirms the task's stated trust assumption rather than custody separation.\n3. **Info.** Size headroom is thin: hook runtime is 941 bytes under EIP-170 and the main factory initcode is about 2.1 KB under EIP-3860. Any repair of finding 1 must be re-measured before re-pinning.\n4. **Info.** The final survivor's accrued treasure, unspent budgets and own-burn budget are never distributed to holders. They are included in the handoff or fallback ETH. Disclosed in a historical response doc but not in the current ADAPTATION or README.\n\n**Coverage limits.** I did not run the two mainnet-fork suites, did not reach the live IMD factory or any deployed state, and did not independently re-derive the Uniswap v4 fee-delta sign conventions beyond the passing router tests. Everything reported is local proof, not deployed state.","treeHash":null,"usage":{"cachedInputTokens":1855723,"inputTokens":482,"model":"claude-fable-5-1","outputTokens":57131,"runtime":"claude","turns":32,"wallClockMs":985774}}],"verification":[{"checks":[{"durationMs":116580,"exitCode":0,"name":"build","output":"Compiling 130 files with Solc 0.8.26\nSolc 0.8.26 finished in 116.45s\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:649:29:\n    |\n649 |     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:650:29:\n    |\n650 |     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:652:28:\n    |\n652 |     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:654:22:\n    |\n654 |     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:655:21:\n    |\n655 |     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:656:24:\n    |\n656 |     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:657:32:\n    |\n657 |     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:658:26:\n    |\n658 |     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:658:61:\n    |\n658 |     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:658:73:\n    |\n658 |     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:658:93:\n    |\n658 |     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:662:26:\n    |\n662 |     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":7999,"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 442.94µ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 384.64µs (54.19µs 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 3.06ms (1.43ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 28784071)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127670)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 476715)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 38.12ms (25.41ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271185)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194604)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339541)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977542)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4101806)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11140650)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325913)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4877130)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221567)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 41.92ms (28.84ms 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.04ms (6.83ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6126106)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 29336743)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 38111477)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6072434)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1355546)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20116549)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5622474)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170667)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 76.06ms (81.57ms CPU time)\n\nRan 7 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCommunityTreasuryCannotBecomeOwner() (gas: 156387)\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7347756)\n[PASS] testExpiryBeforeFinaleFallbackCannotEraseMigrationDeadline() (gas: 32027455)\n[PASS] testFinaleFallbackHasHardDeadlineAndPreservesReservedAssets() (gas: 33163720)\n[PASS] testRejectingCommunityRollsBackFallbackAndAllowsPermissionlessRetry() (gas: 32119000)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 32078099)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 33996865)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 81.50ms (129.11ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934470)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1625388)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6507663)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9364448)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294260)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 27109034)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439097)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 42779645)\nLogs:\n  Settlement and request gas: 5523981\n  Settlement and request gas: 4788239\n  Settlement and request gas: 4376112\n  Settlement and request gas: 3917036\n  Settlement and request gas: 3452832\n  Settlement and request gas: 3002300\n  Settlement and request gas: 2559231\n  Settlement and request gas: 2087443\n  Settlement and request gas: 1621026\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 376097)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1373149)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11162742)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5632587)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341859)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5523412)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 7744778)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1568622)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241731)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 81.47ms (77.33ms 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, μ: 4060790, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 114.61ms (124.22ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 449640)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1042642)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 852134)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 620467)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1013210, ~: 1013847)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5275342)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 902672)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 807282)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 994718)\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 122.09ms (121.94ms 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 474.36ms (5.73ms 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 475.47ms (3.75ms 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 476.01ms (1.78ms 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, μ: 22395884, ~: 21685153)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 476.16ms (506.24ms CPU time)\n\nRan 8 tests for test/imd/MugiTerminalConfiguration.t.sol:MugiTerminalConfigurationTest\n[PASS] testCommunityCannotBeV2Receiver() (gas: 69634447)\n[PASS] testNonzeroFutureV2ContractCanBePinnedBeforeItsDeployment() (gas: 73917688)\n[PASS] testOwnerCannotBeCommunityDestination() (gas: 230121597)\n[PASS] testOwnerCannotBeV2Receiver() (gas: 20272703)\n[PASS] testTeamCannotBeCommunityDestination() (gas: 74924950)\n[PASS] testTeamCannotBeV2Receiver() (gas: 126831952)\n[PASS] testV2ReceiverCannotBecomeOwnerEvenAfterOwnershipTransfer() (gas: 52267373)\n[PASS] testZeroV2ReceiverCannotCreateHook() (gas: 42409306)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 7.63s (550.49ms 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, μ: 54383, ~: 54214)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3525674, ~: 3643842)\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.63s (540.99ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 60779609)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 30756234)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 80690058)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 51069839)\nLogs:\n  Four service module creations: 3693232\n  Runtime code-deposit component: 2795600\n  Conservative independent-transaction bound: 3871640\n  Ten crew token creations: 9091768\n  Runtime code-deposit component: 6618000\n  Conservative independent-transaction bound: 9336736\n  Engine creation: 2499879\n  Runtime code-deposit component: 2407200\n  Conservative independent-transaction bound: 2634255\n  Three accounting module creations: 3831291\n  Runtime code-deposit component: 3003000\n  Conservative independent-transaction bound: 3997411\n  Hook creation: 5992259\n  Runtime code-deposit component: 4727000\n  Conservative independent-transaction bound: 6544411\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 232359)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14359475)\nLogs:\n  Four factory creation bound: 12296955\n  Runtime code-deposit component: 12075000\n  Conservative independent-transaction bound: 14824595\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 106592148)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 39968369)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 50978506)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 50978440)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 52890937)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 26387216)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 7.88s (521.87ms CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 563451)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7024281)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 30536531)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 219506900, ~: 218579390)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 35895439)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 26936260)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.88s (7.93s CPU time)\n\nRan 19 test suites in 7.88s (33.55s CPU time): 153 tests passed, 0 failed, 2 skipped (155 total tests)\n","passed":true},{"durationMs":77,"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.fallbackFinaleToCommunity()\",\"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\":122,\"README.md\":45,\"docs/IMD_COMPATIBLE_R2_RESPONSE.md\":15,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":42,\"docs/IMD_FINDINGS_RESPONSE.md\":63,\"docs/IMD_FOLLOWUP_RESPONSE.md\":106,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":168,\"docs/validation/compatible/VALIDATION.md\":39,\"docs/validation/compatible/artifact-review.json\":968,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2748,\"docs/validation/compatible/full-suite.raw.log\":1,\"docs/validation/compatible/local-imd-factory-gas-receipt.json\":103,\"docs/validation/compatible/test-results.json\":1722,\"docs/validation/compatible/v2-compiler-sources.json\":148,\"docs/validation/compatible/v2-integration-result.json\":35,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":66,\"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/v2-alias-gate/VALIDATION.md\":90,\"docs/validation/v2-alias-gate/artifact-review.json\":968,\"docs/validation/v2-alias-gate/full-suite.json\":1,\"docs/validation/v2-alias-gate/src-test-diff.patch\":300,\"docs/validation/v2-alias-gate/test-results.json\":1749,\"docs/validation/v2-alias-gate/validation-summary.json\":66,\"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\":39,\"inventory.json\":652,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":118,\"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\":663,\"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/MugiTerminalConfiguration.t.sol\":70,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":288,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":236,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":587,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":280,\"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},{"durationMs":21163,"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-1G3bv7/repo)\n'forge config --json' running\n'forge build --build-info --deny never --skip ./test/** ./script/** --force' running (wd: /tmp/imd-verify-1G3bv7/repo)\n","passed":true},{"durationMs":1090,"exitCode":0,"name":"aderyn","output":"[high] eth-send-unchecked-address at src/imd/MugiIMDGameHook.sol:469: ETH transferred without address checks (4 places)\n[high] reentrancy-state-change at src/game/MugiVRFAdapter.sol:91: Reentrancy: State change after external call (19 places)\n[high] unsafe-casting at src/imd/modules/MugiIMDPriceOracle.sol:108: Unsafe Casting of integers\n[high] yul-return at src/imd/MugiIMDGameHook.sol:645: Yul block contains `return`\n[low] centralization-risk at src/game/MugiIMDVerifier.sol:14: Centralization Risk (9 places)\n[low] costly-loop at src/game/MugiAirdrop.sol:74: Costly operations inside loop (13 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 (87 places)\n[low] local-variable-shadowing at src/imd/MugiIMDGameHook.sol:113: 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:51: 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 (22 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:230: Unchecked Return (15 places)\n[low] uninitialized-local-variable at src/game/MugiAirdrop.sol:36: Uninitialized Local Variable (8 places)\n[low] unsafe-erc20-operation at src/game/MugiAirdrop.sol:118: Unsafe ERC20 Operation (12 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":"640474213b13f278256ecd5117ce9e5670f1fd7e22716dc19c5556dfaa9775f4","verifiedTreeHash":"5007a9048fe37d1e9713df444d1228b183dc89c6","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":115713,"exitCode":0,"name":"build","output":"Compiling 130 files with Solc 0.8.26\nSolc 0.8.26 finished in 115.59s\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:649:29:\n    |\n649 |     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:650:29:\n    |\n650 |     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:652:28:\n    |\n652 |     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:654:22:\n    |\n654 |     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:655:21:\n    |\n655 |     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:656:24:\n    |\n656 |     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:657:32:\n    |\n657 |     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:658:26:\n    |\n658 |     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:658:61:\n    |\n658 |     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:658:73:\n    |\n658 |     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:658:93:\n    |\n658 |     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:662:26:\n    |\n662 |     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":7771,"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 494.98µs (92.85µ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 287.47µs (0.00ns 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 7.53ms (1.80ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 28784071)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127670)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 476715)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 28.02ms (16.56ms 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 78.82ms (9.43ms 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 89.92ms (4.49ms CPU time)\n\nRan 7 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCommunityTreasuryCannotBecomeOwner() (gas: 156387)\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7347756)\n[PASS] testExpiryBeforeFinaleFallbackCannotEraseMigrationDeadline() (gas: 32027455)\n[PASS] testFinaleFallbackHasHardDeadlineAndPreservesReservedAssets() (gas: 33163720)\n[PASS] testRejectingCommunityRollsBackFallbackAndAllowsPermissionlessRetry() (gas: 32119000)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 32078099)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 33996865)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 89.90ms (132.90ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 449640)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1042642)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 852134)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 620467)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1013210, ~: 1013847)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5275342)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 902672)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 807282)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 994718)\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 115.04ms (105.77ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934470)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1625388)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6507663)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9364448)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294260)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 27109034)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439097)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 42779645)\nLogs:\n  Settlement and request gas: 5523981\n  Settlement and request gas: 4788239\n  Settlement and request gas: 4376112\n  Settlement and request gas: 3917036\n  Settlement and request gas: 3452832\n  Settlement and request gas: 3002300\n  Settlement and request gas: 2559231\n  Settlement and request gas: 2087443\n  Settlement and request gas: 1621026\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 376097)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1373149)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11162742)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5632587)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341859)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5523412)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 7744778)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1568622)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241731)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 115.11ms (91.73ms 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, μ: 4060790, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 151.40ms (129.51ms CPU time)\n\nRan 8 tests for test/imd/MugiTerminalConfiguration.t.sol:MugiTerminalConfigurationTest\n[PASS] testCommunityCannotBeV2Receiver() (gas: 69634447)\n[PASS] testNonzeroFutureV2ContractCanBePinnedBeforeItsDeployment() (gas: 73917688)\n[PASS] testOwnerCannotBeCommunityDestination() (gas: 230121597)\n[PASS] testOwnerCannotBeV2Receiver() (gas: 20272703)\n[PASS] testTeamCannotBeCommunityDestination() (gas: 74924950)\n[PASS] testTeamCannotBeV2Receiver() (gas: 126831952)\n[PASS] testV2ReceiverCannotBecomeOwnerEvenAfterOwnershipTransfer() (gas: 52267373)\n[PASS] testZeroV2ReceiverCannotCreateHook() (gas: 42409306)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 188.84ms (542.36ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271185)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194604)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339541)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977542)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4101806)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11140650)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325913)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4877130)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221567)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 393.71ms (23.15ms 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, μ: 54383, ~: 54214)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3525674, ~: 3643842)\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 420.95ms (164.46ms 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, μ: 22395884, ~: 21685153)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 420.97ms (456.02ms 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.59s (6.74ms 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 7.59s (1.41ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6126106)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 29336743)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 38111477)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6072434)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1355546)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20116549)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5622474)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170667)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 7.59s (69.46ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 60779609)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 30756234)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 80690058)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 51069839)\nLogs:\n  Four service module creations: 3693232\n  Runtime code-deposit component: 2795600\n  Conservative independent-transaction bound: 3871640\n  Ten crew token creations: 9091768\n  Runtime code-deposit component: 6618000\n  Conservative independent-transaction bound: 9336736\n  Engine creation: 2499879\n  Runtime code-deposit component: 2407200\n  Conservative independent-transaction bound: 2634255\n  Three accounting module creations: 3831291\n  Runtime code-deposit component: 3003000\n  Conservative independent-transaction bound: 3997411\n  Hook creation: 5992259\n  Runtime code-deposit component: 4727000\n  Conservative independent-transaction bound: 6544411\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 232359)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14359475)\nLogs:\n  Four factory creation bound: 12296955\n  Runtime code-deposit component: 12075000\n  Conservative independent-transaction bound: 14824595\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 106592148)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 39968369)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 50978506)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 50978440)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 52890937)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 26387216)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 7.64s (585.01ms CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 563451)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7024281)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 30536531)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 219506900, ~: 218579390)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 35895439)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 26936260)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.64s (7.68s CPU time)\n\nRan 19 test suites in 7.64s (40.16s CPU time): 153 tests passed, 0 failed, 2 skipped (155 total tests)\n","passed":true},{"durationMs":73,"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.fallbackFinaleToCommunity()\",\"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\":122,\"README.md\":45,\"docs/IMD_COMPATIBLE_R2_RESPONSE.md\":15,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":42,\"docs/IMD_FINDINGS_RESPONSE.md\":63,\"docs/IMD_FOLLOWUP_RESPONSE.md\":106,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":168,\"docs/validation/compatible/VALIDATION.md\":39,\"docs/validation/compatible/artifact-review.json\":968,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2748,\"docs/validation/compatible/full-suite.raw.log\":1,\"docs/validation/compatible/local-imd-factory-gas-receipt.json\":103,\"docs/validation/compatible/test-results.json\":1722,\"docs/validation/compatible/v2-compiler-sources.json\":148,\"docs/validation/compatible/v2-integration-result.json\":35,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":66,\"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/v2-alias-gate/VALIDATION.md\":90,\"docs/validation/v2-alias-gate/artifact-review.json\":968,\"docs/validation/v2-alias-gate/full-suite.json\":1,\"docs/validation/v2-alias-gate/src-test-diff.patch\":300,\"docs/validation/v2-alias-gate/test-results.json\":1749,\"docs/validation/v2-alias-gate/validation-summary.json\":66,\"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\":39,\"inventory.json\":652,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":118,\"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\":663,\"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/MugiTerminalConfiguration.t.sol\":70,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":288,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":236,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":587,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":280,\"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":"65c4c2c640f939f6faf37b1eca64958f4bc1bb315ba56168c1c2245d229b034e","verifiedTreeHash":"5c64a3df5154a896c4454a2e7e0a9bc42e194ca4","verifierVersion":"0.1.0+560ab6a2"},{"checks":[{"durationMs":368854,"exitCode":0,"name":"build","output":"Compiling 136 files with Solc 0.8.26\nSolc 0.8.26 finished in 368.56s\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:649:29:\n    |\n649 |     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:650:29:\n    |\n650 |     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:652:28:\n    |\n652 |     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:654:22:\n    |\n654 |     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:655:21:\n    |\n655 |     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:656:24:\n    |\n656 |     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:657:32:\n    |\n657 |     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:658:26:\n    |\n658 |     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:658:61:\n    |\n658 |     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:658:73:\n    |\n658 |     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:658:93:\n    |\n658 |     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:662:26:\n    |\n662 |     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":45653,"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 944.13µ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 1.09ms (84.33µs 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 2.64ms (1.60ms 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 7.75ms (5.60ms 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 9.72ms (5.83ms CPU time)\n\nRan 2 tests for test/imd/MugiManifestConstructors.t.sol:MugiManifestConstructorsTest\n[PASS] testEveryManifestConstructorRejectsValueAndZeroOwner() (gas: 17530628)\n[PASS] testExactManifestBatchHasFourOwnerBoundFactoriesAndNoConstructorDependencies() (gas: 15302193)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 12.60ms (11.01ms CPU time)\n\nRan 9 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiStallRecoveryTest\n[PASS] testConfiguredCallbackBudgetStoresTimeAndDeliversValidZeroWord() (gas: 271185)\n[PASS] testLastSecondRequestDoesNotExtendDeadline() (gas: 3194604)\n[PASS] testLateWordDuringPartialRecoveryCannotChooseLoserOrReopenPools() (gas: 3339541)\n[PASS] testNobodyRequestsBeforeDeadlineCannotStartFreshRandomnessAfterwards() (gas: 2977542)\n[PASS] testOnTimeStoredWordCannotBeDiscardedAfterDeferredDelivery() (gas: 4101806)\n[PASS] testRecoveryPreservesPriorRewardsAndVirtualHolderRights() (gas: 11140650)\n[PASS] testRejectedRequestInitiationCannotFreezeSeasonOrExtendCutoffDeadline() (gas: 3325913)\n[PASS] testSilentRequestRecoversTenPoolsWithoutRerollOrOwnerCashout() (gas: 4877130)\n[PASS] testWordFirstStoredAtDeadlineCannotReviveSeason() (gas: 3221567)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 53.26ms (39.44ms CPU time)\n\nRan 3 tests for test/imd/lifecycle/MugiStallRecovery.t.sol:MugiFinaleRightsTest\n[PASS] testCommittedV2TargetAndOneShotMigrationReserveUnclaimedTokens() (gas: 28784071)\n[PASS] testNoPauseCanDelayTheFixedRandomnessCutoff() (gas: 127670)\n[PASS] testOwnerCannotInstallPauseAndTradingStillWorks() (gas: 476715)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 53.35ms (37.67ms CPU time)\n\nRan 8 tests for test/imd/lifecycle/MugiAdversarial.t.sol:MugiAdversarialTest\n[PASS] testEthRecipientCannotReenterAndWithdrawItsRewardTwice() (gas: 6126106)\n[PASS] testFinalizationMigrationPreservesEarlierRewardsWithoutPauseCapability() (gas: 29336743)\n[PASS] testPartialMaterializationAndFrequentEthClaimsMatchDeferredRewardsExactly() (gas: 38111477)\n[PASS] testPoolManagerClaimCustodyIsExplicitlyExcludedFromHolderRights() (gas: 6072434)\n[PASS] testSpotManipulationCannotForceTreasuryBuyAtManipulatedPrice() (gas: 1355546)\n[PASS] testSubLiquidityUnitRemainderDoesNotPermanentlyFreezeSettlement() (gas: 20116549)\n[PASS] testThirdPartyPoolManagerUnlockCannotRecordCutoffOrWithdrawClaims() (gas: 5622474)\n[PASS] testUnregisteredCallerCannotForgeTokenBalanceAccounting() (gas: 170667)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 90.91ms (95.58ms CPU time)\n\nRan 18 tests for test/imd/lifecycle/MugiGameHook.t.sol:MugiGameHookTest\n[PASS] testAirdropRemainderRetiresAfterDeadline() (gas: 934470)\n[PASS] testAllFourSwapModesFundSeparateEthBudgets() (gas: 1625388)\n[PASS] testDustBuybacksCannotConsumeRoundOrOwnCadence() (gas: 6507663)\n[PASS] testEarnedEthRemainsClaimableDuringNextRandomnessWait() (gas: 9364448)\n[PASS] testExternalPositionsAndAlternativeKeysUsingHookAreRejected() (gas: 1294260)\n[PASS] testFinalClaimsExpireToCommunityAfterThirtyDays() (gas: 27109034)\n[PASS] testFixedCutoffAllowsTransfersButClosesOfficialRoundAndMaterialization() (gas: 439097)\n[PASS] testFullNineRoundsAndFinaleEarlyAndLateClaimsAgree() (gas: 42779645)\nLogs:\n  Settlement and request gas: 5523981\n  Settlement and request gas: 4788239\n  Settlement and request gas: 4376112\n  Settlement and request gas: 3917036\n  Settlement and request gas: 3452832\n  Settlement and request gas: 3002300\n  Settlement and request gas: 2559231\n  Settlement and request gas: 2087443\n  Settlement and request gas: 1621026\n\n[PASS] testInitialAllocationAndAirdropClaimsAreTracked() (gas: 376097)\n[PASS] testModularHookFitsMainnetRuntimeLimit() (gas: 5070)\n[PASS] testOwnBuybackUsesTwapAndBurnsActualPurchasedTokens() (gas: 1373149)\n[PASS] testOwnerCanAbortOnlyBeforeLaunchAndRecoverSeededEth() (gas: 11162742)\n[PASS] testPreviouslyEarnedEthDoesNotFollowTransferredSurvivorTokens() (gas: 5632587)\n[PASS] testRandomnessOnlyRecordsOutcomeAndRejectsDuplicates() (gas: 341859)\nLogs:\n  Randomness callback gas: 62182\n\n[PASS] testRoundBuybackFallbackSpendsOnlyAuthorizedBudgetAndBurns() (gas: 5523412)\n[PASS] testStagedSettlementRewardsPreexistingSurvivors() (gas: 7744778)\n[PASS] testTeamFeeCollectionCannotWithdrawPrincipalOrPlayerRewards() (gas: 1568622)\n[PASS] testWalletTransferHasNoTaxAndPreservesSupplyAccounting() (gas: 241731)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 110.67ms (117.95ms CPU time)\n\nRan 14 tests for test/imd/lifecycle/MugiSwapRouter.t.sol:MugiSwapRouterTest\n[PASS] testBuyAndSellRejectExpiredDeadlines() (gas: 121454)\n[PASS] testBuyMinimumOutputFailureRevertsPaymentAndBothFeeBuckets() (gas: 449640)\n[PASS] testBuyUsesOfficialPoolPaysBothFeesAndDeliversDirectlyToHolder() (gas: 1042642)\n[PASS] testEthRecipientCannotReenterDuringSellSettlement() (gas: 852134)\n[PASS] testForcedEthCannotBeWithdrawnByNextBuyerOrSeller() (gas: 620467)\n[PASS] testFuzzNormalTradesPreserveCustodyAndChargeGameFees(uint96) (runs: 256, μ: 1013210, ~: 1013847)\n[PASS] testOfficialRoundCutoffAndEliminationCannotBeBypassed() (gas: 5275342)\n[PASS] testRejectingEthRecipientRollsBackWholeSale() (gas: 902672)\n[PASS] testRejectsInvalidCrewAndUnsafeInputBounds() (gas: 262638)\n[PASS] testSalesRequireUsersOwnApprovalAndCannotSpendAnotherWallet() (gas: 807282)\n[PASS] testSellDebitsActualTokensAndReceivesNetEthWithNoRouterInventory() (gas: 994718)\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 242.48ms (228.58ms 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 262.89ms (15.43ms 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, μ: 4060790, ~: 4063237)\n[PASS] testPartialMaterializationAndTransferBeforeNextCutoffNeverDoubleCountWalletAndVirtual() (gas: 9121056)\n[PASS] testTransfersBeforeCutoffMoveFutureEntitlementsToTheActualCutoffOwner() (gas: 3751048)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 768.26ms (265.63ms 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 891.57ms (3.99ms 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, μ: 22479319, ~: 21685153)\n[PASS] testNormalFinalizePreservesSyncedAndLazyEscrowAndOnlyUnreservedInventoryCanLeave() (gas: 18183782)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 891.85ms (939.56ms 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, μ: 54363, ~: 54214)\n[PASS] testFuzzHistoricalReadsMatchRecordedBeforeStates(uint256) (runs: 256, μ: 3535571, ~: 3663118)\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 891.79ms (450.53ms CPU time)\n\nRan 7 tests for test/imd/MugiAirdropAuthorization.t.sol:MugiAirdropAuthorizationTest\n[PASS] testAutomaticLaunchThresholdAndSevenDayBoundary() (gas: 177761)\n[PASS] testClaimRejectsForeignWalletAndExpiredAttestationThenAcceptsFreshOne() (gas: 520465)\n[PASS] testFuzzCohortCannotExceedFivePercentOrPerAccountCap(uint8) (runs: 128, μ: 9958193, ~: 3868060)\n[PASS] testRegistrationDeadlineIsInclusiveButExpiredSignatureDoesNotConsumeIdentity() (gas: 192261)\n[PASS] testRegistrationSignatureBindsAccountCrewSocialAndContract() (gas: 362856)\n[PASS] testRejectedTokenPaymentRollsBackClaimFlagAndCanBeRetriedAfterFunding() (gas: 669150)\n[PASS] testSocialIdentityAndWalletCannotRegisterTwiceEvenWithFreshValidSignatures() (gas: 241435)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 941.39ms (941.64ms CPU time)\n\nRan 2 tests for test/imd/invariant/MugiBudgetInvariant.t.sol:MugiBudgetAccountingInvariantTest\n[PASS] invariant_allocationsAndActualSpendingAlwaysConserveTheBudget() (runs: 128, calls: 12288, reverts: 0)\n\n╭-------------------------+--------------+-------+---------+----------╮\n| Contract                | Selector     | Calls | Reverts | Discards |\n+=====================================================================+\n| BudgetAccountingHandler | account      | 2459  | 0       | 0        |\n|-------------------------+--------------+-------+---------+----------|\n| BudgetAccountingHandler | advance      | 2520  | 0       | 0        |\n|-------------------------+--------------+-------+---------+----------|\n| BudgetAccountingHandler | approve      | 2426  | 0       | 0        |\n|-------------------------+--------------+-------+---------+----------|\n| BudgetAccountingHandler | authorize    | 2478  | 0       | 0        |\n|-------------------------+--------------+-------+---------+----------|\n| BudgetAccountingHandler | unauthorized | 2405  | 0       | 0        |\n╰-------------------------+--------------+-------+---------+----------╯\n\n[PASS] testExpiredPlanFallbackPreservesAlreadySpentOverweightAllocation() (gas: 4132979)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 3.37s (3.37s CPU time)\n\nRan 8 tests for test/imd/MugiTerminalConfiguration.t.sol:MugiTerminalConfigurationTest\n[PASS] testCommunityCannotBeV2Receiver() (gas: 69634447)\n[PASS] testNonzeroFutureV2ContractCanBePinnedBeforeItsDeployment() (gas: 73917688)\n[PASS] testOwnerCannotBeCommunityDestination() (gas: 230121597)\n[PASS] testOwnerCannotBeV2Receiver() (gas: 20272703)\n[PASS] testTeamCannotBeCommunityDestination() (gas: 74924950)\n[PASS] testTeamCannotBeV2Receiver() (gas: 126831952)\n[PASS] testV2ReceiverCannotBecomeOwnerEvenAfterOwnershipTransfer() (gas: 52267373)\n[PASS] testZeroV2ReceiverCannotCreateHook() (gas: 42409306)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 14.19s (849.86ms CPU time)\n\nRan 7 tests for test/imd/lifecycle/MugiCompatibilityHandoff.t.sol:MugiCompatibilityHandoffTest\n[PASS] testCommunityTreasuryCannotBecomeOwner() (gas: 156387)\n[PASS] testCutoffAndKnownLoserTransfersDoNotMoveOrDuplicateConversion() (gas: 7347756)\n[PASS] testExpiryBeforeFinaleFallbackCannotEraseMigrationDeadline() (gas: 32027455)\n[PASS] testFinaleFallbackHasHardDeadlineAndPreservesReservedAssets() (gas: 33163720)\n[PASS] testRejectingCommunityRollsBackFallbackAndAllowsPermissionlessRetry() (gas: 32119000)\n[PASS] testRejectingV2ReceiverRollsBackAllTransfersAndAllowsRetry() (gas: 32078099)\n[PASS] testV2HandoffPreservesPlayerEthAndTokensAndRetiresUnusedSupply() (gas: 33996865)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 14.99s (212.37ms CPU time)\n\nRan 12 tests for test/imd/MugiV1IMDDeploymentFactory.t.sol:MugiV1IMDDeploymentFactoryTest\n[PASS] testCompleteConstructorGraphSeedsAllPoolsAndLaunchesWithoutInitializers() (gas: 60779609)\n[PASS] testConstructorFailureRollsBackModuleCommitmentAndCreateNonces() (gas: 30756234)\n[PASS] testEvenCommittedArbitraryCreationCodeCannotReplacePinnedImplementation() (gas: 80690058)\n[PASS] testEveryDescendantCreationCallFitsSeparateTransactionGasCap() (gas: 51069839)\nLogs:\n  Four service module creations: 3693232\n  Runtime code-deposit component: 2795600\n  Conservative independent-transaction bound: 3871640\n  Ten crew token creations: 9091768\n  Runtime code-deposit component: 6618000\n  Conservative independent-transaction bound: 9336736\n  Engine creation: 2499879\n  Runtime code-deposit component: 2407200\n  Conservative independent-transaction bound: 2634255\n  Three accounting module creations: 3831291\n  Runtime code-deposit component: 3003000\n  Conservative independent-transaction bound: 3997411\n  Hook creation: 5992259\n  Runtime code-deposit component: 4727000\n  Conservative independent-transaction bound: 6544411\n\n[PASS] testFactoriesPinSourceHaveNoChildrenAtConstructionAndFitEvmLimits() (gas: 232359)\n[PASS] testFactoryCreationBatchHasConservativeGasHeadroom() (gas: 14359475)\nLogs:\n  Four factory creation bound: 12296955\n  Runtime code-deposit component: 12075000\n  Conservative independent-transaction bound: 14824595\n\n[PASS] testHookConfigurationCannotSubstituteFactoryModuleOrOwner() (gas: 106592148)\n[PASS] testHookRequiresAllFourOwnModulesAndCrewCreationAndExactCommittedCode() (gas: 39968369)\n[PASS] testMismatchedLedgerExclusionBindingRejectsFirstPoolSeed() (gas: 50978506)\n[PASS] testMismatchedLedgerTokenBindingRejectsFirstPoolSeed() (gas: 50978440)\n[PASS] testSingleSeasonCommitmentsCannotBeReplacedAfterSuccess() (gas: 52890937)\n[PASS] testUnauthorizedCallersCannotConsumeAnyPredictedAddress() (gas: 26387216)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 14.99s (824.02ms CPU time)\n\nRan 2 tests for test/imd/invariant/MugiAirdropInvariant.t.sol:MugiAirdropAccountingInvariantTest\n[PASS] invariant_registrationAndFiniteAllocationRemainConserved() (runs: 128, calls: 8192, reverts: 0)\n\n╭--------------------------+-----------------------+-------+---------+----------╮\n| Contract                 | Selector              | Calls | Reverts | Discards |\n+===============================================================================+\n| AirdropAccountingHandler | advance               | 1355  | 0       | 0        |\n|--------------------------+-----------------------+-------+---------+----------|\n| AirdropAccountingHandler | claim                 | 1380  | 0       | 0        |\n|--------------------------+-----------------------+-------+---------+----------|\n| AirdropAccountingHandler | launch                | 1376  | 0       | 0        |\n|--------------------------+-----------------------+-------+---------+----------|\n| AirdropAccountingHandler | register              | 1349  | 0       | 0        |\n|--------------------------+-----------------------+-------+---------+----------|\n| AirdropAccountingHandler | retire                | 1406  | 0       | 0        |\n|--------------------------+-----------------------+-------+---------+----------|\n| AirdropAccountingHandler | unauthorizedLifecycle | 1326  | 0       | 0        |\n╰--------------------------+-----------------------+-------+---------+----------╯\n\n[PASS] testAirdropHandlerExercisesWrongAttestationReplayAndExactWindow() (gas: 3574624)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 15.29s (15.29s CPU time)\n\nRan 6 tests for test/imd/lifecycle/MugiEconomics.t.sol:MugiEconomicsTest\n[PASS] testBuybackTwapExposesRealHistoryAndRejectsInvalidCrew() (gas: 563451)\n[PASS] testEliminationPaysBookedAndUncollectedTokenFeesBeforeRetirement() (gas: 7024281)\n[PASS] testFinalePaysBookedAndExitTokenFeesWithoutConsumingEscrowOrEthRewards() (gas: 30536531)\n[PASS] testFuzzSeasonReconcilesEveryBucketAcrossTradesTransfersAndClaims(uint256) (runs: 256, μ: 220078702, ~: 218435607)\n[PASS] testTerminalMigrationPreservesFinalTokenClaimsAndEarlierEthClaims() (gas: 35895439)\n[PASS] testZeroEligibleFinaleMigratesToV2AndPreservesTeamEth() (gas: 26936260)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 15.71s (15.75s CPU time)\n\nRan 2 tests for test/imd/invariant/MugiTerminalInvariant.t.sol:MugiEmergencyCustodyInvariantTest\n[PASS] invariant_emergencyPreservesLiabilitiesAndNeverMigrates() (runs: 128, calls: 8192, reverts: 0)\n\n╭------------------------+---------------------+-------+---------+----------╮\n| Contract               | Selector            | Calls | Reverts | Discards |\n+===========================================================================+\n| TerminalCustodyHandler | advance             | 932   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | claimEth            | 948   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | claimTokens         | 900   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | excessiveClaim      | 888   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | fallbackToCommunity | 890   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | migrate             | 916   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | sweep               | 897   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | transferOrBurn      | 911   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | withdrawTeam        | 910   | 0       | 0        |\n╰------------------------+---------------------+-------+---------+----------╯\n\n[PASS] testEmergencyHandlerExercisesClaimsAndFullExpiry() (gas: 3791859)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 20.40s (20.36s CPU time)\n\nRan 2 tests for test/imd/invariant/MugiTerminalInvariant.t.sol:MugiFinaleCustodyInvariantTest\n[PASS] invariant_finaleCustodyAndEarnedRightsSurviveEveryOrdering() (runs: 128, calls: 8192, reverts: 0)\n\n╭------------------------+---------------------+-------+---------+----------╮\n| Contract               | Selector            | Calls | Reverts | Discards |\n+===========================================================================+\n| TerminalCustodyHandler | advance             | 932   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | claimEth            | 948   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | claimTokens         | 900   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | excessiveClaim      | 888   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | fallbackToCommunity | 890   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | migrate             | 916   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | sweep               | 897   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | transferOrBurn      | 911   | 0       | 0        |\n|------------------------+---------------------+-------+---------+----------|\n| TerminalCustodyHandler | withdrawTeam        | 910   | 0       | 0        |\n╰------------------------+---------------------+-------+---------+----------╯\n\n[PASS] testTerminalHandlerExercisesPartialClaimsFailureRetryAndExpiry() (gas: 7201489)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 24.22s (24.14s CPU time)\n\nRan 2 tests for test/imd/invariant/MugiSeasonInvariant.t.sol:MugiSeasonAccountingInvariantTest\n[PASS] invariant_realPoolCustodyAndLedgerClaimsReconcile() (runs: 128, calls: 12288, reverts: 0)\n\n╭-------------------------+------------+-------+---------+----------╮\n| Contract                | Selector   | Calls | Reverts | Discards |\n+===================================================================+\n| SeasonAccountingHandler | claim      | 1993  | 0       | 0        |\n|-------------------------+------------+-------+---------+----------|\n| SeasonAccountingHandler | fees       | 2058  | 0       | 0        |\n|-------------------------+------------+-------+---------+----------|\n| SeasonAccountingHandler | progress   | 2118  | 0       | 0        |\n|-------------------------+------------+-------+---------+----------|\n| SeasonAccountingHandler | retireDrop | 2113  | 0       | 0        |\n|-------------------------+------------+-------+---------+----------|\n| SeasonAccountingHandler | trade      | 2028  | 0       | 0        |\n|-------------------------+------------+-------+---------+----------|\n| SeasonAccountingHandler | wallet     | 1978  | 0       | 0        |\n╰-------------------------+------------+-------+---------+----------╯\n\n[PASS] testHandlerReachesNineRoundsWithRealTradesAndClaims() (gas: 79804307)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 45.38s (45.45s CPU time)\n\nRan 26 test suites in 45.38s (173.77s CPU time): 172 tests passed, 0 failed, 2 skipped (174 total tests)\n","passed":true},{"durationMs":227,"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.fallbackFinaleToCommunity()\",\"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\":122,\"README.md\":45,\"docs/IMD_COMPATIBLE_R2_RESPONSE.md\":15,\"docs/IMD_CONSTRUCTOR_DEPLOYMENT.md\":42,\"docs/IMD_FINDINGS_RESPONSE.md\":63,\"docs/IMD_FOLLOWUP_RESPONSE.md\":106,\"docs/validation/compatible/MugiIMDCompatibleV1ToV2.t.sol.txt\":168,\"docs/validation/compatible/VALIDATION.md\":39,\"docs/validation/compatible/artifact-review.json\":968,\"docs/validation/compatible/fork-block.json\":6,\"docs/validation/compatible/full-suite.json\":2748,\"docs/validation/compatible/full-suite.raw.log\":1,\"docs/validation/compatible/local-imd-factory-gas-receipt.json\":103,\"docs/validation/compatible/test-results.json\":1722,\"docs/validation/compatible/v2-compiler-sources.json\":148,\"docs/validation/compatible/v2-integration-result.json\":35,\"docs/validation/compatible/v2-integration.log\":92,\"docs/validation/compatible/v2-source-identities.json\":122,\"docs/validation/compatible/validation-summary.json\":66,\"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/v2-alias-gate/VALIDATION.md\":90,\"docs/validation/v2-alias-gate/artifact-review.json\":968,\"docs/validation/v2-alias-gate/full-suite.json\":1,\"docs/validation/v2-alias-gate/src-test-diff.patch\":300,\"docs/validation/v2-alias-gate/test-results.json\":1749,\"docs/validation/v2-alias-gate/validation-summary.json\":66,\"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\":39,\"inventory.json\":652,\"launch.json\":30,\"scripts/check-compatible-artifacts.py\":265,\"scripts/check-hook-commitment.py\":118,\"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\":663,\"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/MugiAirdropAuthorization.t.sol\":195,\"test/imd/MugiIMDCrewToken.t.sol\":308,\"test/imd/MugiIMDProjectFactoryFork.t.sol\":141,\"test/imd/MugiManifestConstructors.t.sol\":134,\"test/imd/MugiTerminalConfiguration.t.sol\":70,\"test/imd/MugiV1IMDDeploymentFactory.t.sol\":288,\"test/imd/REGRESSION_REVIEW.md\":95,\"test/imd/evidence/audited-source-delta.patch\":95,\"test/imd/evidence/validation.json\":567,\"test/imd/helpers/MugiIMDDeploymentFixture.sol\":153,\"test/imd/invariant/MugiAirdropInvariant.t.sol\":223,\"test/imd/invariant/MugiBudgetInvariant.t.sol\":198,\"test/imd/invariant/MugiSeasonInvariant.t.sol\":305,\"test/imd/invariant/MugiTerminalInvariant.t.sol\":398,\"test/imd/lifecycle/MugiAdversarial.t.sol\":228,\"test/imd/lifecycle/MugiCompatibilityHandoff.t.sol\":236,\"test/imd/lifecycle/MugiEconomics.t.sol\":398,\"test/imd/lifecycle/MugiGameHook.t.sol\":587,\"test/imd/lifecycle/MugiGameHookMainnetFork.t.sol\":92,\"test/imd/lifecycle/MugiStallRecovery.t.sol\":280,\"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":"981bcbf528573ffe1bb6a2ac97f5daeed742ec8f037cdd1bc463088164783c63","verifiedTreeHash":"c98f9ef1ebe49484647f292a9529040e219768ad","verifierVersion":"0.1.0+560ab6a2"}]}