{"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":"f5ad1711-1114-405e-88d2-f5d4ff70f85a","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"dec17f66fb620ff39400b562e8883b63b601d6736f5e053dea3c9a348a1ac83c","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"ffd57781819cbe67f89ef66d0e148954daf492e6707698198e867f96c3d85fa4","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"af3aa01159bbf354f621cafa5c0006f6169e0938a8b015be508b7377dbf165bc","skillId":"audit-judge","state":"waiting"},{"acceptedSubmissionHash":"6caae126957d4b009cf0b72cade12be03623e2baa62c9c0d5a06a8e28eec5ff0","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"05ff062ef9ec027f4c2e3535712da16c47e2eb91755750dd93d1dcf68f312c95","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"4700110e3c5ac820f199f3efd442715a1333de160c0021bae7a9b35fbef614eb","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":null,"dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"failed"},{"acceptedSubmissionHash":"caee0d0775c4eacdee91f0984aa1e0abf892eeb81d11f185694bb6bc68f85d56","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Deploy the SwarmShield hook from this Foundry repo as a Uniswap v4 hook launch: build and test the contracts (forge test must pass — 18 tests), run the audit panel, then deploy the token (name SwarmShield, symbol SHIELD) with the hook beside it and seed the pool with the hook attached. The hook is ownerless. Fees: while unverified, swaps pay a 2% LP fee plus a 1% surcharge burned to 0xdEaD; after a positive verify() verdict (0.5 IMD to the IdentityMD oracle, 7-agent panel, 5/7 quorum) the fee drops to 0.30% and the surcharge turns off. Use the constructor arguments in LAUNCH_SPEC.md §1, substituting the deployed token address into the oracle body. The hook address must carry the permission flags 0x288 (beforeSwap, beforeSwapReturnDelta, beforeRemoveLiquidity) in its low 14 bits — mine the deploy salt accordingly. If the pool can be created with the dynamic fee (0x800000), use it; otherwise, the policy fee works and trust pricing falls back to the hook's surcharge. Repo: https://github.com/Kingjami47/swarmshield.git @ commit 62b7b025db9fbf213ace71880b36963fb77c90b7\n\nToken name: SwarmShield\nToken symbol: SHIELD","parentJobId":null,"planHash":"173cf49c609e657b7970a155daa9fea541cd73ec1f570a47a4624113b828731c","previousHash":"9f79777c8a4b2d4fa4b14760d4b2024b7fb2ab68216cd90fa9481d728b2b42b4","projectId":"f5ad1711-1114-405e-88d2-f5d4ff70f85a","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1876-swarmshield"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52240","feedbackHash":"b2d29650f57441563d50813a357020755396405c7fa8f7600fad8bb0e2e3a3a2","nodeKey":"audit_economics","submissionHash":"dec17f66fb620ff39400b562e8883b63b601d6736f5e053dea3c9a348a1ac83c","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52482","feedbackHash":"b53e764e36286c369da6925779aa61b2a31d536485ab06f6e54d9cfc80fd2909","nodeKey":"audit_flow","submissionHash":"ffd57781819cbe67f89ef66d0e148954daf492e6707698198e867f96c3d85fa4","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51340","feedbackHash":"466fe89a9eee439f1e1388a71ddd0c608f91879d10af4fa0bbd4619b8c29ef9b","nodeKey":"audit_math","submissionHash":"6caae126957d4b009cf0b72cade12be03623e2baa62c9c0d5a06a8e28eec5ff0","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51343","feedbackHash":"7b525cd3f2e9a33dd0929c6e374b9cda892a8ae91e84d0f69c6e81ddb50523e5","nodeKey":"audit_permissions","submissionHash":"05ff062ef9ec027f4c2e3535712da16c47e2eb91755750dd93d1dcf68f312c95","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51174","feedbackHash":"9f88aedf2fd332740d3837f6ba9d0cb0f999ed84096fa73efd2f0e75ab493764","nodeKey":"write_foundry_tests","submissionHash":"caee0d0775c4eacdee91f0984aa1e0abf892eeb81d11f185694bb6bc68f85d56","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"36eafe0a187fa00ebc70a088a5d604b3ebe2166720674fc28b1f40538022b2e0","state":"blocked","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"feba2a869621cab2","findings":[{"citation":"resolved","description":"Asymmetry (branch pair in-range vs out-of-range) and trust-gap (economics x asymmetry). beforeRemoveLiquidity applies the 10%/UTC-day per-position cap only when slot0's tick is inside [tickLower, tickUpper); the out-of-range branch skips every check and every storage write (removedByPosition / removedThisBucket are not updated). The branch condition is read from slot0 at call time and is under the control of the actor the guard restrains: the LP can, inside one PoolManager.unlock, (1) swap ETH->token with an exact-output token amount and a sqrtPriceLimit just below its tickLower (partial fills are allowed on native-unspecified swaps, so AMOUNT_OVERFLOW/PARTIAL_NATIVE_FILL do not bite), (2) call modifyLiquidity with liquidityDelta = -100% of the position (passes, tick is now below tickLower), (3) swap back to the original price. Net cost is the surcharge/LP fee on the two swaps, which for a narrow range is a small fraction of the position. The README (line 76) discloses that 'a position owner can influence price by trading', so this is a documented limitation rather than an unknown defect, and the factory's full-range seed position cannot be escaped this way (the tick cannot leave the usable range with finite capital). It is reported so the judge can decide whether the rugShieldBps guarantee as described in LAUNCH_SPEC section 1 ('applied independently per active position') is strong enough: today it binds only LPs who do not trade, and the storage lifecycle is asymmetric (removedThisBucket never records out-of-range exits, so the 'observability' counter undercounts).","line":192,"path":"src/SwarmShieldHook.sol","reproduction":"State: policy pool (fee 12500, spacing 60) initialized at sqrtPrice 2^96 (tick 0); a wide position [-6120, 6120] with liquidity 1e20 and the LP's position [-120, 120] with liquidity 1e20, same day. Honest input: modifyLiquidity([-120,120], liquidityDelta = -1.1e19) -> reverts RUG_SHIELD (expected, 11% > 10%). Bypass input, one unlock: swap(zeroForOne=true, amountSpecified=+1e27, sqrtPriceLimit=getSqrtPriceAtTick(-180)) then modifyLiquidity([-120,120], liquidityDelta=-1e20) then swap(zeroForOne=false, amountSpecified=-1e27, sqrtPriceLimit=getSqrtPriceAtTick(0)). Expected: the second call reverts RUG_SHIELD because the position was active that day and 100% > 10%. Actual: all three calls succeed, getPositionLiquidity(id, key(LP,-120,120,0)) == 0 and slot0 tick is back inside [-120,120). Reproduced with test/scratch/RugShieldBypass.t.sol (test_BypassByPushingPriceOutOfRangeInOneUnlock passes on current code, i.e. the bypass works; test_InRangeRemovalIsCapped shows the honest path is capped).","severity":"low","snippet":"            if (tick < params.tickLower || tick >= params.tickUpper) return IHooks.beforeRemoveLiquidity.selector;","title":"Rug-shield cap is skipped for out-of-range positions, and the LP can move the price out of range and back inside the same unlock, removing 100% of an active position in one transaction"},{"citation":"resolved","description":"Trust-gap (access x economics), reported as a documented trust assumption rather than a permission bypass. The hook is ownerless by the requester's instruction, so OracleAttestationConsumer._setOracleSigner is reachable only from the constructor and the signer is a bare EOA key per LAUNCH_SPEC (0x5598...2982). The supplied oracle-consumer reference states the signer, intake, asset and price are 'constructor input and owner-settable, never a constant' because 'a new action version (oracle-2) or a moved price must not need a redeploy', and that a callback that reverts 'is recorded as not delivered and is not retried'. Combined with verify() being open to anyone and non-refundable, the failure mode is: after IdentityMD rotates its signing key (or raises the oracle.request price above 0.5 IMD, or retires Intake v2), every verify() call pulls 0.5 IMD from the caller and forwards it to Intake, the panel runs, and onOracleResult reverts BadSignature (or Intake refuses the ask), so the 0.5 IMD is spent and the trusted tier (0.30% / no surcharge) is permanently unreachable; existing trust expires after at most 30 days and the pool stays in the 2%+1% (dynamic) or 1.25%+1% (policy) tier forever. README line 80 and AUDIT.md line 42 disclose this. The judge should confirm the requester accepts a permanent fallback rather than pointing _oracleSigner at an ERC-1271 OracleSignerRegistry (SignatureChecker already takes that path for a signer with code), which would survive key rotation without adding an owner.","line":95,"path":"src/SwarmShieldHook.sol","reproduction":"State: hook deployed with _oracleSigner = EOA K1; the oracle now signs with K2. Input: any account calls imd.approve(hook, 0.5e18); hook.verify() -> succeeds, IMD moved to Intake, pending[id]=true. Intake later calls hook.onOracleResult(id, attestation signed by K2 for this hook's domain, sig). Expected (per the brief): positive verdict lowers the fee. Actual: _verifyAttestation reverts BadSignature, the delivery is recorded as failed and not retried, pending[id] stays true until anyone calls expireRequest(id) after 7 days, 0.5 IMD is gone and trustedUntil is unchanged. Repeating verify() can never succeed. Local check: in ShieldFixture, sign _answer(id,true) with a key other than ORACLE_KEY and deliver: intake.deliver returns false and hook.isTrusted() stays false.","severity":"low","snippet":"    ) OracleAttestationConsumer(_oracleSigner) {","title":"Oracle signer, Intake and price are immutable with no owner: a signer rotation or a price change makes every later verify() spend 0.5 IMD with no possible trust outcome"},{"citation":"resolved","description":"Trust-gap (access x economics x asymmetry), documented design, recorded so its actor and preconditions are explicit. verify() (line 207) has no caller restriction and onOracleResult applies the newest verdict whatever its sign (OLDER_VERDICT only rejects strictly older issuedAt). A competitor can therefore spend 0.5 IMD per attempt to force the 7-agent panel to re-evaluate the launch's identity; the panel is an LLM panel over public evidence (registry page, X account), so a transient outage of either source or a borderline reading can produce agreed>=5 'false', which sets trustedUntil=0 and restores the 1% burned surcharge and the 2% dynamic LP fee for every trader until the project pays again and receives a 'true'. The downside of a wrong 'no' falls entirely on the project and its traders, while the cost of asking is symmetric at 0.5 IMD. The hook cannot distinguish a project-initiated re-verification from an adversarial one because it is ownerless. This matches README line 63 ('A negative result revokes trust') and the supplied oracle guidance that a 'no' answer 'is a result to store'; it is not a bypass, and no fix that preserves ownerlessness and revocability is obviously better, so it is informational.","line":253,"path":"src/SwarmShieldHook.sol","reproduction":"State: hook trusted (trustedUntil = T+30d) after a positive verdict with issuedAt = T. Input: attacker A (not the project) calls imd.approve(hook, 0.5e18); hook.verify() -> id2. Intake delivers onOracleResult(id2, a) with a.answer = abi.encode(false), panelSize 7, quorum 5, agreed 5, issuedAt = T+1, signed by the oracle signer. Expected per the brief: only a positive verify() verdict changes fees. Actual: isTrusted() becomes false immediately; the next swap in the dynamic pool pays 20000 LP fee plus a 1% ETH surcharge to 0xdEaD (test_TrustedSwapsAllFourModesAndExpiry shows the fee switch; the negative path is test-covered in test/OracleFlow.t.sol). Any account can repeat this for 0.5 IMD each time.","severity":"info","snippet":"        trustedUntil = verdict ? until : 0;","title":"Any third party can pay 0.5 IMD to re-ask the identity question, and a single negative panel answer revokes trust that a previous positive answer granted"},{"citation":"resolved","description":"Access-control / deployment note for the manifest step, outside the hook's runtime surface. HookFlags.matches is an equality check, so the constructor reverts WRONG_HOOK_FLAGS for any address whose low 14 bits are not exactly 0x22cc (beforeInitialize, beforeRemoveLiquidity, beforeSwap, afterSwap, beforeSwapReturnDelta, afterSwapReturnDelta). The brief says to mine for 0x288; LAUNCH_SPEC section 2 explains the mask was raised to add the initialization callback the launch floor requires and the afterSwap surcharge path. getHookPermissions (lines 121-128) agrees with 0x22cc, so the protected test test_permissionsMatchTheDeclaredFlags passes only when launch.json's hook.permissions lists all six callbacks and the deployer mines for 0x22cc. No code change is needed; the manifest and miner must not reuse 0x288.","line":34,"path":"src/SwarmShieldHook.sol","reproduction":"Input: CREATE2-deploy the hook's creation code at a salt whose predicted address has low 14 bits 0x288 (the brief's mask). Expected per the brief: deployment succeeds. Actual: constructor line 105 require(HookFlags.matches(address(this), FLAGS)) fails with WRONG_HOOK_FLAGS and the deployment reverts. Deploying at an address with low bits 0x22cc succeeds (ShieldFixture._deploy and the suite's 56 passing tests).","severity":"info","snippet":"    uint160 public constant FLAGS = 0x22cc;","title":"Constructor requires the exact 0x22cc flag mask; a launch manifest or miner that uses the brief's 0x288 cannot deploy this hook"}],"hash":"05ff062ef9ec027f4c2e3535712da16c47e2eb91755750dd93d1dcf68f312c95","nodeId":"69feeb32-5a52-45d1-8a37-954b18c18843","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written and validated: all four snippets match their cited lines, and the coverage record answers all 14 listed entry points plus three invariant rows.\n\n**Outcome:** no permission bypass, escalation path, or unguarded state writer was found in the SwarmShield hook. The full suite builds and passes (56 tests, not the 18 the brief mentions, because earlier contributors added suites). Every hook callback is gated to the PoolManager, the oracle callbacks to the Intake, and every value exit leads only to the immutable burn sink. The two `verify()` leads from Slither (reentrancy, strict equality) were rejected after tracing: the guard blocks reentry, and the Intake pulls exactly the offered amount per the oracle reference.\n\n**Findings recorded (none blocking):**\n\n- **Low, rug shield escapable in one unlock.** The per-position 10%/day cap applies only while the price sits inside the position's range, and the LP controls that condition. My scratch test moved the price out of a narrow range, removed 100% of the position, and moved it back in a single transaction. The README discloses this limitation and the factory's full-range seed position cannot be escaped this way, so I left it at low for the judge to weigh.\n- **Low, immutable signer/price/Intake.** With no owner, an oracle key rotation or price change turns every later `verify()` into a non-refundable 0.5 IMD sink with no reachable trusted tier. Documented in the README; reported as a trust assumption with the concrete failing state.\n- **Info, open re-verification revokes trust.** Anyone can pay to re-ask, and a single negative panel answer resets `trustedUntil` to zero. Design choice, recorded with actor and preconditions.\n- **Info, flag mask.** The constructor requires exactly 0x22cc, so a manifest or miner reusing the brief's 0x288 reverts on deployment.\n\n**Coverage:** 11 entry points hold, 3 carry findings. No rows are unreached. No source files were modified. The scratch test under `test/scratch/` reproduces finding 1 and is disposable.","treeHash":null,"usage":{"cachedInputTokens":1561917,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":41154,"runtime":"claude","turns":33,"wallClockMs":721332}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"6960837f8e61d811","findings":[],"hash":"14d94eafe05989578a59a0f07fc4c38ffcf0213c23e409c077f9d14b6c953c9c","nodeId":"f68645f5-718e-41ea-9af7-05191e8f2b3e","outcome":"failed","summary":"needs input: Authorization for a constructor compatibility revision before the manifest can be completed. SwarmShieldHook's seventh constructor parameter is bytes _oracleBody, which LAUNCH_SPEC.md requires to contain the final deployed token address in two JSON locations. The supplied manifest format describes one ABI word per constructor parameter and whole-argument placeholders; it provides no supported encoding or token interpolation for this dynamic bytes value. The compiled ABI confirms the mismatch. A scratch Foundry check shows that the 13-word, 416-byte head cannot deploy the hook, while the complete 1472-byte encoding with the 1015-byte final-token body deploys successfully. An invented placeholder, unresolved template, or abbreviated body would not implement the requested oracle question. Fixing the constructor and its preparation helper/tests exceeds the launch.json-only write scope. forge build and all 56 repository tests pass with the required fuzz seed; the additional scratch reproduc","treeHash":null,"usage":{"cachedInputTokens":1141760,"inputTokens":75306,"model":"gpt-6-astra","outputTokens":9720,"runtime":"codex","turns":6,"wallClockMs":340084}},{"artifacts":[],"attempt":1,"bundleHash":"fcf2b6384977716a9eece0f2c58bf3c6965da8f054e61db25b41fe3a29e3d3e7","device":"c7b1db4d25939bd5","findings":[],"hash":"4700110e3c5ac820f199f3efd442715a1333de160c0021bae7a9b35fbef614eb","nodeId":"ecff647f-dfe5-484f-b83b-edb77dd44c2c","outcome":"completed","summary":"Implemented the launch deliverable and completed the local audit panel.\n\n- `forge build`, `forge test`, and `forge fmt --check` pass.\n- 56 permanent tests and 11 supplied protected checks pass.\n- Final flags are `0x22cc`, retaining `0x288` plus required callbacks.\n- Withdrawal limits now apply per position to prevent quota interference.\n\nDetails: [audit report](/home/worker/.identitymd/work/f5ad1711-1114-405e-88d2-f5d4ff70f85a/ecff647f-dfe5-484f-b83b-edb77dd44c2c/AUDIT.md) and [launch runbook](/home/worker/.identitymd/work/f5ad1711-1114-405e-88d2-f5d4ff70f85a/ecff647f-dfe5-484f-b83b-edb77dd44c2c/launch/RUNBOOK.md).\n\nMainnet deployment and pool seeding remain the IdentityMD launch stage; no transactions were broadcast.","treeHash":"73a65ac94d1813dc417e0868717ebbd1dbd278df","usage":{"cachedInputTokens":5021824,"inputTokens":158175,"model":"gpt-6-astra","outputTokens":50675,"runtime":"codex","turns":8,"wallClockMs":1624421}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"3b260b68e9ad6a37","findings":[{"citation":"resolved","description":"Seam: boundary x invariant. The 10%/day withdrawal invariant is enforced only when slot0.tick lies inside [tickLower, tickUpper). The tick is a value any trader, including the LP, can move with a swap, and the check reads it at the moment of removal. An LP whose range edge is near the current tick pushes the tick one step past the edge with an exact-output buy or exact-input sell (both allow partial fills, so the price limit stops exactly where wanted), then removes the entire position in the same block: the early return skips the cap, and removedByPosition/removedThisBucket are not even updated. The cost is a round trip through other LPs' liquidity between the current tick and the range edge plus the 1% surcharge on it; it does not scale with the size of the position being withdrawn. The README acknowledges 'a position owner can influence price by trading', so this is a documented limitation rather than an unknown one, but it means the guard holds only for the factory's full-range position (which can never be made inactive) and is advisory for every other LP. Fix options: measure removal against a time-weighted or last-in-range tick, or apply the per-position daily cap regardless of whether the position is currently in range (inactive liquidity still backs a trade once the price returns).","line":192,"path":"src/SwarmShieldHook.sol","reproduction":"Fixture: dynamic-fee pool at tick 0 with the test's [-600,600] position of 1e23 liquidity. (1) Add a second position [0,60) with liquidity 1e21 under salt keccak256('lp'); it is active (0 <= tick 0 < 60). (2) modifyLiquidity(0,60,-1e21,salt) -> reverts RUG_SHIELD (cap 1e20). (3) swap zeroForOne=true, amountSpecified=+1e24 (exact-output buy, not native-specified), sqrtPriceLimit=getSqrtPriceAtTick(-1): fills partially, trader pays 5153447749175025154 wei ETH for tokens at market, 51534477491750252 wei burned as surcharge, tick becomes -1. (4) modifyLiquidity(0,60,-1e21,salt) in the same block succeeds: position liquidity 0, removedThisBucket for the day stays 0. Expected: at most 1e20 of that position leaves today. Actual: all 1e21 leaves. Scratch test test/scratch/RugShieldGaps.t.sol::test_ActivePositionExitsFullyByMovingTickOneStep passes on the current code.","severity":"low","snippet":"            if (tick < params.tickLower || tick >= params.tickUpper) return IHooks.beforeRemoveLiquidity.selector;","title":"Rug-shield cap exempts any position the current tick is outside of, so an active LP exits 100% in one block by nudging the tick one step past its range"},{"citation":"resolved","description":"Seam: precision x invariant. cap on line 195 is floor(remainingLiquidity * rugShieldBps / 10000), read from the position at the time of each call, while removed on line 198 is the day's cumulative total. The two are compared as if they were on the same base. After a removal of r the condition becomes r_total <= 0.1 * (L - r_total), i.e. r_total <= L/11 (9.09%), not 10%. Anyone who removes exactly 10% in one call is refused even 1 unit more for the rest of the UTC day (removed 0.1L > cap 0.09L), and anyone who splits reaches at most 9.09%. The README describes the formula ('alreadyRemoved + requested <= floor(remainingPositionLiquidity x 10%)') so the behaviour is documented, but the stated policy of '10% per day' is only met by a single removal, and the test on line 187-188 of test/SwarmShieldHook.t.sol encodes the lock as expected. Fix: snapshot the position's liquidity at the first removal of the bucket (or compute cap from remaining + removedThisBucket for the position) so the cap base is the day's opening liquidity.","line":198,"path":"src/SwarmShieldHook.sol","reproduction":"Fixture position [-600,600], L = 1e23, active, rugShieldBps = 1000. (1) remove 5e21 (5%): cap floor(1e23/10)=1e22, removed 5e21, ok. (2) remove 4.5e21: cap floor(9.5e22/10)=9.5e21, removed 9.5e21, ok. (3) remove 1 unit: cap floor(9.05e22/10)=9.05e21, removed 9.5e21+1 > cap -> RUG_SHIELD revert. Total withdrawn 9.5% and the position is locked until the next UTC day. Meanwhile a fresh identical position (salt keccak256('other'), liquidity 1e23) removes 1e22 (10%) in one call. Expected: both positions can reach 10% today. Actual: the split one stops at 9.5% and is frozen. Scratch test test/scratch/RugShieldGaps.t.sol::test_SplitRemovalsConvergeBelowTenPercent passes on the current code.","severity":"low","snippet":"            uint256 removed = removedByPosition[id][position][bucket] + removing;\n            require(removed <= cap, \"RUG_SHIELD\");","title":"Daily cap is 10% of the liquidity remaining at each call while the accumulator is cumulative, so split removals converge to L/11 and lock the position for the rest of the day"},{"citation":"resolved","description":"Boundary x precision. mulDiv(liquidity, 1000, 10000) truncates to 0 for liquidity 1..9, so removed = 1 > cap = 0 for any removal of an in-range position that small. Also the tail of any position: once remaining liquidity drops below 10 units the last units are stuck while active. Dust only, and the README states 'Integer rounding can prevent withdrawal of the last few active liquidity units'. Recorded for completeness of the boundary pass; a cap of max(1, floor(...)) or a cap based on the day's opening liquidity (finding 2) removes it.","line":195,"path":"src/SwarmShieldHook.sol","reproduction":"Add position [-600,600] with liquidity 9 under salt keccak256('tiny') while tick 0 is in range. modifyLiquidity(-600,600,-1,salt): cap = floor(9*1000/10000) = 0, removed = 1 > 0 -> RUG_SHIELD revert. Expected: an LP can withdraw at least something each day. Actual: nothing until the position becomes inactive or liquidity is added. Scratch test test/scratch/RugShieldGaps.t.sol::test_TinyActivePositionCannotWithdrawAtAll passes on the current code.","severity":"info","snippet":"            uint256 cap = FullMath.mulDiv(poolManager.getPositionLiquidity(id, position), rugShieldBps, 10_000);","title":"Active positions with fewer than 10 liquidity units have cap 0 and can never withdraw while in range"},{"citation":"resolved","description":"Zero-rounding check from the Math Precision guide, recorded as a non-issue with numbers. Exact-input buy or exact-input sell (afterSwap line 174) of less than 100 wei of ETH pays floor(base*100/10000) = 0 surcharge; exact-output of 1 wei pays ceil(1*100/9900) = 1 wei (a 50% effective rate). The value at stake is below 100 wei per swap, there is no accumulation path because each swap is independent, and the four formulas agree within 1 wei of 1% of gross in both directions (verified in test_UnverifiedBuyExactOutput / SellExactInput and the conservation fuzz). No fix needed; noted so the judge sees the boundary was covered.","line":320,"path":"src/SwarmShieldHook.sol","reproduction":"Unverified dynamic pool. swap zeroForOne=true amountSpecified=-99: cut = floor(99*100/10000) = 0, BURN balance unchanged, swap proceeds with 99 wei. swap zeroForOne=false amountSpecified=+1 (exact-output sell of 1 wei ETH): cut = ceil(1*100/9900) = 1, pool must output 2 wei, 1 wei burned.","severity":"info","snippet":"        return params.amountSpecified < 0\n            ? FullMath.mulDiv(base, surchargeBps, 10_000)\n            : FullMath.mulDivRoundingUp(base, surchargeBps, 10_000 - surchargeBps);","title":"Surcharge truncates to zero below 100 wei of ETH and to 100% at 1 wei exact-output, dust only"}],"hash":"6caae126957d4b009cf0b72cade12be03623e2baa62c9c0d5a06a8e28eec5ff0","nodeId":"0a2c3097-5225-4f51-9081-9b11b008d1d7","outcome":"completed","summary":"The review is complete. The findings file is written and validated, and the working tree holds no tracked changes.\n\n**Outcome.** The hook's swap arithmetic holds across all four modes. I traced the surcharge formulas against v4-core's `Hooks.beforeSwap`, `Hooks.afterSwap` and `Pool.swap`, checked the `PARTIAL_NATIVE_FILL` equality against the pool's exact full-fill condition, and found no value leak, overflow, or wrong rounding direction beyond dust. The defects in my area all sit in the withdrawal guard, `beforeRemoveLiquidity`.\n\n**Findings written to `.imd-findings.json`** (four, none above low):\n\n1. **Low. Tick-boundary exemption defeats the daily cap.** The guard skips any position the current tick is outside of. An LP nudges the tick one step past their range with a partial-fill swap and removes the whole position in the same block. Reproduced: a 1e21 position at [0,60) exits fully after a one-tick buy, and the daily counter stays at zero. Only the factory's full-range seed is actually held to the cap. The README names this limitation.\n2. **Low. Cap base shrinks while the accumulator is cumulative.** The cap is 10% of liquidity remaining at each call, so split removals converge to L/11 and the position locks for the day after any removal near 9%. Reproduced: 5% then 4.5% succeed, one more unit is refused, while a fresh identical position removes 10% in one call.\n3. **Info. Cap rounds to zero below 10 liquidity units**, so a tiny active position can never withdraw. Documented in the README.\n4. **Info. Surcharge is 0 under 100 wei and 1 wei at 1-wei exact output.** Confirmed by test, dust only, no accumulation path.\n\n**Coverage.** All 14 listed entry points have rows, plus three invariant rows. Thirteen entry points hold; `beforeRemoveLiquidity` carries the findings. Static-analysis leads on `verify()` reentrancy and strict equality were traced and rejected: the Intake pulls exactly the amount passed, and both callbacks are guarded.\n\n**Not reached.** I did not audit the oracle body text, the launch manifest, or the live Intake behaviour; those are outside the math area. Anyone can initialize the second valid pool (the dynamic-fee variant) at any price, which is an access question for another specialist rather than a math defect.\n\nScratch tests live under `test/scratch/`, which is gitignored, so nothing in the tree changed.","treeHash":null,"usage":{"cachedInputTokens":1837198,"inputTokens":450,"model":"claude-fable-5-1","outputTokens":45214,"runtime":"claude","turns":31,"wallClockMs":801452}},{"artifacts":[],"attempt":1,"bundleHash":"8ee078d6b9a9090f4072f47029df4706a634376c64a72c67a31187807e54648a","device":"e89087c02a1681bf","findings":[],"hash":"caee0d0775c4eacdee91f0984aa1e0abf892eeb81d11f185694bb6bc68f85d56","nodeId":"4e418531-c233-474b-b8b9-102125771f49","outcome":"completed","summary":"Added failure-path, differential fuzz, atomic launch, and multi-actor invariant tests under `test/`.\n\n- `forge build` passes.\n- Required-seed `forge test`: **94 passed, zero failures or skips**.\n- New invariant campaign: **16,384 calls**, zero unexpected reverts.\n\nNo new defects reproduced. Tests follow the accepted `0x22cc` launch specification. No live deployment or oracle panel was performed.","treeHash":"c3eb48fcc169de59352650d6c9ffe472b0d9d0d1","usage":{"cachedInputTokens":3782528,"inputTokens":172620,"model":"gpt-6-astra","outputTokens":35930,"runtime":"codex","turns":8,"wallClockMs":1140545}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"b0001bc8a5c908cd","findings":[{"citation":"resolved","description":"Economic dependency (Economic Security guide, 'break dependencies'). oraclePrice is immutable (line 46) and is the only amount verify() pulls, approves and passes to intake.requestWithFailure (lines 209-218). The oracle-consumer reference says the Intake sells oracle.request at a price read with Intake.priceOf(action, asset), and that 'a moved price must not need a redeploy'. The hook has no owner, so if the Intake's price for oracle.request@oracle-1 rises above 0.5 IMD, every verify() reverts in requestWithFailure, trustedUntil can never be set again, and once the current verdict expires every swap pays protectedLpFee plus the 1% ETH surcharge to 0xdEaD for the rest of the pool's life. README line 80 accepts that 'a changed price can stop future verification', but this case has a fix that keeps the hook ownerless: read the live price instead of fixing it at construction. The signer and Intake address are real immutability trade-offs; the price does not need to be one.","line":209,"path":"src/SwarmShieldHook.sol","reproduction":"State: hook deployed per LAUNCH_SPEC with _oraclePrice = 500000000000000000. The Intake operator raises priceOf(bytes32(\"oracle.request@oracle-1\"), IMD) to 600000000000000000, so request/requestWithFailure reverts when amount < price. Call: user approves the hook for 0.6 IMD and calls hook.verify(). Expected: the request is paid at the current price and a verdict can restore the 0.30% / no-surcharge pricing. Actual: verify() always passes 0.5 IMD and reverts inside intake.requestWithFailure. No caller and no input can ever create a new pending request, so isTrusted() stays false after the last trustedUntil and every buy of 1 ETH exact-input burns 0.01 ETH forever. Fix (ownerless): add priceOf to IIntake, have verify() read price = intake.priceOf(ORACLE_ACTION, address(imd)) and require(price > 0), then use price in place of oraclePrice for the pull, approve, request and balance checks.","severity":"low","snippet":"        imd.safeTransferFrom(msg.sender, address(this), oraclePrice);","title":"verify() pays a fixed constructor price instead of reading Intake.priceOf, so an Intake price increase stops verification permanently and the hook can never leave the 1% surcharge mode"}],"hash":"dec17f66fb620ff39400b562e8883b63b601d6736f5e053dea3c9a348a1ac83c","nodeId":"6d6afa41-edfa-41bc-b36a-759864d035d0","outcome":"completed","summary":"I found one low-severity defect and nothing critical, high or medium in the economics of the swap, surcharge, trust and withdrawal-limit flows. The findings and coverage are in `.imd-findings.json`: 1 finding and 15 coverage rows (all 14 entry points plus one invariant). No repository files were changed; I deleted the scratch test I used for measuring.\n\n**Finding (low): `verify()` pays a price fixed at deployment** (`src/SwarmShieldHook.sol:209`)\n- The hook always pays the 0.5 IMD set in its constructor. The IdentityMD reference says the price should be read from the Intake (`priceOf`) and that a price change must not need a redeploy.\n- **Trigger:** the Intake raises its `oracle.request` price above 0.5 IMD. Every `verify()` then reverts inside `requestWithFailure`.\n- **Effect:** the pool can never become trusted again. Once the current verdict expires, every swap pays the protected fee plus the 1% surcharge forever.\n- **Fix, keeping the hook ownerless:** read `intake.priceOf(ORACLE_ACTION, imd)` inside `verify()` instead of using the fixed price. The README already accepts that a price change can stop verification, but this case can be fixed without adding an owner.\n\n**What holds**\n- **Swap surcharge:** I traced all four swap modes (buy and sell, exact input and exact output).\n  - The cut is 1% of the gross ETH amount, with consistent rounding.\n  - The swapper pays exactly the amount they specified, and the hook's balance with the PoolManager always nets to zero.\n  - Partial fills where ETH is the specified side revert instead of charging for ETH that was never swapped.\n  - If the PoolManager holds too little ETH, the cut becomes a claim that `redeemSurcharge()` later sends to 0xdEaD.\n  - I found no way to avoid the surcharge or extract fees for free. Swaps under 100 wei pay no surcharge, which gas makes worthless to exploit.\n- **Oracle path:**\n  - Only answers to the hook's own requests are accepted, from the Intake.\n  - The 7-agent, 5-vote panel, the chain ID, the order of verdicts, expiry, and one-time use are all checked.\n  - A failure report never changes trust.\n  - I measured the result callback at about 130k gas with cold storage, under the Intake's 200k limit.\n- **Withdrawal limit:** the factory's zero-amount fee collection always passes. The other ways around the 10%-per-day limit are already documented as accepted trade-offs in README lines 72–80, so I did not raise them:\n  - withdrawing after moving the price out of a position's range\n  - the reset at UTC midnight\n  - leftover dust that cannot be withdrawn\n- **Policy pool:** on the 12500 pool the fee cannot drop to 0.30% after a positive verdict. The brief explicitly allows this fallback.\n\nThe existing suite passes: 56 tests, including the fuzz and stateful conservation tests. I did not review areas outside economics in depth, such as the hook flags differing from the brief's `0x288`, launch preparation and mining, or the manifest.","treeHash":null,"usage":{"cachedInputTokens":1066133,"inputTokens":28,"model":"claude-opus-5-5","outputTokens":31421,"runtime":"claude","turns":14,"wallClockMs":461440}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e8e860c7f2306473","findings":[{"citation":"resolved","description":"beforeRemoveLiquidity exempts any position whose range does not contain the current tick, and the current tick is whatever the last swap left. An LP that holds the dominant active liquidity (the exact actor a 'rug shield' is meant to slow down) sells into its own range until the tick crosses its tickUpper (or buys until it crosses tickLower), which converts the position's ETH side into the LP's wallet through the swap itself, and then removes 100% of the remaining (now single-sided) liquidity in the same block, because the position is 'inactive'. The only cost is the 1% hook surcharge on the ETH side plus the LP fee, most of which flows back to the same LP. Execution trace: beforeSwap -> pool crosses tickUpper -> beforeRemoveLiquidity reads getSlot0 tick >= tickUpper -> returns before the cap check -> removedByPosition is never written. First-principles: the guard's stated purpose (limit withdrawal of active depth to 10% per UTC day) is defeated for 1% while an LP that does not trade against itself is held to 10%/day. README.md already acknowledges 'a position owner can influence price by trading' and that this is 'not a universal time lock'; this finding gives the concrete sequence and cost so the author can decide whether the guard is worth its restriction on honest LPs (e.g. cap on removal regardless of range, or compare against liquidity at the start of the day). Reported as low because the behaviour is documented and no third party loses funds through the hook itself.","line":192,"path":"src/SwarmShieldHook.sol","reproduction":"Fixture (test/helpers/ShieldFixture.sol): dynamic pool, price 1:1, this test is the only LP with L=1e23 in [-600,600]. (1) _modify(key,-600,600,-1e23) -> reverts RUG_SHIELD (over 10%). (2) _swap(key, false, -5e23) (sell 5e23 SHIELD exact-input, token-specified so partial fill is allowed): tick after = 887271 (>= 600), the LP received 2925.7 ETH from its own pool and paid 29.55 ETH surcharge (1% of the ETH side). (3) _modify(key,-600,600,-1e23) now succeeds in the same block/day: position liquidity 0, amount1 = 6062748881374202392721 tokens returned, removedByPosition for the position stays 0. Expected: the per-day 10% cap applies to the LP's exit; actual: full exit in one transaction for ~1% of the ETH side. Scratch test run: test_RugShieldBypassByPricePush passed with these logged values.","severity":"low","snippet":"            if (tick < params.tickLower || tick >= params.tickUpper) return IHooks.beforeRemoveLiquidity.selector;","title":"Rug shield is escaped in one transaction by pushing the price out of the position's range (1% cost), so the 10%/day cap binds only honest LPs"},{"citation":"resolved","description":"_validatePool admits two keys: ETH/SHIELD at fee 12500 and ETH/SHIELD at fee 0x800000, both with spacing 60. beforeInitialize ignores the sender, so after the factory opens one of them atomically with the hook deployment, any address can call PoolManager.initialize on the other key at any sqrtPrice. Nothing is stolen (the second pool starts empty, and its fees, surcharge and rug-shield accounting are per PoolId), but a second ETH/SHIELD venue governed by the same hook exists that the launch did not open, with a price chosen by a stranger. If the author wants exactly one launch pool, take the factory as a constructor argument written \"$factory\" and require sender == factory (the IMD reference's pattern); otherwise this is a trust/design note and no change is required.","line":134,"path":"src/SwarmShieldHook.sol","reproduction":"Fixture: both keys are initialized by the test contract (not a factory) in setUp without any refusal. Direct check: vm.prank(address(manager)); hook.beforeInitialize(address(0xBEEF), key, 1) returns IHooks.beforeInitialize.selector (sender 0xBEEF, price 1 accepted). On mainnet after launch: any EOA calls PoolManager.initialize(PoolKey(ETH, SHIELD, 0x800000, 60, hook), <any sqrtPrice>) when the factory opened the 12500 pool (or the reverse). Expected per the brief's single-pool launch: refused; actual: initialized.","severity":"info","snippet":"    function beforeInitialize(address, PoolKey calldata key, uint160) external view onlyPoolManager returns (bytes4) {","title":"beforeInitialize accepts any initializer: anyone can open the sibling fee-tier pool (dynamic or 12500) on this hook at an arbitrary price"},{"citation":"resolved","description":"The brief says the address must carry 0x288 (beforeSwap, beforeSwapReturnDelta, beforeRemoveLiquidity) in its low 14 bits. The accepted implementation mines 0x22cc, adding beforeInitialize (required by the launch floor test test_permissionsMatchTheDeclaredFlags, which asserts an initialization callback) and afterSwap/afterSwapReturnDelta (needed to charge the ETH side when ETH is the unspecified currency). LAUNCH_SPEC.md section 2 and README.md document this. getHookPermissions, FLAGS and the constructor check all agree on 0x22cc, so the manifest's permissions list must be the six-entry 0x22cc set, not the three-entry 0x288 set; a manifest written from the brief's text would fail the protected flags test. No code change is needed; recorded so the manifest step and the judge use the right mask.","line":34,"path":"src/SwarmShieldHook.sol","reproduction":"HookFlags.matches(hookAddress, 0x288) is false for the deployed hook (constructor requires flagsOf(this) == 0x22cc, line 105). A launch.json with permissions [beforeSwap, beforeSwapReturnDelta, beforeRemoveLiquidity] fails Hook.protected.t.sol test_permissionsMatchTheDeclaredFlags: implemented (0x22cc) != declared (0x288).","severity":"info","snippet":"    uint160 public constant FLAGS = 0x22cc;","title":"Hook address flags are 0x22cc, not the brief's 0x288; the superset is required by the IMD floor but the brief's literal mask is not met"}],"hash":"ffd57781819cbe67f89ef66d0e148954daf492e6707698198e867f96c3d85fa4","nodeId":"cae5edc1-1192-4a48-827c-c9a8880123b8","outcome":"completed","summary":"Review complete. Findings are written to `.imd-findings.json` with coverage rows for all 14 listed entry points plus two invariants. No source files were changed, and the scratch tests were removed.\n\n**Build and tests.** The repository compiles with Solidity 0.8.26 and all 56 tests pass, including the stateful invariant suite. The brief's \"18 tests\" floor is exceeded.\n\n**What I traced in my area** (Execution Trace, Periphery, First Principles): every swap mode against v4's `Hooks.beforeSwap` and `Hooks.afterSwap` delta composition, the claim-mint fallback and `redeemSurcharge` unlock path, the rug shield's position accounting, the whole oracle lifecycle through the canonical Intake v2 callback shapes and the 200k stipend, `verify()`'s exact-balance and approval handling, `flush`, `receive`, and the launch helper library and script. No critical or high defect survived verification, so no proof file was attached.\n\n**Findings reported:**\n\n- **Low. Rug shield bypass by price push** at `src/SwarmShieldHook.sol:192`. The out-of-range exemption is reachable by the LP's own swap. Reproduced on the fixture: a sell of 5e23 SHIELD moved the tick to 887271, the sole LP received 2925.7 ETH from its own pool for a 29.55 ETH surcharge, then removed 100% of the position in the same block where a 100% removal had just reverted. The README acknowledges the limitation, so this is recorded as low with the concrete sequence and cost.\n- **Info. Any address can initialize the sibling fee-tier pool** at `src/SwarmShieldHook.sol:134`. The hook validates the key but not the initializer, so after launch a stranger can open the other admitted pool (dynamic or 12500) at any price. No funds at risk; noted as a design choice with the `$factory` pattern as the fix if a single pool is wanted.\n- **Info. Flags are 0x22cc, not the brief's 0x288** at `src/SwarmShieldHook.sol:34`. The superset is forced by the launch floor's initialization requirement and by charging ETH on token-specified swaps. Recorded so the manifest step declares the six-permission set.\n\n**Static-analysis leads** were checked and not promoted: the `verify()` reentrancy and strict-equality lines are intentional exact-payment checks behind `nonReentrant`; the unused `unlock` return and `getSlot0` tuple are harmless; the \"locks Ether\" lead is false because `flush` exists.\n\n**Not reached.** A fork rehearsal against the live Intake, IMD and PoolManager, and the launch factory's seeding and fee-collection calls, which this repository cannot exercise offline.","treeHash":null,"usage":{"cachedInputTokens":1360489,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":43255,"runtime":"claude","turns":29,"wallClockMs":998325}}],"verification":[{"checks":[{"durationMs":31169,"exitCode":0,"name":"build","output":"Compiling 108 files with Solc 0.8.26\nSolc 0.8.26 finished in 31.05s\nCompiler run successful!\n","passed":true},{"durationMs":513,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 3 tests for test/OracleConformance.t.sol:OracleConformanceTest\n[PASS] test_CanonicalCallbackSelector() (gas: 426)\n[PASS] test_CanonicalDigestAndSignature() (gas: 27044)\n[PASS] test_DomainPreventsCrossChainReplay() (gas: 23531)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 4.88ms (643.05µs CPU time)\n\nRan 5 tests for test/SwarmShieldToken.t.sol:SwarmShieldTokenTest\n[PASS] testFuzz_TransferConservesSupply(uint256) (runs: 128, μ: 74431, ~: 74563)\n[PASS] test_InsufficientBalanceAndZeroRecipientFail() (gas: 57791)\n[PASS] test_LaunchMetadataAndSupply() (gas: 34993)\n[PASS] test_NoMintOwnerOrUpgradeEntryPoints() (gas: 120235)\n[PASS] test_TransferAndAllowancePreserveSupply() (gas: 190290)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 9.39ms (7.72ms CPU time)\n\nRan 5 tests for test/LaunchPreparation.t.sol:LaunchPreparationTest\n[PASS] test_FinalTokenIsSubstitutedAndBodyIsValidJson() (gas: 32385)\n[PASS] test_MinedCodeDeploysAndInitializesPolicyPoolWithNoOracleCode() (gas: 9231910)\n[PASS] test_MinerBindsDeployerAndInitCode() (gas: 2336360)\n[PASS] test_MinerRejectsEmptyOrUnboundedSearch() (gas: 17926)\n[PASS] test_ZeroNetworkInputsAndMissingTokenRefused() (gas: 66439)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 9.46ms (13.37ms CPU time)\n\nRan 21 tests for test/OracleFlow.t.sol:OracleFlowTest\n[PASS] testFuzz_PanelThreshold(uint16,uint16,uint16) (runs: 128, μ: 460977, ~: 460976)\n[PASS] test_BadTamperedAndMalleatedSignaturesRejected() (gas: 621796)\n[PASS] test_CallbackSelectorIsCanonical() (gas: 284)\n[PASS] test_DuplicateIntakeIdRollsBackSecondPayment() (gas: 637343)\n[PASS] test_FailureClearsOnlyOwnRequestWithoutChangingTrust() (gas: 882329)\n[PASS] test_FalseReturningPaymentTokenIsRejected() (gas: 101551)\n[PASS] test_FutureExpiredAndWrongChainAnswersRejected() (gas: 598733)\n[PASS] test_IntakeCannotReenterVerificationPayment() (gas: 455625)\n[PASS] test_IntakeMustActuallyConsumePayment() (gas: 422919)\n[PASS] test_MissingAnswerTimeoutAllowsAnotherPaidRequest() (gas: 752319)\n[PASS] test_NegativeVerdictRevokesEarlierTrust() (gas: 860611)\n[PASS] test_NonBoolAndMalformedAnswersRejected() (gas: 617774)\n[PASS] test_OlderVerdictCannotRestoreTrustAfterNegative() (gas: 804522)\n[PASS] test_OnlyIntakeCanBindAnswerToPendingRequest() (gas: 476410)\n[PASS] test_PaymentFailureRollsBack() (gas: 249070)\n[PASS] test_ReplaySameIntakeIdAndOracleUuidRejected() (gas: 844075)\n[PASS] test_ResultDeliveredUnder200kAndUsesResolvedQuestionHash() (gas: 565650)\n[PASS] test_TrustNeverOutlivesSignedExpiryOrTtl() (gas: 865435)\n[PASS] test_UnknownPendingIdRejected() (gas: 70444)\n[PASS] test_VerifyPaysExactPriceAndPinsBodyAndCallbacks() (gas: 483344)\n[PASS] test_WeakAndInconsistentPanelsRejected() (gas: 647356)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 36.47ms (28.34ms CPU time)\n\nRan 21 tests for test/SwarmShieldHook.t.sol:SwarmShieldHookTest\n[PASS] testFuzz_SwapConservation(uint96,bool,bool) (runs: 128, μ: 232780, ~: 232653)\n[PASS] test_CallbacksRejectUnauthorizedCalls() (gas: 135183)\n[PASS] test_FlushAccidentalTransfersOnlyToBurn() (gas: 216981)\n[PASS] test_InactivePositionCanExitWithNoActiveLiquidity() (gas: 28403542)\n[PASS] test_InactiveRemovalCannotConsumeOtherPositionBudget() (gas: 460309)\n[PASS] test_InitializesAtPolicyFeeFromFactory() (gas: 14747)\n[PASS] test_NativeSpecifiedPartialFillRevertsWithoutBurn() (gas: 151674)\n[PASS] test_OtherPositionCannotSpendExistingPositionAllowance() (gas: 543890)\n[PASS] test_PermissionFlagsAndDeclaration() (gas: 13965)\n[PASS] test_PolicyFeeRemainsStaticBeforeAndAfterTrust() (gas: 868129)\n[PASS] test_RejectsWrongPoolAndTerms() (gas: 61345)\n[PASS] test_RugShieldAccountingIsPerPool() (gas: 389256)\n[PASS] test_RugShieldCumulativeCapRolloverAndFeeCollect() (gas: 749588)\n[PASS] test_SellPartialFillChargesActualEthOutput() (gas: 184454)\n[PASS] test_TokenOnlySeedExactOutputBuyUsesClaim() (gas: 28528859)\n[PASS] test_TokenOnlySeedFirstBuyUsesClaimThenRedeems() (gas: 28607338)\n[PASS] test_TrustedSwapsAllFourModesAndExpiry() (gas: 1217053)\n[PASS] test_UnverifiedBuyExactInput() (gas: 220537)\n[PASS] test_UnverifiedBuyExactOutput() (gas: 204241)\n[PASS] test_UnverifiedSellExactInput() (gas: 201460)\n[PASS] test_UnverifiedSellExactOutput() (gas: 186315)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 58.79ms (89.10ms CPU time)\n\nRan 1 test for test/StatefulAccounting.t.sol:StatefulAccountingTest\n[PASS]\nStatefulAccountingTest invariants:\n[PASS] invariant_HookNeverRetainsSwapAssetsOrUnsettledClaimsOnFundedManager\n[PASS] invariant_NativeAndTokenConservationAcrossAllActions\n StatefulAccountingTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭------------------------+------------+-------+---------+----------╮\n| Contract               | Selector   | Calls | Reverts | Discards |\n+==================================================================+\n| StatefulAccountingTest | stepExpire | 725   | 0       | 0        |\n|------------------------+------------+-------+---------+----------|\n| StatefulAccountingTest | stepSwap   | 686   | 0       | 0        |\n|------------------------+------------+-------+---------+----------|\n| StatefulAccountingTest | stepTrust  | 637   | 0       | 0        |\n╰------------------------+------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 388.82ms (345.77ms CPU time)\n\nRan 6 test suites in 389.99ms (507.81ms CPU time): 56 tests passed, 0 failed, 0 skipped (56 total tests)\n","passed":true},{"durationMs":64,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SwarmShieldHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"SwarmShieldHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"SwarmShieldHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"SwarmShieldHook.expireRequest(bytes32)\",\"SwarmShieldHook.flush(address)\",\"SwarmShieldHook.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"SwarmShieldHook.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"SwarmShieldHook.receive()\",\"SwarmShieldHook.redeemSurcharge()\",\"SwarmShieldHook.unlockCallback(bytes)\",\"SwarmShieldHook.verify()\",\"SwarmShieldToken.approve(address,uint256)\",\"SwarmShieldToken.transfer(address,uint256)\",\"SwarmShieldToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":19,\"AUDIT.md\":48,\"BRANDING.md\":16,\"DEPENDENCIES.md\":16,\"LAUNCH_SPEC.md\":75,\"LICENSE\":21,\"README.md\":84,\"foundry.lock\":14,\"foundry.toml\":24,\"launch/RUNBOOK.md\":15,\"launch/oracle_body.json\":16,\"remappings.txt\":4,\"script/PrepareLaunch.s.sol\":58,\"src/HookFlags.sol\":29,\"src/OracleAttestation.sol\":221,\"src/SwarmShieldHook.sol\":393,\"src/SwarmShieldToken.sol\":10,\"src/interfaces/IIntake.sol\":53,\"src/launch/LaunchParameters.sol\":57,\"test/LaunchPreparation.t.sol\":136,\"test/OracleConformance.t.sol\":74,\"test/OracleFlow.t.sol\":285,\"test/StatefulAccounting.t.sol\":57,\"test/SwarmShieldHook.t.sol\":288,\"test/SwarmShieldToken.t.sol\":65,\"test/helpers/ShieldFixture.sol\":199,\"test/mocks/MockERC20.sol\":13,\"test/mocks/MockIntake.sol\":85},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":4480,"exitCode":0,"name":"slither","output":"[high/medium] reentrancy-balance at src/SwarmShieldHook.sol:207: Reentrancy in SwarmShieldHook.verify() (src/SwarmShieldHook.sol#207-226):\n[medium/high] incorrect-equality at src/SwarmShieldHook.sol:207: SwarmShieldHook.verify() (src/SwarmShieldHook.sol#207-226) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/SwarmShieldHook.sol:207: SwarmShieldHook.verify() (src/SwarmShieldHook.sol#207-226) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/SwarmShieldHook.sol:207: SwarmShieldHook.verify() (src/SwarmShieldHook.sol#207-226) uses a dangerous strict equality:\n[medium/medium] unused-return at src/SwarmShieldHook.sol:278: SwarmShieldHook.redeemSurcharge() (src/SwarmShieldHook.sol#278-282) ignores return value by poolManager.unlock() (src/SwarmShieldHook.sol#280)\n[medium/medium] unused-return at src/SwarmShieldHook.sol:179: SwarmShieldHook.beforeRemoveLiquidity(address,PoolKey,ModifyLiquidityParams,bytes) (src/SwarmShieldHook.sol#179-205) ignores return value by (None,tick,None,None) = poolManager.getSlot0(id) (src/SwarmShieldHook.sol#189)\n[low/medium] reentrancy-benign at src/SwarmShieldHook.sol:278: Reentrancy in SwarmShieldHook.redeemSurcharge() (src/SwarmShieldHook.sol#278-282):\n[low/medium] reentrancy-benign at src/SwarmShieldHook.sol:207: Reentrancy in SwarmShieldHook.verify() (src/SwarmShieldHook.sol#207-226):\n[low/medium] reentrancy-events at src/SwarmShieldHook.sol:284: Reentrancy in SwarmShieldHook.unlockCallback(bytes) (src/SwarmShieldHook.sol#284-292):\n[low/medium] reentrancy-events at src/SwarmShieldHook.sol:302: Reentrancy in SwarmShieldHook._collect(uint256) (src/SwarmShieldHook.sol#302-308):\n[low/medium] timestamp at src/SwarmShieldHook.sol:139: SwarmShieldHook.beforeSwap(address,PoolKey,SwapParams,bytes) (src/SwarmShieldHook.sol#139-153) uses timestamp for comparisons\n[low/medium] timestamp at src/SwarmShieldHook.sol:230: SwarmShieldHook.onOracleResult(bytes32,OracleAttestation.Attestation,bytes) (src/SwarmShieldHook.sol#230-255) uses timestamp for comparisons\n[low/medium] timestamp at src/SwarmShieldHook.sol:155: SwarmShieldHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/SwarmShieldHook.sol#155-177) uses timestamp for comparisons\n[low/medium] timestamp at src/SwarmShieldHook.sol:207: SwarmShieldHook.verify() (src/SwarmShieldHook.sol#207-226) uses timestamp for comparisons\n[low/medium] timestamp at src/SwarmShieldHook.sol:130: SwarmShieldHook.isTrusted() (src/SwarmShieldHook.sol#130-132) uses timestamp for comparisons\n[low/medium] timestamp at src/SwarmShieldHook.sol:270: SwarmShieldHook.expireRequest(bytes32) (src/SwarmShieldHook.sol#270-275) uses timestamp for comparisons\n[low/medium] timestamp at src/OracleAttestation.sol:157: OracleAttestationConsumer._verifyAttestation(OracleAttestation.Attestation,bytes) (src/OracleAttestation.sol#157-165) uses timestamp for comparisons","passed":true},{"durationMs":700,"exitCode":0,"name":"aderyn","output":"[high] contract-locks-ether at src/SwarmShieldHook.sol:28: Contract locks Ether without a withdraw function\n[high] reentrancy-state-change at src/SwarmShieldHook.sol:208: Reentrancy: State change after external call (5 places)\n[low] internal-function-used-once at src/HookFlags.sol:22: Internal Function Used Only Once (3 places)\n[low] large-numeric-literal at src/SwarmShieldHook.sol:101: Large Numeric Literal (10 places)\n[low] literal-instead-of-constant at src/SwarmShieldHook.sol:101: Literal Instead of Constant (7 places)\n[low] non-reentrant-not-first at src/SwarmShieldHook.sol:233: `nonReentrant` is Not the First Modifier (2 places)\n[low] push-zero-opcode at src/interfaces/IIntake.sol:2: PUSH0 Opcode\n[low] state-change-without-event at src/SwarmShieldHook.sol:179: State Change Without Event (2 places)\n[low] state-variable-could-be-immutable at src/SwarmShieldHook.sol:47: State Variable Could Be Immutable\n[low] unchecked-return at src/SwarmShieldHook.sol:280: Unchecked Return\n[low] unsafe-erc20-operation at src/SwarmShieldHook.sol:298: Unsafe ERC20 Operation\n[low] unspecific-solidity-pragma at src/interfaces/IIntake.sol:2: Unspecific Solidity Pragma","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"4700110e3c5ac820f199f3efd442715a1333de160c0021bae7a9b35fbef614eb","verifiedTreeHash":"73a65ac94d1813dc417e0868717ebbd1dbd278df","verifierVersion":"0.1.0+8fbf00a5"},{"checks":[{"durationMs":83192,"exitCode":0,"name":"build","output":"Compiling 115 files with Solc 0.8.26\nSolc 0.8.26 finished in 83.06s\nCompiler run successful!\n","passed":true},{"durationMs":4457,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 3 tests for test/OracleConformance.t.sol:OracleConformanceTest\n[PASS] test_CanonicalCallbackSelector() (gas: 426)\n[PASS] test_CanonicalDigestAndSignature() (gas: 27044)\n[PASS] test_DomainPreventsCrossChainReplay() (gas: 23531)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 810.40µs (673.59µs CPU time)\n\nRan 5 tests for test/SwarmShieldToken.t.sol:SwarmShieldTokenTest\n[PASS] testFuzz_TransferConservesSupply(uint256) (runs: 128, μ: 74601, ~: 74557)\n[PASS] test_InsufficientBalanceAndZeroRecipientFail() (gas: 57791)\n[PASS] test_LaunchMetadataAndSupply() (gas: 34993)\n[PASS] test_NoMintOwnerOrUpgradeEntryPoints() (gas: 120235)\n[PASS] test_TransferAndAllowancePreserveSupply() (gas: 190290)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 10.60ms (11.07ms CPU time)\n\nRan 5 tests for test/LaunchPreparation.t.sol:LaunchPreparationTest\n[PASS] test_FinalTokenIsSubstitutedAndBodyIsValidJson() (gas: 32385)\n[PASS] test_MinedCodeDeploysAndInitializesPolicyPoolWithNoOracleCode() (gas: 9231910)\n[PASS] test_MinerBindsDeployerAndInitCode() (gas: 2336360)\n[PASS] test_MinerRejectsEmptyOrUnboundedSearch() (gas: 17926)\n[PASS] test_ZeroNetworkInputsAndMissingTokenRefused() (gas: 66439)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 17.69ms (23.70ms CPU time)\n\nRan 2 tests for test/AtomicLaunch.t.sol:AtomicLaunchTest\n[PASS] test_AtomicDynamicLaunchAndFactoryFeeCollection() (gas: 22266723)\n[PASS] test_AtomicPolicyLaunchAndFactoryFeeCollection() (gas: 22266504)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 19.07ms (31.46ms CPU time)\n\nRan 10 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] test_AllCallbacksAuthenticateManagerIncludingDisabledOnes() (gas: 371244)\n[PASS] test_ConstructorRejectsEmptyAndOversizedQuestion() (gas: 165916)\n[PASS] test_ConstructorRejectsEveryMissingIdentityOrPaymentInput() (gas: 227579)\n[PASS] test_ConstructorRejectsOldPermissionMask() (gas: 111152)\n[PASS] test_ConstructorRejectsRedirectedBurnAndImpossibleFeeParameters() (gas: 297874)\n[PASS] test_EveryEnabledCallbackRejectsForeignPoolEvenWhenTrusted() (gas: 1046848)\n[PASS] test_FeeCollectionAfterExhaustedQuotaDoesNotChangeQuota() (gas: 582425)\n[PASS] test_LowerTickIsActiveButUpperTickIsInactiveForRemoval() (gas: 481057)\n[PASS] test_NativeSpecifiedAmountsOutsideInt128FailBeforeCollecting() (gas: 142514)\n[PASS] test_RejectedRemovalLeavesPositionAndAllDailyCountersUnchanged() (gas: 296635)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 37.35ms (7.61ms CPU time)\n\nRan 6 tests for test/PaymentTokenFailures.t.sol:PaymentTokenFailuresTest\n[PASS] test_FailedIntakeApprovalRollsBackTheAlreadyPulledPayment() (gas: 181899)\n[PASS] test_FeeOnTransferPaymentRevertsAndRestoresSupplyBalancesAndAllowance() (gas: 186775)\n[PASS] test_NoReturnTokenPaysSuccessfullyAndLeavesNoIntakeAllowance() (gas: 1112833)\n[PASS] test_PausedPaymentTokenFailsAtomicallyAndCanRetryAfterResume() (gas: 1207816)\n[PASS] test_TokenCallbacksCannotReenterEitherPaymentHop() (gas: 1171628)\n[PASS] test_TrueReturningTokenWithoutBalanceMovementCannotBuyVerification() (gas: 146459)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 50.59ms (929.10µs CPU time)\n\nRan 21 tests for test/OracleFlow.t.sol:OracleFlowTest\n[PASS] testFuzz_PanelThreshold(uint16,uint16,uint16) (runs: 128, μ: 460978, ~: 460976)\n[PASS] test_BadTamperedAndMalleatedSignaturesRejected() (gas: 621796)\n[PASS] test_CallbackSelectorIsCanonical() (gas: 284)\n[PASS] test_DuplicateIntakeIdRollsBackSecondPayment() (gas: 637343)\n[PASS] test_FailureClearsOnlyOwnRequestWithoutChangingTrust() (gas: 882329)\n[PASS] test_FalseReturningPaymentTokenIsRejected() (gas: 101551)\n[PASS] test_FutureExpiredAndWrongChainAnswersRejected() (gas: 598733)\n[PASS] test_IntakeCannotReenterVerificationPayment() (gas: 455625)\n[PASS] test_IntakeMustActuallyConsumePayment() (gas: 422919)\n[PASS] test_MissingAnswerTimeoutAllowsAnotherPaidRequest() (gas: 752319)\n[PASS] test_NegativeVerdictRevokesEarlierTrust() (gas: 860611)\n[PASS] test_NonBoolAndMalformedAnswersRejected() (gas: 617774)\n[PASS] test_OlderVerdictCannotRestoreTrustAfterNegative() (gas: 804522)\n[PASS] test_OnlyIntakeCanBindAnswerToPendingRequest() (gas: 476410)\n[PASS] test_PaymentFailureRollsBack() (gas: 249070)\n[PASS] test_ReplaySameIntakeIdAndOracleUuidRejected() (gas: 844075)\n[PASS] test_ResultDeliveredUnder200kAndUsesResolvedQuestionHash() (gas: 565650)\n[PASS] test_TrustNeverOutlivesSignedExpiryOrTtl() (gas: 865435)\n[PASS] test_UnknownPendingIdRejected() (gas: 70444)\n[PASS] test_VerifyPaysExactPriceAndPinsBodyAndCallbacks() (gas: 483344)\n[PASS] test_WeakAndInconsistentPanelsRejected() (gas: 647356)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 66.89ms (37.61ms CPU time)\n\nRan 21 tests for test/SwarmShieldHook.t.sol:SwarmShieldHookTest\n[PASS] testFuzz_SwapConservation(uint96,bool,bool) (runs: 128, μ: 232780, ~: 232653)\n[PASS] test_CallbacksRejectUnauthorizedCalls() (gas: 135183)\n[PASS] test_FlushAccidentalTransfersOnlyToBurn() (gas: 216981)\n[PASS] test_InactivePositionCanExitWithNoActiveLiquidity() (gas: 28403542)\n[PASS] test_InactiveRemovalCannotConsumeOtherPositionBudget() (gas: 460309)\n[PASS] test_InitializesAtPolicyFeeFromFactory() (gas: 14747)\n[PASS] test_NativeSpecifiedPartialFillRevertsWithoutBurn() (gas: 151674)\n[PASS] test_OtherPositionCannotSpendExistingPositionAllowance() (gas: 543890)\n[PASS] test_PermissionFlagsAndDeclaration() (gas: 13965)\n[PASS] test_PolicyFeeRemainsStaticBeforeAndAfterTrust() (gas: 868129)\n[PASS] test_RejectsWrongPoolAndTerms() (gas: 61345)\n[PASS] test_RugShieldAccountingIsPerPool() (gas: 389256)\n[PASS] test_RugShieldCumulativeCapRolloverAndFeeCollect() (gas: 749588)\n[PASS] test_SellPartialFillChargesActualEthOutput() (gas: 184454)\n[PASS] test_TokenOnlySeedExactOutputBuyUsesClaim() (gas: 28528859)\n[PASS] test_TokenOnlySeedFirstBuyUsesClaimThenRedeems() (gas: 28607338)\n[PASS] test_TrustedSwapsAllFourModesAndExpiry() (gas: 1217053)\n[PASS] test_UnverifiedBuyExactInput() (gas: 220537)\n[PASS] test_UnverifiedBuyExactOutput() (gas: 204241)\n[PASS] test_UnverifiedSellExactInput() (gas: 201460)\n[PASS] test_UnverifiedSellExactOutput() (gas: 186315)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 128.26ms (181.71ms CPU time)\n\nRan 12 tests for test/OracleAdversarial.t.sol:OracleAdversarialTest\n[PASS] testFuzz_UnsignedFailureStatusOnlyAcceptsRefusalOrDisagreement(uint8) (runs: 256, μ: 812013, ~: 809610)\n[PASS] test_AllValidAgreementCountsCanGrantAndRevokeTrust() (gas: 2190028)\n[PASS] test_DeadlineBoundaryAndPermissionlessExpiryDoNotRevokeOtherTrust() (gas: 1125098)\n[PASS] test_EverySignedFieldIsBoundAndRejectedMutationPreservesRetry() (gas: 1954855)\n[PASS] test_ExpiryAtIssueTimeRejectedEvenWithGoodSignature() (gas: 462360)\n[PASS] test_FutureToleranceBoundaryAndRetryAfterMalformedSignature() (gas: 661762)\n[PASS] test_InsufficientApprovalCannotSpendHookDonation() (gas: 175686)\n[PASS] test_InvalidBlockWindowDoesNotConsumeRequestOrSignature() (gas: 604789)\n[PASS] test_OldPositiveDeliveryDoesNotRestartTtlAtReceiptTime() (gas: 547342)\n[PASS] test_SettledAndExpiredIntakeIdsCannotBePurchasedAgain() (gas: 1289094)\n[PASS] test_VerificationUsesOnlyCallerPaymentAndPreservesDonation() (gas: 600172)\n[PASS] test_ZeroRequestIdRollsBackPaymentAndApproval() (gas: 458959)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 139.70ms (123.81ms CPU time)\n\nRan 6 tests for test/SwapDifferential.t.sol:SwapDifferentialTest\n[PASS] testFuzz_AllModesMatchUnhookedPool(uint96,bool,bool,bool,bool) (runs: 1000, μ: 899451, ~: 666614)\n[PASS] testFuzz_BuySellRoundTripCannotCreateETH(uint96,bool,bool) (runs: 1000, μ: 568526, ~: 345056)\n[PASS] test_ExactOutputBuyPartialFillChargesOnlyDeliveredTokens() (gas: 599633)\n[PASS] test_ExactOutputSellPartialFillRollsBackPriceBalancesAndFees() (gas: 192517)\n[PASS] test_RoundingEdgesInEverySwapMode() (gas: 20676296)\n[PASS] test_TrustedNativeSpecifiedPartialFillsFollowV4() (gas: 1090168)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 139.76ms (228.80ms CPU time)\n\nRan 1 test for test/StatefulAccounting.t.sol:StatefulAccountingTest\n[PASS]\nStatefulAccountingTest invariants:\n[PASS] invariant_HookNeverRetainsSwapAssetsOrUnsettledClaimsOnFundedManager\n[PASS] invariant_NativeAndTokenConservationAcrossAllActions\n StatefulAccountingTest invariants (runs: 64, calls: 2048, reverts: 0)\n\n╭------------------------+------------+-------+---------+----------╮\n| Contract               | Selector   | Calls | Reverts | Discards |\n+==================================================================+\n| StatefulAccountingTest | stepExpire | 725   | 0       | 0        |\n|------------------------+------------+-------+---------+----------|\n| StatefulAccountingTest | stepSwap   | 686   | 0       | 0        |\n|------------------------+------------+-------+---------+----------|\n| StatefulAccountingTest | stepTrust  | 637   | 0       | 0        |\n╰------------------------+------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 492.92ms (440.05ms CPU time)\n\nRan 2 tests for test/LaunchAccountingInvariant.t.sol:LaunchAccountingInvariantTest\n[PASS]\nLaunchAccountingInvariantTest invariants:\n[PASS] invariant_AllSurchargesAreBurnedOrBackedByRedeemableClaims\n[PASS] invariant_ClosedSystemConservesETHShieldAndPaymentTokens\n[PASS] invariant_PositionLiquidityAndDailyRemovalCountersMatchActions\n[PASS] invariant_RequestTerminalsNeverReopenAndOnlySignedResultsChangeTrust\n LaunchAccountingInvariantTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭-------------------------+-----------------+-------+---------+----------╮\n| Contract                | Selector        | Calls | Reverts | Discards |\n+========================================================================+\n| LaunchAccountingHandler | answer          | 1485  | 0       | 0        |\n|-------------------------+-----------------+-------+---------+----------|\n| LaunchAccountingHandler | ask             | 1397  | 0       | 0        |\n|-------------------------+-----------------+-------+---------+----------|\n| LaunchAccountingHandler | donate          | 1549  | 0       | 0        |\n|-------------------------+-----------------+-------+---------+----------|\n| LaunchAccountingHandler | elapse          | 1487  | 0       | 0        |\n|-------------------------+-----------------+-------+---------+----------|\n| LaunchAccountingHandler | expire          | 1560  | 0       | 0        |\n|-------------------------+-----------------+-------+---------+----------|\n| LaunchAccountingHandler | failRequest     | 1511  | 0       | 0        |\n|-------------------------+-----------------+-------+---------+----------|\n| LaunchAccountingHandler | flush           | 1512  | 0       | 0        |\n|-------------------------+-----------------+-------+---------+----------|\n| LaunchAccountingHandler | modifyLiquidity | 1482  | 0       | 0        |\n|-------------------------+-----------------+-------+---------+----------|\n| LaunchAccountingHandler | redeem          | 1472  | 0       | 0        |\n|-------------------------+-----------------+-------+---------+----------|\n| LaunchAccountingHandler | trade           | 1458  | 0       | 0        |\n|-------------------------+-----------------+-------+---------+----------|\n| LaunchAccountingHandler | transferShield  | 1471  | 0       | 0        |\n╰-------------------------+-----------------+-------+---------+----------╯\n\n[PASS] test_HandlerExercisesClaimRedemptionAndConcurrentRequestLifecycle() (gas: 2340473)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 4.31s (4.30s CPU time)\n\nRan 12 test suites in 4.32s (5.42s CPU time): 94 tests passed, 0 failed, 0 skipped (94 total tests)\n","passed":true},{"durationMs":91,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"SwarmShieldHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"SwarmShieldHook.beforeRemoveLiquidity(address,(address,address,uint24,int24,address),(int24,int24,int256,bytes32),bytes)\",\"SwarmShieldHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"SwarmShieldHook.expireRequest(bytes32)\",\"SwarmShieldHook.flush(address)\",\"SwarmShieldHook.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"SwarmShieldHook.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"SwarmShieldHook.receive()\",\"SwarmShieldHook.redeemSurcharge()\",\"SwarmShieldHook.unlockCallback(bytes)\",\"SwarmShieldHook.verify()\",\"SwarmShieldToken.approve(address,uint256)\",\"SwarmShieldToken.transfer(address,uint256)\",\"SwarmShieldToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":19,\"AUDIT.md\":48,\"BRANDING.md\":16,\"DEPENDENCIES.md\":16,\"LAUNCH_SPEC.md\":75,\"LICENSE\":21,\"README.md\":84,\"foundry.lock\":14,\"foundry.toml\":24,\"launch/RUNBOOK.md\":15,\"launch/oracle_body.json\":16,\"remappings.txt\":4,\"script/PrepareLaunch.s.sol\":58,\"src/HookFlags.sol\":29,\"src/OracleAttestation.sol\":221,\"src/SwarmShieldHook.sol\":393,\"src/SwarmShieldToken.sol\":10,\"src/interfaces/IIntake.sol\":53,\"src/launch/LaunchParameters.sol\":57,\"test/AtomicLaunch.t.sol\":172,\"test/HookBoundaries.t.sol\":305,\"test/LaunchAccountingInvariant.t.sol\":371,\"test/LaunchPreparation.t.sol\":136,\"test/OracleAdversarial.t.sol\":224,\"test/OracleConformance.t.sol\":74,\"test/OracleFlow.t.sol\":285,\"test/PaymentTokenFailures.t.sol\":150,\"test/StatefulAccounting.t.sol\":57,\"test/SwapDifferential.t.sol\":150,\"test/SwarmShieldHook.t.sol\":288,\"test/SwarmShieldToken.t.sol\":65,\"test/TESTING.md\":36,\"test/helpers/AccountingActor.sol\":70,\"test/helpers/ShieldFixture.sol\":199,\"test/mocks/MockERC20.sol\":13,\"test/mocks/MockIntake.sol\":85},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"caee0d0775c4eacdee91f0984aa1e0abf892eeb81d11f185694bb6bc68f85d56","verifiedTreeHash":"c3eb48fcc169de59352650d6c9ffe472b0d9d0d1","verifierVersion":"0.1.0+8fbf00a5"}]}