{"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":"c20158a4-4d4b-46ce-ae53-24c809d47441","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"3015008c535345df9c34c04d92780f6f81be028691828ab80d46a374d325c49e","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":"29d593a0019a1d2ef6b7c72f35e1c807d58fe0c2fed3b359c3407500333cb26a","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":"91b13e251562982faf925c5661c3e13a954a649811d777400bfca55bb922d919","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":"6433e4a12b79a9d6f8cb0292686d5dfaec0838e2b8ce0e27e6b013d273c22e75","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":"3c8c28f79117144b49200b1ef54ce187a8ca2746b13af9008bb2b3e84d220099","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":"6878a7066cb91ce67e7b5311d293fb2ea1ce91be15171f9b3c923bee657a9143","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":"19b6660ee01aa93ad116cd863dd9bc1814d3c656513ee26177715b9b67b6cd26","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":"24916ac28627bd1995e9618089188c4ff1b5f23851a84fcd5f8df73de4cf1056","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"6771b8b1f82bda67c03276292ff3af2efb3fda4a629d57aff7252eb58ea4fcdc","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Launch PLEA test run 3 on Sepolia from this Foundry repository exactly as launch.json lists it: five contracts (PLEA, CabalGate, Seasons, PleaDistributor, PleaLaunch), deployed in order in one transaction with the constructor arguments in launch.json. This is the code of launch #1311 (your accepted run-2 adaptation and its audit fixes kept) plus the changes below. (1) Letters and auto-sell: a new ownerless Letterbox, deployed after the launch by anyone through PleaLaunch.deployLetterbox(creationCode), which checks the code against the keccak256 committed in launch.json, deploys it with CREATE2 (the Letterbox takes no constructor arguments and reads its settings from PleaLaunch) and registers it once with PLEA.setLetterbox; like the hook it is not a launch.json entry. Anyone pleads by sending a transaction whose input data is the plea text (fallback), or by calling letter(text) with the same text from a block explorer's Write Contract tab; commands APPEAL, SELL and NAME (a command word alone is the command, never a plea; an APPEAL letter may retry an appeal the oracle never answered); a letter pleads a fixed 20% of the writer's PLEA, held in escrow. The oracle fee, a 0.25 IMD runner tip and an appeal's 0.35 IMD wall share are paid in the same transaction by the gate selling the writer's PLEA for exactly that IMD (exact-output swap through the hook, at most the hourly snapshot value plus 10%; on Sepolia the Letterbox mints the 0.5 test oracle fee instead, a setting refused on chain id 1). Anyone sells an approved escrowed plea with deliver for at least 95% of its snapshot value and earns the tip; the gate pays the sale's IMD to the Letterbox, which sends the 0.35 IMD auto-sell fee to Seasons (checkpointed into the running season's prize pot) and the rest to the writer, and refuses up front a plea worth less than 0.70 IMD at the snapshot; the fee is taken only from a sale, and selling by hand through the gate costs nothing extra; settle returns the escrow and the tip on every other ending; status and leaderboard are text views; display names (setName or a NAME letter: 3-20 characters a-z 0-9 _, unique) live in the Letterbox. No Letterbox function ID can be the start of valid UTF-8 text (a test checks the ABI). CabalGate gains submitFor, appealFor and executeSellFor that only the Letterbox may call, plea flags with a PleaFlags event, and lastPleaOf; its own executeSell refuses escrowed pleas. PLEA gains setLetterbox (launcher only, once) and courtTake (Letterbox only, moving the caller's own PLEA into escrow); the Letterbox is an exempt sender. (2) Laureates (the season NFTs) are removed; Seasons no longer ranks pleas or mints. (3) A plea is at least 1% of the seller's balance, or 2.5M PLEA when that is less, and at most 50% of it (was 35%); the fact score's share-of-balance bands are 18 points up to 20%, 11 up to 35%, 5 above (were 15% and 25%). (4) The PLEA owner does not play: no season points, IMD prize, PLEA bonus or rebalance keeper tip. (5) A six-season PLEA bonus: PLEA.init mints 87% to the hook, 3% to Seasons and 10% to the distributor; each of the first six seasons pays 5,000,000 PLEA to its qualifying top 10 and burns the unpaid rest; flushToWall burns what is left; nobody can withdraw it. (6) The Cabal's judging rules version 2 in CabalGate.DEFINITIONS (plea, stories, content, manipulation, answer), calibrated with live Sepolia panels: keep the text exactly. (7) A gas pass that changes no behaviour: the oracle body JSON-escapes only the plea texts, the text rules read bytes without bounds checks, PleaHook.latestPrice and price24hAgo read one checkpoint and scan the ring only as a fallback, and a Letterbox escrow fits one slot; test/GasPass.t.sol holds each to the code it replaced. The launch transaction must fit Ethereum's 16,777,216 per-transaction gas cap with the headroom your deployer adds to the gas limit: test/LaunchManifest.t.sol measures it as the chain charges it, plus your factory's overhead as measured by sending these five codes through your mainnet ProjectFactory on a fork (12.7M, 15.5M with 22% headroom), and asserts it; keep any fix within that. An independent pre-audit found three low issues, fixed here with tests (test/AuditRun3.t.sol): an APPEAL letter can retry an appeal that got no verdict, a Letterbox appeal is clamped to 50% of the current balance (appealFor takes the amount), and a bare command word is never a paid plea. Audit the imported code and deploy it unchanged; fix only what the audit proves is a real bug, and keep every number as it is (fees, timings, panel 30, quorum 17, 5-hour seasons, 33-hour dead-man, START 1792162800, credit gas 1300000, letters 20%, plea maximum 50%, share bands 20/35, tip 0.25 IMD, auto-sell fee 0.35 IMD to the season pot, 0.70 IMD minimum plea value, 95% sale minimum, fee cap +10%, 1% plea minimum, six bonus seasons of 5,000,000 PLEA, the 87/3/10 split). If you change the Letterbox, update its code hash in launch.json (a test checks it). CabalGate's runtime is 24,315 bytes, 261 under the EIP-170 limit: keep any fix within it. Keep PLEA.setLauncher accepting either the deploy-transaction flag or PLEA's deployment block. Keep foundry.toml as it is, including [lint] lint_on_build = false and the read-only fs_permissions for ./out and ./launch.json. test/LetterboxInvariant.t.sol checks the Letterbox's custody under random letters, verdicts, deliveries and settles in both fee modes, and test/fork/ForkMainnet.t.sol (with MAINNET_RPC_URL) rehearses letters against the real IMD, sIMD, PoolManager and Intake v2 on an Ethereum fork.","parentJobId":null,"planHash":"20f5b956ea01bb824af072edc9b5f27772d61f3c36e15221115b625fc20a605c","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"c20158a4-4d4b-46ce-ae53-24c809d47441","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1426-launch-plea-test-run"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52142","feedbackHash":"e47559f246832287913ffc975f3e9d7cce82d6007a1257d5ed5f5eee28be7e20","nodeKey":"adapt_contract_project","submissionHash":"3015008c535345df9c34c04d92780f6f81be028691828ab80d46a374d325c49e","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52263","feedbackHash":"8929767f98d1f083949f7ab8432c08b7709ab42455f167a7abe62fce582d7036","nodeKey":"audit_economics","submissionHash":"29d593a0019a1d2ef6b7c72f35e1c807d58fe0c2fed3b359c3407500333cb26a","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52642","feedbackHash":"f4ffe5ae8629e819524e2516419b8ebf02674443515974292f5532c05e10fb59","nodeKey":"audit_flow","submissionHash":"91b13e251562982faf925c5661c3e13a954a649811d777400bfca55bb922d919","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51488","feedbackHash":"74b1e11347940c1e78531f202ba84bfadcf2764213b620335385b54cee411cce","nodeKey":"audit_imported_code","submissionHash":"6433e4a12b79a9d6f8cb0292686d5dfaec0838e2b8ce0e27e6b013d273c22e75","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51251","feedbackHash":"f1c656181d5543279843ab215b221791ad05fe03cea5b13245a249dc50f59167","nodeKey":"audit_judge","submissionHash":"3c8c28f79117144b49200b1ef54ce187a8ca2746b13af9008bb2b3e84d220099","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51512","feedbackHash":"185bb15a4b3400ddf4774efd0e8fc50c7a332834461f886dc26866f56f9903b4","nodeKey":"audit_math","submissionHash":"6878a7066cb91ce67e7b5311d293fb2ea1ce91be15171f9b3c923bee657a9143","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50994","feedbackHash":"8f2a64199f1fc81e953c89ceb61853e3dc8095ec9fed0c4268d8ed8eb34bf246","nodeKey":"audit_permissions","submissionHash":"19b6660ee01aa93ad116cd863dd9bc1814d3c656513ee26177715b9b67b6cd26","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51019","feedbackHash":"14650213b72d113a03b9e1e53d28f52e0c5d60333df2388341194f3e0df143ee","nodeKey":"manifest","submissionHash":"24916ac28627bd1995e9618089188c4ff1b5f23851a84fcd5f8df73de4cf1056","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52011","feedbackHash":"77ba48361213d52a1b9a5b1ea2821a1756d288747ab03e5ce8b9faa4755f2142","nodeKey":"write_foundry_tests","submissionHash":"6771b8b1f82bda67c03276292ff3af2efb3fda4a629d57aff7252eb58ea4fcdc","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"ec7c645a107f9aab18c798fba9c6ac2178e8192a0f44d5279ee652425f112ca0","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"60ffae3cc413a0c6","findings":[{"citation":"resolved","description":"Seam: access x asymmetry. The rule 'the PLEA owner does not play' is enforced against the *live* `plea.owner()` at the moment `closeSeason` runs (`_dropOwner`, src/Seasons.sol:308-313) and at the moment points are recorded (`record`, src/Seasons.sol:154). PLEA inherits plain OpenZeppelin `Ownable` (src/PLEA.sol:13), whose `transferOwnership(address)` is one-step: the new owner never has to accept. So the owner can hand ownership to any wallet, including the running season's leader, right before (or in the same bundle as) `closeSeason`. That wallet is then dropped from the top 10: its IMD share rolls over (`rollover = amountIn - paid`) and its PLEA bonus share is burned (`_payBonus` skips it, then burns the unpaid rest). Its future pleas also earn no points (`record` reverts `OwnerExcluded`) until it moves ownership away. The victim cannot refuse or front-run it. The owner gains nothing directly (the share is not redistributed), so this is a griefing power rather than theft; it is reported because the brief names the owner exclusion as a guarantee for players and because it costs the attacker only the `allow` power, which is all PLEA ownership controls after launch. Minimal fix that keeps the agreed design: make PLEA use `Ownable2Step` (the excluded address can then only change with the new owner's `acceptOwnership`), or have Seasons read the owner once (e.g. at `CabalGate.begin`) instead of at every close/record.","line":309,"path":"src/Seasons.sol","reproduction":"Fixture (test/utils/Fixture.sol), after buy(alice,50e18); buy(bob,50e18); skip(1 days): (1) id1 = approvedPlea(alice,45); seasons.record(id1); skip(4h+8m); id2 = approvedPlea(alice,45); seasons.record(id2) -> seasons.topOf(0)[0].wallet == alice with 90 points, seasons.seasonFees(0) > 0. (2) vm.prank(OWNER); plea.transferOwnership(alice) (no acceptance). (3) vm.warp(gate.lastVerdictAt()+DEADMAN+1h+1); seasons.closeSeason(new uint256[](0)). Expected (brief: top 10 with 60+ points are paid 25% / 1,250,000 PLEA): alice receives 25% of the pot and 1.25M PLEA. Actual: alice's IMD and PLEA balances are unchanged, seasons.rollover() == the whole pot, seasons.bonusBurned() == 5,000,000e18 (the entire season bonus burned). Reproduced in test/scratch/AccessAudit.t.sol::test_ownerTransferStripsTheLeader (passes on this tree, i.e. the behaviour occurs).","severity":"low","snippet":"        address owner_ = plea.owner();\n        for (uint256 i; i < TOP; ++i) {\n            if (t[i].wallet == owner_ && owner_ != address(0)) t[i].wallet = address(0);","title":"One-step PLEA ownership transfer lets the owner strip any season winner of the IMD prize and PLEA bonus"},{"citation":"resolved","description":"Asymmetry between the documented entry point and its guard. `burn(uint256)` is public and documented as 'Burns the caller's own tokens'; its `_update(from, address(0), v)` call reaches the generic branch of the transfer rule because `to == address(0)` is neither the pool manager nor the gate nor the Letterbox, and a normal holder is not `_exempt`. So while `restricted()` is true (before trading opens and for the whole life of the Cabal) only the hook, gate, Seasons, distributor, Letterbox, pool manager and allow-listed senders can burn. Burning is value-destroying for the caller, so nothing is lost and no bypass exists; this is recorded so the author can decide whether the ABI should keep promising a burn it refuses (either let `to == address(0)` through for everyone, or document that `burn` is for the court's contracts only). Also note that before `init` sets `poolManager`, a burn hits the `to == poolManager` (== address(0)) branch instead and is refused for anyone but the gate and hook.","line":134,"path":"src/PLEA.sol","reproduction":"Fixture after seed (plea.restricted() == true), alice holds PLEA from a buy: vm.prank(alice); plea.burn(1). Expected per the NatSpec: alice's balance decreases by 1. Actual: revert CabalIsWatching(). Reproduced in test/scratch/AccessAudit.t.sol::test_holderBurnRefusedWhileWatching.","severity":"info","snippet":"            } else if (!_exempt(from) && !(to == letterbox && msg.sender == to && to != address(0))) {\n                // Escrow into the Letterbox only through `courtTake`; direct sends are refused.\n                revert CabalIsWatching();","title":"PLEA.burn is refused for every ordinary holder while the Cabal watches"},{"citation":"resolved","description":"Trust assumption to document (access x economics). `onOracleResult(intakeId, a, sig)` locates the plea by `pleaOfIntake[intakeId]`, verifies that `a` is signed by the oracle signer for this gate, consumes `a.requestId`, and applies `a.answer` to that plea. Nothing ties `a` to the plea: `a.questionHash` is never compared with anything derived from `question(id)`/`body(id)`, and `a.requestId` (the oracle's UUID) is never compared with `intakeId`. Therefore any valid, unexpired attestation for this gate can be delivered as the callback of any other pending plea of this gate, and the only party that cannot do that is a stranger (msg.sender must be the Intake). The Intake writer is already trusted to call `onPleaFailure` without a signature, so this is consistent with the stated design, but it means the oracle signer's guarantee on chain is 'a panel scored *some* plea of this gate', not 'this plea'. If a binding is wanted, the gate can store `keccak256(body(id))` per plea and require `a.questionHash` to equal the oracle's canonical hash of it, which needs the off-chain canonicalisation to be reproducible on chain; otherwise keep it as a documented trust in the Intake.","line":506,"path":"src/CabalGate.sol","reproduction":"Fixture: idA = plead(alice, small(alice)); idB = plead(bob, small(bob)); a = attestation(45, keccak256(abi.encode('oracle', idA))) with a.questionHash = keccak256(bytes(gate.question(idA))); intake.complete(intakeIdOf(idB), 0, abi.encode(intakeIdOf(idB), a, sign(a))). Expected if verdicts were bound: the gate rejects an answer whose questionHash/requestId belong to plea A. Actual: returns true, gate.getPlea(idB).status == Approved with score 45 while plea A stays Pending. Reproduced in test/scratch/AccessAudit.t.sol::test_attestationNotBoundToPlea.","severity":"info","snippet":"        _verifyAttestation(a, signature);\n        _consume(a.requestId);","title":"A signed verdict is not bound to the plea it answers: the Intake decides which pending plea an attestation approves"}],"hash":"19b6660ee01aa93ad116cd863dd9bc1814d3c656513ee26177715b9b67b6cd26","nodeId":"37bffb4e-9f86-4b70-9f97-09a8b5286219","outcome":"completed","summary":"The review is complete. Findings are in `.imd-findings.json` at the repository root, with a coverage row for all 49 listed entry points plus the manifest and the Letterbox custody invariant. No source file was changed; the only new files are the findings JSON and two scratch tests under `test/scratch/`.\n\n**Outcome.** The permission model holds up. Every state-changing entry point was traced for its guard, its effects and its failure paths against the Access Control, Trust Gap and Asymmetry guides, and I found no permission bypass, no confused-deputy path through `courtTake`, `submitFor`, `appealFor` or `executeSellFor`, and no way for a stranger to direct escrowed PLEA or IMD anywhere but to the writer (or the fixed 0.25 IMD tip). The committed Letterbox code hash in launch.json matches the build, all 13 Letterbox selectors are confirmed not to be valid UTF-8 starts, and the manifest's constructor arguments match each constructor in order.\n\n**Findings reported (none critical or high, so no proof files):**\n\n1. **Low, Seasons.sol:309.** PLEA uses one-step `Ownable`, and Seasons applies the \"owner does not play\" rule against the live owner at close time. The owner can call `transferOwnership(leader)` right before `closeSeason`, and that wallet receives neither its IMD share (it rolls over) nor its PLEA bonus (burned). Reproduced: a 90-point leader ends with unchanged balances and the whole 5M bonus burned. Suggested fix is `Ownable2Step` or reading the excluded owner once.\n2. **Info, PLEA.sol:134.** `burn` is refused for every ordinary holder while the Cabal watches, contrary to its NatSpec. No value at risk.\n3. **Info, CabalGate.sol:506.** A signed verdict is not bound to its plea. The Intake can deliver plea A's attestation as plea B's callback and B is approved. This is a trust assumption on the Intake writer, documented as the guide asks.\n\n**Verified and clean (recorded in coverage):** a stranger settling a denied escrow inside the appeal window does not block the writer's APPEAL letter; an allow-listed sender still cannot send to the pool manager or the gate; the window boundary between `deliver` and `settle` has no gap or overlap; the three static-analysis \"reentrancy\" leads on the Letterbox and gate are gated by the transient guard and `callbackExpected`.\n\n**Not reached in depth:** the hook's fee, cap and wall economics and the Seasons ranking math are outside this area; I traced only their guards, and the coverage rows say so.","treeHash":null,"usage":{"cachedInputTokens":2665842,"inputTokens":514,"model":"claude-fable-5-1","outputTokens":62900,"runtime":"claude","turns":39,"wallClockMs":1458465}},{"artifacts":[],"attempt":1,"bundleHash":"d22ef2d40b8c226be109ab2d8d199abd9c633235c4c671928d8b95e0bb17868d","device":"8b35536ee4821baa","findings":[],"hash":"24916ac28627bd1995e9618089188c4ff1b5f23851a84fcd5f8df73de4cf1056","nodeId":"7be666ba-4a90-4b0b-a391-485d57f2a8d7","outcome":"completed","summary":"Updated only [launch.json](/home/imd-worker/.identitymd/work/c20158a4-4d4b-46ce-ae53-24c809d47441/7be666ba-4a90-4b0b-a391-485d57f2a8d7/launch.json), correcting deployment notes while preserving all five contracts, constructor arguments and verified Letterbox hash.\n\n- `forge build`: passed.\n- `forge test`: 373 passed, zero failures; two fork suites skipped because RPC access was unavailable.\n- Launch gas including 22% headroom: **15,346,305**, below **16,777,216**.","treeHash":"c60961ba4eb8ea56a37c4aab1ac8f2870e09cb07","usage":{"cachedInputTokens":2290304,"inputTokens":105468,"model":"gpt-6-astra","outputTokens":12657,"runtime":"codex","turns":11,"wallClockMs":756912}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"6b16b4979d227241","findings":[{"citation":"resolved","description":"Run 3 raised the plea maximum from 35% to 50% of the seller's balance and moved the fact-score share bands to 20%/35% (CabalGate._checkAmount, CabalGate._factScore). The suite's amount-limit test kept `bal * 35 / 100 + 1` as a 'too large' input and still expects AmountTooLarge. In this fixture alice holds about 8.77M PLEA (a 50 IMD buy), so 35% + 1 is about 3.07M PLEA, above the 2.5M MAX_SELL: the assertion passes for the cap, not for the share rule it was written for. No test in the suite asserts that 50% + 1 wei of a sub-5M balance is refused, that exactly 50% is accepted, or that the fact score steps 18 -> 11 -> 5 just above 20% and 35% (grep for factScore assertions shows only whole-score equalities). I checked these edges with a scratch test on a 1.71M PLEA balance and the code behaves as specified (50% + 1 -> AmountTooLarge, 50% accepted, bands 18/11/5), so this is a coverage note, not a code defect. Note that the band threshold is computed as floor(amount * 10000 / bal) <= 2000, so amounts up to about 20.01% still score 18; a test must step by one basis point plus one wei, not by one wei.","line":175,"path":"test/GateAdversarial.t.sol","reproduction":"State: Fixture after seed, alice buys 10 IMD of PLEA (about 1.71M PLEA, under the 2.5M cap), skip 1 day. Calls: gate.submitSell(bal/2 + 1, text) -> reverts AmountTooLarge; gate.submitSell(bal/2, text) -> accepted with amount bal/2; gate.factScore(alice, bal*2000/10000) - gate.factScore(alice, bal*2001/10000 + 1) == 7; gate.factScore(alice, bal*3500/10000) - gate.factScore(alice, bal*3501/10000 + 1) == 6. Expected and actual agree (code correct). The existing test at test/GateAdversarial.t.sol:175 would fail if alice's balance were under about 7.14M PLEA, because bal*35/100+1 would then be a valid amount under the 50% rule.","severity":"info","snippet":"        uint256[3] memory tooLarge = [2_500_000e18 + 1, bal * 35 / 100 + 1, type(uint256).max];","title":"Test gap: the 50% plea ceiling and the 20%/35% fact-score bands are not exercised; the 'too large' case still uses the old 35% figure and passes only through the 2.5M cap"}],"hash":"29d593a0019a1d2ef6b7c72f35e1c807d58fe0c2fed3b359c3407500333cb26a","nodeId":"5b1e1e88-3382-4534-ace7-60f26e32cfd0","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds the result: one informational finding and a coverage row for all 47 listed entry points plus three invariants.\n\n**Outcome: no economic defect found in the assigned area.** I traced the Economic Security, Invariant and Flow Gap checklists against the Letterbox, CabalGate, PLEA, Seasons and the hook paths they use, and confirmed each with the existing suite (370 non-fork tests pass) and two scratch tests I then removed.\n\nWhat holds, with the key reasoning:\n- **Letterbox custody.** PLEA held equals the sum of open escrows and IMD held equals one 0.25 IMD tip per open escrow in both fee modes. The fee swap buys exactly the fee IMD (partial fills revert), the oracle fee and appeal share are pulled from that, and deliver and settle each release one tip exactly once.\n- **Fee only on a sale.** The 0.35 IMD leaves only in `deliver`, goes to Seasons and is checkpointed into the running season. Settle returns escrow plus tip on every other ending. Escrowed pleas cannot be hand-sold, so no double sale.\n- **Timing seams are disjoint.** Deliver allows up to and including the window end, settle only after it. Pending settles only when the gate's own staleness test passes.\n- **Bonus and owner exclusion.** The 87/3/10 mint sums exactly, six seasons of 5,000,000 PLEA equal the 3%, unpaid shares burn, flush burns the rest, and the owner gets no points, prize, bonus or keeper tip, including after an ownership transfer.\n- **External assumptions checked on Sepolia.** The oracle fee token at 0x44a1 accepts a mint from a random address, TestIMD and the Intake have code.\n\nTwo leads I ran down and dropped as unreachable rather than report:\n- A deliver whose sale pays less than the 0.35 IMD fee would panic instead of refusing cleanly, but it needs spot to fall about 50% within the 27-minute window, which would take 70-plus distinct cap-sized approved sellers.\n- The tip refund after a no-verdict plea converts PLEA to 0.25 IMD without approval, but this is the brief's own design and on mainnet costs 0.5 IMD per 0.25 recovered.\n\nThe one recorded note is informational: the gate's \"too large\" test still uses the old 35% figure and passes only because of the 2.5M cap, so the 50% ceiling and the 20%/35% bands are not unit-tested. My scratch test confirmed the code is correct at those boundaries.","treeHash":null,"usage":{"cachedInputTokens":3844205,"inputTokens":644,"model":"claude-fable-5-1","outputTokens":76961,"runtime":"claude","turns":41,"wallClockMs":1607598}},{"artifacts":[],"attempt":1,"bundleHash":"4e040bb7251b894f1c80f28c6ac7a74c0e4674f40af559a05e09255342a5f5c3","device":"0499829b879ec3d5","findings":[],"hash":"3015008c535345df9c34c04d92780f6f81be028691828ab80d46a374d325c49e","nodeId":"547dc474-b218-4488-bc84-136325d580fc","outcome":"completed","summary":"Implemented the appeal fixes, ownership-transfer tip exclusion, manifest boolean correction and Letterbox hash update. Changes and evidence are documented in [ADAPTATION.md](/home/seat/.identitymd/work/c20158a4-4d4b-46ce-ae53-24c809d47441/547dc474-b218-4488-bc84-136325d580fc/ADAPTATION.md).\n\n- `forge build` passed.\n- `forge test`: **396 passed**, including both fork rehearsals.\n- Launch gas with 22% headroom: **15,346,305**, below the cap.\n- CabalGate retains **740 bytes** of runtime headroom.","treeHash":"a7583e5b187e56a24735e235afa9e1be66777b85","usage":{"cachedInputTokens":7580032,"inputTokens":154327,"model":"gpt-6.1-sol","outputTokens":33894,"runtime":"codex","turns":16,"wallClockMs":1153264}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"723b11f958c65250","findings":[{"citation":"resolved","description":"Merged from audit_math and audit_flow (same root cause). _requireWorthTheFee (src/Letterbox.sol:349-352) enforces amount*snapshot >= 0.70 IMD only when the plea is opened, against hook.latestPrice() of that hour. _deliver recomputes minOut (line 333) from _price() at delivery, which is the next hourly checkpoint whenever the 20-minute verdict window plus the 7-minute sale window crosses an hour boundary and any trade happens in the new hour. When that checkpoint is below ~49.5% of the plead-time one, minOut = 0.95*value < 0.35e18, the gate's sale passes its own slippage check, executeSellFor returns out < AUTO_SELL_FEE and the checked subtraction reverts with Panic(0x11). deliver and the writer's SELL letter both hit this line, so the approval cannot be sold at all; after 7 minutes the writer is Lapsed (4-hour cooldown), the oracle fee is spent (minted on Sepolia, real IMD on mainnet) and the fee PLEA was sold, while a non-escrowed plea could have sold through the gate with any minOut. settle still refunds the escrow and the tip, so nothing is misdirected: low. Reaching it needs a >50% fall between two consecutive hourly checkpoints, which only gate-approved sales can produce. I confirmed the price move is reachable on the real PoolManager in test/scratch/Judge.t.sol (Bisect2Test): 110 wallets that bought 100 IMD each one day earlier, each approved for min(35% of balance, 2.5M PLEA) and sold through gate.executeSell inside one hour, leave spot at 38% of the hour's checkpoint (logged 'spot / P_H bps: 3834'); the underflow then follows arithmetically from line 337 (0.72 IMD * 0.38 * 0.9825 ~ 0.27 IMD < 0.35 IMD, with minOut ~ 0.26 IMD satisfied). Fix that keeps every number: revert with a named error before the swap when minOut < AUTO_SELL_FEE, or cap the fee at the sale (fee = out < AUTO_SELL_FEE ? out : AUTO_SELL_FEE).","line":337,"path":"src/Letterbox.sol","reproduction":"State: Fixture (test/utils/Fixture.sol), Cabal alive (keepAlive(bob) once), hook seeded, past the launch window, 110 wallets that bought 100 IMD of PLEA one day earlier. 1) Hour H minute 1: carol buys 1 IMD -> hook.latestPrice() = P_H. 2) Hour H minute 45: victim buys 10 IMD and calls letterbox.plead(amount, text) with amount = 0.72e18*2^96/P_H + 1 (worth 0.72 IMD at P_H, passes _requireWorthTheFee; fact score 41 so need 29 <= 45). 3) Same timestamp: each of the 110 wallets submitSell(min(balance*35/100, 2.5M PLEA)), is answered 45 (Approved) and calls gate.executeSell(0); spot ends at 0.38*P_H (measured). 4) Hour H+1 minute 1: any 1 IMD buy checkpoints P_{H+1} = 0.38*P_H; the Intake delivers the victim's verdict 45 (16 minutes after submission, inside PENDING_EXPIRY) -> Approved. 5) letterbox.deliver(id) or the victim sends the letter 'SELL'. Expected: the sale completes for at least 95% of the delivery snapshot (brief) or a named refusal. Actual: minOut = 0.95*0.72*0.38 IMD ~ 0.26e18; executeSellFor returns out ~ 0.27e18 >= minOut and `out - AUTO_SELL_FEE` (0.27e18 - 0.35e18) reverts with Panic(0x11) (selector 0x4e487b71); both deliver and SELL revert; after 7 minutes letterbox.settle(id) returns the escrow and the victim's next plea reverts Cooldown.","severity":"low","snippet":"        out = gate.executeSellFor(id, minOut) - AUTO_SELL_FEE;","title":"Letterbox.deliver underflows on the 0.35 IMD auto-sell fee when the delivery-hour snapshot values the escrow below 0.35/0.95 IMD, so an approved letter plea can neither be delivered nor SELL-ed and la"},{"citation":"resolved","description":"A letter plea needs 20% of the balance to be worth >= 0.70 IMD (balance >= 3.5 IMD at the snapshot) and the plea fee cap maxFeePlea = (0.25 IMD * 1.1)/price + 1 to be <= 10% of the balance (balance >= 2.75 IMD). An appeal by letter buys the 0.25 tip plus the 0.35 wall share = 0.60 IMD, capped at +10% = 0.66 IMD worth of PLEA, and the same 10% rule at line 293 then needs a balance >= 6.6 IMD (on the mainnet path, where the 0.5 oracle fee is bought too: letter >= 8.25 IMD, appeal >= 12.1 IMD). Every writer in the gap gets a DENIED status that says 'send APPEAL <text> before HH:MM UTC' (src/Letterbox.sol:496-503) and then has both Letterbox appeal paths revert FeeTooHigh, while gate.appeal(originalId, amount, text) for the identical amount succeeds when the IMD is paid directly. The brief lists the 0.70 IMD minimum as the up-front refusal; the 10% fee-share bound is what blocks the agreed 'APPEAL letter' flow for small holders. Fix without changing fees or shares: apply the 10% bound to the plea fee only, or allow an appeal whenever its original letter was allowed (compare against max(10% of balance, original plea amount)), or make status() not invite an APPEAL letter the Letterbox will refuse.","line":293,"path":"src/Letterbox.sol","reproduction":"Reproduced by test/scratch/Judge.t.sol::JudgeTest::test_appealFeeGap (passes, i.e. the behaviour occurs). State: Fixture, Cabal alive, past the launch window, Sepolia mode (mintOracleFee = true). 1) Wallet w buys 5 IMD of PLEA; after one day its balance is worth 4.909 IMD at hook.latestPrice() (logged 'bag value: 4909028698251516752'). 2) w sends the letter 'A fifth for a bike; the rest stays with me all season.' -> accepted (20% escrowed, fee PLEA sold for 0.25 IMD). 3) The oracle answers 0 -> Denied; letterbox.status(w) returns 'Plea #2 · DENIED (0 vs 28) · send APPEAL <text> before 13:31 UTC · call settle or send a letter to get your PLEA back'. 4) w sends 'APPEAL The bike is how I get to work; I keep the rest.' Expected: an appeal of the denied plea (brief: 'commands APPEAL'). Actual: revert FeeTooHigh(110717540983603302031964, 782431644353960261810751): feesFor(true) = 0.60 IMD -> 0.66 IMD worth of PLEA (logged 'appeal fee value: 660000000000000000'), 14.2% of the balance after the denied escrow is returned; letterbox.appealAuto(id, text) reverts FeeTooHigh the same way. 5) After letterbox.settle(id), w calls gate.appeal(id, originalAmount, text) with IMD approved -> succeeds.","severity":"low","snippet":"        if (maxFeePlea * BPS > bal * MAX_FEE_SHARE_BPS) revert FeeTooHigh(maxFeePlea, bal);","title":"A writer whose PLEA is worth 3.5-6.6 IMD (8.25-12.1 IMD on mainnet) can plead by letter and is told 'send APPEAL <text>', but the APPEAL letter and appealAuto are refused by the 10% fee-share check"},{"citation":"resolved","description":"'The PLEA owner does not play' is enforced against the live plea.owner() at closeSeason (_dropOwner, src/Seasons.sol:308-313) and at record (src/Seasons.sol:154). PLEA inherits plain OpenZeppelin Ownable (src/PLEA.sol:13), whose transferOwnership is one-step: the new owner never accepts. The owner can therefore hand ownership to the running season's leader right before closeSeason (or in the same bundle): that wallet is dropped from the top 10, its IMD share rolls over, its PLEA bonus share is burned (_payBonus skips it and burns the unpaid rest), and its later pleas earn no points (record reverts OwnerExcluded) until it moves ownership away. The owner gains nothing directly (the share is not redistributed), so this is a griefing power rather than theft, reported because the brief names the owner exclusion as a guarantee for players and the fix is small: Ownable2Step for PLEA, or Seasons reading the excluded owner once (e.g. at CabalGate.begin) instead of at every close/record. Trust assumption to document otherwise.","line":309,"path":"src/Seasons.sol","reproduction":"Reproduced by test/scratch/Judge.t.sol::JudgeTest::test_ownerTransferStripsLeader (passes, i.e. the behaviour occurs). Fixture after buy(alice,50e18); buy(bob,50e18); skip(1 days): (1) id1 = approvedPlea(alice,45); seasons.record(id1); skip(4h+8m); id2 = approvedPlea(alice,45); seasons.record(id2) -> seasons.topOf(0)[0] is alice with 90 points, seasons.seasonFees(0) > 0. (2) vm.prank(OWNER); plea.transferOwnership(alice) (no acceptance). (3) vm.warp(gate.lastVerdictAt()+DEADMAN+1h+1); seasons.closeSeason(new uint256[](0)). Expected (brief: top 10 with 60+ points are paid 25% / 1,250,000 PLEA): alice receives 25% of the pot and 1.25M PLEA. Actual: alice's IMD and PLEA balances are unchanged, seasons.rollover() == the whole pot, seasons.bonusBurned() == 5,000,000e18.","severity":"low","snippet":"        address owner_ = plea.owner();","title":"One-step PLEA ownership transfer lets the owner strip any season winner of its IMD prize and PLEA bonus (and of future points) without the victim's consent"},{"citation":"resolved","description":"While reproducing finding 1 on the real PoolManager, the 1 IMD buy that opens hour H+1 reverted inside PleaHook.afterSwap with panic 0x11 (arithmetic underflow/overflow), after _payFees emitted FeesTaken and after exactly one PoolManager.extsload (the getSlot0 read at the top of _applyCap, src/PleaHook.sol:685), i.e. in _applyCap's ratchet/trim arithmetic or _pleaIn, before any further external call. Logged hook state just before that swap: lastCapDecayAt 1800182699 (block.timestamp 1800183660), inventoryCap 796,487,828e18, pleaInMarket 439,432,295e18, capDecayPerDay 34,763,965e18, capDecayRemainder 34,763,965199999999999963095 (one second short of a full day's rate), market liquidity 2080886472306681101043009, tick -107060, refTick -120721, wallGuardTick -120721. I could not isolate the trigger in the time budget: Bisect2Test::test_F and Bisect3Test::test_F (PLEA forced to currency0, as in the panicking run) in the same scratch file perform the same steps (Letterbox plea, 110 sales ending at 38% of the checkpoint, next-hour buy) with the whale setup moved into setUp, and there the buy succeeds, as do later buys and sells; the only remaining differences are harness-side (which contract deployed the fixture, and the gas the test had consumed before the swap). So this is at most a single reverted swap in a specific state, not a persistent block of the pool, and it may be a harness artefact. Reported so the author can run the deterministic sequence against _applyCap (src/PleaHook.sol:682-724); severity low pending isolation, and it should be dropped if the author cannot reproduce it outside this harness.","line":475,"path":"src/PleaHook.sol","reproduction":"Run `forge test --match-path test/scratch/Judge.t.sol --match-test test_deliverUnderflow -vvvv` on this tree: setUp buys 50 IMD for alice and bob and skips one day; 110 wallets buy 100 IMD each; keepAlive(bob); skip 1 day; warp to the next hour boundary + 60 s (H:01) and carol buys 1 IMD; warp +44 min; victim buys 10 IMD and calls letterbox.plead(0.72 IMD worth at the H checkpoint, text); 110 wallets each submitSell(min(35% balance, 2.5M)), are answered 45 and executeSell(0) (spot ends at 38% of the H checkpoint); warp to the next hour boundary + 60 s; carol buys 1 IMD through the fixture's BuyRouter. Expected: the buy succeeds (as in Bisect2Test::test_F). Actual: PoolManager.swap -> PleaHook.afterSwap reverts `panic: arithmetic underflow or overflow (0x11)` (WrappedError(hook, 0xb47b2fb1, 0x4e487b71...11)), observed deterministically on three runs.","severity":"low","snippet":"    function afterSwap(address, PoolKey calldata key, SwapParams calldata params, BalanceDelta delta, bytes calldata)","title":"PleaHook.afterSwap reverts with Panic(0x11) on the first buy of the hour after a crash of ~62% produced by 110 approved sales plus one Letterbox auto-sell plea (not isolated; a later buy in the same s"},{"citation":"resolved","description":"burn calls _update(from, address(0), v); while restricted() is true (before trading opens and for the whole life of the Cabal) the transfer rule's generic branch (src/PLEA.sol:134-136) refuses it unless the sender is exempt (hook, gate, Seasons, distributor, Letterbox, pool manager or allow-listed). Burning only destroys the caller's own value, so nothing is lost or bypassed; recorded so the author decides whether the ABI should keep promising a burn it refuses (let to == address(0) through for everyone, or document burn as the court contracts' own).","line":116,"path":"src/PLEA.sol","reproduction":"Reproduced by test/scratch/Judge.t.sol::JudgeTest::test_holderBurnRefused (passes). Fixture after seed (plea.restricted() == true), alice holds PLEA from a buy: vm.prank(alice); plea.burn(1). Expected per NatSpec: alice's balance decreases by 1. Actual: revert CabalIsWatching().","severity":"info","snippet":"    function burn(uint256 amount) external {\n        _burn(msg.sender, amount);\n    }","title":"PLEA.burn is refused for every ordinary holder while the Cabal watches, although it is documented as 'Burns the caller's own tokens'"},{"citation":"resolved","description":"onOracleResult locates the plea by pleaOfIntake[intakeId], verifies the attestation is signed by the oracle signer for this gate, consumes a.requestId and applies a.answer to that plea. Nothing ties a to the plea: a.questionHash is never compared with anything derived from question(id)/body(id), and a.requestId is never compared with intakeId. Any valid unexpired attestation for this gate can therefore be delivered as the callback of any other pending plea of this gate by the Intake (msg.sender must be the Intake, which is already trusted to call onPleaFailure unsigned). Consistent with the stated design, but the on-chain guarantee is 'a panel scored some plea of this gate', not 'this plea'. If a binding is wanted, store keccak256(body(id)) per plea and require a.questionHash to equal the oracle's canonical hash of it; otherwise keep it as a documented trust in the Intake.","line":506,"path":"src/CabalGate.sol","reproduction":"Fixture: idA = plead(alice, small(alice)); idB = plead(bob, small(bob)); a = attestation(45, keccak256(abi.encode('oracle', idA))) with a.questionHash = keccak256(bytes(gate.question(idA))); intake.complete(intakeIdOf(idB), 0, abi.encode(intakeIdOf(idB), a, sign(a))). Expected if verdicts were bound: the gate rejects an answer whose questionHash/requestId belong to plea A. Actual: returns true, gate.getPlea(idB).status == Approved with score 45 while plea A stays Pending (traced: no questionHash or requestId comparison exists in onOracleResult, src/CabalGate.sol:496-529; the fixture's own attestation() already uses an arbitrary questionHash and every verdict in the suite is accepted).","severity":"info","snippet":"        _verifyAttestation(a, signature);\n        _consume(a.requestId);","title":"A signed verdict is not bound to the plea it answers: the Intake decides which pending plea an attestation approves (trust assumption)"},{"citation":"resolved","description":"Run 3 raised the plea maximum to 50% of the balance and moved the fact-score share bands to 20%/35% (CabalGate._checkAmount line 486, _factScore lines 253-256), and the code does what the brief says. The suite's amount-limit test kept bal*35/100+1 as a 'too large' input: with alice's ~8.77M PLEA that is ~3.07M, above MAX_SELL, so the assertion passes for the cap, not for the share rule. No test asserts that 50% + 1 wei of a sub-5M balance is refused, that exactly 50% is accepted, or that the fact score steps 18 -> 11 -> 5 just above 20% and 35%. The band threshold is floor(amount*10000/bal) <= 2000, so a test must step by one basis point plus one wei.","line":175,"path":"test/GateAdversarial.t.sol","reproduction":"Fixture, alice buys 10 IMD (about 1.7M PLEA, under the cap), skip 1 day, bal = plea.balanceOf(alice): gate.submitSell(bal/2 + 1, text) -> AmountTooLarge; gate.submitSell(bal/2, text) -> accepted; gate.factScore(alice, bal*2000/10000) - gate.factScore(alice, bal*2001/10000 + 1) == 7; gate.factScore(alice, bal*3500/10000) - gate.factScore(alice, bal*3501/10000 + 1) == 6. Code and expectation agree (in my scratch runs a plea of exactly 35% of the balance scored the 11-point band and one of 50% the 5-point band, as specified); the existing test at test/GateAdversarial.t.sol:175 would stop asserting the share rule (and fail) for any alice balance under about 7.14M PLEA because bal*35/100+1 is then a valid amount under the 50% rule.","severity":"info","snippet":"        uint256[3] memory tooLarge = [2_500_000e18 + 1, bal * 35 / 100 + 1, type(uint256).max];","title":"Test gap: the 50% plea ceiling and the 20%/35% fact-score bands are not exercised; the 'too large' case still uses the old 35% figure and passes only through the 2.5M cap"}],"hash":"3c8c28f79117144b49200b1ef54ce187a8ca2746b13af9008bb2b3e84d220099","nodeId":"802aee24-94c5-4222-b531-b871dab169e8","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds 7 findings plus a 49-row coverage record (all 47 entry points answered, plus manifest and runtime-size rows). No repository file was changed; the only writes are the findings file and my scratch tests under `test/scratch/`, both git-ignored.\n\n**What I verified against the tree**\n\n- The Letterbox creation-code hash in launch.json matches the build here, the manifest's constructor argument counts match every constructor, and `test/LaunchManifest.t.sol` passes.\n- Runtime sizes are under the EIP-170 limit (CabalGate 23,836 bytes, PleaHook 23,865, Letterbox 20,688).\n- The GasPass, AuditRun3, Letterbox, LetterboxEdges and LaunchManifest suites all pass.\n\n**Findings kept (after reproduction)**\n\n1. **Low, Letterbox.deliver fee underflow** (merged audit_math + audit_flow). I confirmed the precondition is reachable on the real PoolManager: 110 approved cap-sized sales in one hour leave spot at 38% of the hour's checkpoint, after which the checked subtraction at `src/Letterbox.sol:337` underflows for a 0.72 IMD plea, so neither `deliver` nor a SELL letter can sell it.\n2. **Low, APPEAL letter refused for holders worth 3.5 to 6.6 IMD.** Reproduced with a 5 IMD buyer: status says \"send APPEAL\", the letter and `appealAuto` revert `FeeTooHigh`, while the gate's own `appeal` for the same amount works.\n3. **Low, one-step ownership transfer strips a season leader.** Reproduced: after `transferOwnership(alice)`, `closeSeason` pays alice nothing, rolls the pot over and burns the whole 5M PLEA bonus.\n4. **Low, unisolated PleaHook.afterSwap Panic(0x11).** While building finding 1, the first buy of the next hour reverted deterministically inside `_applyCap`, but a re-implementation of the same steps in a fresh harness passes in both pool orientations. I reported it with the exact sequence and flagged that it may be a harness artefact.\n5. **Info** PLEA.burn refused for ordinary holders (reproduced), the attestation not being bound to its plea (trust assumption, traced), and the test gap on the new 50% ceiling and 20/35 bands.\n\n**Dropped or downgraded**: nothing from the specialists was dropped; the two deliver-underflow reports were merged into one, and the ownership-transfer item stays low rather than medium because the owner gains nothing from it.\n\n**Open point for the author**: finding 4 needs isolation. If it does not reproduce outside my scratch harness, it should be closed.","treeHash":null,"usage":{"cachedInputTokens":6274797,"inputTokens":932,"model":"claude-fable-5-1","outputTokens":110608,"runtime":"claude","turns":46,"wallClockMs":3401679}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"5835e48821d8827d","findings":[{"citation":"resolved","description":"The run-3 pre-audit fix lets an APPEAL letter retry an appeal the oracle never answered by redirecting from the newest plea to its original when that newest plea is an appeal with status Expired. But the common no-verdict ending is the 20-minute timeout with no Intake call: the gate only flips a Pending plea to Expired lazily (in _clearStale, expire or onPleaFailure), so at letter time the newest plea is still Pending and _appealTarget returns the stale appeal itself. Letterbox._appeal then runs _settleOpen (which expires it via gate.expire inside the same transaction) and calls gate.appealFor(writer, <appealId>, ...), whose _appeal reads pleas[appealId].status == Expired and reverts NotDenied, undoing the settle as well. The site path appealAuto(originalId) succeeds in the identical state, and the gate explicitly allows the retry (_expire resets o.appealed), so the stated guarantee 'an APPEAL letter may retry an appeal the oracle never answered' holds only when the Intake delivered a failure callback. No funds are lost: the writer must first call settle(appealId) or gate.expire(appealId) in a separate transaction and send the letter again, paying the 4-hour appeal window against the clock. Minimal fix: in _appealTarget treat a Pending appeal that is stale (block.timestamp > submittedAt + PENDING_EXPIRY or the Intake request completed) like an Expired one, i.e. `if (p.isAppeal && (p.status == Expired || (p.status == Pending && _settleable(id)))) id = p.originalId;`.","line":421,"path":"src/Letterbox.sol","reproduction":"Fixture state (test/utils/Fixture.sol): alice bought 50 IMD of PLEA and waited a day. 1) alice sends letter 'A fifth for rent; the rest stays with me all season.' -> plea #1 Pending; oracle answers score 0 -> Denied. 2) alice sends 'APPEAL Plainly: the rent is due on Friday, and I keep the rest.' -> appeal #2 Pending, escrow open. 3) skip(20 minutes + 1); nobody calls expire/onPleaFailure, gate.getPlea(2).status is still Pending. 4) alice sends 'APPEAL Once more: the rent is due on Friday; the rest stays.'. Expected: a new appeal of plea #1 (as the task text and test_appealLetterRetriesAnAppealTheOracleNeverAnswered promise for an unanswered appeal). Actual: the call reverts with CabalGate.NotDenied (0xd8d915dd) and the stale escrow is not settled either. Control: in the same state vm.prank(alice); letterbox.appealAuto(1, 'Once more: ...') succeeds and opens an appeal with originalId 1. Reproduced in test/scratch/Probe.t.sol test_probe_staleAppealLetter.","severity":"low","snippet":"        if (p.isAppeal && p.status == CabalGate.Status.Expired) id = p.originalId;","title":"APPEAL letter cannot retry an appeal that timed out but was never expired on chain (reverts NotDenied)"},{"citation":"resolved","description":"An appeal must be for at most the original amount (AmountTooLarge) and, through _checkAmount, for at least 1% of the seller's current balance (AmountTooSmall). Both bounds are evaluated against the balance at appeal time, so if the seller bought (or received) PLEA after the denial such that 1% of the new balance exceeds the original amount, no amount satisfies both checks and the appeal that the rules grant within 4 hours of a denial cannot be made at all. For a site plea at the 1% minimum any increase in balance blocks the appeal; for a 20% letter plea a 20x increase does. The Letterbox has no way around it either: Letterbox._appeal clamps the amount down to 50% of the balance but never up, so the APPEAL letter and appealAuto revert AmountTooSmall. The buyer of more PLEA shows more loyalty, not less, so this is the opposite of the fact-score's intent; the 0.5 IMD oracle fee of the denied plea is spent and the appeal right is lost. Minimal fix that keeps every number: in _appeal check the minimum against the original plea's own balance basis instead of the current one, e.g. skip the MIN_SHARE_BPS floor for appeals (`if (amount == 0) revert AmountTooSmall(); if (amount > MAX_SELL || amount > bal * MAX_SHARE_BPS / 10_000) revert AmountTooLarge();`), since the original already satisfied the 1% rule when it was scored.","line":357,"path":"src/CabalGate.sol","reproduction":"Fixture state: alice bought 50 IMD of PLEA (6,761,336.7 PLEA) and waited a day. 1) alice sends a letter -> plea #1 for 20% = 1,701,023.9 PLEA; oracle answers 0 -> Denied at t0. 2) alice buys 5,000 IMD of PLEA -> balance (with the escrow returned) 427,622,124.7 PLEA, so least = 1% = 4,276,221.2 PLEA > original 1,701,023.9. 3) Within 4 hours of t0: APPEAL letter -> reverts CabalGate.AmountTooSmall; letterbox.settle(1) then vm.prank(alice) gate.appeal(1, 1701023.9e18, text) -> reverts AmountTooSmall; gate.appeal(1, 4276221.2e18, text) -> reverts AmountTooLarge. Expected: an appeal of the denied plea for its original amount is possible within 4 hours of the denial. Actual: no amount is accepted on any path. Simplest instance: gate.submitSell(bal/100, text) (exactly the 1% minimum), denial, then buy 1 IMD more and gate.appeal(id, bal/100, text) -> AmountTooSmall, while any larger amount -> AmountTooLarge. Reproduced in test/scratch/Probe.t.sol test_probe_appealBlockedByMinShare.","severity":"low","snippet":"        if (amount > o.amount) revert AmountTooLarge();\n        _checkAmount(amount, bal);","title":"The 1% minimum share makes a denied plea un-appealable once the seller's balance grows (every path: appeal, appealFor, APPEAL letter)"},{"citation":"resolved","description":"PleaLaunch's eleventh constructor parameter is `bool mintOracleFee_`. The evm-contracts launch recipe this task is judged against lists the supported argument encodings as 'address, uint8...uint256, bool (0/1) and bytes32' and 'decimal/hex static words'. The manifest encodes it as the word \"true\", which is neither a decimal nor a hex static word. test/LaunchManifest.t.sol does not exercise this argument through a manifest parser: it hardcodes `MINT_ORACLE_FEE = true` and only reads constructorArgs[11] (the Letterbox hash) from the file, so nothing in the repository proves the deployer's manifest step accepts \"true\". If the deployer's argument parser is as the recipe states, the whole launch is refused at the manifest step, after the build is accepted. The adapter should write \"1\" (the value the ABI encodes for true) unless it has evidence the parser accepts the word; the rest of the file (keys, order, counts, $owner usage, $contract references pointing backward, notes under 4,000 characters) matches the schema.","line":50,"path":"launch.json","reproduction":"Input: launch.json as committed, contracts[4].constructorArgs[10] == \"true\" for PleaLaunch(bool mintOracleFee_). Parse it with the recipe's rule (decimal or hex static word, bool as 0/1): \"true\" is not a decimal or 0x-prefixed hex word, so the argument does not decode and the manifest is refused. With \"1\" in its place the ABI word is identical to what a Solidity `true` encodes (0x...01) and the Letterbox mints the oracle fee on Sepolia exactly as the notes describe. Expected: a manifest every stated parser accepts; actual: an encoding only an undocumented lenient parser accepts. This finding cannot be verified against the deployer's code from this repository and is reported as a configuration lead for the adapter.","severity":"low","snippet":"        \"true\",","title":"launch.json writes the bool constructor argument as \"true\" where the launch recipe specifies bool arguments as 0/1"}],"hash":"6433e4a12b79a9d6f8cb0292686d5dfaec0838e2b8ce0e27e6b013d273c22e75","nodeId":"2ee10e7b-8f25-47df-8c98-20510e0c49a9","outcome":"completed","summary":"Review complete. The findings file holds three low-severity findings, all reproduced locally.\n\n**Scope read in full:** PLEA, CabalGate, Seasons, PleaDistributor, PleaLaunch, Letterbox, PleaHook, OracleAttestation, and both interface files. launch.json was checked against the constructor declarations: five contracts in dependency order, one argument per parameter, only the two owner slots use `$owner`, and the committed Letterbox hash matches this build. The 339-test unit suite passes. **Not reached:** the fork rehearsals in test/fork were not run because no RPC URL is set, and the live IMD contracts the system depends on (Intake v2, TestIMD, the Stacker, the PoolManager) were read only through the interfaces this repository declares.\n\n**Findings written to `.imd-findings.json`:**\n\n- **Low, Letterbox line 421.** An APPEAL letter cannot retry an appeal that hit the 20-minute timeout without anyone expiring it on chain. The target is still Pending, so the letter points at the stale appeal and the gate reverts `NotDenied`, while `appealAuto` succeeds in the same state. The run-3 fix only covers the Intake failure callback path.\n- **Low, CabalGate line 357.** The 1% minimum share and the \"at most the original amount\" rule are both measured against the current balance, so a seller whose balance grew after a denial has no amount that passes both checks. A plea at exactly the 1% minimum becomes un-appealable after buying any PLEA. Every path reverts: `appeal`, `appealFor`, and the APPEAL letter.\n- **Low, launch.json line 50.** The bool argument is written as the word `\"true\"`, while the launch recipe lists bool arguments as 0/1 static words. The manifest test does not parse this argument from the file, so nothing in the repository proves the deployer accepts it. This is a configuration lead, not a verified parser failure.\n\n**No higher-severity defect found.** Custody in the Letterbox balances exactly: it holds one tip per open escrow and the escrowed PLEA, and both probes of lapsed-then-settled and delivered-then-settled paths left zero residue. The exact-output fee swap, the `courtTake` exemption in PLEA's transfer rule, the gate's Letterbox-only entry points, the owner exclusion, and the six-season bonus accounting all behaved as specified under the inputs I tried. One behaviour worth knowing but not reported as a defect: a `deliver` reverts by underflow if the hourly snapshot falls below roughly half its plead-time value, which the gated sell limits make impractical, and `settle` recovers the escrow afterwards.\n\nScratch probes are in test/scratch/Probe.t.sol and Probe2.t.sol. No source, test, or configuration file was changed.","treeHash":null,"usage":{"cachedInputTokens":1774280,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":45881,"runtime":"claude","turns":26,"wallClockMs":1274207}},{"artifacts":[],"attempt":1,"bundleHash":"51c45dcdf84fc7e54d5978ba13a5a167c5206c25ea91887694b66cd401afa861","device":"a406deaac63a93b0","findings":[],"hash":"6771b8b1f82bda67c03276292ff3af2efb3fda4a629d57aff7252eb58ea4fcdc","nodeId":"a74e28a3-470b-4078-874b-82b29aed8854","outcome":"completed","summary":"Work is complete. The new file `test/LetterboxEdges.t.sol` is the only change, and the full suite passes with it.\n\n**Result**\n\n| Run | Outcome |\n|---|---|\n| `forge test` (whole repo) | 407 passed, 0 failed, 2 skipped (fork tests needing an RPC URL) |\n| `test/LetterboxEdges.t.sol` alone | 37 passed across the Sepolia and mainnet fee modes |\n\n**What the new tests cover** that the existing suite did not:\n\n- **Exact clock boundaries.** At the last second of the 7-minute window an approved letter still sells and cannot be settled. One second later it cannot sell, settles, and is still recorded for the season. The pending expiry is checked at exactly 20 minutes and 20 minutes plus one second, and a late verdict is refused after the escrow is gone.\n- **A lapsed letter's aftermath.** The gate keeps the plea Approved after the Letterbox settles it, so the writer's next letter is refused with a cooldown dated from the verdict. The refusal reverts everything, including the gate's clearing. The letter at the end of the cooldown succeeds and marks the old plea Lapsed.\n- **The 10% fee-share cap.** A small holder's APPEAL letter is refused with `FeeTooHigh`, nothing moves, and the gate's hand appeal still works. No existing test exercised that error.\n- **Fuzzed fee swap.** For buyers from 12 to 2,000 IMD the fee spent stays under the snapshot cap, the unspent PLEA is refunded exactly, and the gate holds nothing after.\n- **Site amount limits at their edges.** Zero, one percent minus a wei, one percent, the 50% or 2.5M cap, and that cap plus a wei. The fact score is taken on the balance before the escrow moved.\n- **Share bands in basis points.** One wei over 20% still scores as 20%. The 18 to 11 and 11 to 5 drops land at 2001 and 3501 bps.\n- **Bad flags from the Letterbox itself.** Flags 0, 1, 4 and 7 are refused on both entry points. An approved hand plea and a denied letter cannot be sold through `executeSellFor`. The `PleaFlags` event and `lastPleaOf` are checked for hand pleas too.\n- **A finished escrow never reopens**, fuzzed over all four endings, including a nonexistent id.\n- **PLEA.setLetterbox lifecycle on a fresh PLEA.** Not before launch, not by a stranger, never zero, once only. `courtTake` is refused before registration and bounded by the wallet's balance.\n- **The auto-sell fee is checkpointed into the running season inside the delivery**, while a hand sale of the same size pays no such fee.\n- **A dead Cabal** still settles escrows, accepts names, and returns the dead-state status and leaderboard text.\n\n**Defects found:** none that can be reproduced. I did not write a findings file. One observation I could not reach with a concrete input: `deliver` subtracts the 0.35 IMD fee from the sale and would revert on underflow if the hourly snapshot fell by more than about 47% between a letter and its delivery, leaving the writer unable to sell until the window lapses. That needs a price crash through gate-approved sales within roughly 27 minutes, which the plea caps and cooldowns make impractical, so it stays a note rather than a finding.\n\nThe file has been formatted with `forge fmt`. Nothing outside `test/` was touched, and no commit was made.","treeHash":"7644591c4e38f2941051a981464233eb6dd18ac0","usage":{"cachedInputTokens":1845163,"inputTokens":516,"model":"claude-fable-5-1","outputTokens":44194,"runtime":"claude","turns":27,"wallClockMs":1690846}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"8c9c4986ca881107","findings":[{"citation":"resolved","description":"Seam: boundary x precision x invariant. `_requireWorthTheFee` (src/Letterbox.sol:349-352) enforces the 0.70 IMD minimum against `latestPrice()` at submission, and the comment at lines 347-348 states the invariant 'so the fee can never eat a sale'. But `_deliver` recomputes `minOut` (line 333) from `_price()` at delivery time, which is a different hourly checkpoint whenever the plea's 20-minute verdict window plus 7-minute sale window crosses an hour boundary and any trade happens in the new hour. If the price fell by more than ~50.7% between the two checkpoints (value*0.985 < 0.35 IMD while minOut = 0.95*value is still met by the pool), `gate.executeSellFor` succeeds, returns `out` < AUTO_SELL_FEE (0.35e18) and the checked subtraction reverts with Panic(0x11). `deliver` and the writer's own `SELL` letter both hit the same line, so the approval cannot be sold at all; after 7 minutes it lapses, the writer is put in the 4-hour lapsed cooldown, and the oracle fee plus the fee PLEA (about 0.275 IMD worth) are lost, while a hand sale through the gate with any minOut would have been possible for a non-escrowed plea. Concrete numbers from the attached test (real PoolManager, no mocks): snapshot P_H values the plea at 0.72 IMD; 110 approved cap-sized gate sales inside hour H move spot below 49% of P_H (each 2.5M PLEA sale moves spot about 1%); the first trade of hour H+1 checkpoints the crashed price; the verdict arrives 16 minutes after the plea; at delivery the escrow is worth 0.3017 IMD, minOut = 0.2866 IMD, the pool pays about 0.297 IMD, and 0.297e18 - 0.35e18 underflows. Reachability needs a >50% move between consecutive hourly checkpoints (a launch-hour crash or a sybil of ~75-110 approved sellers), so the impact is limited to the writer's fees and sale opportunity: low. Fix suggestions that keep every agreed number: cap the fee at the sale (`fee = out < AUTO_SELL_FEE ? out : AUTO_SELL_FEE`) or revert with a named error before the swap when `minOut < AUTO_SELL_FEE`, so the status/settle path stays clean.","line":337,"path":"src/Letterbox.sol","reproduction":"State: Cabal alive, hook seeded, past the launch window. 1) Hour H, minute 44: any trade (e.g. a 1 IMD buy) writes the hour-H checkpoint P_H. 2) Minute 45: victim calls Letterbox.plead(amount, text) with amount = 0.72e18 * 2^96 / P_H (worth 0.72 IMD at P_H, above the 0.70 minimum; _requireWorthTheFee passes, fee swap executes at spot ~ P_H). 3) Still in hour H: 110 distinct wallets that bought 100 IMD each and held 7 days each submitSell(min(balance/2, 2.5M PLEA)), are approved (score 45) and executeSell(0); spot ends below 0.49 * P_H. 4) Hour H+1, minute 1: a 1 IMD buy checkpoints P_{H+1} = crashed spot (< 0.49 P_H); the Intake delivers the victim's verdict score 45 (16 min after submission, inside PENDING_EXPIRY). 5) Anyone calls Letterbox.deliver(id) (or the victim sends a 'SELL' letter) inside the 7-minute window. Expected: the sale completes (the brief: 'anyone sells an approved escrowed plea with deliver for at least 95% of its snapshot value') or a named refusal. Actual: executeSellFor returns about 0.297e18 IMD >= minOut (0.2866e18) and `out = 0.297e18 - 0.35e18` reverts with Panic(0x11); both deliver and SELL fail; after 7 minutes settle returns the escrow and the victim's next plea reverts Cooldown (Lapsed). Run: forge test --match-path test/scratch/ProofDeliverUnderflow.t.sol (fails on this tree with 'deliver underflows on the auto-sell fee').","severity":"low","snippet":"        out = gate.executeSellFor(id, minOut) - AUTO_SELL_FEE;","title":"Letterbox.deliver underflows on the auto-sell fee when the delivery-hour snapshot values the escrow below 0.35/0.95 IMD, so an approved letter plea can neither be delivered nor SELL-ed and lapses with"},{"citation":"resolved","description":"Seam: boundary x invariant. A letter plea passes when 20% of the balance is worth >= 0.70 IMD at the snapshot (balance >= 3.5 IMD) and the plea fee cap maxFeePlea = 0.25*1.1/price + 1 (0.275 IMD worth on Sepolia, where the 0.5 oracle fee is minted) is <= 10% of the balance (balance >= 2.75 IMD). An appeal by letter buys 0.25 tip + 0.35 wall share = 0.60 IMD, capped at +10% = 0.66 IMD worth, so the same 10% rule (line 293) needs a balance >= 6.6 IMD; on the mainnet path (oracle fee bought too) a letter needs >= 8.25 IMD and an appeal >= 12.1 IMD. Every writer in the gap [3.5, 6.6) IMD (or [8.25, 12.1) on mainnet) therefore gets a DENIED status that says 'send APPEAL <text> before HH:MM UTC' (src/Letterbox.sol:496-503) and then has both Letterbox appeal paths revert FeeTooHigh, while the gate's own appeal(originalId, amount, text) for the identical amount succeeds when the IMD is paid directly. The brief lists the 0.70 IMD minimum as the up-front refusal; the 10% fee-share bound is not among the agreed numbers and is what blocks the agreed 'APPEAL letter' flow for small holders. Measured in the fixture: a wallet that bought 5 IMD holds PLEA worth 4.81 IMD at the snapshot; the letter plea succeeds (need 28), the appeal's maxFeePlea is worth 0.646 IMD = 13.4% of the balance, and 'APPEAL ...' reverts FeeTooHigh(maxFeePlea, bal). Suggested fix without changing fees or shares: evaluate the 10% bound on the plea fee only, or raise the appeal path's bound so an appeal is allowed whenever its original letter was (e.g. compare against the greater of 10% of balance and the original plea's amount), or make status() not invite an APPEAL letter the Letterbox will refuse.","line":293,"path":"src/Letterbox.sol","reproduction":"State: Cabal alive, past the launch window, Sepolia mode (mintOracleFee = true). 1) Wallet w buys 5 IMD of PLEA through the pool; after one day its balance is worth about 4.81 IMD at hook.latestPrice() (3.5 <= value < 6.6). 2) w sends the letter 'A fifth for a bike; the rest stays with me all season.' -> accepted (plea id, 20% escrowed, fee ~0.275 IMD sold). 3) The oracle answers score 0 -> Denied; letterbox.status(w) contains 'send APPEAL <text> before'. 4) w sends 'APPEAL The bike is how I get to work; I keep the rest.' Expected: an appeal of the denied plea for its original amount (brief: 'commands APPEAL ...'). Actual: revert FeeTooHigh(maxFeePlea, bal) with maxFeePlea*10000 > bal*1000 (feesFor(true) = 0.60 IMD -> 0.66 IMD worth of PLEA, 13.4% of the balance). appealAuto(id, text) reverts the same way. 5) After letterbox.settle(id), w calls gate.appeal(id, originalAmount, text) with IMD approved -> succeeds. Observed in a scratch test on this tree (balance value 4813232496468702827, appeal fee value 645860146759339169, revert selector 0xe757126a).","severity":"low","snippet":"        if (maxFeePlea * BPS > bal * MAX_FEE_SHARE_BPS) revert FeeTooHigh(maxFeePlea, bal);","title":"A writer whose PLEA is worth 3.5-6.6 IMD (8.25-12.1 IMD on mainnet) can plead by letter and is told to 'send APPEAL <text>', but the APPEAL letter and appealAuto are refused by the 10% fee-share check"}],"hash":"6878a7066cb91ce67e7b5311d293fb2ea1ce91be15171f9b3c923bee657a9143","nodeId":"966c171b-c59a-401a-8a94-2af26962f74d","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written at the repository root. Nothing else in the tree changed (git reports a clean status; the findings file and `test/scratch/` are ignored paths).\n\n**What I found (math, boundary and numerical-gap area)**\n\n1. **Low: `Letterbox.deliver` underflows on the auto-sell fee** (`src/Letterbox.sol:337`). The 0.70 IMD minimum is checked against the submission-hour snapshot, but `minOut` is recomputed from the delivery-hour snapshot. When the price falls more than about 50.7% between two consecutive hourly checkpoints, the gate sale succeeds for less than 0.35 IMD and `out - AUTO_SELL_FEE` reverts with Panic(0x11). Both `deliver` and the writer's own `SELL` letter fail, the approval lapses into the 4-hour cooldown, and the oracle fee plus fee PLEA are lost. Reproduced against the real PoolManager with no mocks: 110 approved cap-sized sales inside one hour (each moves spot about 1%), a 16-minute verdict, and a delivery snapshot worth 0.30 IMD. The attached proof file `test/scratch/ProofDeliverUnderflow.t.sol` fails on this tree and is fix-agnostic (it only asserts no arithmetic panic).\n\n2. **Low: small holders are invited to APPEAL by letter but refused** (`src/Letterbox.sol:293`). A letter plea needs a balance worth 3.5 IMD, while the appeal's 0.66 IMD fee cap must fit the 10% fee-share rule, which needs 6.6 IMD (8.25 and 12.1 IMD on the mainnet path). A wallet worth 4.81 IMD pleads successfully, gets a DENIED status saying \"send APPEAL <text> before\", and then both the APPEAL letter and `appealAuto` revert `FeeTooHigh`, while the gate's IMD-paid appeal for the same amount succeeds. Reproduction steps and measured numbers are in the file; no proof attached since the right fix is a design choice.\n\n**Coverage**\n\n- All 47 listed entry points have a row, plus 6 invariant rows: 42 hold, 5 carry a finding, none unreached.\n- Traced in depth: letter and site fee arithmetic, escrow packing, the exact-output fee swap through the hook, gate amount bounds and the 20/35 share bands, Seasons' 3% bonus and share sums, the 87/3/10 mint, the gas-pass price views, the unchecked text reads, and the timing boundaries.\n- Static-analysis leads (ring modulo, uninitialized mappings, tick alignment, strict equalities, `encodePacked` in `deployHook`) were each checked and rejected as non-findings, noted in the coverage record.\n- Not reached: a fresh pass over the hook's cap, wall and guard arithmetic beyond what launch #1311 accepted, the fork tests, and the attestation digest.\n\nThe full non-fork test suite passes on this tree.","treeHash":null,"usage":{"cachedInputTokens":2983285,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":67189,"runtime":"claude","turns":32,"wallClockMs":1203528}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"d73af718d55ba788","findings":[{"citation":"resolved","description":"_requireWorthTheFee (lines 349-352) guarantees amount*snapshot >= 0.70 IMD only when the plea is opened. deliver runs up to ~27 minutes later (20-minute verdict + 7-minute window) against the pool's spot price, and the gate only enforces out >= 95% of the snapshot current at delivery. If spot has fallen by more than 50% since the plead-time snapshot, executeSellFor returns out < 0.35e18 and `out - AUTO_SELL_FEE` underflows: deliver (and the writer's SELL letter) revert with panic 0x11 instead of a named error, the approval lapses after 7 minutes, the writer keeps the escrow and the tip via settle but has paid the oracle fee and the fee PLEA and carries a 4-hour lapse cooldown. Funds are never lost or misdirected (settle refunds everything), and reaching the state needs a >50% spot drop in under two hours, which only gate-approved sales (<1% price impact per 2.5M PLEA sale) can cause; so this is a robustness note, not a loss. Control flow is otherwise correct: the escrow is closed before the external call and the whole call reverts atomically.","line":337,"path":"src/Letterbox.sol","reproduction":"State: a plea opened with plead(justEnough, text) where justEnough*latestPrice/2^96 = 0.72e18 (as test_autoSellFeeOnlyOnASaleAndNeverMoreThanHalfOfIt does), approved with score 45. Before deliver, spot falls below 48.6% of the plead-time price (e.g. ~75 approved 2.5M-PLEA gate sales by other wallets inside the same hour, each moving spot by about 1%) and a trade sets the new hourly checkpoint. deliver(id): minOut = 0.95 * amount * newSnapshot ~ 0.33e18 passes the gate's slippage check, the sale returns out ~ 0.34e18, and `out - AUTO_SELL_FEE` reverts with panic 0x11. Expected: a named revert (or a sale that still pays the writer out - fee only when out >= fee) so the lapse is diagnosable; actual: Panic(0x11). Not reproduced on a live pool within this budget: it needs a >50% spot move that only dozens of approved sales can produce.","severity":"info","snippet":"        out = gate.executeSellFor(id, minOut) - AUTO_SELL_FEE;","title":"deliver reverts with an arithmetic panic (not a named error) when the sale yields less than the 0.35 IMD auto-sell fee; the 0.70 IMD minimum is only checked at plead time"}],"hash":"91b13e251562982faf925c5661c3e13a954a649811d777400bfca55bb922d919","nodeId":"50004b79-75a2-4f6a-af97-ab610b5f45e0","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written at the repository root.\n\n**What I did**\n\n- Read the Pashov Execution Trace, Periphery and First Principles guides, then traced every state-changing entry point across all eight source files, with the Letterbox, the gate's new `submitFor`/`appealFor`/`executeSellFor`, PLEA's `courtTake`/`setLetterbox` and the Seasons bonus flow traced call by call, including cross-transaction interleavings (lapsed approvals, expired appeals, retries, strangers' deliveries, the Cabal dying mid-escrow).\n- Built the project and ran the whole non-fork suite. All 370 tests pass. Fork tests could not run in this sandbox (no RPC).\n- Verified independently: the compiled Letterbox creation code hashes to the value in launch.json, none of the 13 Letterbox selectors can start valid UTF-8 text, and the gate's runtime is under the EIP-170 limit.\n- Ran two scratch tests confirming the hand traces of the lapsed-approval cooldown path and cross-writer deliver/settle ordering. Scratch files were removed afterwards.\n\n**Findings**\n\nOne info-level note only. In `src/Letterbox.sol:337`, `deliver` computes the writer's payout as the sale output minus the 0.35 IMD fee, but the 0.70 IMD value floor is only enforced at plead time. If spot falls by more than 50% before delivery, the subtraction panics instead of reverting with a named error. The approval then lapses and `settle` refunds the escrow and tip, so no funds are lost or misdirected. It needs dozens of approved gate sales inside an hour, so I did not reproduce it on a live pool and reported it as informational.\n\nNo medium or higher defect survived verification. The static-analysis leads (weak-prng, strict equality, reentrancy-no-eth, uninitialized state) were checked and are all benign in context: the modulo reads are ring indices, the strict equalities compare counters and statuses, and every external call either happens after state is settled or sits behind `callbackExpected`, `nonReentrant`, or the PoolManager lock.\n\n**Coverage**\n\nThe file holds a row for all 49 listed entry points plus six invariant rows. Every entry point is marked `holds` except `Letterbox.deliver`, marked `finding` with reference 1. The one area not re-derived in depth is the hook's wall-placement arithmetic inside `rebalance`, which is outside the assigned control-flow area and noted in its row.","treeHash":null,"usage":{"cachedInputTokens":2411715,"inputTokens":420,"model":"claude-fable-5-1","outputTokens":62172,"runtime":"claude","turns":31,"wallClockMs":2172794}}],"verification":[{"checks":[{"durationMs":292870,"exitCode":0,"name":"build","output":"Compiling 144 files with Solc 0.8.26\nSolc 0.8.26 finished in 292.72s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to pure\n   --> src/CabalGate.sol:705:5:\n    |\n705 |     function _text(string storage t, bool json) internal view returns (string memory) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":8690,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/ForkMainnet.t.sol:ForkMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 521.17µs (0.00ns CPU time)\n\nRan 1 test for test/fork/ForkTestnet.t.sol:ForkTestnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 1.76ms (0.00ns CPU time)\n\nRan 1 test for test/AuditOwnerTip.t.sol:AuditOwnerTipTest\n[PASS] test_currentPleaOwnerReceivesNoKeeperTipAfterOwnershipTransfer() (gas: 1417662)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 9.38ms (1.91ms CPU time)\n\nRan 4 tests for test/Token.t.sol:TokenTest\n[PASS] test_distributorAndAllowlistMaySend() (gas: 213430)\n[PASS] test_freeForeverOnceTheCabalDies() (gas: 183982)\n[PASS] test_launcherAndInitAreOneShot() (gas: 127033)\n[PASS] test_walletsCannotSendWhileTheCabalWatches() (gas: 331352)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 13.68ms (477.66µs CPU time)\n\nRan 3 tests for test/LaunchManifest.t.sol:RehearsalManifestTest\n[PASS] test_laterBlockCannotRegisterLauncher() (gas: 13191593)\n[PASS] test_separateConstructorCallsInDeploymentBlockStillWork() (gas: 14106618)\n[PASS] test_separateTransactionsLeaveTheAcceptedDeploymentBlockWindow() (gas: 13325956)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 14.97ms (9.79ms CPU time)\n\nRan 2 tests for test/Letterbox.t.sol:OwnerExclusionTest\n[PASS] test_ownerGetsNoKeeperTip() (gas: 1026181)\n[PASS] test_ownerPleasEarnNoPoints() (gas: 4971822)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 17.43ms (1.25ms CPU time)\n\nRan 16 tests for test/SeasonFunds.t.sol:SeasonFundsTest\n[PASS] testFuzz_lateCloseConservesAssets(uint96,uint96,bool) (runs: 32, μ: 1022946, ~: 1057853)\n[PASS] test_bonusIsMintedToSeasonsAndCannotBeWithdrawn() (gas: 24077)\n[PASS] test_bonusPaysTheTopTenAndBurnsTheUnpaidShares() (gas: 1265221)\n[PASS] test_claimRedemptionCallbackCannotBeInvokedOutsideUnlock() (gas: 75304)\n[PASS] test_deathAtBoundaryFlushesClaimsAndLateDonationsOnce() (gas: 1582206)\n[PASS] test_deathBeforeTheSixthSeasonBurnsTheRest() (gas: 909213)\n[PASS] test_deathMidSeasonPreservesEarlierSeasonFees() (gas: 1364260)\n[PASS] test_emptySeasonBurnsItsWholeBonus() (gas: 210295)\n[PASS] test_failedBonusTransferIsBurnedNotStuck() (gas: 584434)\n[PASS] test_failedPayoutRollsForwardWithoutBlockingOtherWinners() (gas: 1301738)\n[PASS] test_feeAtBoundaryBelongsToNextSeason() (gas: 985098)\n[PASS] test_flushBeforeTheEndCannotTouchTheBonus() (gas: 43338)\n[PASS] test_lateClosesOnlyRollUnpaidSharesForward() (gas: 2057331)\n[PASS] test_onlyTheFirstSixSeasonsPayABonus() (gas: 3724762)\n[PASS] test_prizePleaStaysGatedWhileTheCabalWatches() (gas: 650190)\n[PASS] test_unobservedDonationCannotFlowBackwards() (gas: 895294)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 20.78ms (16.85ms CPU time)\n\nRan 2 tests for test/Letterbox.t.sol:LetterboxMainnetPathTest\n[PASS] test_letterBuysTheOracleFeeAndTheTipWithPlea() (gas: 9203765)\n[PASS] test_mintingTheFeeIsRefusedOnMainnet() (gas: 733988)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 22.84ms (10.24ms CPU time)\n\nRan 2 tests for test/LaunchManifest.t.sol:PostLaunchTest\n[PASS] test_committedHookDeploysLaterAndMintsOnlyTheFixedSplit() (gas: 6733836)\n[PASS] test_committedLetterboxDeploysLater() (gas: 9601388)\nLogs:\n  deployLetterbox transaction gas: 4971340\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 28.21ms (15.80ms CPU time)\n\nRan 7 tests for test/AuditImported.t.sol:AuditImportedPaidFeeTest\n[PASS] test_appealLetterRetriesCompletedRequestWithFailedCallback() (gas: 12707477)\n[PASS] test_appealLetterRetriesLazyTimeoutWithoutSeparateSettlement() (gas: 12640841)\n[PASS] test_autoAppealSurvivesBalanceGrowth() (gas: 9278856)\n[PASS] test_growingBalanceDoesNotEnableDustOrLargerAppeals() (gas: 8526735)\n[PASS] test_rawAppealLetterSurvivesBalanceGrowth() (gas: 9304762)\n[PASS] test_shrinkingBalanceStillUsesCurrentMinimumAndMaximum() (gas: 8170872)\n[PASS] test_siteAppealSurvivesBalanceGrowthAtOriginalMinimum() (gas: 8429759)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 28.37ms (16.20ms CPU time)\n\nRan 7 tests for test/AuditImported.t.sol:AuditImportedTest\n[PASS] test_appealLetterRetriesCompletedRequestWithFailedCallback() (gas: 12763462)\n[PASS] test_appealLetterRetriesLazyTimeoutWithoutSeparateSettlement() (gas: 12696826)\n[PASS] test_autoAppealSurvivesBalanceGrowth() (gas: 9315503)\n[PASS] test_growingBalanceDoesNotEnableDustOrLargerAppeals() (gas: 8538035)\n[PASS] test_rawAppealLetterSurvivesBalanceGrowth() (gas: 9341410)\n[PASS] test_shrinkingBalanceStillUsesCurrentMinimumAndMaximum() (gas: 8182172)\n[PASS] test_siteAppealSurvivesBalanceGrowthAtOriginalMinimum() (gas: 8441059)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 33.02ms (20.93ms CPU time)\n\nRan 4 tests for test/OracleConformance.t.sol:OracleConformanceTest\n[PASS] test_callbackSelectorHasTheProtocolStruct() (gas: 748)\n[PASS] test_digestMatchesTheProtocol() (gas: 10527)\n[PASS] test_liveAttestationRecoversToOracleSigner() (gas: 146367)\n[PASS] test_protocolSignatureRecoversToVectorSigner() (gas: 13943)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.12ms (567.18µs CPU time)\n\nRan 29 tests for test/Gate.t.sol:GateTest\n[PASS] test_appealClosesAfterFourHoursAndOnlyOnce() (gas: 11339864)\n[PASS] test_appealWithinFourHoursForNoMore() (gas: 8885227)\n[PASS] test_approvedScoreOpensTheSellWindow() (gas: 5501297)\n[PASS] test_badAttestationsAreNotDelivered() (gas: 4803739)\n[PASS] test_bodyIsTheNumericPanelQuestion() (gas: 4826177)\n[PASS] test_callbackFitsTheStipend() (gas: 7822663)\nLogs:\n  approve callback gas: 58946\n  deny callback gas: 83545\n\n[PASS] test_callbackOnlyFromIntakeAndOnlyForAPendingPlea() (gas: 5338603)\n[PASS] test_cannotPassIsRefusedBeforePaying() (gas: 1179875)\n[PASS] test_cooldownAfterExecutedSell() (gas: 8094862)\n[PASS] test_failedAppealCanBeRetried() (gas: 11276641)\n[PASS] test_failureAfterExpireIsRefused() (gas: 4791305)\n[PASS] test_failureClearsThePendingPleaWithoutCooldownOrClock() (gas: 7668039)\n[PASS] test_failureFitsTheMainnetGas() (gas: 4762239)\n[PASS] test_failureForAnUnknownOrSettledRequestDoesNothing() (gas: 4934748)\n[PASS] test_failureOnlyFromTheIntake() (gas: 4730780)\n[PASS] test_noPleasWhileTheCabalSleeps() (gas: 56280)\n[PASS] test_noVerdictIsClearedAtOnceWhenTheIntakeCompletes() (gas: 7651310)\n[PASS] test_onePendingPleaPerWallet() (gas: 4714677)\n[PASS] test_pendingExpiresAfterTwentyMinutesAndLateCallbacksFail() (gas: 7614759)\n[PASS] test_pleaAsksWithTheFailureFunction() (gas: 4684621)\n[PASS] test_pleaPaysTheIntakeAndNamesTheCallback() (gas: 4730657)\n[PASS] test_prizePleaOnTopOfAWeekOldBuy() (gas: 1463908)\n[PASS] test_refusalClearsThePleaToo() (gas: 4784139)\n[PASS] test_scoreAboveRangeOrWrongTypeIsRefused() (gas: 7754023)\n[PASS] test_scoreBelowNeedDenies() (gas: 4977742)\n[PASS] test_sellWindowLapses() (gas: 7684244)\n[PASS] test_signerWithDelegationCodeStillVerifies() (gas: 4817065)\n[PASS] test_textFilter() (gas: 5167528)\n[PASS] test_wrongSignerIsRefused() (gas: 4781307)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 35.59ms (27.56ms CPU time)\n\nRan 3 tests for test/HookAdversarial.t.sol:LaunchFeeBoundaryTest\n[PASS] testFuzz_launchFeeOnlyFallsWithTime(uint256,uint256) (runs: 256, μ: 23960, ~: 24089)\n[PASS] test_largeLaunchBuyRollsBackAndSucceedsAtWindowEnd() (gas: 729487)\n[PASS] test_launchFeeHasExactStartMidpointAndEndValues() (gas: 42979)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 18.56ms (5.98ms CPU time)\n\nRan 5 tests for test/Launch.t.sol:LaunchTest\n[PASS] test_deployHookChecksTheInitCodeAndFlags() (gas: 42059764)\n[PASS] test_eachStepFitsAMainnetTransaction() (gas: 46053983)\nLogs:\n  launch (5 contracts + intake mock): 1247882\n  deployLetterbox: 4620117\n  deployHook: 5467835\n  seed: 598376\n\n[PASS] test_launchWiresEverythingWithoutCallingOutside() (gas: 1318408)\n[PASS] test_ownerMaySeedEarly() (gas: 41355998)\n[PASS] test_seedByOwnerAnyTimeByAnyoneAfterStart() (gas: 41454781)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 57.75ms (104.33ms CPU time)\n\nRan 6 tests for test/DistributorAdversarial.t.sol:DistributorAdversarialTest\n[PASS] testFuzz_modifiedLeafOrProofCannotRedirectFunds(uint8,uint8,uint256) (runs: 256, μ: 259249, ~: 259205)\n[PASS] test_claimsCrossBitmapWordsAndCannotBeClaimedTwice() (gas: 1724258)\n[PASS] test_failedTokenTransferRollsBackBitmapAndCanBeRetried() (gas: 317100)\n[PASS] test_fullAllocationAndZeroAmountLeavesDoNotCorruptAdjacentBits() (gas: 260412)\n[PASS] test_rootCannotChangeAfterCommitmentEvenBeforeFirstClaim() (gas: 115955)\n[PASS] test_unsetRootAndUnauthorizedRootDoNotConsumeClaims() (gas: 275957)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 62.58ms (61.30ms CPU time)\n\nRan 26 tests for test/Letterbox.t.sol:LetterboxTest\n[PASS] testFuzz_namesAreUniqueIdempotentAndReleasedOnClear(uint256,uint8) (runs: 32, μ: 323159, ~: 323297)\n[PASS] test_aBareCommandWordIsNotAPlea() (gas: 5961566)\n[PASS] test_aLapsedApprovalSettlesAndStillCounts() (gas: 5499783)\n[PASS] test_anyoneDeliversAnApprovalForTheTip() (gas: 6120425)\n[PASS] test_appealByLetterUsesTheOriginalAmountAndPaysTheWall() (gas: 10161472)\n[PASS] test_appealLetterRetriesAnAppealTheOracleNeverAnswered() (gas: 21367538)\n[PASS] test_autoSellFeeOnlyOnASaleAndNeverMoreThanHalfOfIt() (gas: 9741439)\n[PASS] test_deadCabalRefusesLettersButSettles() (gas: 5337473)\n[PASS] test_deliverNeedsAnApprovalInsideTheWindowAndTheMinimum() (gas: 6093719)\n[PASS] test_deployLetterboxRefusesOtherCode() (gas: 5118295)\n[PASS] test_expiredPendingPleaSettlesAfterTwentyMinutes() (gas: 5205437)\n[PASS] test_explorerLetterIsTheSameAsARawLetter() (gas: 13506003)\n[PASS] test_invalidNamesAndFailedRenamesPreserveTheOldReservation() (gas: 1334827)\n[PASS] test_leaderboardListsTheSeason() (gas: 6189908)\n[PASS] test_letterCommandsParse() (gas: 8814928)\n[PASS] test_letterPleadsTenPercentPaysFeesInPleaAndEscrows() (gas: 5288144)\n[PASS] test_letterRefusesEthTinyBalancesAndBadText() (gas: 1386603)\n[PASS] test_letterboxIsDeployedOnceFromTheCommittedCode() (gas: 469868)\n[PASS] test_noFunctionIdCanStartALetter() (gas: 797227)\n[PASS] test_noVerdictSettlesAtOnceAndTheNextLetterSettlesTheOldOne() (gas: 8640436)\n[PASS] test_settleReturnsEscrowAndTipAfterADenial() (gas: 5559999)\n[PASS] test_siteAutoSellPleadsAnyValidAmount() (gas: 10111071)\n[PASS] test_statusTellsEachState() (gas: 10130730)\n[PASS] test_strangersCannotUseTheCourtEntryPoints() (gas: 210803)\n[PASS] test_theGateRefusesAManualSaleOfAnEscrowedPlea() (gas: 5294773)\n[PASS] test_theSellLetterIsTheWritersOwnSale() (gas: 6014567)\nSuite result: ok. 26 passed; 0 failed; 0 skipped; finished in 82.52ms (68.31ms CPU time)\n\nRan 10 tests for test/Seasons.t.sol:SeasonsTest\n[PASS] test_aLateCallbackCannotRevive() (gas: 4793189)\n[PASS] test_aliveFromSeedDeadAfterSilenceForever() (gas: 236405)\n[PASS] test_bestThreeCountAndTopTenOrder() (gas: 23471015)\n[PASS] test_closeSeasonPaysTheTopTen() (gas: 56575402)\n[PASS] test_deathEndsTheLastSeasonAndTheRestGoesToTheWall() (gas: 11790709)\n[PASS] test_mainnetGuardRefusesShortTimings() (gas: 13499)\n[PASS] test_onlyApprovedPleasScore() (gas: 4904925)\n[PASS] test_secondSeasonScoresSeparately() (gas: 44262937)\n[PASS] test_tenthPlaceIsEvictedByABetterWallet() (gas: 39812879)\n[PASS] test_verdictsKeepItAliveAcrossManySeasons() (gas: 111813204)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 89.70ms (75.79ms CPU time)\n\nRan 3 tests for test/OracleReplay.t.sol:OracleReplayTest\n[PASS] testFuzz_oneSignedRequestCannotSettleTwoPleas(bool,bool) (runs: 32, μ: 7932970, ~: 7943535)\n[PASS] test_deniedRequestCannotBeResignedToApproveItsAppeal() (gas: 8285515)\n[PASS] test_invalidCallbackDoesNotConsumeTheRequest() (gas: 7780353)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 57.54ms (53.78ms CPU time)\n\nRan 11 tests for test/Seasons.t.sol:FastClockTest\n[PASS] test_aLateCallbackCannotRevive() (gas: 4792663)\n[PASS] test_aliveFromSeedDeadAfterSilenceForever() (gas: 236427)\n[PASS] test_bestThreeCountAndTopTenOrder() (gas: 1071914)\n[PASS] test_closeSeasonPaysTheTopTen() (gas: 41912548)\n[PASS] test_deathEndsTheLastSeasonAndTheRestGoesToTheWall() (gas: 1126587)\n[PASS] test_fastFullCycle() (gas: 77170582)\n[PASS] test_mainnetGuardRefusesShortTimings() (gas: 13521)\n[PASS] test_onlyApprovedPleasScore() (gas: 4902100)\n[PASS] test_secondSeasonScoresSeparately() (gas: 47200891)\n[PASS] test_tenthPlaceIsEvictedByABetterWallet() (gas: 2260557)\n[PASS] test_verdictsKeepItAliveAcrossManySeasons() (gas: 117702760)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 101.59ms (80.82ms CPU time)\n\nRan 12 tests for test/AuditRun3.t.sol:AuditRun3Test\n[PASS] test_F1_appealLetterCannotRetryAnAppealTheOracleNeverAnswered() (gas: 16393806)\n[PASS] test_F2_aCapSizedAutoSellPleaCannotBeAppealedThroughTheLetterbox() (gas: 33475799)\n[PASS] test_F3_aBareCommandWordBecomesAPaidPlea() (gas: 112508)\n[PASS] test_aLetterboxDeployedByAnyoneElseHasNoPowers() (gas: 5736167)\n[PASS] test_autoSellCannotAcceptASpotPriceUnderTheSnapshotFloor() (gas: 6739375)\n[PASS] test_escrowsAfterTheCabalDies() (gas: 12782203)\n[PASS] test_feeSaleIsBoundedAndTheTipReturns() (gas: 5224020)\n[PASS] test_letterParsingEdgeCases() (gas: 21078575)\n[PASS] test_markerRuleUnchanged() (gas: 6338280)\n[PASS] test_oneCapSizedSaleMovesSpotUnderOnePercent() (gas: 26977745)\nLogs:\n  price impact of a 2.5M PLEA sale, bps: 80\n\n[PASS] test_oracleBodyIsValidJsonForHostileTexts() (gas: 26147138)\n[PASS] test_priceViewsEqualAFullRingScan() (gas: 47480835)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 104.54ms (114.74ms CPU time)\n\nRan 20 tests for test/Orientation.t.sol:HookPleaIsZeroTest\n[PASS] test_aBuyMustAffordTheCredit() (gas: 1246451)\n[PASS] test_aSellAboveTheCapIsTrimmedAndBurned() (gas: 1695109)\n[PASS] test_avgBuyTimeIsBuyWeighted() (gas: 1104668)\n[PASS] test_capDecayIsSetSoTheFloorIsReachableIn25Days() (gas: 18018)\n[PASS] test_capFollowsBuysAtMostOneDayOfDecayPerDay() (gas: 1683977)\n[PASS] test_everyFeeIsPaidInTheSameSwap() (gas: 1293186)\n[PASS] test_factScoreUsesCheckpointsNotSpot() (gas: 1658273)\n[PASS] test_firstBuyWithAnEmptyPoolSendsPayoutsToLiquidity() (gas: 571078)\n[PASS] test_freeTradingWhenTheCabalSleeps() (gas: 1102060)\n[PASS] test_hourlyCheckpointIsNotSetByTheTradeThatOpensTheHour() (gas: 1929006)\n[PASS] test_orientationIsPleaZero() (gas: 15910)\n[PASS] test_plainImdOnlyWhenTheCreditReverts() (gas: 1199509)\n[PASS] test_rebalanceRedeemsClaimsIntoTheWall() (gas: 4561799)\n[PASS] test_sellsAndExactOutputOnlyThroughTheGateWhileAlive() (gas: 746273)\n[PASS] test_stackerIsApprovedOnlyForTheCashbackBeingCredited() (gas: 1817210)\n[PASS] test_wallGuardDropsAtOnceAndRisesFourPercentADay() (gas: 34287316)\n[PASS] test_wallGuardIgnoresASellerChosenLimitReachedThroughAnEmptyPool() (gas: 2792695)\n[PASS] test_wallGuardIgnoresTheEmptyPoolsPriceLimit() (gas: 2767439)\n[PASS] test_wallGuardLagsAPumpAndCapsTheWall() (gas: 16714927)\n[PASS] test_wallGuardStillDropsAtOnceToASellerChosenLimitInsideTheBand() (gas: 33175607)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 118.59ms (100.82ms CPU time)\n\nRan 3 tests for test/LaunchManifest.t.sol:AtomicManifestTest\n[PASS] test_factoryDeploysExactManifestOnAnEmptySepoliaChain() (gas: 49747346)\nLogs:\n  five-contract launch transaction gas through IMD's factory: 12578939\n  gas limit with IMD's headroom: 15346305\n  margin to the 16,777,216 cap: 1430911\n\n[PASS] test_launchJsonCommitsToThisLetterbox() (gas: 30924)\n[PASS] test_launchJsonEncodesOracleMintFlagAsStaticWord() (gas: 10714)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 121.17ms (112.21ms CPU time)\n\nRan 19 tests for test/Hook.t.sol:HookTest\n[PASS] test_aBuyMustAffordTheCredit() (gas: 1246451)\n[PASS] test_aSellAboveTheCapIsTrimmedAndBurned() (gas: 1695087)\n[PASS] test_avgBuyTimeIsBuyWeighted() (gas: 1104668)\n[PASS] test_capDecayIsSetSoTheFloorIsReachableIn25Days() (gas: 18018)\n[PASS] test_capFollowsBuysAtMostOneDayOfDecayPerDay() (gas: 1683977)\n[PASS] test_everyFeeIsPaidInTheSameSwap() (gas: 1293164)\n[PASS] test_factScoreUsesCheckpointsNotSpot() (gas: 1658273)\n[PASS] test_firstBuyWithAnEmptyPoolSendsPayoutsToLiquidity() (gas: 571056)\n[PASS] test_freeTradingWhenTheCabalSleeps() (gas: 1102038)\n[PASS] test_hourlyCheckpointIsNotSetByTheTradeThatOpensTheHour() (gas: 1929006)\n[PASS] test_plainImdOnlyWhenTheCreditReverts() (gas: 1199509)\n[PASS] test_rebalanceRedeemsClaimsIntoTheWall() (gas: 4561799)\n[PASS] test_sellsAndExactOutputOnlyThroughTheGateWhileAlive() (gas: 746273)\n[PASS] test_stackerIsApprovedOnlyForTheCashbackBeingCredited() (gas: 1817188)\n[PASS] test_wallGuardDropsAtOnceAndRisesFourPercentADay() (gas: 34287316)\n[PASS] test_wallGuardIgnoresASellerChosenLimitReachedThroughAnEmptyPool() (gas: 2792695)\n[PASS] test_wallGuardIgnoresTheEmptyPoolsPriceLimit() (gas: 2767396)\n[PASS] test_wallGuardLagsAPumpAndCapsTheWall() (gas: 16714927)\n[PASS] test_wallGuardStillDropsAtOnceToASellerChosenLimitInsideTheBand() (gas: 33175585)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 121.89ms (107.90ms CPU time)\n\nRan 12 tests for test/AuditRevision.t.sol:AuditRevisionPleaZeroTest\n[PASS] testFuzz_cumulativeCapDecayStaysWithinElapsedBudget(uint256) (runs: 32, μ: 4121371, ~: 4124180)\n[PASS] test_appealRetryClearsTimedOutPendingAppeal() (gas: 11953463)\n[PASS] test_deadCabalBuyStillRequiresARecipient() (gas: 1640577)\n[PASS] test_dustBuyDoesNotGiveUntrackedTokensLossOrHoldingPoints() (gas: 1045182)\n[PASS] test_expiredAppealCanBeRetriedWithoutLiftingDenialCooldown() (gas: 12104572)\n[PASS] test_lapsedApprovalCannotBypassCooldown() (gas: 8575235)\n[PASS] test_largeBuyClaimsAreRedeemableAndNextBuyStacksNormally() (gas: 2170500)\n[PASS] test_lateCloseDoesNotPayFutureSeasonFees() (gas: 13461303)\n[PASS] test_sameSecondCapRatchetsCannotReuseFractionalBudget() (gas: 1050970)\n[PASS] test_seasonClaimsArePaidAsImdAtClose() (gas: 10095880)\n[PASS] test_secondLargeBuyPreservesEveryPayee() (gas: 1238646)\n[PASS] test_unansweredAppealDoesNotExtendTheOriginalWindow() (gas: 8790581)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 168.88ms (177.24ms CPU time)\n\nRan 5 tests for test/SeasonRanking.t.sol:SeasonRankingTest\n[PASS] testFuzz_rankingsMatchSortedResultsInAnyRecordOrder(uint256) (runs: 32, μ: 10521582, ~: 10527327)\n[PASS] test_closeSeasonUsesTheSameTiesForPrizes() (gas: 948745)\n[PASS] test_earlierEqualScoreCanReplaceACountedPleaWithoutChangingPoints() (gas: 737794)\n[PASS] test_replacingALowerScoreRemovesItsIdFromTheTieKey() (gas: 738488)\n[PASS] test_walletTieUsesNewestCountedPleaNotLastRecordedPlea() (gas: 775437)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 189.27ms (186.94ms CPU time)\n\nRan 11 tests for test/Orientation.t.sol:SeasonsPleaIsZeroTest\n[PASS] test_aLateCallbackCannotRevive() (gas: 4793211)\n[PASS] test_aliveFromSeedDeadAfterSilenceForever() (gas: 236516)\n[PASS] test_bestThreeCountAndTopTenOrder() (gas: 23471037)\n[PASS] test_closeSeasonPaysTheTopTen() (gas: 56575402)\n[PASS] test_deathEndsTheLastSeasonAndTheRestGoesToTheWall() (gas: 11790709)\n[PASS] test_mainnetGuardRefusesShortTimings() (gas: 13499)\n[PASS] test_onlyApprovedPleasScore() (gas: 4904947)\n[PASS] test_orientationIsPleaZero() (gas: 15724)\n[PASS] test_secondSeasonScoresSeparately() (gas: 44262937)\n[PASS] test_tenthPlaceIsEvictedByABetterWallet() (gas: 39812901)\n[PASS] test_verdictsKeepItAliveAcrossManySeasons() (gas: 111813226)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 195.55ms (53.11ms CPU time)\n\nRan 11 tests for test/HookAdversarial.t.sol:HookAdversarialPleaZeroTest\n[PASS] testFuzz_immediateRoundTripCannotProfitIncludingCashback(uint256) (runs: 256, μ: 1145946, ~: 1141212)\n[PASS] test_exactOutputBuyWorksAfterDeathAndKeepsAllAccountingSettled() (gas: 1195331)\n[PASS] test_firstPartialFillRefundIsBackedByRedeemableQuoteClaims() (gas: 652660)\n[PASS] test_hookCallbacksRejectCallersAndForeignPools() (gas: 135432)\n[PASS] test_keeperTipsRequireWorkAndRespectTheOneHourCooldown() (gas: 1264225)\n[PASS] test_onlyHookMayInitializeOrAddLiquidity() (gas: 64062)\n[PASS] test_partialFillRefundChargesOnlyRealizedImdAndKeepsCostBasisCorrect() (gas: 1307694)\n[PASS] test_realCreditBudgetMustBeAffordableAndExhaustedCreditFallsBack() (gas: 2552780)\n[PASS] test_seedAndUnlockAreOneShotAndOnlyAuthorizedContextsWork() (gas: 138160)\n[PASS] test_wallFundingCannotCreateUnbackedReserveWhenTransferFails() (gas: 290467)\n[PASS] test_zeroBuyRevertsAndOneWeiBuyConservesSupply() (gas: 600637)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 210.37ms (209.84ms CPU time)\n\nRan 11 tests for test/HookAdversarial.t.sol:HookAdversarialTest\n[PASS] testFuzz_immediateRoundTripCannotProfitIncludingCashback(uint256) (runs: 256, μ: 1145574, ~: 1141000)\n[PASS] test_exactOutputBuyWorksAfterDeathAndKeepsAllAccountingSettled() (gas: 1195023)\n[PASS] test_firstPartialFillRefundIsBackedByRedeemableQuoteClaims() (gas: 652932)\n[PASS] test_hookCallbacksRejectCallersAndForeignPools() (gas: 134604)\n[PASS] test_keeperTipsRequireWorkAndRespectTheOneHourCooldown() (gas: 1248537)\n[PASS] test_onlyHookMayInitializeOrAddLiquidity() (gas: 64122)\n[PASS] test_partialFillRefundChargesOnlyRealizedImdAndKeepsCostBasisCorrect() (gas: 1308210)\n[PASS] test_realCreditBudgetMustBeAffordableAndExhaustedCreditFallsBack() (gas: 2553608)\n[PASS] test_seedAndUnlockAreOneShotAndOnlyAuthorizedContextsWork() (gas: 138160)\n[PASS] test_wallFundingCannotCreateUnbackedReserveWhenTransferFails() (gas: 290491)\n[PASS] test_zeroBuyRevertsAndOneWeiBuyConservesSupply() (gas: 601325)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 198.87ms (185.85ms CPU time)\n\nRan 12 tests for test/HookRevision.t.sol:HookRevisionPleaIsZeroTest\n[PASS] testFuzz_aGreedyStackerCannotReachTheWallReserve(uint256,uint256) (runs: 32, μ: 1312600, ~: 1312360)\n[PASS] testFuzz_aLimitAnywhereInTheLiquidityFreeRegionNeverMovesTheGuard(uint256,uint256) (runs: 32, μ: 2429940, ~: 2394128)\n[PASS] testFuzz_aLimitInsideTheLiquidMarketBandMovesTheGuardToTheStopTick(uint256) (runs: 32, μ: 5198301, ~: 5198317)\n[PASS] testFuzz_aSameHourPumpCannotMoveAPleasFactScore(uint256) (runs: 32, μ: 2702400, ~: 2700443)\n[PASS] testFuzz_repeatedDrainsToTheExtremeNeverMoveTheGuard(uint8) (runs: 32, μ: 3750022, ~: 3657315)\n[PASS] testFuzz_successfulCreditsNeverAccumulateAllowance(uint256,uint256,uint256) (runs: 32, μ: 2144809, ~: 2156650)\n[PASS] testFuzz_theGuardClimbsAtMost400TicksADay(uint256,uint256,uint8) (runs: 32, μ: 2793216, ~: 2526806)\n[PASS] testFuzz_theHoursFirstTradeRecordsThePriceItFoundWhateverItsSize(uint256,uint256) (runs: 32, μ: 2239612, ~: 2233013)\n[PASS] test_aCreditThatBurnsAllItsGasLeavesNoAllowance() (gas: 1593249)\n[PASS] test_anHourOpeningSellRecordsThePriceItFound() (gas: 1846764)\n[PASS] test_orientationIsPleaZero() (gas: 15668)\n[PASS] test_wallGuardFollowsASellThatStopsWhereTheMarketHasLiquidity() (gas: 6114150)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 387.43ms (568.50ms CPU time)\n\nRan 18 tests for test/GateAdversarial.t.sol:GateAdversarialTest\n[PASS] testFuzz_panelAndAnswerValidationCannotConsumeRequests(uint8) (runs: 256, μ: 4953896, ~: 4957456)\n[PASS] testFuzz_printablePleaRoundTripsThroughQuestionJson(uint256,uint16) (runs: 256, μ: 5022095, ~: 4925892)\n[PASS] testFuzz_signedQuorumMustBeReached(uint16,bool) (runs: 256, μ: 5043993, ~: 5054816)\n[PASS] test_aWhaleCanStillPleadTheMaximum() (gas: 5226719)\n[PASS] test_amountLimitsFailBeforeChargingAndOnePercentIsTheMinimum() (gas: 4976995)\n[PASS] test_appealIsAcceptedAtItsLastSecondAndCannotBeStolen() (gas: 8193580)\n[PASS] test_appealOracleFeeFailureRollsBackWallFundingAndOriginalFlag() (gas: 8695273)\n[PASS] test_approvedWindowOnlyClearsAfterTheLastSecond() (gas: 7922263)\n[PASS] test_changingSignedAnswerOrConsumerChainInvalidatesSignature() (gas: 4978122)\n[PASS] test_deadManExpiresAtTheExactSecondAndNeverAcceptsANewVerdict() (gas: 4874024)\n[PASS] test_denialCooldownEndsExactlyAtFourHours() (gas: 7699075)\n[PASS] test_futureIssuanceAndExpiredAttestationsRejectAtExactBoundaries() (gas: 7892232)\n[PASS] test_gateUnlockCallbackCannotBeInvokedOutsideItsOwnSale() (gas: 88091)\n[PASS] test_latePendingCannotConsumeSignatureOrExtendHeartbeat() (gas: 4863758)\n[PASS] test_malformedUtf8AndHiddenControlsFailWithoutCharging() (gas: 957696)\n[PASS] test_missingSellAllowanceDoesNotConsumeTheApprovedPlea() (gas: 4978884)\n[PASS] test_pendingAndExecutionDeadlinesAreInclusive() (gas: 5394499)\n[PASS] test_slippageRevertRestoresApprovalSupplyAndAllFeeState() (gas: 6048091)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 396.51ms (935.66ms CPU time)\n\nRan 7 tests for test/SeasonAdversarial.t.sol:SeasonAdversarialTest\n[PASS] testFuzz_failedPrizeDoesNotBlockOthersAndUnpaidShareReachesWall(bool) (runs: 256, μ: 1821264, ~: 1820399)\n[PASS] testFuzz_prizeRoundingConservesAnOddSizedPot(uint256) (runs: 256, μ: 4914977, ~: 4925095)\n[PASS] test_batchIgnoresUnknownDeniedAndRepeatedIdsButCannotReopenASeason() (gas: 1061570)\n[PASS] test_closeBeforeGraceRollsBackItsBatchRecording() (gas: 634452)\n[PASS] test_flushBeforeFinalCloseCannotMoveAnyFunds() (gas: 552908)\n[PASS] test_prizesRequireSixtyPoints() (gas: 1262479)\n[PASS] test_recordRejectsDenialsDuplicatesAndLateApprovals() (gas: 813726)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 525.26ms (734.23ms CPU time)\n\nRan 11 tests for test/BonusInvariant.t.sol:BonusEdgeTest\n[PASS] testFuzz_anyRankingPaysPlusBurnsExactlyTheBonus(uint256) (runs: 512, μ: 3427912, ~: 3226840)\n[PASS] test_bonusPaidAfterDeathIsFreelyTransferable() (gas: 693866)\n[PASS] test_closeWithinTheGraceHourIsRefused() (gas: 656866)\n[PASS] test_closingTwiceCannotPayASeasonsBonusTwice() (gas: 648548)\n[PASS] test_deathBeforeTradingSeasonZeroEndsBurnsEverythingButSeasonZero() (gas: 817130)\n[PASS] test_eleventhWalletIsNotPaidAndCannotDisplaceRankTen() (gas: 4436264)\n[PASS] test_gateAsSellerForfeitsWhileWatchedButIsPaidAfterDeath() (gas: 1187696)\n[PASS] test_lateApprovalListedAtCloseStillEarnsTheBonus() (gas: 616726)\n[PASS] test_onlyTheBestThreePleasCount() (gas: 1540243)\n[PASS] test_sixtyPointsQualifiesFiftyNineDoesNot() (gas: 1286731)\n[PASS] test_tenQualifiersReceiveTheWholeBonusAndNothingBurns() (gas: 4182661)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 525.51ms (533.94ms CPU time)\n\nRan 12 tests for test/AuditRevision.t.sol:AuditRevisionTest\n[PASS] testFuzz_cumulativeCapDecayStaysWithinElapsedBudget(uint256) (runs: 32, μ: 4124199, ~: 4127061)\n[PASS] test_appealRetryClearsTimedOutPendingAppeal() (gas: 11953900)\n[PASS] test_deadCabalBuyStillRequiresARecipient() (gas: 1640429)\n[PASS] test_dustBuyDoesNotGiveUntrackedTokensLossOrHoldingPoints() (gas: 1045870)\n[PASS] test_expiredAppealCanBeRetriedWithoutLiftingDenialCooldown() (gas: 12105009)\n[PASS] test_lapsedApprovalCannotBypassCooldown() (gas: 8575672)\n[PASS] test_largeBuyClaimsAreRedeemableAndNextBuyStacksNormally() (gas: 2170636)\n[PASS] test_lateCloseDoesNotPayFutureSeasonFees() (gas: 13463520)\n[PASS] test_sameSecondCapRatchetsCannotReuseFractionalBudget() (gas: 1051794)\n[PASS] test_seasonClaimsArePaidAsImdAtClose() (gas: 10097045)\n[PASS] test_secondLargeBuyPreservesEveryPayee() (gas: 1239095)\n[PASS] test_unansweredAppealDoesNotExtendTheOriginalWindow() (gas: 8791018)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 538.90ms (202.43ms CPU time)\n\nRan 11 tests for test/HookRevision.t.sol:HookRevisionTest\n[PASS] testFuzz_aGreedyStackerCannotReachTheWallReserve(uint256,uint256) (runs: 64, μ: 1312461, ~: 1312267)\n[PASS] testFuzz_aLimitAnywhereInTheLiquidityFreeRegionNeverMovesTheGuard(uint256,uint256) (runs: 64, μ: 2435059, ~: 2365233)\n[PASS] testFuzz_aLimitInsideTheLiquidMarketBandMovesTheGuardToTheStopTick(uint256) (runs: 64, μ: 5198269, ~: 5198295)\n[PASS] testFuzz_aSameHourPumpCannotMoveAPleasFactScore(uint256) (runs: 64, μ: 2702735, ~: 2700443)\n[PASS] testFuzz_repeatedDrainsToTheExtremeNeverMoveTheGuard(uint8) (runs: 64, μ: 3943580, ~: 3657293)\n[PASS] testFuzz_successfulCreditsNeverAccumulateAllowance(uint256,uint256,uint256) (runs: 64, μ: 2142762, ~: 2130191)\n[PASS] testFuzz_theGuardClimbsAtMost400TicksADay(uint256,uint256,uint8) (runs: 64, μ: 2728738, ~: 2372419)\n[PASS] testFuzz_theHoursFirstTradeRecordsThePriceItFoundWhateverItsSize(uint256,uint256) (runs: 64, μ: 2239891, ~: 2232991)\n[PASS] test_aCreditThatBurnsAllItsGasLeavesNoAllowance() (gas: 1593227)\n[PASS] test_anHourOpeningSellRecordsThePriceItFound() (gas: 1846742)\n[PASS] test_wallGuardFollowsASellThatStopsWhereTheMarketHasLiquidity() (gas: 6114128)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 408.31ms (1.24s CPU time)\n\nRan 5 tests for test/GasPass.t.sol:GasPassTest\n[PASS] testFuzz_bodyEqualsEscapingTheWholeQuestion(uint256) (runs: 500, μ: 5590325, ~: 5609921)\n[PASS] testFuzz_textCheckMatchesTheOldRules(uint256) (runs: 5000, μ: 884055, ~: 83930)\n[PASS] test_bodyEqualsEscapingTheWholeQuestion() (gas: 12832581)\n[PASS] test_priceViewsMatchAFullScan() (gas: 128930691)\n[PASS] test_textCheckEdgeCases() (gas: 53620436)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 539.09ms (953.11ms CPU time)\n\nRan 3 tests for test/GateFailureInvariant.t.sol:GateFailureInvariantTest\n[PASS]\nGateFailureInvariantTest invariants:\n[PASS] invariant_gateHoldsNothing\n[PASS] invariant_onlyVerdictsMoveTheClock\n[PASS] invariant_pendingBookkeepingIsConsistent\n GateFailureInvariantTest invariants (runs: 64, calls: 4096, reverts: 0)\n\n╭--------------------+---------------+-------+---------+----------╮\n| Contract           | Selector      | Calls | Reverts | Discards |\n+=================================================================+\n| GateFailureHandler | advance       | 439   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | answer        | 450   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | appeal        | 454   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | directFailure | 444   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | execute       | 459   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | expire        | 461   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | fail          | 477   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | plead         | 458   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | strangerFails | 454   | 0       | 0        |\n╰--------------------+---------------+-------+---------+----------╯\n\n[PASS] test_failureAfterDeathDoesNotReviveTheCabal() (gas: 4763262)\n[PASS] test_handlerReachesFailuresVerdictsAndAppeals() (gas: 18556039)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.01s (998.65ms CPU time)\n\nRan 30 tests for test/Orientation.t.sol:GatePleaIsZeroTest\n[PASS] test_appealClosesAfterFourHoursAndOnlyOnce() (gas: 11339886)\n[PASS] test_appealWithinFourHoursForNoMore() (gas: 8885249)\n[PASS] test_approvedScoreOpensTheSellWindow() (gas: 5501297)\n[PASS] test_badAttestationsAreNotDelivered() (gas: 4803761)\n[PASS] test_bodyIsTheNumericPanelQuestion() (gas: 4826199)\n[PASS] test_callbackFitsTheStipend() (gas: 7822685)\nLogs:\n  approve callback gas: 58946\n  deny callback gas: 83545\n\n[PASS] test_callbackOnlyFromIntakeAndOnlyForAPendingPlea() (gas: 5338603)\n[PASS] test_cannotPassIsRefusedBeforePaying() (gas: 1179875)\n[PASS] test_cooldownAfterExecutedSell() (gas: 8094884)\n[PASS] test_failedAppealCanBeRetried() (gas: 11276663)\n[PASS] test_failureAfterExpireIsRefused() (gas: 4791327)\n[PASS] test_failureClearsThePendingPleaWithoutCooldownOrClock() (gas: 7668039)\n[PASS] test_failureFitsTheMainnetGas() (gas: 4762261)\n[PASS] test_failureForAnUnknownOrSettledRequestDoesNothing() (gas: 4934748)\n[PASS] test_failureOnlyFromTheIntake() (gas: 4730780)\n[PASS] test_noPleasWhileTheCabalSleeps() (gas: 56280)\n[PASS] test_noVerdictIsClearedAtOnceWhenTheIntakeCompletes() (gas: 7651310)\n[PASS] test_onePendingPleaPerWallet() (gas: 4714677)\n[PASS] test_orientationIsPleaZero() (gas: 15922)\n[PASS] test_pendingExpiresAfterTwentyMinutesAndLateCallbacksFail() (gas: 7614781)\n[PASS] test_pleaAsksWithTheFailureFunction() (gas: 4684643)\n[PASS] test_pleaPaysTheIntakeAndNamesTheCallback() (gas: 4730679)\n[PASS] test_prizePleaOnTopOfAWeekOldBuy() (gas: 1463930)\n[PASS] test_refusalClearsThePleaToo() (gas: 4784139)\n[PASS] test_scoreAboveRangeOrWrongTypeIsRefused() (gas: 7754045)\n[PASS] test_scoreBelowNeedDenies() (gas: 4977742)\n[PASS] test_sellWindowLapses() (gas: 7684244)\n[PASS] test_signerWithDelegationCodeStillVerifies() (gas: 4817087)\n[PASS] test_textFilter() (gas: 5167528)\n[PASS] test_wrongSignerIsRefused() (gas: 4781307)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 1.05s (24.48ms CPU time)\n\nRan 2 tests for test/BonusInvariant.t.sol:BonusInvariantTest\n[PASS]\nBonusInvariantTest invariants:\n[PASS] invariant_bonusIsHeldPaidOrBurned\n[PASS] invariant_flushedSeasonsStayFinished\n[PASS] invariant_openBonusSeasonsStayFunded\n[PASS] invariant_supplyFallsOnlyByTheBurnedBonus\n BonusInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭--------------+----------+-------+---------+----------╮\n| Contract     | Selector | Calls | Reverts | Discards |\n+======================================================+\n| BonusHandler | advance  | 1177  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | approve  | 1176  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | close    | 1100  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | die      | 1130  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | donate   | 1202  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | flush    | 1229  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | pull     | 1178  | 0       | 0        |\n╰--------------+----------+-------+---------+----------╯\n\n[PASS] test_handlerReachesPaidClosesDeathAndFlush() (gas: 2139975)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 1.35s (1.34s CPU time)\n\nRan 1 test for test/DistributorAdversarial.t.sol:DistributionInvariantTest\n[PASS]\nDistributionInvariantTest invariants:\n[PASS] invariant_deathAndSystemWiringArePermanent\n[PASS] invariant_distributorPaysEachCommittedLeafAtMostOnce\n[PASS] invariant_supplyEqualsAllBalancesAndOnlyBurnsReduceIt\n DistributionInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭---------------------+----------------------------+-------+---------+----------╮\n| Contract            | Selector                   | Calls | Reverts | Discards |\n+===============================================================================+\n| DistributionHandler | advance                    | 1010  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | allowSender                | 1008  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | approveAndSpend            | 1027  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | burnTokens                 | 1004  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | claimAllocation            | 1065  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | donate                     | 1008  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | transferTokens             | 1050  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | unauthorizedAdministration | 1020  | 0       | 0        |\n╰---------------------+----------------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.67s (1.67s CPU time)\n\nRan 2 tests for test/LetterboxInvariant.t.sol:LetterboxMainnetInvariantTest\n[PASS]\nLetterboxMainnetInvariantTest invariants:\n[PASS] invariant_escrowsMatchTheirPleas\n[PASS] invariant_everyWritersPleaIsAccountedFor\n[PASS] invariant_holdsExactlyTheOpenEscrowsAndTips\n[PASS] invariant_noStepBrokeAnExpectation\n LetterboxMainnetInvariantTest invariants (runs: 64, calls: 5120, reverts: 0)\n\n╭------------------+----------+-------+---------+----------╮\n| Contract         | Selector | Calls | Reverts | Discards |\n+==========================================================+\n| LetterboxHandler | advance  | 590   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | answer   | 583   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | appeal   | 593   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | deliver  | 546   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | fail     | 567   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | poke     | 538   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | sell     | 552   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | settle   | 579   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | write    | 572   | 0       | 0        |\n╰------------------+----------+-------+---------+----------╯\n\n[PASS] test_handlerReachesEveryPath() (gas: 25988665)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.25s (2.26s CPU time)\n\nRan 2 tests for test/LetterboxInvariant.t.sol:LetterboxInvariantTest\n[PASS]\nLetterboxInvariantTest invariants:\n[PASS] invariant_escrowsMatchTheirPleas\n[PASS] invariant_everyWritersPleaIsAccountedFor\n[PASS] invariant_holdsExactlyTheOpenEscrowsAndTips\n[PASS] invariant_noStepBrokeAnExpectation\n LetterboxInvariantTest invariants (runs: 64, calls: 5120, reverts: 0)\n\n╭------------------+----------+-------+---------+----------╮\n| Contract         | Selector | Calls | Reverts | Discards |\n+==========================================================+\n| LetterboxHandler | advance  | 590   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | answer   | 583   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | appeal   | 593   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | deliver  | 546   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | fail     | 567   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | poke     | 538   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | sell     | 552   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | settle   | 579   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | write    | 572   | 0       | 0        |\n╰------------------+----------+-------+---------+----------╯\n\n[PASS] test_handlerReachesEveryPath() (gas: 26083685)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.32s (2.31s CPU time)\n\nRan 3 tests for test/TradingInvariant.t.sol:TradingPleaZeroInvariantTest\n[PASS]\nTradingPleaZeroInvariantTest invariants:\n[PASS] invariant_allPleaIsAccountedForAndSupplyOnlyFallsByActualBurns\n[PASS] invariant_quoteConservationAndFeePaymentsMatchTheirCounters\n[PASS] invariant_stackerHoldsNoStandingAllowanceOnTheHooksImd\n[PASS] invariant_wallReservesClaimsAndGateStateRemainBacked\n TradingPleaZeroInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| TradingHandler | advance       | 712   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | buy           | 732   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | donateQuote   | 792   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | execute       | 781   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | freeSell      | 779   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | fundWall      | 773   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | pauseCashback | 722   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | rebalance     | 731   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | redeemClaims  | 722   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | submit        | 760   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | verdict       | 688   | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\n[PASS] testFuzz_handlerAccountsForClaimFeesAndTheirRedemption(bool) (runs: 32, μ: 2944350, ~: 2954300)\n[PASS] test_handlerExercisesTradingVerdictsRebalancesAndDeath() (gas: 9192212)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.52s (3.58s CPU time)\n\nRan 3 tests for test/TradingInvariant.t.sol:TradingInvariantTest\n[PASS]\nTradingInvariantTest invariants:\n[PASS] invariant_allPleaIsAccountedForAndSupplyOnlyFallsByActualBurns\n[PASS] invariant_quoteConservationAndFeePaymentsMatchTheirCounters\n[PASS] invariant_stackerHoldsNoStandingAllowanceOnTheHooksImd\n[PASS] invariant_wallReservesClaimsAndGateStateRemainBacked\n TradingInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| TradingHandler | advance       | 712   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | buy           | 732   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | donateQuote   | 792   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | execute       | 781   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | freeSell      | 779   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | fundWall      | 773   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | pauseCashback | 722   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | rebalance     | 731   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | redeemClaims  | 722   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | submit        | 760   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | verdict       | 688   | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\n[PASS] testFuzz_handlerAccountsForClaimFeesAndTheirRedemption(bool) (runs: 32, μ: 2945166, ~: 2955116)\n[PASS] test_handlerExercisesTradingVerdictsRebalancesAndDeath() (gas: 9187402)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.65s (3.69s CPU time)\n\nRan 3 tests for test/SeasonInvariant.t.sol:SeasonInvariantTest\n[PASS]\nSeasonInvariantTest invariants:\n[PASS] invariant_prizeMoneyIsPaidOnceOrRemainsInThePotOrWall\n[PASS] invariant_rankingsMatchAllRecordedApprovalsAndClosedSeasonsNeverChange\n SeasonInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭---------------+-------------------------+-------+---------+----------╮\n| Contract      | Selector                | Calls | Reverts | Discards |\n+======================================================================+\n| SeasonHandler | advance                 | 827   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | approvePlea             | 849   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | checkpoint              | 854   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | closeOldest             | 825   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | donate                  | 803   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | donateClaims            | 791   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | donateWithoutCheckpoint | 800   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | endCabal                | 815   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | flush                   | 793   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | record                  | 835   | 0       | 0        |\n╰---------------+-------------------------+-------+---------+----------╯\n\n[PASS] test_modelCoversDelayedDonationsAndPostFlushClaims() (gas: 3620081)\n[PASS] test_modelCoversPayableClosesRolloverAndFinalFlush() (gas: 4323657)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 8.54s (8.54s CPU time)\n\nRan 45 test suites in 8.56s (30.81s CPU time): 370 tests passed, 0 failed, 2 skipped (372 total tests)\n","passed":true},{"durationMs":108,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"CabalGate.appeal(uint256,uint256,string)\",\"CabalGate.appealFor(address,uint256,uint256,uint256,string,uint8,uint256,uint256)\",\"CabalGate.begin()\",\"CabalGate.executeSell(uint256)\",\"CabalGate.executeSellFor(uint256,uint256)\",\"CabalGate.expire(uint256)\",\"CabalGate.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"CabalGate.onPleaFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"CabalGate.submitFor(address,uint256,uint256,string,uint8,uint256,uint256)\",\"CabalGate.submitSell(uint256,string)\",\"CabalGate.unlockCallback(bytes)\",\"Letterbox.appealAuto(uint256,string)\",\"Letterbox.deliver(uint256)\",\"Letterbox.fallback()\",\"Letterbox.letter(string)\",\"Letterbox.plead(uint256,string)\",\"Letterbox.setName(string)\",\"Letterbox.settle(uint256)\",\"PLEA.allow(address)\",\"PLEA.approve(address,uint256)\",\"PLEA.burn(uint256)\",\"PLEA.courtTake(address,uint256)\",\"PLEA.init(address,address)\",\"PLEA.renounceOwnership()\",\"PLEA.setLauncher(address,address,address)\",\"PLEA.setLetterbox(address)\",\"PLEA.transfer(address,uint256)\",\"PLEA.transferFrom(address,address,uint256)\",\"PLEA.transferOwnership(address)\",\"PleaDistributor.claim(uint256,address,uint256,bytes32[])\",\"PleaDistributor.renounceOwnership()\",\"PleaDistributor.setMerkleRoot(bytes32)\",\"PleaDistributor.transferOwnership(address)\",\"PleaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"PleaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"PleaHook.fundWall(uint256)\",\"PleaHook.rebalance()\",\"PleaHook.seed()\",\"PleaHook.unlockCallback(bytes)\",\"PleaLaunch.deployHook(bytes32,bytes)\",\"PleaLaunch.deployLetterbox(bytes)\",\"PleaLaunch.seed()\",\"Seasons.checkpoint()\",\"Seasons.closeSeason(uint256[])\",\"Seasons.flushToWall()\",\"Seasons.record(uint256)\",\"Seasons.unlockCallback(bytes)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":39,\"README.md\":267,\"foundry.toml\":25,\"launch.json\":56,\"remappings.txt\":4,\"script/Deploy.s.sol\":55,\"script/DeployLetterbox.s.sol\":22,\"script/MineSalt.s.sol\":44,\"src/CabalGate.sol\":816,\"src/Letterbox.sol\":646,\"src/OracleAttestation.sol\":227,\"src/PLEA.sol\":148,\"src/PleaDistributor.sol\":49,\"src/PleaHook.sol\":1018,\"src/PleaLaunch.sol\":152,\"src/Seasons.sol\":357,\"src/interfaces/IPleaParts.sol\":74,\"src/interfaces/IStacker.sol\":10,\"test/AuditImported.t.sol\":142,\"test/AuditOwnerTip.t.sol\":28,\"test/AuditRevision.t.sol\":270,\"test/AuditRun3.t.sol\":391,\"test/BonusInvariant.t.sol\":526,\"test/DistributorAdversarial.t.sol\":329,\"test/GasPass.t.sol\":329,\"test/Gate.t.sol\":408,\"test/GateAdversarial.t.sol\":400,\"test/GateFailureInvariant.t.sol\":330,\"test/Hook.t.sol\":357,\"test/HookAdversarial.t.sol\":272,\"test/HookRevision.t.sol\":378,\"test/Launch.t.sol\":156,\"test/LaunchManifest.t.sol\":317,\"test/Letterbox.t.sol\":754,\"test/LetterboxInvariant.t.sol\":441,\"test/OracleConformance.t.sol\":114,\"test/OracleReplay.t.sol\":60,\"test/Orientation.t.sol\":58,\"test/SeasonAdversarial.t.sol\":203,\"test/SeasonFunds.t.sol\":343,\"test/SeasonInvariant.t.sol\":341,\"test/SeasonRanking.t.sol\":168,\"test/Seasons.t.sol\":266,\"test/Token.t.sol\":78,\"test/TradingInvariant.t.sol\":476,\"test/fork/ForkMainnet.t.sol\":368,\"test/fork/ForkTestnet.t.sol\":765,\"test/utils/ClaimTree.sol\":41,\"test/utils/Fixture.sol\":238,\"test/utils/Mocks.sol\":266,\"test/utils/SeasonModel.sol\":117,\"test/utils/SepoliaFixture.sol\":34},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"24916ac28627bd1995e9618089188c4ff1b5f23851a84fcd5f8df73de4cf1056","verifiedTreeHash":"c60961ba4eb8ea56a37c4aab1ac8f2870e09cb07","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":697356,"exitCode":0,"name":"build","output":"Compiling 144 files with Solc 0.8.26\nSolc 0.8.26 finished in 696.99s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to pure\n   --> src/CabalGate.sol:705:5:\n    |\n705 |     function _text(string storage t, bool json) internal view returns (string memory) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":16951,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/ForkMainnet.t.sol:ForkMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 965.75µs (0.00ns CPU time)\n\nRan 1 test for test/fork/ForkTestnet.t.sol:ForkTestnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 1.02ms (0.00ns CPU time)\n\nRan 4 tests for test/OracleConformance.t.sol:OracleConformanceTest\n[PASS] test_callbackSelectorHasTheProtocolStruct() (gas: 748)\n[PASS] test_digestMatchesTheProtocol() (gas: 10527)\n[PASS] test_liveAttestationRecoversToOracleSigner() (gas: 146367)\n[PASS] test_protocolSignatureRecoversToVectorSigner() (gas: 13943)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 7.52ms (6.16ms CPU time)\n\nRan 2 tests for test/Letterbox.t.sol:OwnerExclusionTest\n[PASS] test_ownerGetsNoKeeperTip() (gas: 1026181)\n[PASS] test_ownerPleasEarnNoPoints() (gas: 4971822)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 20.21ms (2.71ms CPU time)\n\nRan 2 tests for test/Letterbox.t.sol:LetterboxMainnetPathTest\n[PASS] test_letterBuysTheOracleFeeAndTheTipWithPlea() (gas: 9203765)\n[PASS] test_mintingTheFeeIsRefusedOnMainnet() (gas: 733988)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 19.23ms (3.91ms CPU time)\n\nRan 1 test for test/AuditOwnerTip.t.sol:AuditOwnerTipTest\n[PASS] test_currentPleaOwnerReceivesNoKeeperTipAfterOwnershipTransfer() (gas: 1417662)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 19.79ms (1.30ms CPU time)\n\nRan 3 tests for test/LaunchManifest.t.sol:RehearsalManifestTest\n[PASS] test_laterBlockCannotRegisterLauncher() (gas: 13191593)\n[PASS] test_separateConstructorCallsInDeploymentBlockStillWork() (gas: 14106618)\n[PASS] test_separateTransactionsLeaveTheAcceptedDeploymentBlockWindow() (gas: 13325956)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 22.11ms (9.58ms CPU time)\n\nRan 7 tests for test/AuditImported.t.sol:AuditImportedPaidFeeTest\n[PASS] test_appealLetterRetriesCompletedRequestWithFailedCallback() (gas: 12707477)\n[PASS] test_appealLetterRetriesLazyTimeoutWithoutSeparateSettlement() (gas: 12640841)\n[PASS] test_autoAppealSurvivesBalanceGrowth() (gas: 9278856)\n[PASS] test_growingBalanceDoesNotEnableDustOrLargerAppeals() (gas: 8526735)\n[PASS] test_rawAppealLetterSurvivesBalanceGrowth() (gas: 9304762)\n[PASS] test_shrinkingBalanceStillUsesCurrentMinimumAndMaximum() (gas: 8170872)\n[PASS] test_siteAppealSurvivesBalanceGrowthAtOriginalMinimum() (gas: 8429759)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 34.89ms (24.50ms CPU time)\n\nRan 2 tests for test/LaunchManifest.t.sol:PostLaunchTest\n[PASS] test_committedHookDeploysLaterAndMintsOnlyTheFixedSplit() (gas: 6733836)\n[PASS] test_committedLetterboxDeploysLater() (gas: 9601388)\nLogs:\n  deployLetterbox transaction gas: 4971340\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 35.18ms (17.58ms CPU time)\n\nRan 3 tests for test/HookAdversarial.t.sol:LaunchFeeBoundaryTest\n[PASS] testFuzz_launchFeeOnlyFallsWithTime(uint256,uint256) (runs: 256, μ: 23978, ~: 24108)\n[PASS] test_largeLaunchBuyRollsBackAndSucceedsAtWindowEnd() (gas: 729487)\n[PASS] test_launchFeeHasExactStartMidpointAndEndValues() (gas: 42979)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 47.02ms (12.87ms CPU time)\n\nRan 29 tests for test/Gate.t.sol:GateTest\n[PASS] test_appealClosesAfterFourHoursAndOnlyOnce() (gas: 11339864)\n[PASS] test_appealWithinFourHoursForNoMore() (gas: 8885227)\n[PASS] test_approvedScoreOpensTheSellWindow() (gas: 5501297)\n[PASS] test_badAttestationsAreNotDelivered() (gas: 4803739)\n[PASS] test_bodyIsTheNumericPanelQuestion() (gas: 4826177)\n[PASS] test_callbackFitsTheStipend() (gas: 7822663)\nLogs:\n  approve callback gas: 58946\n  deny callback gas: 83545\n\n[PASS] test_callbackOnlyFromIntakeAndOnlyForAPendingPlea() (gas: 5338603)\n[PASS] test_cannotPassIsRefusedBeforePaying() (gas: 1179875)\n[PASS] test_cooldownAfterExecutedSell() (gas: 8094862)\n[PASS] test_failedAppealCanBeRetried() (gas: 11276641)\n[PASS] test_failureAfterExpireIsRefused() (gas: 4791305)\n[PASS] test_failureClearsThePendingPleaWithoutCooldownOrClock() (gas: 7668039)\n[PASS] test_failureFitsTheMainnetGas() (gas: 4762239)\n[PASS] test_failureForAnUnknownOrSettledRequestDoesNothing() (gas: 4934748)\n[PASS] test_failureOnlyFromTheIntake() (gas: 4730780)\n[PASS] test_noPleasWhileTheCabalSleeps() (gas: 56280)\n[PASS] test_noVerdictIsClearedAtOnceWhenTheIntakeCompletes() (gas: 7651310)\n[PASS] test_onePendingPleaPerWallet() (gas: 4714677)\n[PASS] test_pendingExpiresAfterTwentyMinutesAndLateCallbacksFail() (gas: 7614759)\n[PASS] test_pleaAsksWithTheFailureFunction() (gas: 4684621)\n[PASS] test_pleaPaysTheIntakeAndNamesTheCallback() (gas: 4730657)\n[PASS] test_prizePleaOnTopOfAWeekOldBuy() (gas: 1463908)\n[PASS] test_refusalClearsThePleaToo() (gas: 4784139)\n[PASS] test_scoreAboveRangeOrWrongTypeIsRefused() (gas: 7754023)\n[PASS] test_scoreBelowNeedDenies() (gas: 4977742)\n[PASS] test_sellWindowLapses() (gas: 7684244)\n[PASS] test_signerWithDelegationCodeStillVerifies() (gas: 4817065)\n[PASS] test_textFilter() (gas: 5167528)\n[PASS] test_wrongSignerIsRefused() (gas: 4781307)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 49.88ms (44.95ms CPU time)\n\nRan 30 tests for test/Orientation.t.sol:GatePleaIsZeroTest\n[PASS] test_appealClosesAfterFourHoursAndOnlyOnce() (gas: 11339886)\n[PASS] test_appealWithinFourHoursForNoMore() (gas: 8885249)\n[PASS] test_approvedScoreOpensTheSellWindow() (gas: 5501297)\n[PASS] test_badAttestationsAreNotDelivered() (gas: 4803761)\n[PASS] test_bodyIsTheNumericPanelQuestion() (gas: 4826199)\n[PASS] test_callbackFitsTheStipend() (gas: 7822685)\nLogs:\n  approve callback gas: 58946\n  deny callback gas: 83545\n\n[PASS] test_callbackOnlyFromIntakeAndOnlyForAPendingPlea() (gas: 5338603)\n[PASS] test_cannotPassIsRefusedBeforePaying() (gas: 1179875)\n[PASS] test_cooldownAfterExecutedSell() (gas: 8094884)\n[PASS] test_failedAppealCanBeRetried() (gas: 11276663)\n[PASS] test_failureAfterExpireIsRefused() (gas: 4791327)\n[PASS] test_failureClearsThePendingPleaWithoutCooldownOrClock() (gas: 7668039)\n[PASS] test_failureFitsTheMainnetGas() (gas: 4762261)\n[PASS] test_failureForAnUnknownOrSettledRequestDoesNothing() (gas: 4934748)\n[PASS] test_failureOnlyFromTheIntake() (gas: 4730780)\n[PASS] test_noPleasWhileTheCabalSleeps() (gas: 56280)\n[PASS] test_noVerdictIsClearedAtOnceWhenTheIntakeCompletes() (gas: 7651310)\n[PASS] test_onePendingPleaPerWallet() (gas: 4714677)\n[PASS] test_orientationIsPleaZero() (gas: 15922)\n[PASS] test_pendingExpiresAfterTwentyMinutesAndLateCallbacksFail() (gas: 7614781)\n[PASS] test_pleaAsksWithTheFailureFunction() (gas: 4684643)\n[PASS] test_pleaPaysTheIntakeAndNamesTheCallback() (gas: 4730679)\n[PASS] test_prizePleaOnTopOfAWeekOldBuy() (gas: 1463930)\n[PASS] test_refusalClearsThePleaToo() (gas: 4784139)\n[PASS] test_scoreAboveRangeOrWrongTypeIsRefused() (gas: 7754045)\n[PASS] test_scoreBelowNeedDenies() (gas: 4977742)\n[PASS] test_sellWindowLapses() (gas: 7684244)\n[PASS] test_signerWithDelegationCodeStillVerifies() (gas: 4817087)\n[PASS] test_textFilter() (gas: 5167528)\n[PASS] test_wrongSignerIsRefused() (gas: 4781307)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 67.56ms (33.51ms CPU time)\n\nRan 6 tests for test/DistributorAdversarial.t.sol:DistributorAdversarialTest\n[PASS] testFuzz_modifiedLeafOrProofCannotRedirectFunds(uint8,uint8,uint256) (runs: 256, μ: 259238, ~: 259196)\n[PASS] test_claimsCrossBitmapWordsAndCannotBeClaimedTwice() (gas: 1724258)\n[PASS] test_failedTokenTransferRollsBackBitmapAndCanBeRetried() (gas: 317100)\n[PASS] test_fullAllocationAndZeroAmountLeavesDoNotCorruptAdjacentBits() (gas: 260412)\n[PASS] test_rootCannotChangeAfterCommitmentEvenBeforeFirstClaim() (gas: 115955)\n[PASS] test_unsetRootAndUnauthorizedRootDoNotConsumeClaims() (gas: 275957)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 84.89ms (82.40ms CPU time)\n\nRan 3 tests for test/LaunchManifest.t.sol:AtomicManifestTest\n[PASS] test_factoryDeploysExactManifestOnAnEmptySepoliaChain() (gas: 49747346)\nLogs:\n  five-contract launch transaction gas through IMD's factory: 12578939\n  gas limit with IMD's headroom: 15346305\n  margin to the 16,777,216 cap: 1430911\n\n[PASS] test_launchJsonCommitsToThisLetterbox() (gas: 30490)\n[PASS] test_launchJsonEncodesOracleMintFlagAsStaticWord() (gas: 10393)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 109.95ms (95.51ms CPU time)\n\nRan 4 tests for test/Token.t.sol:TokenTest\n[PASS] test_distributorAndAllowlistMaySend() (gas: 213430)\n[PASS] test_freeForeverOnceTheCabalDies() (gas: 183982)\n[PASS] test_launcherAndInitAreOneShot() (gas: 127033)\n[PASS] test_walletsCannotSendWhileTheCabalWatches() (gas: 331352)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 10.23ms (951.47µs CPU time)\n\nRan 26 tests for test/Letterbox.t.sol:LetterboxTest\n[PASS] testFuzz_namesAreUniqueIdempotentAndReleasedOnClear(uint256,uint8) (runs: 32, μ: 320996, ~: 319975)\n[PASS] test_aBareCommandWordIsNotAPlea() (gas: 5961566)\n[PASS] test_aLapsedApprovalSettlesAndStillCounts() (gas: 5499783)\n[PASS] test_anyoneDeliversAnApprovalForTheTip() (gas: 6120425)\n[PASS] test_appealByLetterUsesTheOriginalAmountAndPaysTheWall() (gas: 10161472)\n[PASS] test_appealLetterRetriesAnAppealTheOracleNeverAnswered() (gas: 21367538)\n[PASS] test_autoSellFeeOnlyOnASaleAndNeverMoreThanHalfOfIt() (gas: 9741439)\n[PASS] test_deadCabalRefusesLettersButSettles() (gas: 5337473)\n[PASS] test_deliverNeedsAnApprovalInsideTheWindowAndTheMinimum() (gas: 6093719)\n[PASS] test_deployLetterboxRefusesOtherCode() (gas: 5118295)\n[PASS] test_expiredPendingPleaSettlesAfterTwentyMinutes() (gas: 5205437)\n[PASS] test_explorerLetterIsTheSameAsARawLetter() (gas: 13506003)\n[PASS] test_invalidNamesAndFailedRenamesPreserveTheOldReservation() (gas: 1334827)\n[PASS] test_leaderboardListsTheSeason() (gas: 6189908)\n[PASS] test_letterCommandsParse() (gas: 8814928)\n[PASS] test_letterPleadsTenPercentPaysFeesInPleaAndEscrows() (gas: 5288144)\n[PASS] test_letterRefusesEthTinyBalancesAndBadText() (gas: 1386603)\n[PASS] test_letterboxIsDeployedOnceFromTheCommittedCode() (gas: 469868)\n[PASS] test_noFunctionIdCanStartALetter() (gas: 797227)\n[PASS] test_noVerdictSettlesAtOnceAndTheNextLetterSettlesTheOldOne() (gas: 8640436)\n[PASS] test_settleReturnsEscrowAndTipAfterADenial() (gas: 5559999)\n[PASS] test_siteAutoSellPleadsAnyValidAmount() (gas: 10111071)\n[PASS] test_statusTellsEachState() (gas: 10130730)\n[PASS] test_strangersCannotUseTheCourtEntryPoints() (gas: 210803)\n[PASS] test_theGateRefusesAManualSaleOfAnEscrowedPlea() (gas: 5294773)\n[PASS] test_theSellLetterIsTheWritersOwnSale() (gas: 6014567)\nSuite result: ok. 26 passed; 0 failed; 0 skipped; finished in 137.11ms (112.45ms CPU time)\n\nRan 3 tests for test/OracleReplay.t.sol:OracleReplayTest\n[PASS] testFuzz_oneSignedRequestCannotSettleTwoPleas(bool,bool) (runs: 32, μ: 7930854, ~: 7920994)\n[PASS] test_deniedRequestCannotBeResignedToApproveItsAppeal() (gas: 8285515)\n[PASS] test_invalidCallbackDoesNotConsumeTheRequest() (gas: 7780353)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 150.94ms (109.36ms CPU time)\n\nRan 7 tests for test/AuditImported.t.sol:AuditImportedTest\n[PASS] test_appealLetterRetriesCompletedRequestWithFailedCallback() (gas: 12763462)\n[PASS] test_appealLetterRetriesLazyTimeoutWithoutSeparateSettlement() (gas: 12696826)\n[PASS] test_autoAppealSurvivesBalanceGrowth() (gas: 9315503)\n[PASS] test_growingBalanceDoesNotEnableDustOrLargerAppeals() (gas: 8538035)\n[PASS] test_rawAppealLetterSurvivesBalanceGrowth() (gas: 9341410)\n[PASS] test_shrinkingBalanceStillUsesCurrentMinimumAndMaximum() (gas: 8182172)\n[PASS] test_siteAppealSurvivesBalanceGrowthAtOriginalMinimum() (gas: 8441059)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 239.16ms (30.41ms CPU time)\n\nRan 20 tests for test/Orientation.t.sol:HookPleaIsZeroTest\n[PASS] test_aBuyMustAffordTheCredit() (gas: 1246451)\n[PASS] test_aSellAboveTheCapIsTrimmedAndBurned() (gas: 1695109)\n[PASS] test_avgBuyTimeIsBuyWeighted() (gas: 1104668)\n[PASS] test_capDecayIsSetSoTheFloorIsReachableIn25Days() (gas: 18018)\n[PASS] test_capFollowsBuysAtMostOneDayOfDecayPerDay() (gas: 1683977)\n[PASS] test_everyFeeIsPaidInTheSameSwap() (gas: 1293186)\n[PASS] test_factScoreUsesCheckpointsNotSpot() (gas: 1658273)\n[PASS] test_firstBuyWithAnEmptyPoolSendsPayoutsToLiquidity() (gas: 571078)\n[PASS] test_freeTradingWhenTheCabalSleeps() (gas: 1102060)\n[PASS] test_hourlyCheckpointIsNotSetByTheTradeThatOpensTheHour() (gas: 1929006)\n[PASS] test_orientationIsPleaZero() (gas: 15910)\n[PASS] test_plainImdOnlyWhenTheCreditReverts() (gas: 1199509)\n[PASS] test_rebalanceRedeemsClaimsIntoTheWall() (gas: 4561799)\n[PASS] test_sellsAndExactOutputOnlyThroughTheGateWhileAlive() (gas: 746273)\n[PASS] test_stackerIsApprovedOnlyForTheCashbackBeingCredited() (gas: 1817210)\n[PASS] test_wallGuardDropsAtOnceAndRisesFourPercentADay() (gas: 34287316)\n[PASS] test_wallGuardIgnoresASellerChosenLimitReachedThroughAnEmptyPool() (gas: 2792695)\n[PASS] test_wallGuardIgnoresTheEmptyPoolsPriceLimit() (gas: 2767439)\n[PASS] test_wallGuardLagsAPumpAndCapsTheWall() (gas: 16714927)\n[PASS] test_wallGuardStillDropsAtOnceToASellerChosenLimitInsideTheBand() (gas: 33175607)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 183.37ms (166.16ms CPU time)\n\nRan 12 tests for test/AuditRevision.t.sol:AuditRevisionPleaZeroTest\n[PASS] testFuzz_cumulativeCapDecayStaysWithinElapsedBudget(uint256) (runs: 32, μ: 4118920, ~: 4122903)\n[PASS] test_appealRetryClearsTimedOutPendingAppeal() (gas: 11953463)\n[PASS] test_deadCabalBuyStillRequiresARecipient() (gas: 1640577)\n[PASS] test_dustBuyDoesNotGiveUntrackedTokensLossOrHoldingPoints() (gas: 1045182)\n[PASS] test_expiredAppealCanBeRetriedWithoutLiftingDenialCooldown() (gas: 12104572)\n[PASS] test_lapsedApprovalCannotBypassCooldown() (gas: 8575235)\n[PASS] test_largeBuyClaimsAreRedeemableAndNextBuyStacksNormally() (gas: 2170500)\n[PASS] test_lateCloseDoesNotPayFutureSeasonFees() (gas: 13461303)\n[PASS] test_sameSecondCapRatchetsCannotReuseFractionalBudget() (gas: 1050970)\n[PASS] test_seasonClaimsArePaidAsImdAtClose() (gas: 10095880)\n[PASS] test_secondLargeBuyPreservesEveryPayee() (gas: 1238646)\n[PASS] test_unansweredAppealDoesNotExtendTheOriginalWindow() (gas: 8790581)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 231.65ms (235.86ms CPU time)\n\nRan 16 tests for test/SeasonFunds.t.sol:SeasonFundsTest\n[PASS] testFuzz_lateCloseConservesAssets(uint96,uint96,bool) (runs: 32, μ: 1021818, ~: 1073254)\n[PASS] test_bonusIsMintedToSeasonsAndCannotBeWithdrawn() (gas: 24077)\n[PASS] test_bonusPaysTheTopTenAndBurnsTheUnpaidShares() (gas: 1265221)\n[PASS] test_claimRedemptionCallbackCannotBeInvokedOutsideUnlock() (gas: 75304)\n[PASS] test_deathAtBoundaryFlushesClaimsAndLateDonationsOnce() (gas: 1582206)\n[PASS] test_deathBeforeTheSixthSeasonBurnsTheRest() (gas: 909213)\n[PASS] test_deathMidSeasonPreservesEarlierSeasonFees() (gas: 1364260)\n[PASS] test_emptySeasonBurnsItsWholeBonus() (gas: 210295)\n[PASS] test_failedBonusTransferIsBurnedNotStuck() (gas: 584434)\n[PASS] test_failedPayoutRollsForwardWithoutBlockingOtherWinners() (gas: 1301738)\n[PASS] test_feeAtBoundaryBelongsToNextSeason() (gas: 985098)\n[PASS] test_flushBeforeTheEndCannotTouchTheBonus() (gas: 43338)\n[PASS] test_lateClosesOnlyRollUnpaidSharesForward() (gas: 2057331)\n[PASS] test_onlyTheFirstSixSeasonsPayABonus() (gas: 3724762)\n[PASS] test_prizePleaStaysGatedWhileTheCabalWatches() (gas: 650190)\n[PASS] test_unobservedDonationCannotFlowBackwards() (gas: 895294)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 43.79ms (41.55ms CPU time)\n\nRan 12 tests for test/AuditRevision.t.sol:AuditRevisionTest\n[PASS] testFuzz_cumulativeCapDecayStaysWithinElapsedBudget(uint256) (runs: 32, μ: 4119726, ~: 4120538)\n[PASS] test_appealRetryClearsTimedOutPendingAppeal() (gas: 11953900)\n[PASS] test_deadCabalBuyStillRequiresARecipient() (gas: 1640429)\n[PASS] test_dustBuyDoesNotGiveUntrackedTokensLossOrHoldingPoints() (gas: 1045870)\n[PASS] test_expiredAppealCanBeRetriedWithoutLiftingDenialCooldown() (gas: 12105009)\n[PASS] test_lapsedApprovalCannotBypassCooldown() (gas: 8575672)\n[PASS] test_largeBuyClaimsAreRedeemableAndNextBuyStacksNormally() (gas: 2170636)\n[PASS] test_lateCloseDoesNotPayFutureSeasonFees() (gas: 13463520)\n[PASS] test_sameSecondCapRatchetsCannotReuseFractionalBudget() (gas: 1051794)\n[PASS] test_seasonClaimsArePaidAsImdAtClose() (gas: 10097045)\n[PASS] test_secondLargeBuyPreservesEveryPayee() (gas: 1239095)\n[PASS] test_unansweredAppealDoesNotExtendTheOriginalWindow() (gas: 8791018)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 285.92ms (278.52ms CPU time)\n\nRan 5 tests for test/Launch.t.sol:LaunchTest\n[PASS] test_deployHookChecksTheInitCodeAndFlags() (gas: 42059764)\n[PASS] test_eachStepFitsAMainnetTransaction() (gas: 46053983)\nLogs:\n  launch (5 contracts + intake mock): 1247882\n  deployLetterbox: 4620117\n  deployHook: 5467835\n  seed: 598376\n\n[PASS] test_launchWiresEverythingWithoutCallingOutside() (gas: 1318408)\n[PASS] test_ownerMaySeedEarly() (gas: 41355998)\n[PASS] test_seedByOwnerAnyTimeByAnyoneAfterStart() (gas: 41454781)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 379.28ms (206.20ms CPU time)\n\nRan 5 tests for test/SeasonRanking.t.sol:SeasonRankingTest\n[PASS] testFuzz_rankingsMatchSortedResultsInAnyRecordOrder(uint256) (runs: 32, μ: 10533487, ~: 10512934)\n[PASS] test_closeSeasonUsesTheSameTiesForPrizes() (gas: 948745)\n[PASS] test_earlierEqualScoreCanReplaceACountedPleaWithoutChangingPoints() (gas: 737794)\n[PASS] test_replacingALowerScoreRemovesItsIdFromTheTieKey() (gas: 738488)\n[PASS] test_walletTieUsesNewestCountedPleaNotLastRecordedPlea() (gas: 775437)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 469.79ms (468.79ms CPU time)\n\nRan 11 tests for test/Seasons.t.sol:FastClockTest\n[PASS] test_aLateCallbackCannotRevive() (gas: 4792663)\n[PASS] test_aliveFromSeedDeadAfterSilenceForever() (gas: 236427)\n[PASS] test_bestThreeCountAndTopTenOrder() (gas: 1071914)\n[PASS] test_closeSeasonPaysTheTopTen() (gas: 41912548)\n[PASS] test_deathEndsTheLastSeasonAndTheRestGoesToTheWall() (gas: 1126587)\n[PASS] test_fastFullCycle() (gas: 77170582)\n[PASS] test_mainnetGuardRefusesShortTimings() (gas: 13521)\n[PASS] test_onlyApprovedPleasScore() (gas: 4902100)\n[PASS] test_secondSeasonScoresSeparately() (gas: 47200891)\n[PASS] test_tenthPlaceIsEvictedByABetterWallet() (gas: 2260557)\n[PASS] test_verdictsKeepItAliveAcrossManySeasons() (gas: 117702760)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 140.05ms (121.78ms CPU time)\n\nRan 10 tests for test/Seasons.t.sol:SeasonsTest\n[PASS] test_aLateCallbackCannotRevive() (gas: 4793189)\n[PASS] test_aliveFromSeedDeadAfterSilenceForever() (gas: 236405)\n[PASS] test_bestThreeCountAndTopTenOrder() (gas: 23471015)\n[PASS] test_closeSeasonPaysTheTopTen() (gas: 56575402)\n[PASS] test_deathEndsTheLastSeasonAndTheRestGoesToTheWall() (gas: 11790709)\n[PASS] test_mainnetGuardRefusesShortTimings() (gas: 13499)\n[PASS] test_onlyApprovedPleasScore() (gas: 4904925)\n[PASS] test_secondSeasonScoresSeparately() (gas: 44262937)\n[PASS] test_tenthPlaceIsEvictedByABetterWallet() (gas: 39812879)\n[PASS] test_verdictsKeepItAliveAcrossManySeasons() (gas: 111813204)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 79.96ms (120.84ms CPU time)\n\nRan 11 tests for test/HookAdversarial.t.sol:HookAdversarialTest\n[PASS] testFuzz_immediateRoundTripCannotProfitIncludingCashback(uint256) (runs: 256, μ: 1145440, ~: 1141000)\n[PASS] test_exactOutputBuyWorksAfterDeathAndKeepsAllAccountingSettled() (gas: 1195023)\n[PASS] test_firstPartialFillRefundIsBackedByRedeemableQuoteClaims() (gas: 652932)\n[PASS] test_hookCallbacksRejectCallersAndForeignPools() (gas: 134604)\n[PASS] test_keeperTipsRequireWorkAndRespectTheOneHourCooldown() (gas: 1248537)\n[PASS] test_onlyHookMayInitializeOrAddLiquidity() (gas: 64122)\n[PASS] test_partialFillRefundChargesOnlyRealizedImdAndKeepsCostBasisCorrect() (gas: 1308210)\n[PASS] test_realCreditBudgetMustBeAffordableAndExhaustedCreditFallsBack() (gas: 2553608)\n[PASS] test_seedAndUnlockAreOneShotAndOnlyAuthorizedContextsWork() (gas: 138160)\n[PASS] test_wallFundingCannotCreateUnbackedReserveWhenTransferFails() (gas: 290491)\n[PASS] test_zeroBuyRevertsAndOneWeiBuyConservesSupply() (gas: 601325)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 612.05ms (580.64ms CPU time)\n\nRan 5 tests for test/GasPass.t.sol:GasPassTest\n[PASS] testFuzz_bodyEqualsEscapingTheWholeQuestion(uint256) (runs: 500, μ: 5574400, ~: 5564718)\n[PASS] testFuzz_textCheckMatchesTheOldRules(uint256) (runs: 5000, μ: 940266, ~: 84153)\n[PASS] test_bodyEqualsEscapingTheWholeQuestion() (gas: 12832581)\n[PASS] test_priceViewsMatchAFullScan() (gas: 128930691)\n[PASS] test_textCheckEdgeCases() (gas: 53620436)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 741.61ms (1.55s CPU time)\n\nRan 7 tests for test/SeasonAdversarial.t.sol:SeasonAdversarialTest\n[PASS] testFuzz_failedPrizeDoesNotBlockOthersAndUnpaidShareReachesWall(bool) (runs: 256, μ: 1821352, ~: 1822276)\n[PASS] testFuzz_prizeRoundingConservesAnOddSizedPot(uint256) (runs: 256, μ: 4901175, ~: 4925089)\n[PASS] test_batchIgnoresUnknownDeniedAndRepeatedIdsButCannotReopenASeason() (gas: 1061570)\n[PASS] test_closeBeforeGraceRollsBackItsBatchRecording() (gas: 634452)\n[PASS] test_flushBeforeFinalCloseCannotMoveAnyFunds() (gas: 552908)\n[PASS] test_prizesRequireSixtyPoints() (gas: 1262479)\n[PASS] test_recordRejectsDenialsDuplicatesAndLateApprovals() (gas: 813726)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 671.39ms (766.06ms CPU time)\n\nRan 19 tests for test/Hook.t.sol:HookTest\n[PASS] test_aBuyMustAffordTheCredit() (gas: 1246451)\n[PASS] test_aSellAboveTheCapIsTrimmedAndBurned() (gas: 1695087)\n[PASS] test_avgBuyTimeIsBuyWeighted() (gas: 1104668)\n[PASS] test_capDecayIsSetSoTheFloorIsReachableIn25Days() (gas: 18018)\n[PASS] test_capFollowsBuysAtMostOneDayOfDecayPerDay() (gas: 1683977)\n[PASS] test_everyFeeIsPaidInTheSameSwap() (gas: 1293164)\n[PASS] test_factScoreUsesCheckpointsNotSpot() (gas: 1658273)\n[PASS] test_firstBuyWithAnEmptyPoolSendsPayoutsToLiquidity() (gas: 571056)\n[PASS] test_freeTradingWhenTheCabalSleeps() (gas: 1102038)\n[PASS] test_hourlyCheckpointIsNotSetByTheTradeThatOpensTheHour() (gas: 1929006)\n[PASS] test_plainImdOnlyWhenTheCreditReverts() (gas: 1199509)\n[PASS] test_rebalanceRedeemsClaimsIntoTheWall() (gas: 4561799)\n[PASS] test_sellsAndExactOutputOnlyThroughTheGateWhileAlive() (gas: 746273)\n[PASS] test_stackerIsApprovedOnlyForTheCashbackBeingCredited() (gas: 1817188)\n[PASS] test_wallGuardDropsAtOnceAndRisesFourPercentADay() (gas: 34287316)\n[PASS] test_wallGuardIgnoresASellerChosenLimitReachedThroughAnEmptyPool() (gas: 2792695)\n[PASS] test_wallGuardIgnoresTheEmptyPoolsPriceLimit() (gas: 2767396)\n[PASS] test_wallGuardLagsAPumpAndCapsTheWall() (gas: 16714927)\n[PASS] test_wallGuardStillDropsAtOnceToASellerChosenLimitInsideTheBand() (gas: 33175585)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 764.31ms (196.55ms CPU time)\n\nRan 12 tests for test/HookRevision.t.sol:HookRevisionPleaIsZeroTest\n[PASS] testFuzz_aGreedyStackerCannotReachTheWallReserve(uint256,uint256) (runs: 32, μ: 1312623, ~: 1312740)\n[PASS] testFuzz_aLimitAnywhereInTheLiquidityFreeRegionNeverMovesTheGuard(uint256,uint256) (runs: 32, μ: 2493704, ~: 2562695)\n[PASS] testFuzz_aLimitInsideTheLiquidMarketBandMovesTheGuardToTheStopTick(uint256) (runs: 32, μ: 5198243, ~: 5198288)\n[PASS] testFuzz_aSameHourPumpCannotMoveAPleasFactScore(uint256) (runs: 32, μ: 2704256, ~: 2706226)\n[PASS] testFuzz_repeatedDrainsToTheExtremeNeverMoveTheGuard(uint8) (runs: 32, μ: 4050412, ~: 3657315)\n[PASS] testFuzz_successfulCreditsNeverAccumulateAllowance(uint256,uint256,uint256) (runs: 32, μ: 2141805, ~: 2133680)\n[PASS] testFuzz_theGuardClimbsAtMost400TicksADay(uint256,uint256,uint8) (runs: 32, μ: 2625070, ~: 2347825)\n[PASS] testFuzz_theHoursFirstTradeRecordsThePriceItFoundWhateverItsSize(uint256,uint256) (runs: 32, μ: 2241143, ~: 2233885)\n[PASS] test_aCreditThatBurnsAllItsGasLeavesNoAllowance() (gas: 1593249)\n[PASS] test_anHourOpeningSellRecordsThePriceItFound() (gas: 1846764)\n[PASS] test_orientationIsPleaZero() (gas: 15668)\n[PASS] test_wallGuardFollowsASellThatStopsWhereTheMarketHasLiquidity() (gas: 6114150)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 764.45ms (1.19s CPU time)\n\nRan 11 tests for test/HookAdversarial.t.sol:HookAdversarialPleaZeroTest\n[PASS] testFuzz_immediateRoundTripCannotProfitIncludingCashback(uint256) (runs: 256, μ: 1145561, ~: 1141204)\n[PASS] test_exactOutputBuyWorksAfterDeathAndKeepsAllAccountingSettled() (gas: 1195331)\n[PASS] test_firstPartialFillRefundIsBackedByRedeemableQuoteClaims() (gas: 652660)\n[PASS] test_hookCallbacksRejectCallersAndForeignPools() (gas: 135432)\n[PASS] test_keeperTipsRequireWorkAndRespectTheOneHourCooldown() (gas: 1264225)\n[PASS] test_onlyHookMayInitializeOrAddLiquidity() (gas: 64062)\n[PASS] test_partialFillRefundChargesOnlyRealizedImdAndKeepsCostBasisCorrect() (gas: 1307694)\n[PASS] test_realCreditBudgetMustBeAffordableAndExhaustedCreditFallsBack() (gas: 2552780)\n[PASS] test_seedAndUnlockAreOneShotAndOnlyAuthorizedContextsWork() (gas: 138160)\n[PASS] test_wallFundingCannotCreateUnbackedReserveWhenTransferFails() (gas: 290467)\n[PASS] test_zeroBuyRevertsAndOneWeiBuyConservesSupply() (gas: 600637)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 764.53ms (756.44ms CPU time)\n\nRan 18 tests for test/GateAdversarial.t.sol:GateAdversarialTest\n[PASS] testFuzz_panelAndAnswerValidationCannotConsumeRequests(uint8) (runs: 256, μ: 4955591, ~: 4957491)\n[PASS] testFuzz_printablePleaRoundTripsThroughQuestionJson(uint256,uint16) (runs: 256, μ: 5019733, ~: 4941016)\n[PASS] testFuzz_signedQuorumMustBeReached(uint16,bool) (runs: 256, μ: 5043813, ~: 5054810)\n[PASS] test_aWhaleCanStillPleadTheMaximum() (gas: 5226719)\n[PASS] test_amountLimitsFailBeforeChargingAndOnePercentIsTheMinimum() (gas: 4976995)\n[PASS] test_appealIsAcceptedAtItsLastSecondAndCannotBeStolen() (gas: 8193580)\n[PASS] test_appealOracleFeeFailureRollsBackWallFundingAndOriginalFlag() (gas: 8695273)\n[PASS] test_approvedWindowOnlyClearsAfterTheLastSecond() (gas: 7922263)\n[PASS] test_changingSignedAnswerOrConsumerChainInvalidatesSignature() (gas: 4978122)\n[PASS] test_deadManExpiresAtTheExactSecondAndNeverAcceptsANewVerdict() (gas: 4874024)\n[PASS] test_denialCooldownEndsExactlyAtFourHours() (gas: 7699075)\n[PASS] test_futureIssuanceAndExpiredAttestationsRejectAtExactBoundaries() (gas: 7892232)\n[PASS] test_gateUnlockCallbackCannotBeInvokedOutsideItsOwnSale() (gas: 88091)\n[PASS] test_latePendingCannotConsumeSignatureOrExtendHeartbeat() (gas: 4863758)\n[PASS] test_malformedUtf8AndHiddenControlsFailWithoutCharging() (gas: 957696)\n[PASS] test_missingSellAllowanceDoesNotConsumeTheApprovedPlea() (gas: 4978884)\n[PASS] test_pendingAndExecutionDeadlinesAreInclusive() (gas: 5394499)\n[PASS] test_slippageRevertRestoresApprovalSupplyAndAllFeeState() (gas: 6048091)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 765.80ms (1.22s CPU time)\n\nRan 11 tests for test/BonusInvariant.t.sol:BonusEdgeTest\n[PASS] testFuzz_anyRankingPaysPlusBurnsExactlyTheBonus(uint256) (runs: 512, μ: 3253603, ~: 3112502)\n[PASS] test_bonusPaidAfterDeathIsFreelyTransferable() (gas: 693866)\n[PASS] test_closeWithinTheGraceHourIsRefused() (gas: 656866)\n[PASS] test_closingTwiceCannotPayASeasonsBonusTwice() (gas: 648548)\n[PASS] test_deathBeforeTradingSeasonZeroEndsBurnsEverythingButSeasonZero() (gas: 817130)\n[PASS] test_eleventhWalletIsNotPaidAndCannotDisplaceRankTen() (gas: 4436264)\n[PASS] test_gateAsSellerForfeitsWhileWatchedButIsPaidAfterDeath() (gas: 1187696)\n[PASS] test_lateApprovalListedAtCloseStillEarnsTheBonus() (gas: 616726)\n[PASS] test_onlyTheBestThreePleasCount() (gas: 1540243)\n[PASS] test_sixtyPointsQualifiesFiftyNineDoesNot() (gas: 1286731)\n[PASS] test_tenQualifiersReceiveTheWholeBonusAndNothingBurns() (gas: 4182661)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 819.13ms (817.82ms CPU time)\n\nRan 11 tests for test/HookRevision.t.sol:HookRevisionTest\n[PASS] testFuzz_aGreedyStackerCannotReachTheWallReserve(uint256,uint256) (runs: 64, μ: 1312515, ~: 1312468)\n[PASS] testFuzz_aLimitAnywhereInTheLiquidityFreeRegionNeverMovesTheGuard(uint256,uint256) (runs: 64, μ: 2470548, ~: 2439072)\n[PASS] testFuzz_aLimitInsideTheLiquidMarketBandMovesTheGuardToTheStopTick(uint256) (runs: 64, μ: 5198188, ~: 5198231)\n[PASS] testFuzz_aSameHourPumpCannotMoveAPleasFactScore(uint256) (runs: 64, μ: 2703530, ~: 2706214)\n[PASS] testFuzz_repeatedDrainsToTheExtremeNeverMoveTheGuard(uint8) (runs: 64, μ: 3944816, ~: 3657293)\n[PASS] testFuzz_successfulCreditsNeverAccumulateAllowance(uint256,uint256,uint256) (runs: 64, μ: 2142737, ~: 2130242)\n[PASS] testFuzz_theGuardClimbsAtMost400TicksADay(uint256,uint256,uint8) (runs: 64, μ: 2765387, ~: 2525676)\n[PASS] testFuzz_theHoursFirstTradeRecordsThePriceItFoundWhateverItsSize(uint256,uint256) (runs: 64, μ: 2240967, ~: 2233616)\n[PASS] test_aCreditThatBurnsAllItsGasLeavesNoAllowance() (gas: 1593227)\n[PASS] test_anHourOpeningSellRecordsThePriceItFound() (gas: 1846742)\n[PASS] test_wallGuardFollowsASellThatStopsWhereTheMarketHasLiquidity() (gas: 6114128)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 819.11ms (2.24s CPU time)\n\nRan 3 tests for test/GateFailureInvariant.t.sol:GateFailureInvariantTest\n[PASS]\nGateFailureInvariantTest invariants:\n[PASS] invariant_gateHoldsNothing\n[PASS] invariant_onlyVerdictsMoveTheClock\n[PASS] invariant_pendingBookkeepingIsConsistent\n GateFailureInvariantTest invariants (runs: 64, calls: 4096, reverts: 0)\n\n╭--------------------+---------------+-------+---------+----------╮\n| Contract           | Selector      | Calls | Reverts | Discards |\n+=================================================================+\n| GateFailureHandler | advance       | 485   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | answer        | 437   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | appeal        | 501   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | directFailure | 452   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | execute       | 453   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | expire        | 453   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | fail          | 433   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | plead         | 448   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | strangerFails | 434   | 0       | 0        |\n╰--------------------+---------------+-------+---------+----------╯\n\n[PASS] test_failureAfterDeathDoesNotReviveTheCabal() (gas: 4763262)\n[PASS] test_handlerReachesFailuresVerdictsAndAppeals() (gas: 18556039)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.88s (1.87s CPU time)\n\nRan 2 tests for test/BonusInvariant.t.sol:BonusInvariantTest\n[PASS]\nBonusInvariantTest invariants:\n[PASS] invariant_bonusIsHeldPaidOrBurned\n[PASS] invariant_flushedSeasonsStayFinished\n[PASS] invariant_openBonusSeasonsStayFunded\n[PASS] invariant_supplyFallsOnlyByTheBurnedBonus\n BonusInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭--------------+----------+-------+---------+----------╮\n| Contract     | Selector | Calls | Reverts | Discards |\n+======================================================+\n| BonusHandler | advance  | 1168  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | approve  | 1161  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | close    | 1183  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | die      | 1192  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | donate   | 1200  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | flush    | 1138  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | pull     | 1150  | 0       | 0        |\n╰--------------+----------+-------+---------+----------╯\n\n[PASS] test_handlerReachesPaidClosesDeathAndFlush() (gas: 2139975)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.57s (2.56s CPU time)\n\nRan 1 test for test/DistributorAdversarial.t.sol:DistributionInvariantTest\n[PASS]\nDistributionInvariantTest invariants:\n[PASS] invariant_deathAndSystemWiringArePermanent\n[PASS] invariant_distributorPaysEachCommittedLeafAtMostOnce\n[PASS] invariant_supplyEqualsAllBalancesAndOnlyBurnsReduceIt\n DistributionInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭---------------------+----------------------------+-------+---------+----------╮\n| Contract            | Selector                   | Calls | Reverts | Discards |\n+===============================================================================+\n| DistributionHandler | advance                    | 1046  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | allowSender                | 1067  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | approveAndSpend            | 1093  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | burnTokens                 | 973   | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | claimAllocation            | 999   | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | donate                     | 997   | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | transferTokens             | 1016  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | unauthorizedAdministration | 1001  | 0       | 0        |\n╰---------------------+----------------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.23s (3.21s CPU time)\n\nRan 2 tests for test/LetterboxInvariant.t.sol:LetterboxInvariantTest\n[PASS]\nLetterboxInvariantTest invariants:\n[PASS] invariant_escrowsMatchTheirPleas\n[PASS] invariant_everyWritersPleaIsAccountedFor\n[PASS] invariant_holdsExactlyTheOpenEscrowsAndTips\n[PASS] invariant_noStepBrokeAnExpectation\n LetterboxInvariantTest invariants (runs: 64, calls: 5120, reverts: 0)\n\n╭------------------+----------+-------+---------+----------╮\n| Contract         | Selector | Calls | Reverts | Discards |\n+==========================================================+\n| LetterboxHandler | advance  | 581   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | answer   | 569   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | appeal   | 596   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | deliver  | 576   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | fail     | 576   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | poke     | 555   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | sell     | 556   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | settle   | 532   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | write    | 579   | 0       | 0        |\n╰------------------+----------+-------+---------+----------╯\n\n[PASS] test_handlerReachesEveryPath() (gas: 26083685)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 4.18s (4.17s CPU time)\n\nRan 2 tests for test/LetterboxInvariant.t.sol:LetterboxMainnetInvariantTest\n[PASS]\nLetterboxMainnetInvariantTest invariants:\n[PASS] invariant_escrowsMatchTheirPleas\n[PASS] invariant_everyWritersPleaIsAccountedFor\n[PASS] invariant_holdsExactlyTheOpenEscrowsAndTips\n[PASS] invariant_noStepBrokeAnExpectation\n LetterboxMainnetInvariantTest invariants (runs: 64, calls: 5120, reverts: 0)\n\n╭------------------+----------+-------+---------+----------╮\n| Contract         | Selector | Calls | Reverts | Discards |\n+==========================================================+\n| LetterboxHandler | advance  | 581   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | answer   | 569   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | appeal   | 596   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | deliver  | 576   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | fail     | 576   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | poke     | 555   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | sell     | 556   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | settle   | 532   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | write    | 579   | 0       | 0        |\n╰------------------+----------+-------+---------+----------╯\n\n[PASS] test_handlerReachesEveryPath() (gas: 25988665)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 4.39s (4.39s CPU time)\n\nRan 3 tests for test/TradingInvariant.t.sol:TradingPleaZeroInvariantTest\n[PASS]\nTradingPleaZeroInvariantTest invariants:\n[PASS] invariant_allPleaIsAccountedForAndSupplyOnlyFallsByActualBurns\n[PASS] invariant_quoteConservationAndFeePaymentsMatchTheirCounters\n[PASS] invariant_stackerHoldsNoStandingAllowanceOnTheHooksImd\n[PASS] invariant_wallReservesClaimsAndGateStateRemainBacked\n TradingPleaZeroInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| TradingHandler | advance       | 762   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | buy           | 739   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | donateQuote   | 669   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | execute       | 798   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | freeSell      | 752   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | fundWall      | 739   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | pauseCashback | 741   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | rebalance     | 739   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | redeemClaims  | 729   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | submit        | 758   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | verdict       | 766   | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\n[PASS] testFuzz_handlerAccountsForClaimFeesAndTheirRedemption(bool) (runs: 32, μ: 2934401, ~: 2927768)\n[PASS] test_handlerExercisesTradingVerdictsRebalancesAndDeath() (gas: 9192212)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 6.98s (7.11s CPU time)\n\nRan 3 tests for test/TradingInvariant.t.sol:TradingInvariantTest\n[PASS]\nTradingInvariantTest invariants:\n[PASS] invariant_allPleaIsAccountedForAndSupplyOnlyFallsByActualBurns\n[PASS] invariant_quoteConservationAndFeePaymentsMatchTheirCounters\n[PASS] invariant_stackerHoldsNoStandingAllowanceOnTheHooksImd\n[PASS] invariant_wallReservesClaimsAndGateStateRemainBacked\n TradingInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| TradingHandler | advance       | 762   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | buy           | 739   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | donateQuote   | 669   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | execute       | 798   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | freeSell      | 752   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | fundWall      | 739   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | pauseCashback | 741   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | rebalance     | 739   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | redeemClaims  | 729   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | submit        | 758   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | verdict       | 766   | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\n[PASS] testFuzz_handlerAccountsForClaimFeesAndTheirRedemption(bool) (runs: 32, μ: 2935217, ~: 2928584)\n[PASS] test_handlerExercisesTradingVerdictsRebalancesAndDeath() (gas: 9187402)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 7.29s (7.38s CPU time)\n\nRan 3 tests for test/SeasonInvariant.t.sol:SeasonInvariantTest\n[PASS]\nSeasonInvariantTest invariants:\n[PASS] invariant_prizeMoneyIsPaidOnceOrRemainsInThePotOrWall\n[PASS] invariant_rankingsMatchAllRecordedApprovalsAndClosedSeasonsNeverChange\n SeasonInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭---------------+-------------------------+-------+---------+----------╮\n| Contract      | Selector                | Calls | Reverts | Discards |\n+======================================================================+\n| SeasonHandler | advance                 | 822   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | approvePlea             | 843   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | checkpoint              | 854   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | closeOldest             | 782   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | donate                  | 806   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | donateClaims            | 794   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | donateWithoutCheckpoint | 816   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | endCabal                | 831   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | flush                   | 820   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | record                  | 824   | 0       | 0        |\n╰---------------+-------------------------+-------+---------+----------╯\n\n[PASS] test_modelCoversDelayedDonationsAndPostFlushClaims() (gas: 3620081)\n[PASS] test_modelCoversPayableClosesRolloverAndFinalFlush() (gas: 4323657)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 16.35s (16.34s CPU time)\n\nRan 11 tests for test/Orientation.t.sol:SeasonsPleaIsZeroTest\n[PASS] test_aLateCallbackCannotRevive() (gas: 4793211)\n[PASS] test_aliveFromSeedDeadAfterSilenceForever() (gas: 236516)\n[PASS] test_bestThreeCountAndTopTenOrder() (gas: 23471037)\n[PASS] test_closeSeasonPaysTheTopTen() (gas: 56575402)\n[PASS] test_deathEndsTheLastSeasonAndTheRestGoesToTheWall() (gas: 11790709)\n[PASS] test_mainnetGuardRefusesShortTimings() (gas: 13499)\n[PASS] test_onlyApprovedPleasScore() (gas: 4904947)\n[PASS] test_orientationIsPleaZero() (gas: 15724)\n[PASS] test_secondSeasonScoresSeparately() (gas: 44262937)\n[PASS] test_tenthPlaceIsEvictedByABetterWallet() (gas: 39812901)\n[PASS] test_verdictsKeepItAliveAcrossManySeasons() (gas: 111813226)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 16.47s (124.57ms CPU time)\n\nRan 12 tests for test/AuditRun3.t.sol:AuditRun3Test\n[PASS] test_F1_appealLetterCannotRetryAnAppealTheOracleNeverAnswered() (gas: 16393806)\n[PASS] test_F2_aCapSizedAutoSellPleaCannotBeAppealedThroughTheLetterbox() (gas: 33475799)\n[PASS] test_F3_aBareCommandWordBecomesAPaidPlea() (gas: 112508)\n[PASS] test_aLetterboxDeployedByAnyoneElseHasNoPowers() (gas: 5736167)\n[PASS] test_autoSellCannotAcceptASpotPriceUnderTheSnapshotFloor() (gas: 6739375)\n[PASS] test_escrowsAfterTheCabalDies() (gas: 12782203)\n[PASS] test_feeSaleIsBoundedAndTheTipReturns() (gas: 5224020)\n[PASS] test_letterParsingEdgeCases() (gas: 21078575)\n[PASS] test_markerRuleUnchanged() (gas: 6338280)\n[PASS] test_oneCapSizedSaleMovesSpotUnderOnePercent() (gas: 26977745)\nLogs:\n  price impact of a 2.5M PLEA sale, bps: 80\n\n[PASS] test_oracleBodyIsValidJsonForHostileTexts() (gas: 26147138)\n[PASS] test_priceViewsEqualAFullRingScan() (gas: 47480835)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 16.64s (211.88ms CPU time)\n\nRan 45 test suites in 16.66s (89.57s CPU time): 370 tests passed, 0 failed, 2 skipped (372 total tests)\n","passed":true},{"durationMs":333,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"CabalGate.appeal(uint256,uint256,string)\",\"CabalGate.appealFor(address,uint256,uint256,uint256,string,uint8,uint256,uint256)\",\"CabalGate.begin()\",\"CabalGate.executeSell(uint256)\",\"CabalGate.executeSellFor(uint256,uint256)\",\"CabalGate.expire(uint256)\",\"CabalGate.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"CabalGate.onPleaFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"CabalGate.submitFor(address,uint256,uint256,string,uint8,uint256,uint256)\",\"CabalGate.submitSell(uint256,string)\",\"CabalGate.unlockCallback(bytes)\",\"Letterbox.appealAuto(uint256,string)\",\"Letterbox.deliver(uint256)\",\"Letterbox.fallback()\",\"Letterbox.letter(string)\",\"Letterbox.plead(uint256,string)\",\"Letterbox.setName(string)\",\"Letterbox.settle(uint256)\",\"PLEA.allow(address)\",\"PLEA.approve(address,uint256)\",\"PLEA.burn(uint256)\",\"PLEA.courtTake(address,uint256)\",\"PLEA.init(address,address)\",\"PLEA.renounceOwnership()\",\"PLEA.setLauncher(address,address,address)\",\"PLEA.setLetterbox(address)\",\"PLEA.transfer(address,uint256)\",\"PLEA.transferFrom(address,address,uint256)\",\"PLEA.transferOwnership(address)\",\"PleaDistributor.claim(uint256,address,uint256,bytes32[])\",\"PleaDistributor.renounceOwnership()\",\"PleaDistributor.setMerkleRoot(bytes32)\",\"PleaDistributor.transferOwnership(address)\",\"PleaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"PleaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"PleaHook.fundWall(uint256)\",\"PleaHook.rebalance()\",\"PleaHook.seed()\",\"PleaHook.unlockCallback(bytes)\",\"PleaLaunch.deployHook(bytes32,bytes)\",\"PleaLaunch.deployLetterbox(bytes)\",\"PleaLaunch.seed()\",\"Seasons.checkpoint()\",\"Seasons.closeSeason(uint256[])\",\"Seasons.flushToWall()\",\"Seasons.record(uint256)\",\"Seasons.unlockCallback(bytes)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":39,\"README.md\":267,\"foundry.toml\":25,\"launch.json\":56,\"remappings.txt\":4,\"script/Deploy.s.sol\":55,\"script/DeployLetterbox.s.sol\":22,\"script/MineSalt.s.sol\":44,\"src/CabalGate.sol\":816,\"src/Letterbox.sol\":646,\"src/OracleAttestation.sol\":227,\"src/PLEA.sol\":148,\"src/PleaDistributor.sol\":49,\"src/PleaHook.sol\":1018,\"src/PleaLaunch.sol\":152,\"src/Seasons.sol\":357,\"src/interfaces/IPleaParts.sol\":74,\"src/interfaces/IStacker.sol\":10,\"test/AuditImported.t.sol\":142,\"test/AuditOwnerTip.t.sol\":28,\"test/AuditRevision.t.sol\":270,\"test/AuditRun3.t.sol\":391,\"test/BonusInvariant.t.sol\":526,\"test/DistributorAdversarial.t.sol\":329,\"test/GasPass.t.sol\":329,\"test/Gate.t.sol\":408,\"test/GateAdversarial.t.sol\":400,\"test/GateFailureInvariant.t.sol\":330,\"test/Hook.t.sol\":357,\"test/HookAdversarial.t.sol\":272,\"test/HookRevision.t.sol\":378,\"test/Launch.t.sol\":156,\"test/LaunchManifest.t.sol\":317,\"test/Letterbox.t.sol\":754,\"test/LetterboxInvariant.t.sol\":441,\"test/OracleConformance.t.sol\":114,\"test/OracleReplay.t.sol\":60,\"test/Orientation.t.sol\":58,\"test/SeasonAdversarial.t.sol\":203,\"test/SeasonFunds.t.sol\":343,\"test/SeasonInvariant.t.sol\":341,\"test/SeasonRanking.t.sol\":168,\"test/Seasons.t.sol\":266,\"test/Token.t.sol\":78,\"test/TradingInvariant.t.sol\":476,\"test/fork/ForkMainnet.t.sol\":368,\"test/fork/ForkTestnet.t.sol\":765,\"test/utils/ClaimTree.sol\":41,\"test/utils/Fixture.sol\":238,\"test/utils/Mocks.sol\":266,\"test/utils/SeasonModel.sol\":117,\"test/utils/SepoliaFixture.sol\":34},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":35167,"exitCode":0,"name":"slither","output":"[high/medium] weak-prng at src/PleaHook.sol:956: PleaHook._checkpoint(uint160) (src/PleaHook.sol#956-966) uses a weak PRNG: \"c = ring[hour % 25] (src/PleaHook.sol#958)\"\n[high/medium] weak-prng at src/PleaHook.sol:929: PleaHook._updateWallGuard(int24) (src/PleaHook.sol#929-954) uses a weak PRNG: \"guardRemainder = numerator % 86400 (src/PleaHook.sol#941)\"\n[high/medium] weak-prng at src/PleaHook.sol:283: PleaHook.price24hAgo() (src/PleaHook.sol#283-296) uses a weak PRNG: \"t = ring[target % 25] (src/PleaHook.sol#286)\"\n[high/medium] weak-prng at src/PleaHook.sol:267: PleaHook.latestPrice() (src/PleaHook.sol#267-280) uses a weak PRNG: \"best = ring[lastCheckpointHour % 25].priceX96 (src/PleaHook.sol#270)\"\n[high/high] uninitialized-state at src/Seasons.sol:90: Seasons._best (src/Seasons.sol#63) is never initialized. It is used in:\n[high/high] uninitialized-state at src/Seasons.sol:164: Seasons._bestPleaIds (src/Seasons.sol#64) is never initialized. It is used in:\n[high/high] uninitialized-state at src/Seasons.sol:86: Seasons._top (src/Seasons.sol#62) is never initialized. It is used in:\n[medium/medium] divide-before-multiply at src/PleaHook.sol:994: PleaHook._alignDown(int24) (src/PleaHook.sol#994-998) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/PleaHook.sol:988: PleaHook._alignUp(int24) (src/PleaHook.sol#988-992) performs a multiplication on the result of a division:\n[medium/high] incorrect-equality at src/PleaHook.sol:745: PleaHook.rebalance() (src/PleaHook.sol#745-752) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PleaHook.sol:894: PleaHook._settleImd(uint256) (src/PleaHook.sol#894-899) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/CabalGate.sol:207: CabalGate.restricted() (src/CabalGate.sol#207-209) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/Letterbox.sol:377: Letterbox._settleOpen(address) (src/Letterbox.sol#377-382) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/Letterbox.sol:384: Letterbox._settleable(uint256) (src/Letterbox.sol#384-391) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PleaHook.sol:682: PleaHook._applyCap() (src/PleaHook.sol#682-724) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PleaHook.sol:329: PleaHook._pleaIn(PleaHook.Band,uint160) (src/PleaHook.sol#329-341) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/Letterbox.sol:384: Letterbox._settleable(uint256) (src/Letterbox.sol#384-391) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/Seasons.sol:256: Seasons.flushToWall() (src/Seasons.sol#256-274) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PleaHook.sol:682: PleaHook._applyCap() (src/PleaHook.sol#682-724) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/Letterbox.sol:322: Letterbox._close(uint256,Letterbox.Escrow) (src/Letterbox.sol#322-326) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/Letterbox.sol:354: Letterbox._settle(uint256) (src/Letterbox.sol#354-374) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/CabalGate.sol:212: CabalGate.diedAt() (src/CabalGate.sol#212-215) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/Letterbox.sol:354: Letterbox._settle(uint256) (src/Letterbox.sol#354-374) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PleaHook.sol:757: PleaHook._rebalance() (src/PleaHook.sol#757-818) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PleaHook.sol:757: PleaHook._rebalance() (src/PleaHook.sol#757-818) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PleaHook.sol:299: PleaHook.launchExtraBps() (src/PleaHook.sol#299-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PleaHook.sol:820: PleaHook._closeWall() (src/PleaHook.sol#820-837) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/Seasons.sol:126: Seasons.checkpoint() (src/Seasons.sol#126-137) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/CabalGate.sol:251: CabalGate._factScore(address,uint256,uint256) (src/CabalGate.sol#251-282) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/Seasons.sol:353: Seasons._pay(address,uint256) (src/Seasons.sol#353-356) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/Letterbox.sol:354: Letterbox._settle(uint256) (src/Letterbox.sol#354-374) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/PleaHook.sol:283: PleaHook.price24hAgo() (src/PleaHook.sol#283-296) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/Letterbox.sol:263: Reentrancy in Letterbox._plead(address,uint256,string,uint8) (src/Letterbox.sol#263-279):\n[medium/medium] reentrancy-no-eth at src/PleaHook.sol:682: Reentrancy in PleaHook._applyCap() (src/PleaHook.sol#682-724):\n[medium/medium] reentrancy-no-eth at src/Letterbox.sol:281: Reentrancy in Letterbox._appeal(address,uint256,string,uint8) (src/Letterbox.sol#281-299):\n[medium/medium] reentrancy-no-eth at src/PleaHook.sol:846: Reentrancy in PleaHook._payTip(address,uint256) (src/PleaHook.sol#846-855):\n[medium/medium] reentrancy-no-eth at src/Letterbox.sol:354: Reentrancy in Letterbox._settle(uint256) (src/Letterbox.sol#354-374):\n[medium/medium] reentrancy-no-eth at src/CabalGate.sol:330: Reentrancy in CabalGate.appealFor(address,uint256,uint256,uint256,string,uint8,uint256,uint256) (src/CabalGate.sol#330-345):\n[medium/medium] reentrancy-no-eth at src/PleaHook.sol:475: Reentrancy in PleaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/PleaHook.sol#475-546):\n[medium/medium] reentrancy-no-eth at src/PleaHook.sol:475: Reentrancy in PleaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/PleaHook.sol#475-546):\n[medium/medium] reentrancy-no-eth at src/PleaHook.sol:745: Reentrancy in PleaHook.rebalance() (src/PleaHook.sol#745-752):\n[medium/medium] reentrancy-no-eth at src/PleaHook.sol:820: Reentrancy in PleaHook._closeWall() (src/PleaHook.sol#820-837):\n[medium/medium] reentrancy-no-eth at src/CabalGate.sol:415: Reentrancy in CabalGate._ask(uint256) (src/CabalGate.sol#415-430):\n[medium/medium] reentrancy-no-eth at src/PleaHook.sol:757: Reentrancy in PleaHook._rebalance() (src/PleaHook.sol#757-818):\n[medium/medium] reentrancy-no-eth at src/PleaHook.sol:657: Reentrancy in PleaHook._payCashback(address,uint256) (src/PleaHook.sol#657-674):\n[medium/medium] reentrancy-no-eth at src/CabalGate.sol:301: Reentrancy in CabalGate.submitFor(address,uint256,uint256,string,uint8,uint256,uint256) (src/CabalGate.sol#301-318):\n[medium/medium] reentrancy-no-eth at src/Seasons.sol:221: Reentrancy in Seasons.closeSeason(uint256[]) (src/Seasons.sol#221-252):\n[medium/medium] reentrancy-no-eth at src/Seasons.sol:256: Reentrancy in Seasons.flushToWall() (src/Seasons.sol#256-274):\n[medium/medium] uninitialized-local at src/Seasons.sol:332: Seasons._payBonus(uint256,Seasons.Entry[10]).paid (src/Seasons.sol#332) is a local variable never initialized\n[medium/medium] uninitialized-local at src/Seasons.sol:168: Seasons._record(uint256,uint256,address,uint8).mi (src/Seasons.sol#168) is a local variable never initialized\n[medium/medium] uninitialized-local at src/PleaHook.sol:288: PleaHook.price24hAgo().bestHour (src/PleaHook.sol#288) is a local variable never initialized\n[medium/medium] uninitialized-local at src/PleaHook.sol:564: PleaHook._payFees(address,bool,uint256,uint256,uint256).toPrize (src/PleaHook.sol#564) is a local variable never initialized\n[medium/medium] uninitialized-local at src/CabalGate.sol:758: CabalGate._validateText(string).len (src/CabalGate.sol#758) is a local variable never initialized\n[medium/medium] uninitialized-local at src/Seasons.sol:236: Seasons.closeSeason(uint256[]).paid (src/Seasons.sol#236) is a local variable never initialized\n[medium/medium] uninitialized-local at src/Seasons.sol:173: Seasons._record(uint256,uint256,address,uint8).pts (src/Seasons.sol#173) is a local variable never initialized\n[medium/medium] uninitialized-local at src/PleaHook.sol:272: PleaHook.latestPrice().bestHour (src/PleaHook.sol#272) is a local variable never initialized\n[medium/medium] unused-return at src/Seasons.sol:278: Seasons._redeemClaims() (src/Seasons.sol#278-285) ignores return value by pm.unlock(abi.encode(amount)) (src/Seasons.sol#284)\n[medium/medium] unused-return at src/PleaHook.sol:245: PleaHook.currentSqrtPriceX96() (src/PleaHook.sol#245-247) ignores return value by (sqrtPriceX96,None,None,None) = poolManager.getSlot0(poolId()) (src/PleaHook.sol#246)\n[medium/medium] unused-return at src/CabalGate.sol:460: CabalGate._stale(CabalGate.Plea) (src/CabalGate.sol#460-464) ignores return value by (None,None,None,completed) = intake.requests(p.intakeId) (src/CabalGate.sol#462)\n[medium/medium] unused-return at src/PleaHook.sol:726: PleaHook._removeLiquidity(int24,int24,uint256) (src/PleaHook.sol#726-738) ignores return value by (d,None) = poolManager.modifyLiquidity(poolKey(),ModifyLiquidityParams({tickLower:lower,tickUpper:upper,liquidityDelta:- int256(liquidity),salt:0}),) (src/PleaHook.sol#730-734)\n[medium/medium] unused-return at src/PleaHook.sol:864: PleaHook.unlockCallback(bytes) (src/PleaHook.sol#864-892) ignores return value by poolManager.settle() (src/PleaHook.sol#884)\n[medium/medium] unused-return at src/PleaHook.sol:894: PleaHook._settleImd(uint256) (src/PleaHook.sol#894-899) ignores return value by poolManager.settle() (src/PleaHook.sol#898)\n[medium/medium] unused-return at src/PleaHook.sol:249: PleaHook.currentTick() (src/PleaHook.sol#249-251) ignores return value by (None,tick,None,None) = poolManager.getSlot0(poolId()) (src/PleaHook.sol#250)\n[medium/medium] unused-return at src/OracleAttestation.sol:158: OracleAttestationConsumer._verifyAttestation(OracleAttestation.Attestation,bytes) (src/OracleAttestation.sol#158-171) ignores return value by (recovered,err,None) = ECDSA.tryRecover(digest,signature) (src/OracleAttestation.sol#166)\n[medium/medium] unused-return at src/PleaHook.sol:757: PleaHook._rebalance() (src/PleaHook.sol#757-818) ignores return value by (d,None) = poolManager.modifyLiquidity(poolKey(),ModifyLiquidityParams({tickLower:lower,tickUpper:upper,liquidityDelta:int256(uint256(liquidity)),salt:0}),) (src/PleaHook.sol#798-804)\n[medium/medium] unused-return at src/CabalGate.sol:612: CabalGate.unlockCallback(bytes) (src/CabalGate.sol#612-645) ignores return value by pm.settle() (src/CabalGate.sol#642)\n[medium/medium] unused-return at src/PleaHook.sol:864: PleaHook.unlockCallback(bytes) (src/PleaHook.sol#864-892) ignores return value by (d,None) = poolManager.modifyLiquidity(poolKey(),ModifyLiquidityParams({tickLower:lower,tickUpper:upper,liquidityDelta:int256(uint256(liquidity)),salt:0}),) (src/PleaHook.sol#871-877)\n[medium/medium] unused-return at src/Letterbox.sol:393: Letterbox._intakeDone(bytes32) (src/Letterbox.sol#393-395) ignores return value by (None,None,None,done) = gate.intake().requests(intakeId) (src/Letterbox.sol#394)\n[low/medium] missing-zero-check at src/PleaLaunch.sol:66: PleaLaunch.constructor(address,address,address,address,address,address,address,uint256,uint256,address,bool,bytes32).plea_ (src/PleaLaunch.sol#66) lacks a zero-check on :\n[low/medium] missing-zero-check at src/PleaLaunch.sol:70: PleaLaunch.constructor(address,address,address,address,address,address,address,uint256,uint256,address,bool,bytes32).poolManager_ (src/PleaLaunch.sol#70) lacks a zero-check on :\n[low/medium] missing-zero-check at src/PleaLaunch.sol:68: PleaLaunch.constructor(address,address,address,address,address,address,address,uint256,uint256,address,bool,bytes32).seasons_ (src/PleaLaunch.sol#68) lacks a zero-check on :\n[low/medium] missing-zero-check at src/PleaLaunch.sol:88: PleaLaunch.constructor(address,address,address,address,address,address,address,uint256,uint256,address,bool,bytes32).owner_ (src/PleaLaunch.sol#88) lacks a zero-check on :\n[low/medium] missing-zero-check at src/PleaLaunch.sol:71: PleaLaunch.constructor(address,address,address,address,address,address,address,uint256,uint256,address,bool,bytes32).imd_ (src/PleaLaunch.sol#71) lacks a zero-check on :\n[low/medium] missing-zero-check at src/PleaHook.sol:195: PleaHook.constructor(IPoolManager,address,IERC20,IStacker,address,address,uint256).seasons_ (src/PleaHook.sol#195) lacks a zero-check on :\n[low/medium] missing-zero-check at src/PleaLaunch.sol:67: PleaLaunch.constructor(address,address,address,address,address,address,address,uint256,uint256,address,bool,bytes32).gate_ (src/PleaLaunch.sol#67) lacks a zero-check on :\n[low/medium] missing-zero-check at src/PleaLaunch.sol:75: PleaLaunch.constructor(address,address,address,address,address,address,address,uint256,uint256,address,bool,bytes32).oracleAsset_ (src/PleaLaunch.sol#75) lacks a zero-check on :\n[low/medium] missing-zero-check at src/PleaHook.sol:194: PleaHook.constructor(IPoolManager,address,IERC20,IStacker,address,address,uint256).owner_ (src/PleaHook.sol#194) lacks a zero-check on :\n[low/medium] missing-zero-check at src/PleaHook.sol:191: PleaHook.constructor(IPoolManager,address,IERC20,IStacker,address,address,uint256).plea_ (src/PleaHook.sol#191) lacks a zero-check on :\n[low/medium] calls-loop at src/Seasons.sol:297: Seasons._tryRecord(uint256) (src/Seasons.sol#297-304) has external calls inside a loop: (seller,score,approved,verdictAt) = gate.result(pleaId) (src/Seasons.sol#299)\n[low/medium] calls-loop at src/Seasons.sol:330: Seasons._payBonus(uint256,Seasons.Entry[10]) (src/Seasons.sol#330-350) has external calls inside a loop: (ok,ret) = address(token).call(abi.encodeCall(IERC20.transfer,(t[i].wallet,amount))) (src/Seasons.sol#336)\n[low/medium] calls-loop at src/Seasons.sol:160: Seasons._seasonOf(uint64) (src/Seasons.sol#160-162) has external calls inside a loop: (uint256(verdictAt) - gate.startedAt()) / SEASON (src/Seasons.sol#161)\n[low/medium] calls-loop at src/Seasons.sol:353: Seasons._pay(address,uint256) (src/Seasons.sol#353-356) has external calls inside a loop: (ok,ret) = address(imd).call(abi.encodeCall(IERC20.transfer,(to,amount))) (src/Seasons.sol#354)\n[low/medium] calls-loop at src/Seasons.sol:297: Seasons._tryRecord(uint256) (src/Seasons.sol#297-304) has external calls inside a loop: ! approved || seller == plea.owner() (src/Seasons.sol#300)\n[low/medium] reentrancy-benign at src/CabalGate.sol:372: Reentrancy in CabalGate._payAppeal(uint256) (src/CabalGate.sol#372-378):\n[low/medium] reentrancy-benign at src/PleaHook.sol:757: Reentrancy in PleaHook._rebalance() (src/PleaHook.sol#757-818):\n[low/medium] reentrancy-benign at src/PleaHook.sol:553: Reentrancy in PleaHook._payFees(address,bool,uint256,uint256,uint256) (src/PleaHook.sol#553-597):\n[low/medium] reentrancy-benign at src/PleaHook.sol:820: Reentrancy in PleaHook._closeWall() (src/PleaHook.sol#820-837):\n[low/medium] reentrancy-benign at src/PleaHook.sol:820: Reentrancy in PleaHook._closeWall() (src/PleaHook.sol#820-837):\n[low/medium] reentrancy-benign at src/PleaHook.sol:365: Reentrancy in PleaHook.seed() (src/PleaHook.sol#365-407):\n[low/medium] reentrancy-benign at src/PleaHook.sol:682: Reentrancy in PleaHook._applyCap() (src/PleaHook.sol#682-724):\n[low/medium] reentrancy-benign at src/PleaHook.sol:365: Reentrancy in PleaHook.seed() (src/PleaHook.sol#365-407):\n[low/medium] reentrancy-benign at src/PleaHook.sol:820: Reentrancy in PleaHook._closeWall() (src/PleaHook.sol#820-837):\n[low/medium] reentrancy-benign at src/CabalGate.sol:415: Reentrancy in CabalGate._ask(uint256) (src/CabalGate.sol#415-430):\n[low/medium] reentrancy-benign at src/PleaHook.sol:475: Reentrancy in PleaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/PleaHook.sol#475-546):\n[low/medium] reentrancy-benign at sr","passed":true},{"durationMs":2225,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/PleaLaunch.sol:91: `abi.encodePacked()` Hash Collision\n[high] reentrancy-state-change at src/CabalGate.sol:192: Reentrancy: State change after external call (17 places)\n[high] storage-array-memory-edit at src/PleaHook.sol:307: Storage Array Edited with Memory (3 places)\n[high] unsafe-casting at src/CabalGate.sol:401: Unsafe Casting of integers (2 places)\n[low] centralization-risk at src/PLEA.sol:13: Centralization Risk (4 places)\n[low] costly-loop at src/Seasons.sol:211: Costly operations inside loop (2 places)\n[low] internal-function-used-once at src/OracleAttestation.sol:206: Internal Function Used Only Once\n[low] large-numeric-literal at src/CabalGate.sol:253: Large Numeric Literal (10 places)\n[low] literal-instead-of-constant at src/CabalGate.sol:253: Literal Instead of Constant (110 places)\n[low] missing-inheritance at src/PleaHook.sol:35: Missing Inheritance (3 places)\n[low] require-revert-in-loop at src/CabalGate.sol:750: Loop Contains `require`/`revert` (4 places)\n[low] state-change-without-event at src/CabalGate.sol:612: State Change Without Event (3 places)\n[low] unchecked-return at src/CabalGate.sol:642: Unchecked Return (7 places)\n[low] uninitialized-local-variable at src/Letterbox.sol:233: Uninitialized Local Variable (9 places)\n[low] unsafe-erc20-operation at src/PleaHook.sol:667: Unsafe ERC20 Operation (4 places)\n[low] unused-import at src/PleaLaunch.sol:4: Unused Import (3 places)\n[low] unused-public-function at src/CabalGate.sol:212: Public Function Not Used Internally (8 places)\n[low] unused-state-variable at src/PLEA.sol:28: Unused State Variable (5 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"3015008c535345df9c34c04d92780f6f81be028691828ab80d46a374d325c49e","verifiedTreeHash":"a7583e5b187e56a24735e235afa9e1be66777b85","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":310707,"exitCode":0,"name":"build","output":"Compiling 145 files with Solc 0.8.26\nSolc 0.8.26 finished in 310.55s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to pure\n   --> src/CabalGate.sol:705:5:\n    |\n705 |     function _text(string storage t, bool json) internal view returns (string memory) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\n","passed":true},{"durationMs":8483,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/ForkTestnet.t.sol:ForkTestnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 588.14µs (0.00ns CPU time)\n\nRan 4 tests for test/OracleConformance.t.sol:OracleConformanceTest\n[PASS] test_callbackSelectorHasTheProtocolStruct() (gas: 748)\n[PASS] test_digestMatchesTheProtocol() (gas: 10527)\n[PASS] test_liveAttestationRecoversToOracleSigner() (gas: 146367)\n[PASS] test_protocolSignatureRecoversToVectorSigner() (gas: 13943)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 4.46ms (557.92µs CPU time)\n\nRan 1 test for test/AuditOwnerTip.t.sol:AuditOwnerTipTest\n[PASS] test_currentPleaOwnerReceivesNoKeeperTipAfterOwnershipTransfer() (gas: 1417662)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 7.60ms (842.56µs CPU time)\n\nRan 2 tests for test/Letterbox.t.sol:LetterboxMainnetPathTest\n[PASS] test_letterBuysTheOracleFeeAndTheTipWithPlea() (gas: 9203765)\n[PASS] test_mintingTheFeeIsRefusedOnMainnet() (gas: 733988)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 8.48ms (2.48ms CPU time)\n\nRan 2 tests for test/Letterbox.t.sol:OwnerExclusionTest\n[PASS] test_ownerGetsNoKeeperTip() (gas: 1026181)\n[PASS] test_ownerPleasEarnNoPoints() (gas: 4971822)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 8.74ms (1.05ms CPU time)\n\nRan 3 tests for test/LaunchManifest.t.sol:RehearsalManifestTest\n[PASS] test_laterBlockCannotRegisterLauncher() (gas: 13191593)\n[PASS] test_separateConstructorCallsInDeploymentBlockStillWork() (gas: 14106618)\n[PASS] test_separateTransactionsLeaveTheAcceptedDeploymentBlockWindow() (gas: 13325956)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 12.37ms (6.22ms CPU time)\n\nRan 2 tests for test/LaunchManifest.t.sol:PostLaunchTest\n[PASS] test_committedHookDeploysLaterAndMintsOnlyTheFixedSplit() (gas: 6733836)\n[PASS] test_committedLetterboxDeploysLater() (gas: 9601388)\nLogs:\n  deployLetterbox transaction gas: 4971340\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 16.74ms (8.43ms CPU time)\n\nRan 3 tests for test/HookAdversarial.t.sol:LaunchFeeBoundaryTest\n[PASS] testFuzz_launchFeeOnlyFallsWithTime(uint256,uint256) (runs: 256, μ: 23986, ~: 24108)\n[PASS] test_largeLaunchBuyRollsBackAndSucceedsAtWindowEnd() (gas: 729487)\n[PASS] test_launchFeeHasExactStartMidpointAndEndValues() (gas: 42979)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 23.86ms (5.91ms CPU time)\n\nRan 7 tests for test/AuditImported.t.sol:AuditImportedTest\n[PASS] test_appealLetterRetriesCompletedRequestWithFailedCallback() (gas: 12763462)\n[PASS] test_appealLetterRetriesLazyTimeoutWithoutSeparateSettlement() (gas: 12696826)\n[PASS] test_autoAppealSurvivesBalanceGrowth() (gas: 9315503)\n[PASS] test_growingBalanceDoesNotEnableDustOrLargerAppeals() (gas: 8538035)\n[PASS] test_rawAppealLetterSurvivesBalanceGrowth() (gas: 9341410)\n[PASS] test_shrinkingBalanceStillUsesCurrentMinimumAndMaximum() (gas: 8182172)\n[PASS] test_siteAppealSurvivesBalanceGrowthAtOriginalMinimum() (gas: 8441059)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 35.31ms (24.10ms CPU time)\n\nRan 30 tests for test/Orientation.t.sol:GatePleaIsZeroTest\n[PASS] test_appealClosesAfterFourHoursAndOnlyOnce() (gas: 11339886)\n[PASS] test_appealWithinFourHoursForNoMore() (gas: 8885249)\n[PASS] test_approvedScoreOpensTheSellWindow() (gas: 5501297)\n[PASS] test_badAttestationsAreNotDelivered() (gas: 4803761)\n[PASS] test_bodyIsTheNumericPanelQuestion() (gas: 4826199)\n[PASS] test_callbackFitsTheStipend() (gas: 7822685)\nLogs:\n  approve callback gas: 58946\n  deny callback gas: 83545\n\n[PASS] test_callbackOnlyFromIntakeAndOnlyForAPendingPlea() (gas: 5338603)\n[PASS] test_cannotPassIsRefusedBeforePaying() (gas: 1179875)\n[PASS] test_cooldownAfterExecutedSell() (gas: 8094884)\n[PASS] test_failedAppealCanBeRetried() (gas: 11276663)\n[PASS] test_failureAfterExpireIsRefused() (gas: 4791327)\n[PASS] test_failureClearsThePendingPleaWithoutCooldownOrClock() (gas: 7668039)\n[PASS] test_failureFitsTheMainnetGas() (gas: 4762261)\n[PASS] test_failureForAnUnknownOrSettledRequestDoesNothing() (gas: 4934748)\n[PASS] test_failureOnlyFromTheIntake() (gas: 4730780)\n[PASS] test_noPleasWhileTheCabalSleeps() (gas: 56280)\n[PASS] test_noVerdictIsClearedAtOnceWhenTheIntakeCompletes() (gas: 7651310)\n[PASS] test_onePendingPleaPerWallet() (gas: 4714677)\n[PASS] test_orientationIsPleaZero() (gas: 15922)\n[PASS] test_pendingExpiresAfterTwentyMinutesAndLateCallbacksFail() (gas: 7614781)\n[PASS] test_pleaAsksWithTheFailureFunction() (gas: 4684643)\n[PASS] test_pleaPaysTheIntakeAndNamesTheCallback() (gas: 4730679)\n[PASS] test_prizePleaOnTopOfAWeekOldBuy() (gas: 1463930)\n[PASS] test_refusalClearsThePleaToo() (gas: 4784139)\n[PASS] test_scoreAboveRangeOrWrongTypeIsRefused() (gas: 7754045)\n[PASS] test_scoreBelowNeedDenies() (gas: 4977742)\n[PASS] test_sellWindowLapses() (gas: 7684244)\n[PASS] test_signerWithDelegationCodeStillVerifies() (gas: 4817087)\n[PASS] test_textFilter() (gas: 5167528)\n[PASS] test_wrongSignerIsRefused() (gas: 4781307)\nSuite result: ok. 30 passed; 0 failed; 0 skipped; finished in 40.45ms (22.52ms CPU time)\n\nRan 29 tests for test/Gate.t.sol:GateTest\n[PASS] test_appealClosesAfterFourHoursAndOnlyOnce() (gas: 11339864)\n[PASS] test_appealWithinFourHoursForNoMore() (gas: 8885227)\n[PASS] test_approvedScoreOpensTheSellWindow() (gas: 5501297)\n[PASS] test_badAttestationsAreNotDelivered() (gas: 4803739)\n[PASS] test_bodyIsTheNumericPanelQuestion() (gas: 4826177)\n[PASS] test_callbackFitsTheStipend() (gas: 7822663)\nLogs:\n  approve callback gas: 58946\n  deny callback gas: 83545\n\n[PASS] test_callbackOnlyFromIntakeAndOnlyForAPendingPlea() (gas: 5338603)\n[PASS] test_cannotPassIsRefusedBeforePaying() (gas: 1179875)\n[PASS] test_cooldownAfterExecutedSell() (gas: 8094862)\n[PASS] test_failedAppealCanBeRetried() (gas: 11276641)\n[PASS] test_failureAfterExpireIsRefused() (gas: 4791305)\n[PASS] test_failureClearsThePendingPleaWithoutCooldownOrClock() (gas: 7668039)\n[PASS] test_failureFitsTheMainnetGas() (gas: 4762239)\n[PASS] test_failureForAnUnknownOrSettledRequestDoesNothing() (gas: 4934748)\n[PASS] test_failureOnlyFromTheIntake() (gas: 4730780)\n[PASS] test_noPleasWhileTheCabalSleeps() (gas: 56280)\n[PASS] test_noVerdictIsClearedAtOnceWhenTheIntakeCompletes() (gas: 7651310)\n[PASS] test_onePendingPleaPerWallet() (gas: 4714677)\n[PASS] test_pendingExpiresAfterTwentyMinutesAndLateCallbacksFail() (gas: 7614759)\n[PASS] test_pleaAsksWithTheFailureFunction() (gas: 4684621)\n[PASS] test_pleaPaysTheIntakeAndNamesTheCallback() (gas: 4730657)\n[PASS] test_prizePleaOnTopOfAWeekOldBuy() (gas: 1463908)\n[PASS] test_refusalClearsThePleaToo() (gas: 4784139)\n[PASS] test_scoreAboveRangeOrWrongTypeIsRefused() (gas: 7754023)\n[PASS] test_scoreBelowNeedDenies() (gas: 4977742)\n[PASS] test_sellWindowLapses() (gas: 7684244)\n[PASS] test_signerWithDelegationCodeStillVerifies() (gas: 4817065)\n[PASS] test_textFilter() (gas: 5167528)\n[PASS] test_wrongSignerIsRefused() (gas: 4781307)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 18.38ms (20.12ms CPU time)\n\nRan 5 tests for test/Launch.t.sol:LaunchTest\n[PASS] test_deployHookChecksTheInitCodeAndFlags() (gas: 42059764)\n[PASS] test_eachStepFitsAMainnetTransaction() (gas: 46053983)\nLogs:\n  launch (5 contracts + intake mock): 1247882\n  deployLetterbox: 4620117\n  deployHook: 5467835\n  seed: 598376\n\n[PASS] test_launchWiresEverythingWithoutCallingOutside() (gas: 1318408)\n[PASS] test_ownerMaySeedEarly() (gas: 41355998)\n[PASS] test_seedByOwnerAnyTimeByAnyoneAfterStart() (gas: 41454781)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 42.21ms (84.18ms CPU time)\n\nRan 3 tests for test/OracleReplay.t.sol:OracleReplayTest\n[PASS] testFuzz_oneSignedRequestCannotSettleTwoPleas(bool,bool) (runs: 32, μ: 7933679, ~: 7943535)\n[PASS] test_deniedRequestCannotBeResignedToApproveItsAppeal() (gas: 8285515)\n[PASS] test_invalidCallbackDoesNotConsumeTheRequest() (gas: 7780353)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 42.34ms (33.11ms CPU time)\n\nRan 4 tests for test/Token.t.sol:TokenTest\n[PASS] test_distributorAndAllowlistMaySend() (gas: 213430)\n[PASS] test_freeForeverOnceTheCabalDies() (gas: 183982)\n[PASS] test_launcherAndInitAreOneShot() (gas: 127033)\n[PASS] test_walletsCannotSendWhileTheCabalWatches() (gas: 331352)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 4.63ms (366.33µs CPU time)\n\nRan 6 tests for test/DistributorAdversarial.t.sol:DistributorAdversarialTest\n[PASS] testFuzz_modifiedLeafOrProofCannotRedirectFunds(uint8,uint8,uint256) (runs: 256, μ: 259282, ~: 259248)\n[PASS] test_claimsCrossBitmapWordsAndCannotBeClaimedTwice() (gas: 1724258)\n[PASS] test_failedTokenTransferRollsBackBitmapAndCanBeRetried() (gas: 317100)\n[PASS] test_fullAllocationAndZeroAmountLeavesDoNotCorruptAdjacentBits() (gas: 260412)\n[PASS] test_rootCannotChangeAfterCommitmentEvenBeforeFirstClaim() (gas: 115955)\n[PASS] test_unsetRootAndUnauthorizedRootDoNotConsumeClaims() (gas: 275957)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 33.01ms (31.79ms CPU time)\n\nRan 1 test for test/fork/ForkMainnet.t.sol:ForkMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 367.63µs (0.00ns CPU time)\n\nRan 3 tests for test/LaunchManifest.t.sol:AtomicManifestTest\n[PASS] test_factoryDeploysExactManifestOnAnEmptySepoliaChain() (gas: 49747346)\nLogs:\n  five-contract launch transaction gas through IMD's factory: 12578939\n  gas limit with IMD's headroom: 15346305\n  margin to the 16,777,216 cap: 1430911\n\n[PASS] test_launchJsonCommitsToThisLetterbox() (gas: 30490)\n[PASS] test_launchJsonEncodesOracleMintFlagAsStaticWord() (gas: 10393)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 68.15ms (61.71ms CPU time)\n\nRan 11 tests for test/Orientation.t.sol:SeasonsPleaIsZeroTest\n[PASS] test_aLateCallbackCannotRevive() (gas: 4793211)\n[PASS] test_aliveFromSeedDeadAfterSilenceForever() (gas: 236516)\n[PASS] test_bestThreeCountAndTopTenOrder() (gas: 23471037)\n[PASS] test_closeSeasonPaysTheTopTen() (gas: 56575402)\n[PASS] test_deathEndsTheLastSeasonAndTheRestGoesToTheWall() (gas: 11790709)\n[PASS] test_mainnetGuardRefusesShortTimings() (gas: 13499)\n[PASS] test_onlyApprovedPleasScore() (gas: 4904947)\n[PASS] test_orientationIsPleaZero() (gas: 15724)\n[PASS] test_secondSeasonScoresSeparately() (gas: 44262937)\n[PASS] test_tenthPlaceIsEvictedByABetterWallet() (gas: 39812901)\n[PASS] test_verdictsKeepItAliveAcrossManySeasons() (gas: 111813226)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 67.61ms (51.10ms CPU time)\n\nRan 20 tests for test/Orientation.t.sol:HookPleaIsZeroTest\n[PASS] test_aBuyMustAffordTheCredit() (gas: 1246451)\n[PASS] test_aSellAboveTheCapIsTrimmedAndBurned() (gas: 1695109)\n[PASS] test_avgBuyTimeIsBuyWeighted() (gas: 1104668)\n[PASS] test_capDecayIsSetSoTheFloorIsReachableIn25Days() (gas: 18018)\n[PASS] test_capFollowsBuysAtMostOneDayOfDecayPerDay() (gas: 1683977)\n[PASS] test_everyFeeIsPaidInTheSameSwap() (gas: 1293186)\n[PASS] test_factScoreUsesCheckpointsNotSpot() (gas: 1658273)\n[PASS] test_firstBuyWithAnEmptyPoolSendsPayoutsToLiquidity() (gas: 571078)\n[PASS] test_freeTradingWhenTheCabalSleeps() (gas: 1102060)\n[PASS] test_hourlyCheckpointIsNotSetByTheTradeThatOpensTheHour() (gas: 1929006)\n[PASS] test_orientationIsPleaZero() (gas: 15910)\n[PASS] test_plainImdOnlyWhenTheCreditReverts() (gas: 1199509)\n[PASS] test_rebalanceRedeemsClaimsIntoTheWall() (gas: 4561799)\n[PASS] test_sellsAndExactOutputOnlyThroughTheGateWhileAlive() (gas: 746273)\n[PASS] test_stackerIsApprovedOnlyForTheCashbackBeingCredited() (gas: 1817210)\n[PASS] test_wallGuardDropsAtOnceAndRisesFourPercentADay() (gas: 34287316)\n[PASS] test_wallGuardIgnoresASellerChosenLimitReachedThroughAnEmptyPool() (gas: 2792695)\n[PASS] test_wallGuardIgnoresTheEmptyPoolsPriceLimit() (gas: 2767439)\n[PASS] test_wallGuardLagsAPumpAndCapsTheWall() (gas: 16714927)\n[PASS] test_wallGuardStillDropsAtOnceToASellerChosenLimitInsideTheBand() (gas: 33175607)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 118.30ms (136.30ms CPU time)\n\nRan 12 tests for test/AuditRevision.t.sol:AuditRevisionTest\n[PASS] testFuzz_cumulativeCapDecayStaysWithinElapsedBudget(uint256) (runs: 32, μ: 4120487, ~: 4122332)\n[PASS] test_appealRetryClearsTimedOutPendingAppeal() (gas: 11953900)\n[PASS] test_deadCabalBuyStillRequiresARecipient() (gas: 1640429)\n[PASS] test_dustBuyDoesNotGiveUntrackedTokensLossOrHoldingPoints() (gas: 1045870)\n[PASS] test_expiredAppealCanBeRetriedWithoutLiftingDenialCooldown() (gas: 12105009)\n[PASS] test_lapsedApprovalCannotBypassCooldown() (gas: 8575672)\n[PASS] test_largeBuyClaimsAreRedeemableAndNextBuyStacksNormally() (gas: 2170636)\n[PASS] test_lateCloseDoesNotPayFutureSeasonFees() (gas: 13463520)\n[PASS] test_sameSecondCapRatchetsCannotReuseFractionalBudget() (gas: 1051794)\n[PASS] test_seasonClaimsArePaidAsImdAtClose() (gas: 10097045)\n[PASS] test_secondLargeBuyPreservesEveryPayee() (gas: 1239095)\n[PASS] test_unansweredAppealDoesNotExtendTheOriginalWindow() (gas: 8791018)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 124.73ms (131.10ms CPU time)\n\nRan 7 tests for test/AuditImported.t.sol:AuditImportedPaidFeeTest\n[PASS] test_appealLetterRetriesCompletedRequestWithFailedCallback() (gas: 12707477)\n[PASS] test_appealLetterRetriesLazyTimeoutWithoutSeparateSettlement() (gas: 12640841)\n[PASS] test_autoAppealSurvivesBalanceGrowth() (gas: 9278856)\n[PASS] test_growingBalanceDoesNotEnableDustOrLargerAppeals() (gas: 8526735)\n[PASS] test_rawAppealLetterSurvivesBalanceGrowth() (gas: 9304762)\n[PASS] test_shrinkingBalanceStillUsesCurrentMinimumAndMaximum() (gas: 8170872)\n[PASS] test_siteAppealSurvivesBalanceGrowthAtOriginalMinimum() (gas: 8429759)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 158.07ms (23.45ms CPU time)\n\nRan 19 tests for test/LetterboxEdges.t.sol:LetterboxEdgesMainnetTest\n[PASS] testFuzz_aFinishedEscrowNeverReopens(uint8) (runs: 32, μ: 5898130, ~: 6075878)\n[PASS] testFuzz_feeSwapStaysUnderTheCapAndRefundsTheRest(uint256) (runs: 32, μ: 9159073, ~: 9152692)\n[PASS] test_aFailedRequestSettlesBeforeTheTwentyMinutes() (gas: 8514978)\n[PASS] test_aLapsedLetterStartsTheCooldownFromItsVerdict() (gas: 9220578)\n[PASS] test_appealFeesAboveTenPercentOfTheBalanceAreRefused() (gas: 11944911)\n[PASS] test_appealLetterAppealsAHandPleaAndEscrowsOnlyTheAppeal() (gas: 8996081)\n[PASS] test_appealLetterRefusesAnExecutedPleaAndAClosedWindow() (gas: 10328923)\n[PASS] test_approvedEscrowAtTheWindowsLastSecondSellsAndCannotSettle() (gas: 6088421)\n[PASS] test_approvedEscrowOneSecondAfterTheWindowSettlesAndStillCounts() (gas: 5750398)\n[PASS] test_autoSellFeeIsCheckpointedIntoTheRunningSeason() (gas: 9500350)\n[PASS] test_deadCabalStillSettlesAndNames() (gas: 5647803)\n[PASS] test_feesForBuysTheOracleFeeToo() (gas: 38748)\n[PASS] test_pendingEscrowSettlesOnlyOnceStale() (gas: 5592867)\n[PASS] test_pleaFlagsAreEmittedAndReadable() (gas: 8064178)\n[PASS] test_setLetterboxLifecycleOnAFreshPlea() (gas: 434053)\n[PASS] test_shareBandsAt20And35Percent() (gas: 252187)\n[PASS] test_siteAmountLimitsAtTheirBoundaries() (gas: 13901172)\n[PASS] test_theGateRefusesBadFlagsAndUnflaggedSalesEvenFromTheLetterbox() (gas: 9376995)\n[PASS] test_theLiveLetterboxCannotBeReplaced() (gas: 83425)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 173.72ms (156.89ms CPU time)\n\nRan 5 tests for test/SeasonRanking.t.sol:SeasonRankingTest\n[PASS] testFuzz_rankingsMatchSortedResultsInAnyRecordOrder(uint256) (runs: 32, μ: 10555631, ~: 10531174)\n[PASS] test_closeSeasonUsesTheSameTiesForPrizes() (gas: 948745)\n[PASS] test_earlierEqualScoreCanReplaceACountedPleaWithoutChangingPoints() (gas: 737794)\n[PASS] test_replacingALowerScoreRemovesItsIdFromTheTieKey() (gas: 738488)\n[PASS] test_walletTieUsesNewestCountedPleaNotLastRecordedPlea() (gas: 775437)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 174.38ms (173.56ms CPU time)\n\nRan 16 tests for test/SeasonFunds.t.sol:SeasonFundsTest\n[PASS] testFuzz_lateCloseConservesAssets(uint96,uint96,bool) (runs: 32, μ: 1019729, ~: 1006385)\n[PASS] test_bonusIsMintedToSeasonsAndCannotBeWithdrawn() (gas: 24077)\n[PASS] test_bonusPaysTheTopTenAndBurnsTheUnpaidShares() (gas: 1265221)\n[PASS] test_claimRedemptionCallbackCannotBeInvokedOutsideUnlock() (gas: 75304)\n[PASS] test_deathAtBoundaryFlushesClaimsAndLateDonationsOnce() (gas: 1582206)\n[PASS] test_deathBeforeTheSixthSeasonBurnsTheRest() (gas: 909213)\n[PASS] test_deathMidSeasonPreservesEarlierSeasonFees() (gas: 1364260)\n[PASS] test_emptySeasonBurnsItsWholeBonus() (gas: 210295)\n[PASS] test_failedBonusTransferIsBurnedNotStuck() (gas: 584434)\n[PASS] test_failedPayoutRollsForwardWithoutBlockingOtherWinners() (gas: 1301738)\n[PASS] test_feeAtBoundaryBelongsToNextSeason() (gas: 985098)\n[PASS] test_flushBeforeTheEndCannotTouchTheBonus() (gas: 43338)\n[PASS] test_lateClosesOnlyRollUnpaidSharesForward() (gas: 2057331)\n[PASS] test_onlyTheFirstSixSeasonsPayABonus() (gas: 3724762)\n[PASS] test_prizePleaStaysGatedWhileTheCabalWatches() (gas: 650190)\n[PASS] test_unobservedDonationCannotFlowBackwards() (gas: 895294)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 18.49ms (17.69ms CPU time)\n\nRan 11 tests for test/HookAdversarial.t.sol:HookAdversarialTest\n[PASS] testFuzz_immediateRoundTripCannotProfitIncludingCashback(uint256) (runs: 256, μ: 1145937, ~: 1141036)\n[PASS] test_exactOutputBuyWorksAfterDeathAndKeepsAllAccountingSettled() (gas: 1195023)\n[PASS] test_firstPartialFillRefundIsBackedByRedeemableQuoteClaims() (gas: 652932)\n[PASS] test_hookCallbacksRejectCallersAndForeignPools() (gas: 134604)\n[PASS] test_keeperTipsRequireWorkAndRespectTheOneHourCooldown() (gas: 1248537)\n[PASS] test_onlyHookMayInitializeOrAddLiquidity() (gas: 64122)\n[PASS] test_partialFillRefundChargesOnlyRealizedImdAndKeepsCostBasisCorrect() (gas: 1308210)\n[PASS] test_realCreditBudgetMustBeAffordableAndExhaustedCreditFallsBack() (gas: 2553608)\n[PASS] test_seedAndUnlockAreOneShotAndOnlyAuthorizedContextsWork() (gas: 138160)\n[PASS] test_wallFundingCannotCreateUnbackedReserveWhenTransferFails() (gas: 290491)\n[PASS] test_zeroBuyRevertsAndOneWeiBuyConservesSupply() (gas: 601325)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 216.85ms (198.61ms CPU time)\n\nRan 11 tests for test/HookAdversarial.t.sol:HookAdversarialPleaZeroTest\n[PASS] testFuzz_immediateRoundTripCannotProfitIncludingCashback(uint256) (runs: 256, μ: 1146320, ~: 1141250)\n[PASS] test_exactOutputBuyWorksAfterDeathAndKeepsAllAccountingSettled() (gas: 1195331)\n[PASS] test_firstPartialFillRefundIsBackedByRedeemableQuoteClaims() (gas: 652660)\n[PASS] test_hookCallbacksRejectCallersAndForeignPools() (gas: 135432)\n[PASS] test_keeperTipsRequireWorkAndRespectTheOneHourCooldown() (gas: 1264225)\n[PASS] test_onlyHookMayInitializeOrAddLiquidity() (gas: 64062)\n[PASS] test_partialFillRefundChargesOnlyRealizedImdAndKeepsCostBasisCorrect() (gas: 1307694)\n[PASS] test_realCreditBudgetMustBeAffordableAndExhaustedCreditFallsBack() (gas: 2552780)\n[PASS] test_seedAndUnlockAreOneShotAndOnlyAuthorizedContextsWork() (gas: 138160)\n[PASS] test_wallFundingCannotCreateUnbackedReserveWhenTransferFails() (gas: 290467)\n[PASS] test_zeroBuyRevertsAndOneWeiBuyConservesSupply() (gas: 600637)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 262.74ms (258.08ms CPU time)\n\nRan 11 tests for test/Seasons.t.sol:FastClockTest\n[PASS] test_aLateCallbackCannotRevive() (gas: 4792663)\n[PASS] test_aliveFromSeedDeadAfterSilenceForever() (gas: 236427)\n[PASS] test_bestThreeCountAndTopTenOrder() (gas: 1071914)\n[PASS] test_closeSeasonPaysTheTopTen() (gas: 41912548)\n[PASS] test_deathEndsTheLastSeasonAndTheRestGoesToTheWall() (gas: 1126587)\n[PASS] test_fastFullCycle() (gas: 77170582)\n[PASS] test_mainnetGuardRefusesShortTimings() (gas: 13521)\n[PASS] test_onlyApprovedPleasScore() (gas: 4902100)\n[PASS] test_secondSeasonScoresSeparately() (gas: 47200891)\n[PASS] test_tenthPlaceIsEvictedByABetterWallet() (gas: 2260557)\n[PASS] test_verdictsKeepItAliveAcrossManySeasons() (gas: 117702760)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 181.65ms (54.34ms CPU time)\n\nRan 7 tests for test/SeasonAdversarial.t.sol:SeasonAdversarialTest\n[PASS] testFuzz_failedPrizeDoesNotBlockOthersAndUnpaidShareReachesWall(bool) (runs: 256, μ: 1821264, ~: 1820399)\n[PASS] testFuzz_prizeRoundingConservesAnOddSizedPot(uint256) (runs: 256, μ: 4904920, ~: 4925071)\n[PASS] test_batchIgnoresUnknownDeniedAndRepeatedIdsButCannotReopenASeason() (gas: 1061570)\n[PASS] test_closeBeforeGraceRollsBackItsBatchRecording() (gas: 634452)\n[PASS] test_flushBeforeFinalCloseCannotMoveAnyFunds() (gas: 552908)\n[PASS] test_prizesRequireSixtyPoints() (gas: 1262479)\n[PASS] test_recordRejectsDenialsDuplicatesAndLateApprovals() (gas: 813726)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 340.78ms (337.96ms CPU time)\n\nRan 12 tests for test/HookRevision.t.sol:HookRevisionPleaIsZeroTest\n[PASS] testFuzz_aGreedyStackerCannotReachTheWallReserve(uint256,uint256) (runs: 32, μ: 1312543, ~: 1312350)\n[PASS] testFuzz_aLimitAnywhereInTheLiquidityFreeRegionNeverMovesTheGuard(uint256,uint256) (runs: 32, μ: 2482851, ~: 2433585)\n[PASS] testFuzz_aLimitInsideTheLiquidMarketBandMovesTheGuardToTheStopTick(uint256) (runs: 32, μ: 5198240, ~: 5198271)\n[PASS] testFuzz_aSameHourPumpCannotMoveAPleasFactScore(uint256) (runs: 32, μ: 2702584, ~: 2700427)\n[PASS] testFuzz_repeatedDrainsToTheExtremeNeverMoveTheGuard(uint8) (runs: 32, μ: 4308286, ~: 3657315)\n[PASS] testFuzz_successfulCreditsNeverAccumulateAllowance(uint256,uint256,uint256) (runs: 32, μ: 2138938, ~: 2130056)\n[PASS] testFuzz_theGuardClimbsAtMost400TicksADay(uint256,uint256,uint8) (runs: 32, μ: 2744599, ~: 2372125)\n[PASS] testFuzz_theHoursFirstTradeRecordsThePriceItFoundWhateverItsSize(uint256,uint256) (runs: 32, μ: 2234892, ~: 2233013)\n[PASS] test_aCreditThatBurnsAllItsGasLeavesNoAllowance() (gas: 1593249)\n[PASS] test_anHourOpeningSellRecordsThePriceItFound() (gas: 1846764)\n[PASS] test_orientationIsPleaZero() (gas: 15668)\n[PASS] test_wallGuardFollowsASellThatStopsWhereTheMarketHasLiquidity() (gas: 6114150)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 367.81ms (589.70ms CPU time)\n\nRan 11 tests for test/BonusInvariant.t.sol:BonusEdgeTest\n[PASS] testFuzz_anyRankingPaysPlusBurnsExactlyTheBonus(uint256) (runs: 512, μ: 3325723, ~: 3079719)\n[PASS] test_bonusPaidAfterDeathIsFreelyTransferable() (gas: 693866)\n[PASS] test_closeWithinTheGraceHourIsRefused() (gas: 656866)\n[PASS] test_closingTwiceCannotPayASeasonsBonusTwice() (gas: 648548)\n[PASS] test_deathBeforeTradingSeasonZeroEndsBurnsEverythingButSeasonZero() (gas: 817130)\n[PASS] test_eleventhWalletIsNotPaidAndCannotDisplaceRankTen() (gas: 4436264)\n[PASS] test_gateAsSellerForfeitsWhileWatchedButIsPaidAfterDeath() (gas: 1187696)\n[PASS] test_lateApprovalListedAtCloseStillEarnsTheBonus() (gas: 616726)\n[PASS] test_onlyTheBestThreePleasCount() (gas: 1540243)\n[PASS] test_sixtyPointsQualifiesFiftyNineDoesNot() (gas: 1286731)\n[PASS] test_tenQualifiersReceiveTheWholeBonusAndNothingBurns() (gas: 4182661)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 347.25ms (352.71ms CPU time)\n\nRan 18 tests for test/GateAdversarial.t.sol:GateAdversarialTest\n[PASS] testFuzz_panelAndAnswerValidationCannotConsumeRequests(uint8) (runs: 256, μ: 4954653, ~: 4957491)\n[PASS] testFuzz_printablePleaRoundTripsThroughQuestionJson(uint256,uint16) (runs: 256, μ: 5000907, ~: 4905983)\n[PASS] testFuzz_signedQuorumMustBeReached(uint16,bool) (runs: 256, μ: 5044699, ~: 5054889)\n[PASS] test_aWhaleCanStillPleadTheMaximum() (gas: 5226719)\n[PASS] test_amountLimitsFailBeforeChargingAndOnePercentIsTheMinimum() (gas: 4976995)\n[PASS] test_appealIsAcceptedAtItsLastSecondAndCannotBeStolen() (gas: 8193580)\n[PASS] test_appealOracleFeeFailureRollsBackWallFundingAndOriginalFlag() (gas: 8695273)\n[PASS] test_approvedWindowOnlyClearsAfterTheLastSecond() (gas: 7922263)\n[PASS] test_changingSignedAnswerOrConsumerChainInvalidatesSignature() (gas: 4978122)\n[PASS] test_deadManExpiresAtTheExactSecondAndNeverAcceptsANewVerdict() (gas: 4874024)\n[PASS] test_denialCooldownEndsExactlyAtFourHours() (gas: 7699075)\n[PASS] test_futureIssuanceAndExpiredAttestationsRejectAtExactBoundaries() (gas: 7892232)\n[PASS] test_gateUnlockCallbackCannotBeInvokedOutsideItsOwnSale() (gas: 88091)\n[PASS] test_latePendingCannotConsumeSignatureOrExtendHeartbeat() (gas: 4863758)\n[PASS] test_malformedUtf8AndHiddenControlsFailWithoutCharging() (gas: 957696)\n[PASS] test_missingSellAllowanceDoesNotConsumeTheApprovedPlea() (gas: 4978884)\n[PASS] test_pendingAndExecutionDeadlinesAreInclusive() (gas: 5394499)\n[PASS] test_slippageRevertRestoresApprovalSupplyAndAllFeeState() (gas: 6048091)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 462.66ms (581.79ms CPU time)\n\nRan 10 tests for test/Seasons.t.sol:SeasonsTest\n[PASS] test_aLateCallbackCannotRevive() (gas: 4793189)\n[PASS] test_aliveFromSeedDeadAfterSilenceForever() (gas: 236405)\n[PASS] test_bestThreeCountAndTopTenOrder() (gas: 23471015)\n[PASS] test_closeSeasonPaysTheTopTen() (gas: 56575402)\n[PASS] test_deathEndsTheLastSeasonAndTheRestGoesToTheWall() (gas: 11790709)\n[PASS] test_mainnetGuardRefusesShortTimings() (gas: 13499)\n[PASS] test_onlyApprovedPleasScore() (gas: 4904925)\n[PASS] test_secondSeasonScoresSeparately() (gas: 44262937)\n[PASS] test_tenthPlaceIsEvictedByABetterWallet() (gas: 39812879)\n[PASS] test_verdictsKeepItAliveAcrossManySeasons() (gas: 111813204)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 279.28ms (48.82ms CPU time)\n\nRan 12 tests for test/AuditRun3.t.sol:AuditRun3Test\n[PASS] test_F1_appealLetterCannotRetryAnAppealTheOracleNeverAnswered() (gas: 16393806)\n[PASS] test_F2_aCapSizedAutoSellPleaCannotBeAppealedThroughTheLetterbox() (gas: 33475799)\n[PASS] test_F3_aBareCommandWordBecomesAPaidPlea() (gas: 112508)\n[PASS] test_aLetterboxDeployedByAnyoneElseHasNoPowers() (gas: 5736167)\n[PASS] test_autoSellCannotAcceptASpotPriceUnderTheSnapshotFloor() (gas: 6739375)\n[PASS] test_escrowsAfterTheCabalDies() (gas: 12782203)\n[PASS] test_feeSaleIsBoundedAndTheTipReturns() (gas: 5224020)\n[PASS] test_letterParsingEdgeCases() (gas: 21078575)\n[PASS] test_markerRuleUnchanged() (gas: 6338280)\n[PASS] test_oneCapSizedSaleMovesSpotUnderOnePercent() (gas: 26977745)\nLogs:\n  price impact of a 2.5M PLEA sale, bps: 80\n\n[PASS] test_oracleBodyIsValidJsonForHostileTexts() (gas: 26147138)\n[PASS] test_priceViewsEqualAFullRingScan() (gas: 47480835)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 462.62ms (148.34ms CPU time)\n\nRan 11 tests for test/HookRevision.t.sol:HookRevisionTest\n[PASS] testFuzz_aGreedyStackerCannotReachTheWallReserve(uint256,uint256) (runs: 64, μ: 1312396, ~: 1312267)\n[PASS] testFuzz_aLimitAnywhereInTheLiquidityFreeRegionNeverMovesTheGuard(uint256,uint256) (runs: 64, μ: 2450266, ~: 2382450)\n[PASS] testFuzz_aLimitInsideTheLiquidMarketBandMovesTheGuardToTheStopTick(uint256) (runs: 64, μ: 5198214, ~: 5198240)\n[PASS] testFuzz_aSameHourPumpCannotMoveAPleasFactScore(uint256) (runs: 64, μ: 2703161, ~: 2703267)\n[PASS] testFuzz_repeatedDrainsToTheExtremeNeverMoveTheGuard(uint8) (runs: 64, μ: 4051639, ~: 3657293)\n[PASS] testFuzz_successfulCreditsNeverAccumulateAllowance(uint256,uint256,uint256) (runs: 64, μ: 2137482, ~: 2129964)\n[PASS] testFuzz_theGuardClimbsAtMost400TicksADay(uint256,uint256,uint8) (runs: 64, μ: 2752413, ~: 2357762)\n[PASS] testFuzz_theHoursFirstTradeRecordsThePriceItFoundWhateverItsSize(uint256,uint256) (runs: 64, μ: 2240213, ~: 2232991)\n[PASS] test_aCreditThatBurnsAllItsGasLeavesNoAllowance() (gas: 1593227)\n[PASS] test_anHourOpeningSellRecordsThePriceItFound() (gas: 1846742)\n[PASS] test_wallGuardFollowsASellThatStopsWhereTheMarketHasLiquidity() (gas: 6114128)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 462.70ms (1.22s CPU time)\n\nRan 26 tests for test/Letterbox.t.sol:LetterboxTest\n[PASS] testFuzz_namesAreUniqueIdempotentAndReleasedOnClear(uint256,uint8) (runs: 32, μ: 323775, ~: 323547)\n[PASS] test_aBareCommandWordIsNotAPlea() (gas: 5961566)\n[PASS] test_aLapsedApprovalSettlesAndStillCounts() (gas: 5499783)\n[PASS] test_anyoneDeliversAnApprovalForTheTip() (gas: 6120425)\n[PASS] test_appealByLetterUsesTheOriginalAmountAndPaysTheWall() (gas: 10161472)\n[PASS] test_appealLetterRetriesAnAppealTheOracleNeverAnswered() (gas: 21367538)\n[PASS] test_autoSellFeeOnlyOnASaleAndNeverMoreThanHalfOfIt() (gas: 9741439)\n[PASS] test_deadCabalRefusesLettersButSettles() (gas: 5337473)\n[PASS] test_deliverNeedsAnApprovalInsideTheWindowAndTheMinimum() (gas: 6093719)\n[PASS] test_deployLetterboxRefusesOtherCode() (gas: 5118295)\n[PASS] test_expiredPendingPleaSettlesAfterTwentyMinutes() (gas: 5205437)\n[PASS] test_explorerLetterIsTheSameAsARawLetter() (gas: 13506003)\n[PASS] test_invalidNamesAndFailedRenamesPreserveTheOldReservation() (gas: 1334827)\n[PASS] test_leaderboardListsTheSeason() (gas: 6189908)\n[PASS] test_letterCommandsParse() (gas: 8814928)\n[PASS] test_letterPleadsTenPercentPaysFeesInPleaAndEscrows() (gas: 5288144)\n[PASS] test_letterRefusesEthTinyBalancesAndBadText() (gas: 1386603)\n[PASS] test_letterboxIsDeployedOnceFromTheCommittedCode() (gas: 469868)\n[PASS] test_noFunctionIdCanStartALetter() (gas: 797227)\n[PASS] test_noVerdictSettlesAtOnceAndTheNextLetterSettlesTheOldOne() (gas: 8640436)\n[PASS] test_settleReturnsEscrowAndTipAfterADenial() (gas: 5559999)\n[PASS] test_siteAutoSellPleadsAnyValidAmount() (gas: 10111071)\n[PASS] test_statusTellsEachState() (gas: 10130730)\n[PASS] test_strangersCannotUseTheCourtEntryPoints() (gas: 210803)\n[PASS] test_theGateRefusesAManualSaleOfAnEscrowedPlea() (gas: 5294773)\n[PASS] test_theSellLetterIsTheWritersOwnSale() (gas: 6014567)\nSuite result: ok. 26 passed; 0 failed; 0 skipped; finished in 462.67ms (60.56ms CPU time)\n\nRan 3 tests for test/GateFailureInvariant.t.sol:GateFailureInvariantTest\n[PASS]\nGateFailureInvariantTest invariants:\n[PASS] invariant_gateHoldsNothing\n[PASS] invariant_onlyVerdictsMoveTheClock\n[PASS] invariant_pendingBookkeepingIsConsistent\n GateFailureInvariantTest invariants (runs: 64, calls: 4096, reverts: 0)\n\n╭--------------------+---------------+-------+---------+----------╮\n| Contract           | Selector      | Calls | Reverts | Discards |\n+=================================================================+\n| GateFailureHandler | advance       | 476   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | answer        | 471   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | appeal        | 456   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | directFailure | 422   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | execute       | 446   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | expire        | 481   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | fail          | 476   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | plead         | 436   | 0       | 0        |\n|--------------------+---------------+-------+---------+----------|\n| GateFailureHandler | strangerFails | 432   | 0       | 0        |\n╰--------------------+---------------+-------+---------+----------╯\n\n[PASS] test_failureAfterDeathDoesNotReviveTheCabal() (gas: 4763262)\n[PASS] test_handlerReachesFailuresVerdictsAndAppeals() (gas: 18556039)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 831.77ms (826.89ms CPU time)\n\nRan 2 tests for test/BonusInvariant.t.sol:BonusInvariantTest\n[PASS]\nBonusInvariantTest invariants:\n[PASS] invariant_bonusIsHeldPaidOrBurned\n[PASS] invariant_flushedSeasonsStayFinished\n[PASS] invariant_openBonusSeasonsStayFunded\n[PASS] invariant_supplyFallsOnlyByTheBurnedBonus\n BonusInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭--------------+----------+-------+---------+----------╮\n| Contract     | Selector | Calls | Reverts | Discards |\n+======================================================+\n| BonusHandler | advance  | 1137  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | approve  | 1201  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | close    | 1160  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | die      | 1157  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | donate   | 1159  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | flush    | 1168  | 0       | 0        |\n|--------------+----------+-------+---------+----------|\n| BonusHandler | pull     | 1210  | 0       | 0        |\n╰--------------+----------+-------+---------+----------╯\n\n[PASS] test_handlerReachesPaidClosesDeathAndFlush() (gas: 2139975)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 1.22s (1.22s CPU time)\n\nRan 1 test for test/DistributorAdversarial.t.sol:DistributionInvariantTest\n[PASS]\nDistributionInvariantTest invariants:\n[PASS] invariant_deathAndSystemWiringArePermanent\n[PASS] invariant_distributorPaysEachCommittedLeafAtMostOnce\n[PASS] invariant_supplyEqualsAllBalancesAndOnlyBurnsReduceIt\n DistributionInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭---------------------+----------------------------+-------+---------+----------╮\n| Contract            | Selector                   | Calls | Reverts | Discards |\n+===============================================================================+\n| DistributionHandler | advance                    | 1006  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | allowSender                | 969   | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | approveAndSpend            | 1019  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | burnTokens                 | 1014  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | claimAllocation            | 1030  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | donate                     | 998   | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | transferTokens             | 1099  | 0       | 0        |\n|---------------------+----------------------------+-------+---------+----------|\n| DistributionHandler | unauthorizedAdministration | 1057  | 0       | 0        |\n╰---------------------+----------------------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.73s (1.72s CPU time)\n\nRan 2 tests for test/LetterboxInvariant.t.sol:LetterboxInvariantTest\n[PASS]\nLetterboxInvariantTest invariants:\n[PASS] invariant_escrowsMatchTheirPleas\n[PASS] invariant_everyWritersPleaIsAccountedFor\n[PASS] invariant_holdsExactlyTheOpenEscrowsAndTips\n[PASS] invariant_noStepBrokeAnExpectation\n LetterboxInvariantTest invariants (runs: 64, calls: 5120, reverts: 0)\n\n╭------------------+----------+-------+---------+----------╮\n| Contract         | Selector | Calls | Reverts | Discards |\n+==========================================================+\n| LetterboxHandler | advance  | 523   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | answer   | 591   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | appeal   | 585   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | deliver  | 564   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | fail     | 542   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | poke     | 581   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | sell     | 548   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | settle   | 596   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | write    | 590   | 0       | 0        |\n╰------------------+----------+-------+---------+----------╯\n\n[PASS] test_handlerReachesEveryPath() (gas: 26083685)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.12s (2.12s CPU time)\n\nRan 2 tests for test/LetterboxInvariant.t.sol:LetterboxMainnetInvariantTest\n[PASS]\nLetterboxMainnetInvariantTest invariants:\n[PASS] invariant_escrowsMatchTheirPleas\n[PASS] invariant_everyWritersPleaIsAccountedFor\n[PASS] invariant_holdsExactlyTheOpenEscrowsAndTips\n[PASS] invariant_noStepBrokeAnExpectation\n LetterboxMainnetInvariantTest invariants (runs: 64, calls: 5120, reverts: 0)\n\n╭------------------+----------+-------+---------+----------╮\n| Contract         | Selector | Calls | Reverts | Discards |\n+==========================================================+\n| LetterboxHandler | advance  | 523   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | answer   | 591   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | appeal   | 585   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | deliver  | 564   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | fail     | 542   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | poke     | 581   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | sell     | 548   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | settle   | 596   | 0       | 0        |\n|------------------+----------+-------+---------+----------|\n| LetterboxHandler | write    | 590   | 0       | 0        |\n╰------------------+----------+-------+---------+----------╯\n\n[PASS] test_handlerReachesEveryPath() (gas: 25988665)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.17s (2.16s CPU time)\n\nRan 3 tests for test/TradingInvariant.t.sol:TradingPleaZeroInvariantTest\n[PASS]\nTradingPleaZeroInvariantTest invariants:\n[PASS] invariant_allPleaIsAccountedForAndSupplyOnlyFallsByActualBurns\n[PASS] invariant_quoteConservationAndFeePaymentsMatchTheirCounters\n[PASS] invariant_stackerHoldsNoStandingAllowanceOnTheHooksImd\n[PASS] invariant_wallReservesClaimsAndGateStateRemainBacked\n TradingPleaZeroInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| TradingHandler | advance       | 752   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | buy           | 768   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | donateQuote   | 784   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | execute       | 710   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | freeSell      | 730   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | fundWall      | 746   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | pauseCashback | 783   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | rebalance     | 690   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | redeemClaims  | 797   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | submit        | 715   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | verdict       | 717   | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\n[PASS] testFuzz_handlerAccountsForClaimFeesAndTheirRedemption(bool) (runs: 32, μ: 2944350, ~: 2954300)\n[PASS] test_handlerExercisesTradingVerdictsRebalancesAndDeath() (gas: 9192212)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.24s (3.29s CPU time)\n\nRan 3 tests for test/TradingInvariant.t.sol:TradingInvariantTest\n[PASS]\nTradingInvariantTest invariants:\n[PASS] invariant_allPleaIsAccountedForAndSupplyOnlyFallsByActualBurns\n[PASS] invariant_quoteConservationAndFeePaymentsMatchTheirCounters\n[PASS] invariant_stackerHoldsNoStandingAllowanceOnTheHooksImd\n[PASS] invariant_wallReservesClaimsAndGateStateRemainBacked\n TradingInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭----------------+---------------+-------+---------+----------╮\n| Contract       | Selector      | Calls | Reverts | Discards |\n+=============================================================+\n| TradingHandler | advance       | 752   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | buy           | 768   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | donateQuote   | 784   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | execute       | 710   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | freeSell      | 730   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | fundWall      | 746   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | pauseCashback | 783   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | rebalance     | 690   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | redeemClaims  | 797   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | submit        | 715   | 0       | 0        |\n|----------------+---------------+-------+---------+----------|\n| TradingHandler | verdict       | 717   | 0       | 0        |\n╰----------------+---------------+-------+---------+----------╯\n\n[PASS] testFuzz_handlerAccountsForClaimFeesAndTheirRedemption(bool) (runs: 32, μ: 2945166, ~: 2955116)\n[PASS] test_handlerExercisesTradingVerdictsRebalancesAndDeath() (gas: 9187402)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.42s (3.47s CPU time)\n\nRan 12 tests for test/AuditRevision.t.sol:AuditRevisionPleaZeroTest\n[PASS] testFuzz_cumulativeCapDecayStaysWithinElapsedBudget(uint256) (runs: 32, μ: 4116861, ~: 4119927)\n[PASS] test_appealRetryClearsTimedOutPendingAppeal() (gas: 11953463)\n[PASS] test_deadCabalBuyStillRequiresARecipient() (gas: 1640577)\n[PASS] test_dustBuyDoesNotGiveUntrackedTokensLossOrHoldingPoints() (gas: 1045182)\n[PASS] test_expiredAppealCanBeRetriedWithoutLiftingDenialCooldown() (gas: 12104572)\n[PASS] test_lapsedApprovalCannotBypassCooldown() (gas: 8575235)\n[PASS] test_largeBuyClaimsAreRedeemableAndNextBuyStacksNormally() (gas: 2170500)\n[PASS] test_lateCloseDoesNotPayFutureSeasonFees() (gas: 13461303)\n[PASS] test_sameSecondCapRatchetsCannotReuseFractionalBudget() (gas: 1050970)\n[PASS] test_seasonClaimsArePaidAsImdAtClose() (gas: 10095880)\n[PASS] test_secondLargeBuyPreservesEveryPayee() (gas: 1238646)\n[PASS] test_unansweredAppealDoesNotExtendTheOriginalWindow() (gas: 8790581)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 3.47s (183.13ms CPU time)\n\nRan 3 tests for test/SeasonInvariant.t.sol:SeasonInvariantTest\n[PASS]\nSeasonInvariantTest invariants:\n[PASS] invariant_prizeMoneyIsPaidOnceOrRemainsInThePotOrWall\n[PASS] invariant_rankingsMatchAllRecordedApprovalsAndClosedSeasonsNeverChange\n SeasonInvariantTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭---------------+-------------------------+-------+---------+----------╮\n| Contract      | Selector                | Calls | Reverts | Discards |\n+======================================================================+\n| SeasonHandler | advance                 | 832   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | approvePlea             | 795   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | checkpoint              | 787   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | closeOldest             | 851   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | donate                  | 811   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | donateClaims            | 758   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | donateWithoutCheckpoint | 833   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | endCabal                | 861   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | flush                   | 829   | 0       | 0        |\n|---------------+-------------------------+-------+---------+----------|\n| SeasonHandler | record                  | 835   | 0       | 0        |\n╰---------------+-------------------------+-------+---------+----------╯\n\n[PASS] test_modelCoversDelayedDonationsAndPostFlushClaims() (gas: 3620081)\n[PASS] test_modelCoversPayableClosesRolloverAndFinalFlush() (gas: 4323657)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 8.15s (8.15s CPU time)\n\nRan 19 tests for test/Hook.t.sol:HookTest\n[PASS] test_aBuyMustAffordTheCredit() (gas: 1246451)\n[PASS] test_aSellAboveTheCapIsTrimmedAndBurned() (gas: 1695087)\n[PASS] test_avgBuyTimeIsBuyWeighted() (gas: 1104668)\n[PASS] test_capDecayIsSetSoTheFloorIsReachableIn25Days() (gas: 18018)\n[PASS] test_capFollowsBuysAtMostOneDayOfDecayPerDay() (gas: 1683977)\n[PASS] test_everyFeeIsPaidInTheSameSwap() (gas: 1293164)\n[PASS] test_factScoreUsesCheckpointsNotSpot() (gas: 1658273)\n[PASS] test_firstBuyWithAnEmptyPoolSendsPayoutsToLiquidity() (gas: 571056)\n[PASS] test_freeTradingWhenTheCabalSleeps() (gas: 1102038)\n[PASS] test_hourlyCheckpointIsNotSetByTheTradeThatOpensTheHour() (gas: 1929006)\n[PASS] test_plainImdOnlyWhenTheCreditReverts() (gas: 1199509)\n[PASS] test_rebalanceRedeemsClaimsIntoTheWall() (gas: 4561799)\n[PASS] test_sellsAndExactOutputOnlyThroughTheGateWhileAlive() (gas: 746273)\n[PASS] test_stackerIsApprovedOnlyForTheCashbackBeingCredited() (gas: 1817188)\n[PASS] test_wallGuardDropsAtOnceAndRisesFourPercentADay() (gas: 34287316)\n[PASS] test_wallGuardIgnoresASellerChosenLimitReachedThroughAnEmptyPool() (gas: 2792695)\n[PASS] test_wallGuardIgnoresTheEmptyPoolsPriceLimit() (gas: 2767396)\n[PASS] test_wallGuardLagsAPumpAndCapsTheWall() (gas: 16714927)\n[PASS] test_wallGuardStillDropsAtOnceToASellerChosenLimitInsideTheBand() (gas: 33175585)\nSuite result: ok. 19 passed; 0 failed; 0 skipped; finished in 8.31s (107.29ms CPU time)\n\nRan 5 tests for test/GasPass.t.sol:GasPassTest\n[PASS] testFuzz_bodyEqualsEscapingTheWholeQuestion(uint256) (runs: 500, μ: 5565611, ~: 5558922)\n[PASS] testFuzz_textCheckMatchesTheOldRules(uint256) (runs: 5000, μ: 925266, ~: 84118)\n[PASS] test_bodyEqualsEscapingTheWholeQuestion() (gas: 12832581)\n[PASS] test_priceViewsMatchAFullScan() (gas: 128930691)\n[PASS] test_textCheckEdgeCases() (gas: 53620436)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 8.34s (8.88s CPU time)\n\nRan 18 tests for test/LetterboxEdges.t.sol:LetterboxEdgesTest\n[PASS] testFuzz_aFinishedEscrowNeverReopens(uint8) (runs: 32, μ: 5886335, ~: 6093893)\n[PASS] testFuzz_feeSwapStaysUnderTheCapAndRefundsTheRest(uint256) (runs: 32, μ: 9176295, ~: 9170030)\n[PASS] test_aFailedRequestSettlesBeforeTheTwentyMinutes() (gas: 8549593)\n[PASS] test_aLapsedLetterStartsTheCooldownFromItsVerdict() (gas: 9292431)\n[PASS] test_appealFeesAboveTenPercentOfTheBalanceAreRefused() (gas: 11958329)\n[PASS] test_appealLetterAppealsAHandPleaAndEscrowsOnlyTheAppeal() (gas: 9073446)\n[PASS] test_appealLetterRefusesAnExecutedPleaAndAClosedWindow() (gas: 10535841)\n[PASS] test_approvedEscrowAtTheWindowsLastSecondSellsAndCannotSettle() (gas: 6106613)\n[PASS] test_approvedEscrowOneSecondAfterTheWindowSettlesAndStillCounts() (gas: 5767705)\n[PASS] test_autoSellFeeIsCheckpointedIntoTheRunningSeason() (gas: 9519459)\n[PASS] test_deadCabalStillSettlesAndNames() (gas: 5739587)\n[PASS] test_pendingEscrowSettlesOnlyOnceStale() (gas: 5610174)\n[PASS] test_pleaFlagsAreEmittedAndReadable() (gas: 8081463)\n[PASS] test_setLetterboxLifecycleOnAFreshPlea() (gas: 434053)\n[PASS] test_shareBandsAt20And35Percent() (gas: 252187)\n[PASS] test_siteAmountLimitsAtTheirBoundaries() (gas: 14047484)\n[PASS] test_theGateRefusesBadFlagsAndUnflaggedSalesEvenFromTheLetterbox() (gas: 9393385)\n[PASS] test_theLiveLetterboxCannotBeReplaced() (gas: 83403)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 8.34s (125.13ms CPU time)\n\nRan 47 test suites in 8.34s (56.39s CPU time): 407 tests passed, 0 failed, 2 skipped (409 total tests)\n","passed":true},{"durationMs":126,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"CabalGate.appeal(uint256,uint256,string)\",\"CabalGate.appealFor(address,uint256,uint256,uint256,string,uint8,uint256,uint256)\",\"CabalGate.begin()\",\"CabalGate.executeSell(uint256)\",\"CabalGate.executeSellFor(uint256,uint256)\",\"CabalGate.expire(uint256)\",\"CabalGate.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"CabalGate.onPleaFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"CabalGate.submitFor(address,uint256,uint256,string,uint8,uint256,uint256)\",\"CabalGate.submitSell(uint256,string)\",\"CabalGate.unlockCallback(bytes)\",\"Letterbox.appealAuto(uint256,string)\",\"Letterbox.deliver(uint256)\",\"Letterbox.fallback()\",\"Letterbox.letter(string)\",\"Letterbox.plead(uint256,string)\",\"Letterbox.setName(string)\",\"Letterbox.settle(uint256)\",\"PLEA.allow(address)\",\"PLEA.approve(address,uint256)\",\"PLEA.burn(uint256)\",\"PLEA.courtTake(address,uint256)\",\"PLEA.init(address,address)\",\"PLEA.renounceOwnership()\",\"PLEA.setLauncher(address,address,address)\",\"PLEA.setLetterbox(address)\",\"PLEA.transfer(address,uint256)\",\"PLEA.transferFrom(address,address,uint256)\",\"PLEA.transferOwnership(address)\",\"PleaDistributor.claim(uint256,address,uint256,bytes32[])\",\"PleaDistributor.renounceOwnership()\",\"PleaDistributor.setMerkleRoot(bytes32)\",\"PleaDistributor.transferOwnership(address)\",\"PleaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"PleaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"PleaHook.fundWall(uint256)\",\"PleaHook.rebalance()\",\"PleaHook.seed()\",\"PleaHook.unlockCallback(bytes)\",\"PleaLaunch.deployHook(bytes32,bytes)\",\"PleaLaunch.deployLetterbox(bytes)\",\"PleaLaunch.seed()\",\"Seasons.checkpoint()\",\"Seasons.closeSeason(uint256[])\",\"Seasons.flushToWall()\",\"Seasons.record(uint256)\",\"Seasons.unlockCallback(bytes)\"],\"files\":{\".gitignore\":4,\"ADAPTATION.md\":39,\"README.md\":267,\"foundry.toml\":25,\"launch.json\":56,\"remappings.txt\":4,\"script/Deploy.s.sol\":55,\"script/DeployLetterbox.s.sol\":22,\"script/MineSalt.s.sol\":44,\"src/CabalGate.sol\":816,\"src/Letterbox.sol\":646,\"src/OracleAttestation.sol\":227,\"src/PLEA.sol\":148,\"src/PleaDistributor.sol\":49,\"src/PleaHook.sol\":1018,\"src/PleaLaunch.sol\":152,\"src/Seasons.sol\":357,\"src/interfaces/IPleaParts.sol\":74,\"src/interfaces/IStacker.sol\":10,\"test/AuditImported.t.sol\":142,\"test/AuditOwnerTip.t.sol\":28,\"test/AuditRevision.t.sol\":270,\"test/AuditRun3.t.sol\":391,\"test/BonusInvariant.t.sol\":526,\"test/DistributorAdversarial.t.sol\":329,\"test/GasPass.t.sol\":329,\"test/Gate.t.sol\":408,\"test/GateAdversarial.t.sol\":400,\"test/GateFailureInvariant.t.sol\":330,\"test/Hook.t.sol\":357,\"test/HookAdversarial.t.sol\":272,\"test/HookRevision.t.sol\":378,\"test/Launch.t.sol\":156,\"test/LaunchManifest.t.sol\":317,\"test/Letterbox.t.sol\":754,\"test/LetterboxEdges.t.sol\":579,\"test/LetterboxInvariant.t.sol\":441,\"test/OracleConformance.t.sol\":114,\"test/OracleReplay.t.sol\":60,\"test/Orientation.t.sol\":58,\"test/SeasonAdversarial.t.sol\":203,\"test/SeasonFunds.t.sol\":343,\"test/SeasonInvariant.t.sol\":341,\"test/SeasonRanking.t.sol\":168,\"test/Seasons.t.sol\":266,\"test/Token.t.sol\":78,\"test/TradingInvariant.t.sol\":476,\"test/fork/ForkMainnet.t.sol\":368,\"test/fork/ForkTestnet.t.sol\":765,\"test/utils/ClaimTree.sol\":41,\"test/utils/Fixture.sol\":238,\"test/utils/Mocks.sol\":266,\"test/utils/SeasonModel.sol\":117,\"test/utils/SepoliaFixture.sol\":34},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"6771b8b1f82bda67c03276292ff3af2efb3fda4a629d57aff7252eb58ea4fcdc","verifiedTreeHash":"7644591c4e38f2941051a981464233eb6dd18ac0","verifierVersion":"0.1.0+fb8278c5"}]}