{"assessments":[],"deployments":[{"attestationHash":"37770cc6eac611ace39ed9fd96522d0259f6d6058b2411962024c76b67a75e41","chainId":1,"contracts":[],"id":"484c3cf7-7409-4a7c-97ea-a0ed5a955118","manifestHash":"c2bbe09031228f6d5f0a00725fc60ff25995de4def61fb80de41599497e78a80","status":"parked"}],"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":"0925298b-5eb6-4da2-ad34-b0e5aa2d1fdc","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"04326df014fca469a56cb4a6af328324facebfa0f60048516de38be784c8f002","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":"843678b83af230488bdd29ee49bc8f2f39b86e187f8cb065d28cc9f1d2c9851f","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":"468921f675edd0e443c8d6a8682df00e868eff75741d380c02eb820256ce7dad","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":"d14e760cc3202a1df8c90820200461b20c944d69cd41244f365baae51ede7661","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":"bce3763f23ee41e5bbc457447ba95a44833d7cde885fcd11b19671ab106c0b69","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":"e2672db8113049dd167de58201a11d103c85ade6700604027b6220ee55dc37e8","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":"7b87a4878945fb8fb9a05401d5e97798f46263acc0c4b1259f745c1e18629cdb","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":"36b15b4a7454fab599e03e51b5323222192b9f22870abd4ffe132b7dfaa52957","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"bd6dffedc1ff15aed661964235ed3f43d241bc191b02d88547e722540cd8c46c","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":"Deploy MarginaliaPages (src/MarginaliaPages.sol) on Ethereum mainnet: ONE contract, constructor (address hook, address intake, bytes32 action, address signer) = (0xf0457dd0cf526686190e4f057ba19db14d34a0cc the live MarginaliaHook of launch 1283, 0x1397434cd35e8a9C8aC312A61D3A285EB31dea56 the IdentityMD Intake, bytes32('oracle.request@oracle-1') the oracle action, 0x5598Aa9146215Bc13eb26f2c692Ad1461Fd32982 the IdentityMD oracle signer) — the same three oracle constants the live hook holds as INTAKE, ACTION and ORACLE_SIGNER and passes to its judge. What it is: the page market of Marginalia, notes in the margin of every trade. A page of an author's marginalia is the seat in that writer's room: the site delivers the author's sealed notes and reasoning to page holders first. Pages are bought and sold against a linear bonding curve priced in IMD 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7 (the n-th page costs BASE 0.1 IMD x n), with NO cap on supply (access is always open at the price demand sets), and are never transferable (buy and sell on the curve only; the curve reserve always covers every holder selling out at any depth). Every trade pays FEE_BPS = 10% of its value: ISSUER_BPS 90% of the fee to the issuer in IMD, BURN_BPS 5% of the fee buys MARG on the launch pool through the hook's PoolManager (a quiet buy, no hook fee) and sends it to 0x000000000000000000000000000000000000dEaD, the remaining 5% of the fee goes to the hook's pools through hook.fundPot (70% thesis prize / 30% writer refund). An issuer is any address (subjectOf(address) pays itself) or an X handle nobody has claimed (subjectOfHandle(string), lower-cased and validated on chain: 1-15 of a-z 0-9 underscore): pages of a handle trade on the same curve while the issuer's 90% waits in escrow. CLAIMS ARE ORACLE-ATTESTED, there is no attester of ours: the handle's owner posts a tweet naming their wallet; anyone calls requestClaim(handle, tweetId), paying the Intake's current price for action oracle.request@oracle-1 (refused above MAX_PRICE 1 IMD); the contract builds the question itself (questionBody: fetch X's public embed JSON https://cdn.syndication.twimg.com/tweet-result?id=<tweetId>&token=a, if user.screen_name is the handle answer the single address in text, else zero; answerType address, evidence panel, head 1, panelSize 5, quorum 4, guards.sources the syndication prefix, consumer = this contract) and buys one answer through the Intake with callback onOracleResult. The callback accepts only the Intake, verifies the EIP-712 attestation against the signer (OracleAttestationConsumer, domain IdentityMD Oracle v2), requires chainId == block.chainid, agreed >= quorum >= 4 and panelSize >= 5, consumes the request id once, and: a real address becomes the payee, takes the escrow less the oracle price reimbursed to whoever asked (if the escrow covers it), and is paid directly from then on; the zero address is a failed claim, retriable at once, costing only the asker. One request in flight per subject; an unanswered one may be abandoned by anyone after ANSWER_DEADLINE 3 days (a late delivery is then refused). One successful claim per subject ever. Escrow unclaimed CLAIM_WINDOW = 90 days after the first buy is recycled into the hook's pools by anyone, never while a claim is pending. No owner, no pause, no upgrade, no attester, nonReentrant trades, claims and callback, unlockCallback accepts only the PoolManager. The constructor reads no chain state (the launcher rehearses constructors in an empty EVM); it stores the four values. Deploy from this repository as it is; adapt only what deployment strictly requires; keep every number. Tests: forge test --match-path test/Pages.t.sol (12 tests against the local hook, a local Intake mock and an EOA signer, incl. the 200k callback stipend and replay/tamper refusals).","parentJobId":null,"planHash":"702454c71a6638164bf3cd36a251a9fcd6d124a45d8c0fe60381f93abbf05a32","previousHash":"6232c58b5023b10d8a810cbb3261f3aec6353a873e510910f4e5d57f56521300","projectId":"0925298b-5eb6-4da2-ad34-b0e5aa2d1fdc","publication":{"commit":"8f2266649eb6c6a28cb2964b14e65d2fa990fc46","deliveredAt":"2026-10-12T11:43:41.108Z","repoUrl":"https://github.com/identity-md-launches/launch-1365-src-marginaliapages-sol"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51465","feedbackHash":"01486e531221b1154638eb1c59b12f530ce43d08a4614ee3cc2ac3279349c2df","nodeKey":"adapt_contract_project","submissionHash":"04326df014fca469a56cb4a6af328324facebfa0f60048516de38be784c8f002","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52585","feedbackHash":"aef6e3aca5a948c2dfb20ef687fb5d567fd46eb017dfcdc867a5fcd4883be184","nodeKey":"audit_judge","submissionHash":"44f99be3f5156507d8f991f3f3fc5a5c1e6b7860ec499caddb53907422de653c","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51064","feedbackHash":"abaae37a2959f1ac345e9aa8c5110627e1a5d77f1718d1abdfe2761c4251be2d","nodeKey":"audit_judge","submissionHash":"bce3763f23ee41e5bbc457447ba95a44833d7cde885fcd11b19671ab106c0b69","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50903","feedbackHash":"149a79669d4b8d924e82e546391752f68c4cb6e7845b84a164ba09944c67cea4","nodeKey":"manifest","submissionHash":"36b15b4a7454fab599e03e51b5323222192b9f22870abd4ffe132b7dfaa52957","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"50969","feedbackHash":"f6b0c37c837abb0aa1346159517f9b6cb4fa4e012f3b17c40f5485720f275e4d","nodeKey":"manifest","submissionHash":"fda023596c5c4ad236f573c12eb5efc94741462063bcd87642925f816793e48c","tag1":"verification:checks","tag2":"acceptance-v2","value":0},{"agentId":"52549","feedbackHash":"f7430724e48024addca7fb06f5091e755189848a1bb97b4997425a685ceffde6","nodeKey":"manifest","submissionHash":"698d174ced06600cb34cd11944687725892f9502abd9902f8bd7657946d237f8","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51285","feedbackHash":"4639ed2858a073d3cdce10eab4c8e40f70b1b925cfdf579419ffd4f545eed30d","nodeKey":"write_foundry_tests","submissionHash":"7c895bda997d2480b17a6eed398b680af9f8175cb4ddc0358c6c2e37d86729b5","tag1":"verification:checks","tag2":"acceptance-v2","value":0},{"agentId":"51146","feedbackHash":"9b71c9ed296160b2a6a5c76f244c6eed1d3e35d5f8fba914072ea0000d4f8c8e","nodeKey":"write_foundry_tests","submissionHash":"0060f368f79ad3c2c44b7762ed2d5f8a41939d0397c390a006da4df75f1fbe62","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52252","feedbackHash":"11df6ad10acceda324081441e3287c669298ba7e55c067511a1fc730b885bb48","nodeKey":"write_foundry_tests","submissionHash":"bd6dffedc1ff15aed661964235ed3f43d241bc191b02d88547e722540cd8c46c","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"37e45643d855fdc3a16289fd69303089f7f6aeea98bfb76d424d52fccf04b057","state":"completed","submissions":[{"artifacts":[],"attempt":2,"bundleHash":"b1c3e87b2a83234d924d9933efdb7589ca23931ceeeaca4e8c22661849fd1c1b","device":"824e6de6196c686f","findings":[{"description":"_distributeFee restarts Subject.escrowSince whenever a share lands at or after escrowSince + CLAIM_WINDOW (the revision for review item 0680ae89). The restart covers the entire accumulated escrow, not only the new share. The brief says escrow unclaimed 90 days after the first buy is recycled by anyone; here a stranger who buys one page at any moment from the window's end onward (including in the same block as, and ahead of, a recycle transaction, since recycle allows block.timestamp >= escrowSince + CLAIM_WINDOW and the buy restarts at the same timestamp) pushes the whole escrow another 90 days out, and can repeat this every window. The cost is two trade fees on one page at the current supply (0.02 IMD at supply 1, 2.02 IMD at supply 100), and 90% of those fees land in the very escrow being deferred. The deferred escrow stays claimable by the handle's owner, so the loss is to the hook's pools (the 70/30 thesis prize and writer refund), not to any holder; the market's balance accounting is unaffected (the invariant suite holds across the restart). If this is the intended trade-off, it should be stated in the README beside the 90-day rule; otherwise restarting only when the previous escrow has been recycled (escrowSince == 0), or keeping separate clocks per window, would honour the brief's wording.","line":273,"path":"src/MarginaliaPages.sol","reproduction":"Deploy MarginaliaPages against the local fixture. alice buys 100 pages of subjectOfHandle(\"silent\") at t0 (escrow 45.45 IMD, escrowSince = t0). Warp to t0 + 90 days. Expected per the brief: recycle(subject) succeeds and 45.45 IMD goes to hook.fundPot. Actual: bob (any address) first buys 1 page (gross 11.11 IMD, of which 10.1 comes back on an immediate sell), escrowSince becomes t0 + 90 days, recycle(subject) reverts TooEarly; repeating the buy at t0 + 180, 270, 360 days keeps recycle reverting TooEarly at every point, including t0 + 360 days + 1 day. Scratch test test/scratch/WindowGrief.t.sol (not submitted) demonstrates four consecutive deferrals.","severity":"low","title":"A one-page buy on or after the window's end restarts the whole escrow's clock, so recycling can be deferred indefinitely by anyone"}],"hash":"0060f368f79ad3c2c44b7762ed2d5f8a41939d0397c390a006da4df75f1fbe62","nodeId":"8734f817-b327-4ca9-819c-8aa0a32ccfdd","outcome":"completed","summary":"Done. The tree holds only my two test files as changes, plus the requested findings file at the root, which the harness excludes from git on its own.\n\n**What was wrong with the last attempt:** the rejection was a tree mismatch, not a test fault. The other contributor's revision of `src/MarginaliaPages.sol` had landed under my accepted tests, and my two files no longer compiled against it. Four behaviours had changed: `burnPending` takes one argument and fills partially under a per-block sqrt-price bound, the oracle callback now only stores a payout that a separate `settleClaim` pays, an escrow share landing after the 90-day window restarts the clock, and the market and hook are refused as subjects.\n\n**What I changed, in the two files I own:**\n\n- `test/PagesInvariant.t.sol`: the handler now drives the bounded burn (asserting partial fills stop exactly at the block's limit, spent IMD reaches the pool, MARG reaches the dead address, and refusals are named: `InsufficientBurn`, `BurnBudgetSpent`, `NothingBurned`), a new `settle` action with ghosts for the stored payout, the window-restart rule in the escrow ghost, and a new invariant that the pool price never passes the block's bound and that the limit is exactly the anchor moved by BURN_SQRT_BPS. The pool is re-seeded at the live pool's depth so the bound is actually hit. A deterministic 3,000-step drive in scratch showed 24 partial fills, 22 budget refusals, settlements, abandons and recycles, so the paths are reached, not just declared.\n- `test/PagesEdges.t.sol`: the claim tests settle before checking balances and assert nothing is paid inside the 200k callback; six new tests cover an owner who asked collecting both halves, a claimed-but-unsettled handle being closed to every other path with its escrow frozen, the window boundary one second before and exactly at 90 days, the anchor and limit arithmetic, an external trade past the bound refusing burns by name until the next block, and zero or over-queue burn amounts.\n\n**Results:** `forge build` passes. The full `forge test` is 315 passed, 0 failed, 2 skipped (the optional fork suites without an RPC). The invariant suite ran clean under four different seeds with fail-on-revert, 4,608 calls and zero reverts each.\n\n**One finding reported, low severity,** in `.imd-findings.json`: because a share landing on or after the window's end restarts the clock for the whole escrow, anyone can defer recycling indefinitely by buying one page every 90 days (two trade fees at the current supply, most of which lands in the deferred escrow itself). This is the trade-off the prior review asked for, so I reported it with a reproduction rather than asserting it as correct. One non-defect worth knowing: when a pool's price reaches the edge of all seeded liquidity, the hook's afterSwap refuses the burn with `PartialFill` and the queue is untouched, which the existing audit test already covers.","treeHash":"2bc42560dfa819baf5f4f16892b6eafa7c14749a","usage":{"cachedInputTokens":5399523,"inputTokens":1060,"model":"claude-fable-5-1","outputTokens":59348,"runtime":"claude","turns":50,"wallClockMs":2960853}},{"artifacts":[],"attempt":1,"bundleHash":"1dbb637865d0169170cb43fc212937ac7b197dfbc3650d36760a0bd7d4cda27d","device":"f0c4ae5b8ada215c","findings":[],"hash":"04326df014fca469a56cb4a6af328324facebfa0f60048516de38be784c8f002","nodeId":"0ae19a5b-0de8-4d38-a624-f0912d65a276","outcome":"completed","summary":"The responses file is written in the repository root as required. It is excluded from git by the harness's own `.git/info/exclude` entry, not by anything I changed, so the pipeline collects it from the working tree. Both findings are answered and the work is complete.\n\n## Recap\n\n**Finding 19412c9f (medium, burn / sell / burn sandwich): reproduced and fixed.**\nI rebuilt the reviewer's loop in scratch and got their exact figures on the accepted tree: one transaction drained the whole 601 IMD burn budget in 17 to 20 tranches, netting +37.44 / +66.43 / +96.61 / +127.94 IMD at pushes of 700 / 1000 / 1400 / 2000 IMD. The cause was that the bound compared only the current price against the block's limit, so selling MARG back between tranches re-opened it.\n\nThe fix in `src/MarginaliaPages.sol` is that a block burns once: the unlock callback reverts with `BurnBudgetSpent` when the anchor block is already the current block, before reading any price. The single tranche is still bounded at the unchanged 0.5% sqrt-price move from the price it finds, so the bound now caps the block's volume as well as its level. No number changed.\n\nRegressions in `test/PagesRevision.t.sol` run the reviewer's loop at all four sizes and assert exactly one tranche, the named refusal, more than 90% of the budget left pending, and a loss for the attacker. Measured: −30.71 / −43.59 / −60.57 / −85.65 IMD. A second test shows the refusal holds after a sale brings the price back under the limit and that the next block burns again. The existing across-blocks test still burns the full budget and 540.077 MARG.\n\nI also reworded the README and NatSpec so they claim only what the bound delivers. One residual that the reviewer did not raise is now stated openly: the only on-chain reference is the pool's spot, so someone who pushes the price and also supplies the tranche's MARG as liquidity at that price can capture at most the slippage their own push paid, bounded by the roughly 30 IMD one block's tranche is at the live depth.\n\n**Finding 681b03fb (info, window restart carries older escrow): reproduced, resolved by documentation.**\nThe behaviour is as described. It is the deliberate trade-off of one clock per subject chosen last round over the recycle race, and the finding itself offers stating it as the resolution. The README now says the restart carries the whole escrow, that trading at or after day 90 can defer recycling indefinitely, and why that is accepted. Code is unchanged.\n\n**Verification.** `forge build` passes with warnings only. `forge test` passes 288 tests with 0 failures; the 2 skips are the mainnet fork suites, which skip without an RPC URL. `ADAPTATION.md` has a new section for this round and `.imd-responses.json` answers both ids. Nothing was committed, and no build configuration or dependency was touched.","treeHash":"c398d0a2d18d882b24e8cab868f07cf7038861e6","usage":{"cachedInputTokens":2588062,"inputTokens":706,"model":"claude-fable-5-1","outputTokens":43492,"runtime":"claude","turns":32,"wallClockMs":1152634}},{"artifacts":[],"attempt":1,"bundleHash":"e4d2f76f426151dcdb081c6e817aac6a293a408d208b905c6c31fe47ab897129","device":"0630d73f571c3dd5","findings":[],"hash":"0cb45f1d4f5b9bca7dad7ec157ee4fdd8d7929cb4a3cf36cad0279db5fe74c13","nodeId":"0ae19a5b-0de8-4d38-a624-f0912d65a276","outcome":"completed","summary":"Prepared the single-contract Pages launch. Claims now require a deployment-specific tweet; burns are queued with caller-supplied output floors; supply no longer truncates.\n\nChecks passed: `forge build`, 278 tests, the protected deployment check, and both Pages mainnet-fork tests. No mainnet transaction was broadcast.\n\nChanges, limitations, and deployment arguments are recorded in [ADAPTATION.md](/home/ubuntu/.identitymd/work/0925298b-5eb6-4da2-ad34-b0e5aa2d1fdc/0ae19a5b-0de8-4d38-a624-f0912d65a276/ADAPTATION.md).","treeHash":"5e1f46bf23e70cdb5dd088999e3dddfb5f893dd2","usage":{"cachedInputTokens":6430848,"inputTokens":169741,"model":"gpt-6-astra","outputTokens":46352,"runtime":"codex","turns":14,"wallClockMs":1610099}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"11e4593175677f7e","findings":[{"citation":"resolved","description":"Merged from audit_economics (medium), audit_permissions (medium) and audit_math (low): one root cause. burnPending is permissionless and the swap in unlockCallback runs exact-input to the extreme sqrt price limit (line 413: `zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1`) with no on-chain reference price; the only execution-quality check is `marg < minMargOut` (line 421) against a floor the same caller supplies, and a floor of 1 wei is accepted. The caller can therefore be the sandwicher: buy MARG on the launch pool, call burnPending(pendingBurn, 1), sell the MARG back. The burn budget (0.5% of every page trade's value) then pays the attacker's price impact; far less MARG reaches 0xdEaD than the brief's 'BURN_BPS 5% of the fee buys MARG on the launch pool ... and sends it to dEaD' implies, and the difference, net of the attacker's two 1.25% LP fees and the hook's 3% quiet-sell fee, is the attacker's profit. Nobody is paid to burn honestly, so pendingBurn accumulates until the adversarial burn is profitable; the same lever moves MARG's spot price at zero cost to the caller. The README discloses that the floor is caller-chosen, but the guarantee the brief states is not enforced on chain and the party who breaks it is unprivileged and profits. No reserve, escrow or holder funds are at risk (the IMD still enters the pool), which is why this is medium, not high. Fix that keeps every number: derive the floor on chain from the hook's observation/TWAP price (not the manipulable spot) with a bounded tolerance, and/or cap a tranche relative to the pool's in-range liquidity, and/or pass a sqrtPriceLimitX96 bounded around that reference instead of the extreme tick.","line":396,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/Repro.t.sol testBurnSandwich on the local fixture (test/helpers/Fixture.sol), pool re-seeded with 6,000 ether of liquidity in [-6000, 6000] at 1 MARG = 1 IMD (about 6k IMD depth, the order of the live pool). 1) alice buys 1,550 pages of subjectOf(carol): value 120,202.5 IMD, pendingBurn = 601.0125 IMD. 2) Honest burnPending(601.0125e18, 1) alone sends 540.077 MARG to 0xdEaD. 3) Instead bob, in one transaction: plain-router swap X IMD -> MARG, pages.burnPending(601.0125e18, 1), swap all MARG received back. Measured (bob's net IMD after all LP and hook fees / MARG actually burned): X=400 IMD: +49.65 IMD / 478.08 MARG; X=700: +78.76 / 438.33; X=1000: +102.29 / 403.34; X=1400: +126.62 / 362.86 (21% of the burn budget to bob, 33% less MARG burned). Expected: the burn buys MARG at the market price whoever calls; actual: an unprivileged caller sets the floor to 1 wei and converts part of the burn into profit.","severity":"medium","snippet":"        if (minMargOut == 0) revert Slippage();","title":"burnPending's only output floor is the caller's own minMargOut, so any caller can sandwich the protocol's MARG burn and keep part of the burn budget once pendingBurn is a few percent of pool depth"},{"citation":"resolved","description":"Merged from audit_economics (medium) and audit_permissions (low); recalibrated to low because the letter of the brief ('Escrow unclaimed CLAIM_WINDOW = 90 days after the first buy is recycled') permits it and the loss is bounded to the issuer share and the 0.5 IMD price, so this needs a scope decision rather than a straight fix. escrowSince is set once, at the first fee that lands in escrow (line 235), and cleared only by recycle (line 382). recycle tests that single timestamp against the whole escrow balance, so once 90 days have passed since the first page of a handle was bought, the 90% issuer share of every later trade, including one made seconds earlier, is recyclable by anyone at once, and nothing restarts the window while any escrow is unrecycled. Dust escrow left past day 90 is a standing trap: a recycler waits for a large buy and sweeps its share. Because a claim is preceded by a public tweet and the requestClaim transaction is visible, the recycler wins the race, and the owner's claim then finds owed = 0, so reimbursement is 0 (line 354: `owed >= c.price ? c.price : 0`) and the owner is 0.5 IMD poorer with no escrow. Options that keep every number: restart escrowSince on every escrow deposit, or let recycle take only the part older than CLAIM_WINDOW.","line":379,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/Repro.t.sol testRecycleRace on the local fixture with the ClaimIntake mock from test/Pages.t.sol and an EOA signer. 1) t0: alice buys 1 page of subjectOfHandle('writer'): escrow 0.009 IMD, escrowSince = t0. 2) t0 + 91 days: bob buys 100 pages: escrow becomes 46.359 IMD, escrowSince unchanged (asserted equal). 3) Same block: anyone calls recycle(subject): succeeds, hook pools (refundPool(today) + thesisPool(week)) grow by exactly 46.359 IMD, escrow = 0. 4) carol calls requestClaim('writer', 1) paying 0.5 IMD; the Intake delivers a signed answer naming carol; payeeOf = carol, Claimed(subject, carol, 0, 0). Measured: carol's IMD delta is -0.5 IMD. Expected per the brief's claim rule ('takes the escrow less the oracle price reimbursed to whoever asked'): the 45.45 IMD accrued seconds earlier waits in escrow and pays for the claim; actual: it went to the pools and the owner paid the oracle for an empty escrow.","severity":"low","snippet":"        if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();","title":"After CLAIM_WINDOW from a handle's first escrow, every later issuer accrual is recyclable in the same block, so a recycler can front-run the owner's claim and the owner pays the oracle price for nothi"},{"citation":"resolved","description":"Merged from audit_economics (low) and audit_flow (low), same root cause and both reproduced. The oracle-consumer reference says the callback gets 200,000 gas inside a try, is attempted once and never retried, and advises 'verify and store; act in a later call'. Pages instead verifies the EIP-712 signature, consumes the request, writes payee, deletes three slots and makes two ERC-20 transfers (lines 357-358) in the callback. The live IMD token at 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7 is not the MockERC20 of the unit tests; its transfers cost roughly twice as much. Measured on a mainnet fork with the real hook and real IMD, the worst realistic shape (asker's balance exactly zero after paying the price, answered wallet cold) costs 194,116 gas, so the delivery still succeeds today but with about 3% margin. Anything adding a few thousand gas to the path (the oracle signer gaining code so SignatureChecker also tries ERC-1271 after the ECDSA mismatch, an IMD upgrade, or the Intake's complete being called with a tighter limit under EIP-150) turns a correct answer into one the Intake records as not delivered: the claim stays pending, the asker's 0.5 IMD is spent, escrow cannot be recycled or re-asked for until abandonClaim after 3 days, and the panel's answer is thrown away. Minimal fix that keeps the design: store (payee, owed, reimbursed, claimant) in the callback and pay in a separate permissionless settle call, or move the two transfers behind a pull.","line":357,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/ForkGas.t.sol (mainnet fork via https://ethereum-rpc.publicnode.com, investigation only): deploy MarginaliaPages(hook 0xf0457dD0..., ClaimIntake mock, action, vm.addr(key)); trader buys 20 pages of subjectOfHandle('writer') so escrow = 1.89 IMD; an asker holding exactly 0.5 IMD calls requestClaim('writer', 1) so its balance is 0; the Intake delivers a signed address answer naming a fresh wallet. Measured gas around onOracleResult: 194,116; ClaimIntake.deliver with gas: 200_000 returns true. Local baseline with MockERC20 (test/scratch/Repro.t.sol testCallbackGasLocal, same shape): 192,155. Expected per the reference: a callback that only verifies and stores with comfortable margin; actual: the full payout runs about 5,900 gas below the stipend against the live token.","severity":"low","snippet":"        if (reimbursed > 0) imd.safeTransfer(c.claimant, reimbursed);","title":"onOracleResult performs the whole payout (two live-IMD transfers) inside the Intake's 200,000-gas callback stipend with about 6k gas of headroom; any small cost increase makes every correct answer und"},{"citation":"resolved","description":"From audit_math (low), reproduced. payeeOf returns address(uint160(subject)) for every subject whose top 96 bits are zero (line 169) with no exclusion for address(this) or the hook. subjectOf(address(pages)) therefore has payee == pages and _distributeFee self-transfers toIssuer: 90% of every fee of that subject stays inside Pages, counted in no reserveOf, no escrow and not in pendingBurn, and no function can ever move it. subjectOf(address(hook)) sends the 90% to the hook as a raw ERC-20 balance that bypasses fundPot/_accrue: the hook pays pools only from ERC-6909 claims it minted, so that IMD is likewise unreachable. Impact is bounded to the fee a trader chose to pay on a nonsensical subject, so this is low, but the invariant test/PagesAudit.t.sol asserts (balance == sum of reserves + escrow + pendingBurn) silently breaks for these subjects. Fix: refuse address subjects equal to address(this) and address(hook) in payeeOf/buy (BadClaim), or route them to the escrow path.","line":233,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/Repro.t.sol testSelfPayeeStrands on the local fixture. (1) subject = pages.subjectOf(address(pages)); pages.payeeOf(subject) == address(pages). (2) alice: pages.buy(subject, 1, max): value 0.1 IMD, fee 0.01, toIssuer 0.009. Measured: imd.balanceOf(pages) = 0.1095 IMD, reserveOf + pendingBurn = 0.1005 IMD, 0.009 IMD unaccounted. (3) alice: pages.sell(subject, 1, 0): balance 0.019 IMD, pendingBurn 0.001 IMD: 0.018 IMD stranded forever. (4) subject = pages.subjectOf(address(hook)), buy 1 page: hook raw IMD balance +0.009 IMD while the pools (refundPool + thesisPool) grow by only 0.0005 IMD. Expected: the issuer share reaches a payee who can use it, or the escrow; actual: it is stranded.","severity":"low","snippet":"            IERC20(imd).safeTransfer(payee, toIssuer);","title":"An address subject equal to the Pages contract or the hook self-transfers the 90% issuer share and strands it outside every accounted balance"},{"citation":"resolved","description":"From write_foundry_tests (low), reproduced and recalibrated to info: no value is at risk, the wei stay queued and burn with the next tranche. When a tranche is consumed entirely by the pool's 1.25% LP fee rounding (1 wei at the fixture's depth), the swap returns zero MARG, `outD <= 0` holds and unlockCallback reverts UnauthorizedCallback, which the PoolManager bubbles to the burnPending caller. The tester's claim that 10 wei also fails did not reproduce at the fixture's depth (10 wei burns fine); 1 wei does. A dedicated error or a minimum tranche would make the refusal legible.","line":419,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/Repro.t.sol testDustTranche. alice buys 1 page of subjectOf(carol): pendingBurn = 5e14 wei. burnPending(1, 1) reverts with selector 0xf5c6c81a = UnauthorizedCallback(); pendingBurn stays 5e14. burnPending(5e14 - 10, 1) succeeds, then burnPending(10, 1) succeeds and pendingBurn = 0. Expected: a refusal that names the dust tranche; actual: UnauthorizedCallback.","severity":"info","snippet":"        if (inD >= 0 || outD <= 0 || uint256(-int256(inD)) != imdIn) revert UnauthorizedCallback();","title":"A burn tranche too small to yield any MARG is refused with UnauthorizedCallback, which reads as an access failure rather than a dust tranche"},{"citation":"resolved","description":"Merged from audit_economics (info) and audit_permissions (info). Not a code defect: the brief orders no owner and four stored constructor values matching the live hook's INTAKE, ACTION and ORACLE_SIGNER constants, and the contract honours that. The oracle-consumer reference, however, says the intake, action and signer should be settable because a rotated key or a new action version 'must not need a redeploy', and recommends Intake v2 (0xa43e6f75ee006411f79ac1c84120606c2330de82) for anything new. If the oracle signer key rotates, every delivery fails BadSignature; if version 1 stops completing requests or the action's price moves to 0 or above 1 IMD, requestClaim reverts PriceMismatch or every claim is abandoned after 3 days with the asker's price lost. In both states no handle can ever be claimed, and because recycle is permissionless the issuer share of every handle subject goes to the hook's pools after 90 days instead of to the authors. Address subjects and page holders' curve exits are unaffected. Recorded for the README and for the author's scope decision (accept, or point the signer at an ERC-1271 registry the oracle operator can rotate behind, which SignatureChecker already supports).","line":60,"path":"src/MarginaliaPages.sol","reproduction":"Deploy with signer S; the oracle signs with S2 != S. alice buys 20 pages of subjectOfHandle('writer') (escrow 1.89 IMD); carol requestClaim('writer', tweetId) pays 0.5 IMD; the Intake delivers an attestation signed by S2: onOracleResult reverts BadSignature in _verifyAttestation (the 'tampered after signing' branch of test/Pages.t.sol testRejectedAnswersDoNotCloseTheClaim exercises this path and the delivery returns false). After 3 days anyone abandons the claim; after 90 days anyone recycles the 1.89 IMD to the pools. With Intake.priceOf(action, IMD) == 0, requestClaim reverts PriceMismatch (test/Pages.t.sol testPriceGuardAndAddressSubjectsNeedNoClaim). Expected under the brief: no owner, so this is the accepted cost; actual matches.","severity":"info","snippet":"    IIntake public immutable intake;","title":"Trust assumption: intake, action and oracle signer are immutable with no owner, so a signer rotation or Intake v1 retirement permanently disables handle claims and routes all handle escrow to the hook"}],"hash":"0f9d0c4807be2dad990326c50e128a6d13bc8401572e094fb3684b76b7500717","nodeId":"a6d3618a-2945-48f4-817f-4d1b3fe3ec41","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written and validated. No source files were changed.\n\n**Outcome.** Six findings survived reproduction, none critical or high, so no proof files were required. The 12 specialist entries collapsed into six after merging duplicates.\n\n| Severity | Finding | Reproduced by |\n|---|---|---|\n| medium | burnPending's caller-chosen floor lets anyone sandwich the MARG burn (merged from 3 specialists) | local test, pool thinned to ~6k IMD depth: attacker nets +49 to +127 IMD, burn drops from 540 to 363 MARG |\n| low | After day 90 every new escrow accrual is recyclable at once, front-running the owner's claim (merged from 2) | local test: 46.359 IMD recycled in the same block as the buy, owner pays 0.5 IMD for nothing |\n| low | onOracleResult pays out inside the 200k stipend with ~6k headroom against live IMD (merged from 2) | mainnet fork: 194,116 gas, delivery still succeeds |\n| low | Address subject equal to Pages or the hook strands the 90% issuer share | local test: 0.018 IMD stranded after buy and sell |\n| info | Dust tranche reverts with UnauthorizedCallback | 1 wei reverts, 10 wei does not at fixture depth, so the tester's exact claim was corrected |\n| info | Immutable intake, action and signer are a trust assumption, not a defect (merged from 2) | existing test paths |\n\n**Dropped.** The zero-price refusal in requestClaim mirrors the live Judge and guards an unsold action, and the agreed-above-panelSize check only concerns a field the trusted signer signs. Neither has impact.\n\n**Own pass.** I traced every Pages entry point, the manifest, deployability (runtime 15,834 bytes, no forbidden opcodes, constructor reads no chain state) and the question body bounds (at most 1,019 characters). Nothing the specialists missed turned up.\n\n**Coverage.** All 40 listed entry points have rows: 29 hold, 6 carry findings, and 6 live launch-1283 functions that Pages does not call (observe, seal, settle, and three Router entry points) are marked unreached.","treeHash":null,"usage":{"cachedInputTokens":2646479,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":45184,"runtime":"claude","turns":40,"wallClockMs":1197433}},{"artifacts":[],"attempt":3,"bundleHash":"54d522c944cc0cb23f58967e4dab1c2802256233d811f01f70d13abbf0e79083","device":"fa99051b60a858d6","findings":[],"hash":"19938d50ccac28ea353fe795296a906188b1839cb22fe54067bd587932d73775","nodeId":"0ae19a5b-0de8-4d38-a624-f0912d65a276","outcome":"completed","summary":"The responses file is excluded by the harness's own `.git/info/exclude`, so it is read from the working tree as intended. Everything is in place.\n\n**Outcome.** The reopened finding reproduced exactly, and it is fixed on chain; four of the five advisories also reproduced and are fixed, the fifth is recorded as the trust assumption the brief orders. All checks pass.\n\n**The reopened sandwich (fixed).** On the accepted tree, bob's push plus `burnPending(601 IMD, 1)` plus sell-back netted the reviewer's figures to the wei (+49.65 to +126.62 IMD). The burn's floor is now the chain's, not the caller's. `burnPending(imdIn)` swaps with a price limit set 0.5% in sqrt price (about 1% in price) from the pool's price at the block's first burn, fills partially past that bound, and refuses with `BurnBudgetSpent` once the block's budget is used. The hook keeps no TWAP of the launch pool, so the anchor is the spot the attacker may have pushed, but the bound still caps a sandwich's gain at about 1% of the position while the round trip pays about 5.5% in LP and hook fees. The same attack against the fixed code loses 17.7 to 60.6 IMD at all four sizes, and honest tranches over about twenty blocks burn the full 540.077 MARG one unbounded swap would have. Every number of the brief is unchanged; the one new constant is the tolerance the finding asked for.\n\n**Advisories.**\n- Recycle race: an issuer share landing after the 90-day window has elapsed restarts the window, so a fresh accrual is never recyclable the moment it lands. Inside a window, the first buy's clock stands.\n- Callback headroom: the callback now only verifies and stores the payout in one slot. A permissionless `settleClaim` pays escrow less reimbursement, and the escrow is frozen meanwhile. Delivery dropped from 182.8k to 153.2k gas with the mock overhead.\n- Self subjects: buying `subjectOf(pages)` or `subjectOf(hook)` is refused with `BadSubject`.\n- Dust tranche: a swap returning no MARG reverts `NothingBurned`.\n- Immutable oracle terms: no code change, recorded in the README as the brief's accepted cost.\n\n**Files.** `src/MarginaliaPages.sol` is the only production change. Tests: new `test/PagesRevision.t.sol` (7 tests), and `test/Pages.t.sol`, `test/PagesAudit.t.sol`, `test/PagesOracle.t.sol`, `test/fork/PagesMainnet.t.sol` follow the new burn signature and settle before checking balances. `README.md`, `ADAPTATION.md` and `.imd-responses.json` document each change and verdict.\n\n**Checks.** Pages suites: 36 passed. Full `forge test`: 287 passed, 0 failed, 2 skipped (optional fork setups with no RPC). `git diff --check` clean. No protected configuration or dependency path changed, and no Slither run was available.","treeHash":"1f36488555d900aa68726945cc64c0c2852737a4","usage":{"cachedInputTokens":2889472,"inputTokens":706,"model":"claude-fable-5-1","outputTokens":62484,"runtime":"claude","turns":71,"wallClockMs":1219378}},{"artifacts":[],"attempt":1,"bundleHash":"f80222297d31675c0086147962bf923cf7b9a6246ae0f5a8731d68ebd6ac13f7","device":"523ef565dd740e25","findings":[],"hash":"36b15b4a7454fab599e03e51b5323222192b9f22870abd4ffe132b7dfaa52957","nodeId":"6293b162-09df-438e-8474-990ee57d86b6","outcome":"completed","summary":"The manifest is done and verified. Only launch.json changed.\n\n**What the rejected attempt failed on.** The rejection was a tree mismatch between the start commit and its accepted dependencies, not a defect in the manifest content. This round I re-verified the manifest against the current accepted tree and rewrote it in place.\n\n**What launch.json now holds.** One contract, MarginaliaPages, with four constructor arguments in declaration order: the live hook of launch 1283, the IdentityMD Intake, the oracle action as a right-padded bytes32, and the oracle signer. These are the same three oracle constants the live hook holds. The notes were expanded to state the pot split, the handle rule, and the claim lifecycle the brief names. The constructor arguments are unchanged from the accepted round.\n\n**What I checked.**\n- The constructor in src/MarginaliaPages.sol takes exactly these four parameters, rejects zero values, and reads no chain state.\n- Every constant the notes cite matches the source: BASE, FEE_BPS, ISSUER_BPS, BURN_BPS, BURN_SQRT_BPS, PANEL_SIZE, QUORUM, MAX_PRICE, ANSWER_DEADLINE, CLAIM_WINDOW, MAX_HANDLE, the DEAD burn address, and the hook's 70/30 pot split.\n- The manifest parses as JSON with only the three schema keys, one valid contract identifier, string arguments, and notes of 2640 characters.\n- The full build succeeded and the 12 Pages tests all passed.\n\n```\nRan 12 tests for test/Pages.t.sol:PagesTest\nSuite result: ok. 12 passed; 0 failed; 0 skipped\n```\n\nGit status shows launch.json as the only modified file.","treeHash":"a374d1aa9a4d1a4587d2494e10242f492c29380d","usage":{"cachedInputTokens":572031,"inputTokens":356,"model":"claude-fable-5-1","outputTokens":6625,"runtime":"claude","turns":13,"wallClockMs":932140}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"3c1226d190150ef0","findings":[{"citation":"resolved","description":"Settles earlier finding b28cbca9 (burnPending sandwich): NOT FIXED. The revision anchors each block's bound at the sqrt price the block's first burn finds (lines 489-492) and refuses a tranche only while the CURRENT price is at or past anchor*1.005 (line 494: `if (zeroForOne ? current <= limit : current >= limit) revert BurnBudgetSpent();`). Nothing limits how much IMD the block burns in total: as soon as the caller sells MARG and brings the price back under the limit, burnPending is accepted again in the same block against the same (already pushed) anchor. So the caller still chooses the price the whole budget is spent at: push MARG up with X IMD (the first burn anchors there), burn a tranche up to the bound, sell exactly the MARG that tranche bought (price returns under the limit, the caller sells at the elevated price), burn again, ... until pendingBurn is 0, then sell the rest. All of it runs in one transaction and one block, with no market risk. The README/NatSpec claim (lines 55-58: 'the burn budget cannot be converted into an attacker's profit') is false, and the author's regression testSandwichingTheBurnLosesMoneyAtEverySize only tries a single burn-then-sell, never burn/sell/burn. Same impact as the original finding: part of the 0.5%-of-trade-value burn budget becomes an unprivileged caller's profit and far less MARG reaches 0xdEaD; no reserve, escrow or holder funds are at risk, hence medium. Fix that keeps every number: bound the block's cumulative effect, not the current level, e.g. once a block's burns have reached the limit refuse further burns in that block even if the price came back (record a `burnBlockDone` flag, or cap the IMD spent per block at the amount that moves the anchor price by BURN_SQRT_BPS), or derive the bound from a manipulation-resistant reference (the hook's observations / a TWAP) instead of the first in-block spot.","line":494,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/BurnBoundCycle.t.sol (self-contained: real MarginaliaHook mined and deployed, MARG/IMD pool at 1:1 with 6,000 ether of liquidity in [-6000, 6000], the depth used by test/PagesRevision.t.sol). alice buys 1,550 pages of subjectOf(carol): pendingBurn = 601.0125 IMD. Then bob, in ONE transaction/block: plain v4 swap 1,400 IMD -> MARG; loop { pages.burnPending(pendingBurn) (fills up to the block's bound); sell exactly the MARG that tranche burned back to the pool }; sell the remaining MARG. Measured: pendingBurn ends at 0 (the whole budget burned in that block despite the 'per block' bound), only 389.90 MARG reach 0xdEaD versus 540.077 for honest bounded burning, and bob's IMD balance rises by +96.61 IMD after all LP fees and the hook's 3% quiet-sell fee. Same loop with other push sizes (fixture probe): X=700 -> +37.44 IMD / 474.59 MARG burned; X=1000 -> +66.43 / 435.21; X=2000 -> +127.94 / 334.14. Expected (the revision's stated guarantee): an in-block sandwich of the burn loses money; actual: it profits, essentially as much as before the fix (+126.62 at X=1400 before vs +96.61 now). The proof asserts bob's balance does not rise and fails: 'one transaction sandwiched the bounded burn for profit: 100096605182894544048583 > 100000000000000000000000'. It passes once further burns are refused in a block whose bound was reached (the loop breaks after the first tranche and bob's round trip loses money, as in the author's own regression).","severity":"medium","snippet":"if (zeroForOne ? current <= limit : current >= limit) revert BurnBudgetSpent();","title":"The fix for the burn sandwich does not hold: the per-block bound caps the price level, not the volume, so selling back between tranches lets one transaction sandwich the whole pending burn for profit"},{"citation":"resolved","description":"Settles the write_foundry_tests lead on the revised window. Earlier finding 0680ae89 is fixed: an accrual landing after the window elapsed is no longer recyclable at once (escrowSince restarts at line 274). The restart, however, applies to the entire escrow balance, including issuer shares accrued 90+ days earlier, so the brief's 'Escrow unclaimed CLAIM_WINDOW = 90 days after the first buy is recycled' no longer holds for any handle that keeps trading: a buy in the same block as (and ordered before) a recycle turns recycle into TooEarly, and repeating it every 90 days defers recycling indefinitely. Recalibrated to info, not low: this is the trade-off of the remedy the earlier finding offered (restart the clock on accrual), the deferred escrow stays claimable by the handle's owner (no one is paid wrongly), the deferring party pays trade fees 90% of which land in that same escrow, and only the hook pools' recycled income is delayed. README lines 151-153 describe the restart but not that it carries the older escrow with it; stating that, or restarting only the new accrual (separate clocks), resolves it. Not blocking.","line":273,"path":"src/MarginaliaPages.sol","reproduction":"Fixture as in test/PagesRevision.t.sol. t0: alice buys 100 pages of subjectOfHandle('silent') -> escrow 45.45 IMD, escrowSince = t0. Warp to t0 + 90 days. Expected per the brief: recycle(subject) succeeds. Actual: bob first buys 1 page of the same subject; _distributeFee sees block.timestamp >= escrowSince + CLAIM_WINDOW (line 273) and sets escrowSince = now; recycle(subject) in the same block reverts TooEarly (line 437: block.timestamp < escrowSince + CLAIM_WINDOW). Repeating the 1-page buy at t0+180d, t0+270d, ... keeps every recycle reverting; carol can still claim and settle the full escrow.","severity":"info","snippet":"if (s.escrowSince == 0 || block.timestamp >= uint256(s.escrowSince) + CLAIM_WINDOW) {","title":"The escrow window restart (fix for 0680ae89) lets any trade at or after day 90 push the whole older escrow's recycling out another 90 days"}],"hash":"44f99be3f5156507d8f991f3f3fc5a5c1e6b7860ec499caddb53907422de653c","nodeId":"a6d3618a-2945-48f4-817f-4d1b3fe3ec41","outcome":"completed","summary":"Of the six findings from last round, five are settled. The medium one, the sandwich of the MARG burn, is **not fixed**. My findings and the coverage record (48 rows) are in `.imd-findings.json`. I changed no project files; my only other file is the proof test under `test/scratch/`.\n\n**1. [medium] The burn can still be sandwiched in one transaction** (`src/MarginaliaPages.sol:494`)\n\nThe fix anchors each block at the price the block's first burn finds. It only refuses a burn while the *current* price is past that anchor plus 0.5% on the square-root price, about 1% on the price. Nothing caps how much is burned in the block. Once the caller sells MARG and the price drops back under the limit, `burnPending` is allowed again against the same pushed anchor.\n\n- **Attack, one transaction:** buy MARG with 1,400 IMD, then loop { `burnPending` up to the bound; sell back exactly the MARG that tranche burned }, then sell the rest.\n- **Setup:** the author's own test pool (about 6k IMD of depth), with a pending burn of 601.0125 IMD.\n- **Result:** the whole budget burns in that one block. Only 389.90 MARG reaches the burn address, against 540.077 when burned honestly. The attacker nets **+96.61 IMD** after the pool's fees and the hook's 3% sell fee. Before the fix the same push netted +126.62.\n- **Other push sizes:** 700 IMD nets +37.44, 1,000 nets +66.43, 2,000 nets +127.94.\n- **Why the regression missed it:** `testSandwichingTheBurnLosesMoneyAtEverySize` only tries one burn followed by one sell, never burn/sell/burn.\n- **Proof:** `test/scratch/BurnBoundCycle.t.sol` deploys the real hook and needs no other test files. It fails today with \"one transaction sandwiched the bounded burn for profit\". It will pass once a block that has reached its bound refuses further burns, or the bound is taken from a time-averaged price instead of the first in-block price.\n\n**2. [info] The escrow window restart can delay recycling indefinitely** (`src/MarginaliaPages.sol:273`)\n\nThis is the independent tester's lead, and it reproduces. The fix for the recycle race restarts the 90-day clock for the *whole* escrow when a trade lands after the window. So a one-page buy just before `recycle` makes it revert `TooEarly`, and this can be repeated every 90 days. I rated it info: it is the trade-off of the remedy I proposed last round, the owner can still claim the escrow, and the delayer's fees mostly land in that same escrow. The README should state it.\n\n**Settled from last round:**\n- **Recycle race:** fixed. A new issuer share is no longer recyclable the moment it lands.\n- **Callback gas:** fixed. `onOracleResult` now only verifies and stores the result, and anyone can then call `settleClaim` to pay out. The escrow cannot change in between.\n- **Market or hook as a subject:** fixed. `buy` refuses both with `BadSubject`.\n- **Dust burn:** fixed. It now reverts with `NothingBurned`.\n- **Fixed oracle settings with no owner:** accepted as a trust assumption the brief requires, now written in the README.\n\n`launch.json` checks out: one contract, four arguments in constructor order, and the action decodes to `oracle.request@oracle-1`.\n\n**Coverage:** every `MarginaliaPages` entry point is answered. The token's three functions hold, as do the three hook functions Pages and my test rely on (`fundPot`, `beforeSwap`, `afterSwap`). The other already-deployed Marginalia contracts (hook, judge, router, treasury) are marked `unreached`: they are not part of this deployment and I did not re-trace them this round.","treeHash":null,"usage":{"cachedInputTokens":1424001,"inputTokens":28,"model":"claude-opus-5-5","outputTokens":27443,"runtime":"claude","turns":14,"wallClockMs":453973}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fcb71e606c933181","findings":[{"citation":"resolved","description":"The oracle guide for this consumer says a callback should verify and store and act in a later call, because the Intake delivers under a 200,000 gas try and never retries. onOracleResult instead performs the whole effect in the callback: ECDSA verification, one SSTORE for consumed, the payee write, three slot deletes, and two IMD transfers. Against the live IMD token (a LayerZero OFT at 0xD34a...63B7, not the test mock) on a mainnet fork the worst-case delivery measures 192,242 gas from the caller's side (both recipients starting at zero balance, escrow above the price so both transfers run). The 12 unit tests measure the stipend only with MockERC20 and warm state (163k). The margin is about 4%: any increase in the cost of an IMD transfer or of the callback's cold accesses makes every successful claim delivery run out of gas, the Intake records it as not delivered, the claimant's 0.5 IMD is spent, and the handle can only be claimed again by paying again (the same shape fails again). No present input makes it fail, which is why this is low; it is reported because the suite's stipend test does not measure the live token and the design contradicts the reference guidance.","line":356,"path":"src/MarginaliaPages.sol","reproduction":"State: Pages deployed against the live hook/Intake on a mainnet fork (forge test with MAINNET_RPC_URL); trader buys 20 pages of subjectOfHandle('writer') so escrow = 1.89 IMD; asker holds exactly 0.5 IMD, approves Pages and calls requestClaim('writer', 1) so its balance is 0; wallet W has balance 0. Then prank the Intake and call onOracleResult(rid, a, sig) with a valid attestation (chainId 1, answerType 1, answer=abi.encode(W), panelSize 5, quorum 4, agreed 5) under call{gas: 200_000}. Measured: 192,242 gas used (193,174 when the asker balance is nonzero but wallet fresh: 176,083). Expected per the oracle guide: a callback that only verifies and stores, leaving a comfortable margin; actual: the callback moves both IMD payments and sits 8k gas below the stipend. Scratch test used: deploy MarginaliaPages(hook, intake, action, vm.addr(key)) on the fork, deal IMD, buy, requestClaim, vm.prank(INTAKE), address(pages).call{gas:200000}(abi.encodeCall(MarginaliaPages.onOracleResult,(rid,a,sig))) and read gasleft() before and after.","severity":"low","snippet":"        IERC20 imd = IERC20(hook.imd());\n        if (reimbursed > 0) imd.safeTransfer(c.claimant, reimbursed);\n        if (owed > 0) imd.safeTransfer(wallet, owed);","title":"onOracleResult pays out inside the Intake's 200k stipend with ~8k gas of headroom on mainnet state"}],"hash":"468921f675edd0e443c8d6a8682df00e868eff75741d380c02eb820256ce7dad","nodeId":"eae4d606-9267-4c19-acf5-955055af62ad","outcome":"completed","summary":"The review is complete and the findings file is written.\n\n**Outcome:** `MarginaliaPages` holds under the Execution Trace, Periphery and First Principles checks. I found one low-severity issue and no fund-loss defect, so no proof test is attached.\n\n**What I verified**\n- **Trade flow:** the reserve equals the curve integral exactly (the price formula is rounding-free and additive), the 90/5/5 split sums to the fee, allowances to the hook and Intake are consumed exactly with no residual, and the contract's IMD balance always equals reserves plus escrow plus the pending burn.\n- **Claim flow:** the pending claim and the request-to-subject map are written and cleared together, a late delivery after abandonment is refused, the oracle UUID is consumed once, and a zero answer returns cleanly. Front-running a request only delays the owner; it never redirects escrow.\n- **Live state:** via a public RPC I confirmed the hook is initialized with the brief's IMD, the Intake prices the action at 0.5 IMD, and the existing mainnet fork rehearsal passes. The question body shape matches the paid probe recorded in the repo.\n- **Static-analysis leads:** the Pages reentrancy and unused-return lines are not reachable defects; the guard and the exact-fill check cover them.\n\n**Finding (low):** the oracle callback performs both IMD payouts inside the Intake's 200k stipend. On a mainnet fork with the live IMD token and both recipients at zero balance it uses about 192k gas, leaving roughly 8k of headroom. The unit tests only measure this with the mock token. Nothing fails today, but the oracle reference asks callbacks to verify and store, then act in a later call, and a small transfer-cost increase would make every claim delivery fail with the claimant's price spent.\n\n**Not reported:** the permissionless burn floor on `burnPending` can be sandwiched by its own caller. The author already weighed and accepted this in the prior round, so it is noted in the coverage row rather than re-raised.\n\nThe coverage record answers all 40 listed entry points plus three invariant rows. Scratch tests were removed. The next step is the judge's merge of the four specialist reports.","treeHash":null,"usage":{"cachedInputTokens":2804118,"inputTokens":610,"model":"claude-fable-5-1","outputTokens":51272,"runtime":"claude","turns":46,"wallClockMs":940114}},{"artifacts":[],"attempt":1,"bundleHash":"2cac4ff274f6c89be3a876bc00f599c5626c1bf44baf920d7d9519fe1e8b0750","device":"9e122b922ce3ac83","findings":[],"hash":"578a448cb84ac2a402ca388c24acf88716618f1e200362295e05750273455012","nodeId":"6293b162-09df-438e-8474-990ee57d86b6","outcome":"completed","summary":"Created `launch.json` for one `MarginaliaPages` contract with the exact four supplied constructor arguments.\n\nValidation passed: manifest structure, compiled ABI, `forge build`, all 12 Pages tests, and the full suite (278 passed, 0 failed). Two mainnet fork suites were skipped without an RPC URL.\n\nOnly `launch.json` changed.","treeHash":"5957da2b802546459ebc82101194199dad0984aa","usage":{"cachedInputTokens":2171904,"inputTokens":69699,"model":"gpt-6.1-sol","outputTokens":6028,"runtime":"codex","turns":16,"wallClockMs":966914}},{"artifacts":[],"attempt":2,"bundleHash":"b4aab1292e8c59fbfec3680d9f19aa8972a49e5e5d8a6da6847474d3bc03aa59","device":"da72e21237e01c8a","findings":[],"hash":"698d174ced06600cb34cd11944687725892f9502abd9902f8bd7657946d237f8","nodeId":"6293b162-09df-438e-8474-990ee57d86b6","outcome":"completed","summary":"Updated only [launch.json](/Users/zhangtao/.identitymd-seat3/work/0925298b-5eb6-4da2-ad34-b0e5aa2d1fdc/6293b162-09df-438e-8474-990ee57d86b6/launch.json), preserving the exact constructor arguments and correcting notes to match accepted code.\n\nChecks passed:\n- Manifest structure and compiled ABI.\n- `forge build`.\n- Pages tests: 12 passed.\n- Full suite: 285 passed, 0 failed; 2 fork suites skipped without RPC.\n\nStarting tree matches `0863b8b616ce`.","treeHash":"faad1ce58d0305e7528a255ecbbe4b71d625eb67","usage":{"cachedInputTokens":1348480,"inputTokens":69172,"model":"gpt-6-astra","outputTokens":6011,"runtime":"codex","turns":6,"wallClockMs":362053}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f9a12c57a094ca8d","findings":[{"citation":"resolved","description":"Access x economics seam (Trust Gap guide, seam 1). burnPending is permissionless and the only execution guard on the swap is minMargOut, which the same caller chooses; minMargOut = 1 is accepted. The swap itself runs with the extreme sqrt price limit (unlockCallback line 413) and exact input. An unprivileged caller can therefore front-run the burn with an IMD->MARG buy, call burnPending(pendingBurn, 1), and sell the MARG back: the pending burn IMD (0.5% of every page trade's value, meant to buy and burn MARG at market) is swapped at a manipulated price and most of its value lands in the caller's wallet instead of in burned MARG. The roundtrip costs the caller about 5.5% (1.25% LP fee twice plus the hook's 3% quiet sell fee), so the attack is only profitable when the unburnt pending balance is a sizeable fraction of the pool's IMD reserve; below that it loses money, which is what the earlier adaptation note measured. The README discloses that the floor is caller-selected and 'not a guarantee against malicious low-floor burns', so this is a known accepted gap; it is reported because the guarantee the brief states ('BURN_BPS 5% of the fee buys MARG ... and sends it to dEaD') is not enforced on chain and the party who breaks it is unprivileged and profits. A fix that keeps every number: bound each tranche to a fraction of the pool's in-range liquidity (or of the last observed price via the hook's observations) and/or derive a floor from a pre-trade reference rather than from the caller.","line":396,"path":"src/MarginaliaPages.sol","reproduction":"Local fixture (test/helpers/Fixture.sol: MARG/IMD pool at 1:1, 10,000,000 liquidity in [-6000,6000]). State A: thin the pool to 1,000,000 liquidity (reserve ~260k IMD), alice buys 20,000 pages of subjectOf(carol) (value 20,001,000 IMD, fee 2,000,100, pendingBurn 100,005 IMD). Honest burnPending(100,005e18, floor) burns 89,878.9 MARG. Attacker bob instead: (1) plain-router buy of MARG with 50,000 IMD, (2) burnPending(100,005e18, 1), (3) sell all MARG received. Measured: bob nets +6,402 IMD, only 81,966.6 MARG reach dEaD (7,912 MARG, 8.8%, less than the honest burn). State B: pool thinned to 100,000 liquidity (reserve ~26k IMD), 10,000 pages bought (pendingBurn 25,002.5 IMD): bob front-runs with 10,000 IMD, burnPending(25,002.5e18, 1), sells back: nets +3,925 IMD; 16,699 MARG burned versus 19,801 honest (15.7% less). Below roughly 10% pending-burn-to-reserve the same sequence loses money (e.g. full fixture depth, 1,000 pages, any front-run size: net negative). Expected: the burn buys MARG at the market price regardless of who calls; actual: the caller chooses the floor, so a 1-wei floor converts a fraction of the burn into caller profit.","severity":"medium","snippet":"        if (minMargOut == 0) revert Slippage();\n        pendingBurn -= imdIn;\n        hook.poolManager().unlock(abi.encode(imdIn, minMargOut));","title":"burnPending lets any caller set the burn's output floor, so the caller can sandwich the protocol's own MARG buy once the pending burn is large relative to pool depth"},{"citation":"resolved","description":"Access x asymmetry: recycle is permissionless and keyed only on escrowSince (the first buy) and the absence of a pending claim, while a claim is necessarily preceded by a public tweet (the question body needs the tweet id). Once 90 days have passed since the first buy, a watcher who sees the claim tweet (or simply the pending transaction) can call recycle(subject) first. The owner's requestClaim then succeeds against a zero escrow: reimbursed = 0 because owed (0) < c.price, the owner has paid 0.5 IMD to the Intake and receives nothing, and the 90% issuer share of every earlier trade has gone to the hook's pools. The escrow itself going to the pools after 90 days is the brief's rule; the asymmetry is that the claim's cost is reimbursed only from the escrow and the recycle has no grace once a claim is being prepared, so the race is lost by the handle owner for the price of gas. Possible mitigations without changing a number: let a requestClaim within the same block as a recycle take priority is impossible, but recycle could be refused for a short grace after a subject's last buy, or the oracle price reimbursement could be drawn from the pools share instead of the escrow.","line":379,"path":"src/MarginaliaPages.sol","reproduction":"Fixture from test/Pages.t.sol. 1) alice: pages.buy(subjectOfHandle('quiet'), 20, max) at t0 -> escrow 1.89 IMD, escrowSince = t0. 2) warp to t0 + 90 days. Carol (handle owner) tweets the claim statement. 3) bob: pages.recycle(subject) -> succeeds, 1.89 IMD to hook.fundPot, escrow = 0. 4) carol: pages.requestClaim('quiet', tweetId) -> pays 0.5 IMD to the Intake. 5) Intake delivers a signed answer = carol: onOracleResult sets payee = carol, owed = 0, reimbursed = 0, emits Claimed(subject, carol, 0, 0). Expected (brief): 'takes the escrow less the oracle price reimbursed to whoever asked'; actual: carol is 0.5 IMD poorer and receives none of the 1.89 IMD her pages earned. With the same sequence but step 3 omitted, carol nets 1.39 IMD (testEscrowThenOracleAttestedClaim).","severity":"low","snippet":"        if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();","title":"After CLAIM_WINDOW anyone can recycle a handle's escrow in front of the owner's visible claim, so the owner's requestClaim still costs the oracle price but pays and reimburses nothing"},{"citation":"resolved","description":"Trust assumption, not a code defect: the brief orders no owner and four stored constructor values, and the contract honours that. The oracle-consumer reference, however, says every protocol-facing value (intake, action, signer) must be settable because a new action version or rotated key 'must not need a redeploy', and that the brief's Intake 0x1397... is version 1, kept only for contracts already pointing at it. If the oracle signer key is rotated, every delivered attestation fails _verifyAttestation with BadSignature; if version 1 stops completing requests, every requestClaim spends 0.5 IMD and is abandoned after 3 days. In both states no handle can ever be claimed, and because recycle is permissionless, 100% of the issuer share of every handle subject goes to the hook's pools after 90 days instead of to the authors. Pages of address subjects are unaffected. Recorded so the author can decide the scope question (accept, or point the signer at an ERC-1271 registry address that the oracle operator can rotate behind, which SignatureChecker already supports).","line":126,"path":"src/MarginaliaPages.sol","reproduction":"Deploy with signer S. State: oracle operator signs with S2 != S. alice buys 20 pages of subjectOfHandle('writer') (escrow 1.89 IMD). carol requestClaim('writer', tweetId) pays 0.5 IMD; the Intake delivers an attestation signed by S2: onOracleResult reverts BadSignature (test pattern: testRejectedAnswersDoNotCloseTheClaim, 'tampered after signing' branch). After 3 days anyone abandons the claim; after 90 days anyone recycles 1.89 IMD to the pools. Expected by the brief's spirit: the handle owner can claim; actual: no path ever pays the handle owner and nothing on chain can repair it.","severity":"info","snippet":"        OracleAttestationConsumer(signer_)","title":"Oracle signer, Intake and action are immutable with no owner: a signer rotation or Intake v1 retirement permanently disables handle claims and routes all handle escrow to the pools"}],"hash":"7b87a4878945fb8fb9a05401d5e97798f46263acc0c4b1259f745c1e18629cdb","nodeId":"63c75fcf-faeb-4c59-98d6-b1b869f7a168","outcome":"completed","summary":"Review complete. The findings file is written at the repository root with three findings and a 42-row coverage record, and the one proof test fails on the current code as required.\n\n**Scope covered.** Access Control, Trust Gap and Asymmetry passes over every MarginaliaPages entry point, plus the two hook functions Pages calls into. The live hook, judge, router, treasury and token entry points are marked as holding only in the sense that nothing in Pages' permission model reaches them. I could not reach the live IMD token or Intake bytecode because the contributor RPC endpoint refused connections, so the 200k callback stipend is verified only against the mock token.\n\n**Findings**\n\n- **Medium, `burnPending` (line 396).** The swap's only execution guard is the caller's own `minMargOut`, and the price limit is the extreme tick. An unprivileged caller can buy MARG, burn the whole pending balance with a 1 wei floor, and sell back. On a pool with about 26k IMD in range and 25k IMD pending, the caller nets 3,925 IMD and 15.7% less MARG reaches the dead address. The roundtrip costs about 5.5% in fees, so it only pays once the pending burn is roughly a tenth of the pool's reserve or more. The README discloses the gap. A self-contained proof under `test/scratch/BurnSandwichProof.t.sol` is attached and fails today.\n- **Low, `recycle` (line 379).** After 90 days, anyone can recycle escrow ahead of the handle owner's claim, which is always preceded by a public tweet. The owner's claim then succeeds with zero escrow and no reimbursement, leaving them 0.5 IMD poorer. Reproduced against the fixture.\n- **Info, constructor (line 126).** Signer, Intake and action are immutable by the brief's own rule, but a signer rotation or Intake v1 retirement would permanently disable claims and route all handle escrow to the pools. Recorded as a trust assumption for the author's scope decision.\n\n**What held.** Buy and sell mirror each other exactly, the reserve invariant is integer-exact, the callback accepts only the Intake for a pending id and consumes the oracle UUID once, the unlock callback is bound to the PoolManager and a live guard, and transient approvals to the hook and Intake are fully consumed.","treeHash":null,"usage":{"cachedInputTokens":2623028,"inputTokens":578,"model":"claude-fable-5-1","outputTokens":48746,"runtime":"claude","turns":34,"wallClockMs":1223705}},{"artifacts":[],"attempt":1,"bundleHash":"7fbd424e1b7da9fd7447510e1b5cf763555347ac0b8c7c6ed3815812de264c0f","device":"7e929507773df661","findings":[{"description":"burnPending allows one burn per block (burnBlock == block.number reverts OneBurnPerBlock) and the lock is armed by any burn that goes through, regardless of size. The smallest tranche the pool returns MARG for is a few hundred wei of IMD. Anyone can therefore front-run every meaningful burnPending call in a block with burnPending(~1000 wei, 1), after which the honest caller's burn reverts for that block. No value is lost (the queued IMD stays in pendingBurn and remains fully backed; conservation and reserve invariants hold through such sequences) and the griefer pays gas every block, so this is a liveness nuisance rather than a loss. It is a direct consequence of the one-per-block design and the per-block 1% band; a minimum tranche (for example, refuse burns below some fraction of pendingBurn or below an absolute floor such as 1e15 wei) would make the slot cost something to take. Reported for the author's judgment rather than asserted as correct; the test suite asserts the lock behaviour as specified.","line":433,"path":"src/MarginaliaPages.sol","reproduction":"Same block, pendingBurn = P > 1e15 wei: (1) griefer calls burnPending(1000, 1) -> succeeds, spends about 1000 wei, burnBlock = block.number. (2) honest keeper calls burnPending(P - 1000, 1) -> reverts OneBurnPerBlock. Expected (by the brief): the fee IMD is burned at the pace the band allows, about 1% of price impact per block. Actual: at most ~1000 wei per block is burned while the griefer keeps paying gas; the rest waits. Covered as specified in test/PagesEdges.t.sol testARefusedBurnDoesNotArmTheBlockLockButASuccessfulOneDoes (the dust-sized follow-up is refused with OneBurnPerBlock).","severity":"low","title":"Any successful burn, however small, takes the block's single burn slot, so a griefer can starve the MARG burn one block at a time"}],"hash":"7c895bda997d2480b17a6eed398b680af9f8175cb4ddc0358c6c2e37d86729b5","nodeId":"8734f817-b327-4ca9-819c-8aa0a32ccfdd","outcome":"completed","summary":"The findings file is in place and is hidden from git by the harness's own exclude list, as intended. Everything is verified, so nothing further is needed.\n\n## Recap\n\n**What happened.** My previous round's tests were accepted against an implementation that another contributor then revised. The revision moved the escrow payout out of the oracle callback into a separate `settleClaim` call, and changed the MARG burn to one per block with a 1% price band and a `BurnTooSmall` refusal. Three of my edge tests and the invariant handler failed against that new code, which is what this revision fixes.\n\n**Changes, limited to my two files.**\n- `test/PagesEdges.t.sol`: the three stale claim tests now assert the callback moves nothing and settle afterwards. Five new tests cover `settleClaim` refusals at every stage, the frozen escrow between acceptance and settlement with every other path closed, settling an empty escrow, the block lock (refused burns do not arm it, successful ones do, pre-lock checks still answer first), and a band-bound fill on a shallow pool checked against the caller's floor, the 1% impact bound and the requeue.\n- `test/PagesInvariant.t.sol`: the handler now mirrors the two-step claim with a `settle` action and a settle-due ghost, treats the burn as a band-bound fill with a price-derived floor and per-block lock, and adds outside pool trades that move the price while tracking the hook's own sell fee. The fixture shallows the pool and pre-queues a burn so partial fills occur in random sequences, and the handler opens its ledger from the live state.\n\n**Results.**\n\n| Suite | Result |\n| --- | --- |\n| `test/PagesEdges.t.sol` | 28 passed |\n| `test/PagesInvariant.t.sol` | 5 invariants, 96 runs, 0 reverts |\n| Full `forge test` | 316 passed, 0 failed, 2 fork tests skipped |\n\n**Finding reported.** One low-severity item in `.imd-findings.json`: any successful burn, however tiny, takes the block's single burn slot, so a griefer paying gas each block can starve the burn queue. No value is lost and the invariants hold, so it is a liveness nuisance for the author's judgment rather than a defect I could test around. I checked the missing `questionHash` comparison against the oracle protocol reference and it is not a defect for a same-chain consumer that gates on its own request id, so it is not filed.","treeHash":"c71dfe01d833356e3f9416d6dcb8178d38ae67af","usage":{"cachedInputTokens":3001363,"inputTokens":548,"model":"claude-fable-5-1","outputTokens":58336,"runtime":"claude","turns":49,"wallClockMs":2101002}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"644eb561f6d70a85","findings":[{"citation":"resolved","description":"Economic Security / Flow Gap (execution x periphery x first principles). The 5% burn share of every fee (BURN_BPS) is parked in pendingBurn and spent by burnPending, which anyone may call with any tranche size and any minMargOut >= 1. The only slippage protection is the caller's own floor, and in unlockCallback the swap runs to MIN_SQRT_PRICE+1 / MAX_SQRT_PRICE-1 with no on-chain price reference. The caller is therefore free to be the sandwicher: buy MARG, call burnPending(pendingBurn, 1), sell MARG back. The protocol then pays the pool's 1.25% LP fee and the full price impact out of the burn budget and burns far less MARG than it should; the difference, less the attacker's own LP fees (1.25% each leg) and the hook's 3% quiet-sell fee on the exit, is the attacker's profit. Nobody is paid to burn honestly (it costs gas and yields nothing), while the attacker is paid to burn adversarially, so pendingBurn will accumulate until the adversarial burn is profitable. Live state (mainnet, block ~26174333): the launch pool 0x436763bf...2f20 has liquidity 1.3479e24 at sqrtPriceX96 1.735e31 (tick 107787), i.e. an IMD virtual reserve of about 6,150 IMD. Break-even is pendingBurn > ~(1.25%+1.25%+3%)/2 of that depth = ~170 IMD, which is 0.5% of ~34,000 IMD of page trade value (e.g. 820 pages of one subject: priceOf(0,820) = 33,661 IMD). The same lever moves MARG's spot price at zero cost to the caller (the pump is paid by the burn budget), which is what every MARG call and thesis in the hook settles against; the pricer's observation TWAP dampens but does not remove a repeated, free pump. Proposed fix (keeps every number): derive the floor on chain instead of trusting the caller, e.g. require marg >= imdIn * 1e18 / twapPriceInImd * (10_000 - MAX_BURN_SLIPPAGE_BPS) / 10_000 using the hook's observation-based MARG price (not the manipulable spot), and/or cap a tranche at a small fraction of the pool's current liquidity; alternatively pass a sqrtPriceLimitX96 bounded around that reference instead of the extreme tick.","line":393,"path":"src/MarginaliaPages.sol","reproduction":"Local reproduction (test/scratch/BurnSandwich.t.sol, Fixture pool re-seeded with 6,000 ether of liquidity in [-6000, 6000] at 1 MARG = 1 IMD, i.e. ~6k IMD depth like the live pool). 1) alice buys 1,550 pages of subjectOf(carol): value 120,202.5 IMD, pendingBurn = 601.0125 IMD. 2) Honest burnPending(601.0125e18, 1) burns 540.08 MARG. 3) Attacker bob instead, in one transaction: swap 1,400 IMD -> MARG on the launch pool (plain router), call pages.burnPending(601.0125e18, 1), swap all the MARG back. Observed: bob's IMD balance rises by 126.62 IMD net of all LP and hook fees (profit = 21% of the burn budget); only 362.86 MARG reach 0xdEaD instead of 540.08. With X = 400 IMD the profit is 49.65 IMD; with pendingBurn = 1,199.57 IMD (2,190 pages) and X = 700 IMD the profit is 202.19 IMD and the burn shrinks from 989.27 to 809.21 MARG. With pendingBurn = 160.2 IMD (800 pages) every X loses money (-0.46 .. -12.16 IMD), confirming the ~3%-of-depth threshold. Expected per the brief: 'BURN_BPS 5% of the fee buys MARG on the launch pool ... and sends it to dEaD' at the market price the burn finds, not a price an unprivileged caller sets against it. Actual: the burn is an unbounded-slippage swap any caller can sandwich; the victim is the burn (MARG holders), the beneficiary is the caller.","severity":"medium","snippet":"    function burnPending(uint256 imdIn, uint256 minMargOut) external nonReentrant {\n        if (imdIn == 0) revert ZeroAmount();\n        if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n        if (minMargOut == 0) revert Slippage();","title":"burnPending's MARG floor is caller-chosen, so anyone can sandwich the burn budget for profit once it exceeds ~3% of the pool's IMD depth"},{"citation":"resolved","description":"Invariant / Flow Gap (execution x first principles). escrowSince is set once, at the first fee that lands in escrow (line 235: `if (s.escrowSince == 0) s.escrowSince = uint64(block.timestamp);`), and only cleared by recycle. recycle (line 379) tests that single timestamp against the whole escrow balance. So once 90 days have passed since the first page of a handle was bought, the issuer share of every later trade, including one made seconds earlier, can be sent to the hook's pools by anyone in the same block, and nothing restarts the window while any escrow is unrecycled. Dust escrow left past day 90 is a standing trap: a recycler has no reason to clear 0.009 IMD, so they wait for a large buy and snipe its 90% share. The guarantee the brief states, 'pages of a handle trade on the same curve while the issuer's 90% waits in escrow' and 'the escrow pays for its own claim', no longer holds for any subject older than 90 days: the owner's only defence is to have a claim pending before each large buy, which they cannot know about. Because recycle needs no tweet and no oracle round-trip while the claim needs both (the tweet is public, the requestClaim tx is in the mempool), the owner reliably loses the race, and then reimbursement is 0 (line 354: `owed >= c.price ? c.price : 0` with owed = 0), so the claimant pays 0.5 IMD for a payee with no escrow. Who gains: the thesis and refund pools (indirectly the week's judged writers). Who loses: the handle owner, an identifiable victim. The letter of the brief ('CLAIM_WINDOW = 90 days after the first buy') permits this, so the fix needs a scope decision; two options that keep every number: (a) restart the 90-day clock on every accrual (escrowSince = block.timestamp on each escrow deposit), so recycle takes only escrow that has sat 90 days without a new trade; or (b) keep escrowSince per accrual epoch and let recycle take only the part older than CLAIM_WINDOW. Either way reimburse the claimant from escrow before any recycle that lands in the same block is not possible, so (a) is the simplest.","line":379,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/RecycleRace.t.sol against the local hook. 1) t0: alice buys 1 page of subjectOfHandle(\"writer\"): escrow 0.009 IMD, escrowSince = t0. 2) t0 + 91 days: bob buys 100 pages: value 505 IMD, fee 50.5, escrow += 45.45 -> 45.459 IMD. 3) Same block, before carol's requestClaim: any address calls recycle(subject): passes NothingToRecycle (escrow 45.459 > 0), ClaimPending (none), TooEarly (t0 + 91d >= t0 + 90d); 45.459 IMD go to hook.fundPot. 4) carol (the handle's owner) calls requestClaim(\"writer\", tweetId) paying 0.5 IMD; the panel answers carol; onOracleResult sets payee = carol with owed = 0, reimbursed = 0. Observed: pools +45.459 IMD, carol -0.5 IMD net, 0 escrow received. Expected: the 45.45 IMD accrued 0 seconds earlier waits in escrow for the owner's claim, which the escrow pays for.","severity":"medium","snippet":"        if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();","title":"After CLAIM_WINDOW from the first buy, every later issuer accrual is recyclable immediately, and recycle front-runs the owner's requestClaim: the owner pays the oracle and gets nothing"},{"citation":"resolved","description":"Periphery / Flow Gap (execution x periphery). The oracle-consumer reference says the callback gets 200,000 gas inside a try, is attempted once and never retried, and advises 'verify and store; act in a later call'. Pages verifies, consumes, writes payee, and performs two ERC-20 transfers inside the callback. The live IMD token (0xD34a99Bc..., 23 KB of runtime, not a plain OpenZeppelin ERC-20) costs 57,358 gas for a transfer to a cold recipient and 35,755 to a warm one on a mainnet fork, roughly twice the MockERC20 the tests use. Measured on a fork with the real hook and real IMD, an EOA signer and a mock Intake: 177,116 gas when the asker still holds IMD and the wallet is cold; 194,205 gas when the asker's balance is exactly zero after paying the price (zero->nonzero SSTORE on reimbursement) and the wallet is cold. The 200k delivery still succeeds (ClaimIntake.deliver with gas: 200_000 returns true), so this is not a failure today, but the margin is ~6k gas (3%). Any state that adds a few thousand gas to the path turns a correct answer into a lost one: the oracle signer gaining code (SignatureChecker then also tries ERC-1271 after the ECDSA mismatch), an IMD token upgrade or a more expensive transfer branch, or the Intake granting slightly less than 200k after EIP-150's 63/64 rule when `complete` itself is called with a tight gas limit. When that happens the claim stays pending, the asker's 0.5 IMD is spent, the escrow cannot be recycled or re-asked for until abandonClaim after 3 days, and the panel's correct answer is thrown away. Minimal fix that keeps the design: store the answer (payee, owed, reimbursed, claimant) in the callback and pay out in a separate permissionless `settleClaim(subject)` call, or at least move the two transfers behind a `claimPayout` pull; the brief's 'paid directly from then on' is unaffected for later trades.","line":357,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/ForkProbe.t.sol (fork of mainnet via public RPC, investigation only): deploy MarginaliaPages(hook 0xf0457dD0..., mock ClaimIntake, action, vm.addr(key)); trader buys 20 pages of subjectOfHandle(\"writer\"); an asker funded with exactly 0.5 IMD calls requestClaim(\"writer\", 123); deliver a signed address answer naming a fresh wallet with zero IMD. Measured gas around the onOracleResult call: 194,205 (asker balance 0, wallet cold), 177,105 (asker balance 0.5 IMD, wallet cold), 172,305 (asker == wallet). Passing state today; failing state: any of the three additions above costing >= ~6,000 gas, e.g. an ERC-1271 signer, after which intake.deliver returns false, claims(subject) stays set, and only abandonClaim after ANSWER_DEADLINE clears it.","severity":"low","snippet":"        if (reimbursed > 0) imd.safeTransfer(c.claimant, reimbursed);\n        if (owed > 0) imd.safeTransfer(wallet, owed);","title":"onOracleResult acts inside the Intake's 200,000-gas stipend with ~6k headroom against the live IMD token; a delivery that runs out of gas strands the claim for 3 days and costs the asker the price"},{"citation":"resolved","description":"Economic Security, 'break dependencies'. The brief requires no owner and pins Intake v1 (0x1397...), action oracle.request@oracle-1 and the signer 0x5598..., matching the live hook's constants, so this is by design and not a defect to fix by adding an owner. The oracle-consumer reference, however, states that each of these 'is constructor input and owner-settable, never a constant' and that 'a new action version (oracle-2) or a moved price must not need a redeploy', and recommends Intake v2 (0xa43e...) for anything new. The economic consequence to record as a trust assumption: if the oracle plane rotates its signing key (every attestation then fails BadSignature), stops serving v1, retires the oracle-1 action (priceOf returns 0 -> PriceMismatch), or raises the price above MAX_PRICE 1 IMD, no handle can ever be claimed again; every handle's escrow then recycles into the hook's pools after 90 days and future issuer shares of handle pages go to the pools forever, while address subjects are unaffected. Holders of handle pages keep their curve exit. No code change is proposed within the brief; the README should state this dependency and that the live Judge shares it.","line":59,"path":"src/MarginaliaPages.sol","reproduction":"State: oracle signer rotated away from 0x5598Aa9146215Bc13eb26f2c692Ad1461Fd32982 (or Intake.priceOf(action, IMD) == 0). Call requestClaim(handle, tweetId): with price 0 it reverts PriceMismatch; with a rotated signer the request is paid (0.5 IMD) and every delivery reverts BadSignature in _verifyAttestation, so the claim is abandoned after 3 days and the asker's price is lost; recycle(subject) after CLAIM_WINDOW sends the escrow to hook.fundPot. Expected under the reference: a settable signer/intake/action; under the brief: no owner, so this is the accepted cost.","severity":"info","snippet":"    IMarginaliaHookPages public immutable hook;\n    IIntake public immutable intake;\n    bytes32 public immutable action;","title":"Trust assumption: intake, action and signer are immutable with no owner, so a signer rotation or retirement of Intake v1 / oracle-1 permanently disables handle claims and routes all handle escrow to t"}],"hash":"843678b83af230488bdd29ee49bc8f2f39b86e187f8cb065d28cc9f1d2c9851f","nodeId":"3931255c-7c88-450b-bef1-1718a9130a9e","outcome":"completed","summary":"The review is complete. The findings file holds four findings and a 43-row coverage record (all 40 listed entry points plus three invariants). No tracked file was changed; scratch tests live under test/scratch.\n\n**Findings**\n\n1. **Medium. The burn budget is sandwichable.** `burnPending` takes any tranche and any floor of 1 wei and swaps to the extreme tick with no on-chain price reference. Nobody is paid to burn honestly, so pendingBurn accumulates until an adversarial burn pays. On a pool re-seeded to the live depth of roughly 6k IMD, a 601 IMD budget sandwiched with 1,400 IMD nets the attacker 126.6 IMD after all LP and hook fees, and the burn drops from 540 to 363 MARG. Break-even is about 3% of pool depth, around 170 IMD of budget, or 34k IMD of page volume. The same lever pumps MARG spot for free, which the hook's calls and theses settle against.\n\n2. **Medium. Escrow accrued after day 90 is recyclable instantly and recycle front-runs the owner's claim.** The 90-day clock is set once at the first accrual. Reproduced: one page on day 0, a 100-page buy on day 91 adds 45.45 IMD of escrow, anyone recycles it in the same block, then the owner's claim lands, pays 0.5 IMD, and receives nothing with no reimbursement. This matches the brief's letter, so the fix needs a scope decision; restarting the clock on each accrual keeps every number.\n\n3. **Low. The claim callback acts inside the 200k stipend with thin headroom.** Against the live IMD token on a mainnet fork, the worst case measured 194,205 gas when the asker's balance is zero and the wallet is cold. It passes today. An ERC-1271 signer or a costlier IMD transfer would turn a correct answer into a lost one, stranding the claim three days and costing the asker the price.\n\n4. **Info. Immutable oracle constants with no owner.** A signer rotation or retirement of Intake v1 permanently disables handle claims and routes all handle escrow to the pools. This is the brief's design, recorded as a trust assumption.\n\n**What held**: curve math and reserve conservation, the fee split and rounding, slippage guards, the quiet burn swap taking no hook fee, claim replay and tamper refusals, abandon and recycle guards, and the live IMD token delivering full amounts with no recipient hooks.\n\n**Not reached in depth**: the hook's note, settlement and judging entry points, which Pages does not touch beyond funding the pools.","treeHash":null,"usage":{"cachedInputTokens":2035812,"inputTokens":450,"model":"claude-fable-5-1","outputTokens":59532,"runtime":"claude","turns":35,"wallClockMs":1158616}},{"artifacts":[],"attempt":1,"bundleHash":"d2baf95b4f3582b9cb8bc3ed8ace4d221bb4d5d40cf4792ec55a122ccd4b6704","device":"b57ae3a96321a0e1","findings":[],"hash":"87ee4bc12b5805697166284443a9c4b86ef7418b80720c9c3b7cd8d2bd6ebba9","nodeId":"0ae19a5b-0de8-4d38-a624-f0912d65a276","outcome":"completed","summary":"Done. The revision is complete, verified, and answered in `.imd-responses.json`.\n\n**What I found**\n\nEvery finding reproduced except the trust-assumption note, which is not a defect. The medium finding reproduced with the reviewer's exact numbers on the pre-revision contract: a 1,000 IMD push before `burnPending(601.0125e18, 1)` cut the burn from 540.08 to 403.34 MARG and left the sandwicher up 102.29 IMD.\n\n**What changed, all in `src/MarginaliaPages.sol`, every number kept**\n\n- **Burn price bound (medium).** Pages now keeps its own tick-seconds accumulator of the launch pool, fed by a permissionless `observe()` and by every burn. The anchor always spans at least 30 minutes. A tranche swaps with a sqrt price limit 100 ticks (about 1%) beyond the lower of spot and that TWAP, fills only up to it, and leaves the rest pending. A spot already beyond the limit is refused before any swap. The 1% bound sits below the LP and hook fees a sandwicher pays, so sandwiching loses money whatever floor the caller passes. Tested on the reviewer's pool with pushes from 10 to 1,400 IMD, and separately with mainnet's orientation where IMD is currency0, since the default fixture has the opposite order.\n- **Aged escrow buckets (low).** Recycling pays out only the share that has itself waited 90 days. The first buy's share is still recyclable exactly 90 days after the first buy, but a share deposited seconds before cannot be swept ahead of the owner's claim.\n- **Store-then-settle callback (low).** The Intake callback only verifies and records the payee. A permissionless `settleClaim` pays the escrow and reimbursement. Cold-recipient delivery now measures 115,581 gas including the mock's overhead, asserted under 120,000.\n- **Self subjects (low)** are refused in `buy`, and a claim answer naming the market or hook fails like a zero answer.\n- **Dust tranche (info)** reverts with a named `NoFill` error.\n\n**Verification**\n\n- `forge build` passes. Runtime is 19,668 bytes, no forbidden opcodes, constructor unchanged.\n- `forge test --match-path 'test/Pages*.t.sol'`: 37 passed. Full suite without the fork tests: 287 passed, 0 failed.\n- ADAPTATION.md and README.md document each change, the operating steps for the first burn, and the accepted trust assumption.\n\n**Not done:** no mainnet fork run, since the fork suites skip without an RPC. The fork test was updated to observe and wait the window before burning.","treeHash":"0814907aa11c86b41fb08997804a051a5de9e9aa","usage":{"cachedInputTokens":3143697,"inputTokens":674,"model":"claude-fable-5-1","outputTokens":78952,"runtime":"claude","turns":32,"wallClockMs":1724391}},{"artifacts":[],"attempt":1,"bundleHash":"dcf3e43ef112a57f9796a6b19eb8c33f72ea70b7a0d5f69a69349b0d45c15ccf","device":"9e51ef2afd7c2af8","findings":[{"description":"burnPending lets the caller choose the tranche. When the tranche is below what the pool's 1.25% LP fee rounding leaves anything for (a few hundred wei), the swap returns zero MARG and unlockCallback reverts with UnauthorizedCallback, a name that suggests an access problem rather than a dust tranche. No value is at risk: the wei stay queued and are burned with the next fee. A dedicated error (or a minimum tranche) would make the refusal legible. The invariant handler in test/PagesInvariant.t.sol asserts this behaviour as it is today.","line":419,"path":"src/MarginaliaPages.sol","reproduction":"Buy one page of any subject (pendingBurn becomes 5e14 wei). Call burnPending(5e14 - 10, floor) so 10 wei remain, then call burnPending(10, 1). Expected: a refusal that says the tranche is dust, or the ten wei burned. Actual: the PoolManager bubbles UnauthorizedCallback() from unlockCallback because the swap output is zero; pendingBurn stays 10 wei.","severity":"low","title":"A burn tranche too small to yield any MARG is refused with UnauthorizedCallback, so a few wei can sit in pendingBurn until more fees accrue"},{"description":"The callback requires agreed >= quorum, quorum >= 4 and panelSize >= 5, but not agreed <= panelSize. An attestation with panelSize 5, quorum 4 and agreed 9 is accepted. Only the trusted oracle signer can produce such a message, so this is a consistency check that is missing, not an exploit; it is recorded here because it is a signed field the contract reads and does not bound.","line":336,"path":"src/MarginaliaPages.sol","reproduction":"Request a claim for any handle, then deliver from the Intake an attestation signed by the configured signer with panelSize = 5, quorum = 4, agreed = 9 and a nonzero address answer. Expected (strict reading of the brief's panel terms): BadAnswer. Actual: the claim succeeds and the address becomes the payee.","severity":"info","title":"onOracleResult accepts an attestation whose agreed count exceeds its panelSize"}],"hash":"aabe5943cb273647aaff6181cb400ecea1e8dbfe1604b2cea106b7e2d18b4813","nodeId":"8734f817-b327-4ca9-819c-8aa0a32ccfdd","outcome":"completed","summary":"The findings file is in place and intentionally excluded by the repository's own git exclude list, which is how the network collects it. Work is complete.\n\n## Summary\n\nThe accepted implementation of MarginaliaPages already had its 12 required tests in test/Pages.t.sol passing. What was missing against the acceptance criteria was an invariant suite over random call sequences for a contract that holds IMD, and coverage of the inputs the code did not obviously consider. I added two files under test/ and changed nothing else.\n\n**test/PagesInvariant.t.sol** drives the market against the real local PoolManager, hook and pool with a handler, four actors and six subjects: two address issuers, the zero address, and three handles including one with upper-case letters. The handler buys, sells, requests claims, delivers good, zero, tampered, thin, stale, wrong-chain and wrong-key answers, abandons, recycles, burns and warps time. It runs with fail-on-revert, so every refusal it provokes is asserted by exact error. Invariants checked after every call:\n\n- The market's IMD balance equals curve reserves plus escrow plus the burn queue, and equals everything paid in minus everything paid out.\n- Every reserve is the curve integral of its supply, so all holders can sell out at any depth, and every page is held by a trader.\n- Escrow, payee, pending claim and consumed oracle ids match the ledger. A payee never changes once set, and a claimed handle never has escrow or a pending claim.\n- The pools' share and recycled escrow land in the hook's IMD claims, and burned IMD reaches the dead address as MARG, never below the floors set.\n\n**test/PagesEdges.t.sol** holds 23 tests: constructor zero inputs, zero amounts, one wei of slippage either way, overflow reverting rather than wrapping, sell-fee split, selling out and restarting at BASE, independent curves, the zero-address subject, claims with no escrow, escrow exactly equal to and one wei short of the oracle price, the 1 IMD price cap boundary, every panel threshold at its boundary, upper-case requests, handle length and character limits, the escrow clock across a failed claim, a claimed handle being closed to all later paths, abandon at exactly the deadline, foreign-request and foreign-domain answers, a cold claim under the 200k stipend with the real hook, and the absence of any owner or pause surface. Two fuzz properties cover curve additivity and the exact cost of a round trip.\n\n**Results**\n\n| Check | Outcome |\n| --- | --- |\n| Full suite | 302 passed, 0 failed, 2 fork tests skipped without RPC |\n| Pages invariant campaign | 96 runs, 4608 calls, 0 reverts |\n| Scratch path check | every handler path reached, invariants hold after |\n\n**Findings** went to .imd-findings.json, both minor. A burn tranche too small to yield any MARG is refused with the misleading error UnauthorizedCallback, leaving a few wei queued until the next fee. The callback does not bound the signed agreed count by panelSize, which only the trusted signer could abuse. I found no defect that moves value or breaks a stated rule.","treeHash":"d38a982b8af5f96ef8273eb7374faeaf4bb763df","usage":{"cachedInputTokens":3274910,"inputTokens":770,"model":"claude-fable-5-1","outputTokens":71360,"runtime":"claude","turns":39,"wallClockMs":1925363}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"63274cc86a9400de","findings":[{"citation":"resolved","description":"Settles earlier finding 19412c9f (burn / sell / burn sandwich): PARTLY FIXED. The loop I reported is refused: `if (burnAnchorBlock == block.number) revert BurnBudgetSpent();` (line 496) makes a block burn once, and the author's regression testBurnSellBurnSandwichIsRefusedAndLosesMoneyAtEverySize reproduces my loop at the four push sizes with one tranche and a loss for the attacker; I re-ran test/PagesRevision.t.sol and the 68 Pages tests, all pass. The root cause, however, is unchanged: the tranche is bounded against the block's own spot (line 498: the anchor is `current`, the price the burn finds) and only by price level (line 499 and the sqrtPriceLimit of the swap at line 501). Nothing caps the IMD a block's one tranche may spend, so an attacker who first pushes the spot and then supplies liquidity in the band [anchor, limit] sells the whole pendingBurn to the burn at the pushed price without the price ever reaching the limit. The hook has no beforeAddLiquidity / beforeRemoveLiquidity permission (getHookPermissions, src/MarginaliaHook.sol line 239), so anyone adds and removes liquidity on the launch pool through the PoolManager in the same transaction; burnPending is permissionless. README lines 146-150 acknowledge this exact variant but state it 'is bounded by the tranche size, which the per-block bound holds to about 30 IMD'; that is false: with in-band liquidity the tranche is the entire budget (601 IMD in the reproduction, not 30), and the attacker's gain scales with the budget times the push, not with 30 IMD. Impact as before: part of the 0.5%-of-trade-value burn budget becomes an unprivileged caller's profit and far less MARG reaches 0xdEaD (436 instead of 540 MARG at a 1,000 IMD push); no curve reserve, escrow or holder funds are at risk, hence medium, as in the original finding. Fixes that keep every number: bound the block's tranche in IMD volume rather than in price level (e.g. spent <= the amount that moves the anchor by BURN_SQRT_BPS at the pool's liquidity observed in an earlier block, or a fixed per-block IMD cap), and/or take the reference price from something an in-block push cannot set (the hook's observations / the pricer's TWAP, or the sqrt price recorded in a previous block) and require marg >= imdIn * 1e18 / reference * (10_000 - 2 * BURN_SQRT_BPS) / 10_000. A level bound anchored at the in-block spot cannot hold against liquidity the attacker supplies.","line":498,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/BurnJit.t.sol (self-contained on the project's Fixture, the pool re-seeded as in test/PagesRevision.t.sol: 6,000 ether of liquidity in [-6000, 6000] at 1 MARG = 1 IMD, real MarginaliaHook mined and deployed). alice buys 1,550 pages of subjectOf(carol): pendingBurn = 601.0125 IMD. bob, in ONE block/transaction sequence: (1) plain v4 swap of X IMD -> MARG (push); (2) read pages.burnLimit() and add 200,000 ether of liquidity in the tick range covering [current, limit] through his own unlock contract (LiquidityHelper from test/helpers/Fixture.sol, 20,000 MARG + 20,000 IMD funded); (3) pages.burnPending(601.0125e18): the whole tranche fills (spent == 601.0125 IMD, pendingBurn == 0) because bob's liquidity absorbs it before the price reaches the limit; (4) remove the liquidity; (5) sell back exactly the MARG bob holds above his starting balance (he ends flat on MARG). Measured net IMD for bob after the pool's 1.25% LP fee on every leg and the hook's 3% quiet-sell fee: X = 600 -> +56.15 IMD, 490.33 MARG burned; X = 1,000 -> +95.51 IMD, 436.52 MARG burned; X = 2,000 -> +155.80 IMD, 335.21 MARG burned. Honest bounded burning (testBoundedBurnsAcrossBlocksBurnTheWholeBudgetAtMarket) burns 540.077 MARG. Expected per the revised README (lines 146-150): the in-band-liquidity pusher 'captures at most the slippage their own push paid ... bounded by the tranche size, which the per-block bound holds to about 30 IMD'; actual: the tranche is the full 601 IMD budget, the budget is gone in one block, and bob profits at every size tried. testJitSandwichProfits asserts bob's balance does not rise and fails: 'one transaction sandwiched the bounded burn for profit: 95513553230998808846 > 0'. (The scratch's testDustTrancheSpendsTheBlock belongs to finding 2.) Run: forge test --match-path test/scratch/BurnJit.t.sol -vv.","severity":"medium","snippet":"        burnAnchorSqrtPrice = current;\n        uint160 limit = _limitFrom(current, zeroForOne);","title":"Burn sandwich still profits: a pusher who supplies in-band liquidity burns the whole budget at the pushed price in one block, so the per-block bound caps the level, not the volume"},{"citation":"resolved","description":"Introduced by this round's fix. The block is marked done (line 497) by any tranche that produces at least 1 wei of MARG, whatever its size: burnPending(imdIn) with a tiny imdIn anchors the block and every later burn in it reverts BurnBudgetSpent (line 496). Before the fix a dust tranche left the block's bound open. So a caller who lands burnPending(0.001 IMD) first in each block pins the burn rate to dust and the budget never reaches 0xdEaD while they keep paying gas; the IMD is not lost (it stays in pendingBurn) and the griefer gains nothing, so this is a liveness delay at the griefer's cost, low. It also hands the sandwicher of finding 1 a cheap way to make sure the budget is still pending when they want it. Fix that keeps every number: only mark the block done when the tranche actually reached the bound or drained pendingBurn, i.e. set burnAnchorBlock only if `spent < imdIn` (the limit cut the swap) or `spent == pendingBurn`, or require imdIn == pendingBurn (the caller may not choose a smaller tranche: the bound already cuts it).","line":496,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/BurnJit.t.sol testDustTrancheSpendsTheBlock (same fixture as finding 1). alice buys 1,550 pages of subjectOf(carol): pendingBurn = 601.0125 IMD. bob calls pages.burnPending(0.001 ether): spent = 1e15 wei, burned = 987,499,837,473,985 wei of MARG, the block is anchored. In the same block anyone calls pages.burnPending(pendingBurn): expected per the brief (the budget buys MARG at the market's price) a tranche up to the block's bound (about 30 IMD at this depth); actual: revert BurnBudgetSpent and pendingBurn stays at 601.0115 IMD. Repeat in every block to defer the burn indefinitely. The test passes on the current code, i.e. the refusal happens.","severity":"low","snippet":"        if (burnAnchorBlock == block.number) revert BurnBudgetSpent();\n        burnAnchorBlock = uint64(block.number);","title":"The one-burn-per-block rule lets a dust tranche spend a block: anyone can starve the burn for the cost of gas"}],"hash":"bce3763f23ee41e5bbc457447ba95a44833d7cde885fcd11b19671ab106c0b69","nodeId":"a6d3618a-2945-48f4-817f-4d1b3fe3ec41","outcome":"completed","summary":"The review is complete. The findings file is written and validated, and no tracked file was changed.\n\n**Outcome of the two earlier findings**\n\n- **Burn sandwich (19412c9f, medium): partly fixed, kept as finding 1.** The one-burn-per-block rule does refuse the burn/sell/burn loop I reported, and the author's regression plus the 68 Pages tests pass. But the root cause stands: the tranche is bounded against the block's own spot and only by price level. An attacker who pushes the price and then supplies liquidity inside the band sells the entire pending budget to the burn without the price ever reaching the limit. The hook has no add-liquidity permission, so anyone can do this through the PoolManager in one transaction. The README's claim that this variant is held to about 30 IMD is wrong. Measured on the revision fixture with a 601 IMD budget:\n\n| Push (IMD) | Attacker net (IMD) | MARG burned | Honest burn |\n|---|---|---|---|\n| 600 | +56.15 | 490.33 | 540.08 |\n| 1,000 | +95.51 | 436.52 | 540.08 |\n| 2,000 | +155.80 | 335.21 | 540.08 |\n\n  Reproduction is in test/scratch/BurnJit.t.sol. Its assertion test fails on the current code. Suggested fixes keep every number: cap the per-block tranche by IMD volume, or take the reference price from something an in-block push cannot set, such as the hook's observations or a prior block's price.\n\n- **Escrow window restart (681b03fb, info): settled.** The README now states the trade-off as I offered. No code change was needed.\n\n**One new defect, introduced by the fix (finding 2, low)**\n\n- Any tranche that yields one wei of MARG now marks the block as burned. A caller landing burnPending with 0.001 IMD first in each block pins the burn rate to dust for the cost of gas. Nothing is lost, only delayed. Reproduced in the same scratch file.\n\n**Coverage**\n\nAll 40 entry points have a row. The nine Pages entry points are traced, with two marked as findings. The hook's fundPot, unlockCallback, swap callbacks and beforeInitialize, the token, the Treasury and the clone initialisers hold. The remaining 22 entry points of the already-live hook, judge and router are marked unreached: they are unchanged this round and not deployed by this manifest.","treeHash":null,"usage":{"cachedInputTokens":1729911,"inputTokens":514,"model":"claude-fable-5-1","outputTokens":28929,"runtime":"claude","turns":26,"wallClockMs":611665}},{"artifacts":[],"attempt":1,"bundleHash":"f28c988fc094146da0c566488666b45226f9c9e14501b79ac470597a9ae1db8e","device":"c0fc4ea4f50e3380","findings":[],"hash":"bd6dffedc1ff15aed661964235ed3f43d241bc191b02d88547e722540cd8c46c","nodeId":"8734f817-b327-4ca9-819c-8aa0a32ccfdd","outcome":"completed","summary":"Done. The full suite passes and only my two accepted test files changed.\n\n**What was wrong.** The implementation's latest accepted revision changed the MARG burn so that a block burns once: the first tranche anchors at the price it finds, and any further `burnPending` in that block reverts with `BurnBudgetSpent`, even when the price is still inside the bound. My accepted tests in `test/PagesEdges.t.sol` and `test/PagesInvariant.t.sol` were written against the old many-tranches-per-block rule, so two tests failed against the current tree, which was also the cause of the previous attempt's tree mismatch against its accepted dependency.\n\n**What I changed, minimally.**\n- `test/PagesEdges.t.sol`: the anchor test now asserts a second tranche in the same block is refused by name while the price is inside the bound, that the refusal leaves the anchor and queue alone, and that the next block anchors at the moved price and burns the rest. The external-push test keeps its assertions and is renamed to state the per-block rule it actually checks.\n- `test/PagesInvariant.t.sol`: the handler's burn action detects an anchored block, expects `BurnBudgetSpent` for both the whole queue and one wei, and checks the anchor, queue, pool balance and limit are untouched. A per-block ghost counter asserts no block ever takes two tranches, and the post-burn checks assert the anchor equals the price the tranche found. All six invariants still hold under fail-on-revert.\n\n**Verification.**\n\n| Check | Result |\n| --- | --- |\n| `forge test --match-path 'test/Pages*.sol'` | 68 passed, 0 failed |\n| `forge test` (whole repo) | 317 passed, 0 failed, 2 skipped (fork suites without an RPC URL) |\n| Scratch drive of the handler | the refusal branch and the next-block burn branch are both reached |\n\nNo defects found in the revised implementation, so no findings file was written. Nothing outside `test/` was touched and nothing was installed.","treeHash":"487110a063ebae913bfcb886825a7824571cb208","usage":{"cachedInputTokens":1526129,"inputTokens":706,"model":"claude-fable-5-1","outputTokens":14138,"runtime":"claude","turns":23,"wallClockMs":833839}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f009de0ce52c7b3a","findings":[{"citation":"resolved","description":"requestClaim(handle, tweetId) is permissionless and the question it builds tells the panel to answer 'the single Ethereum address written in the text field' of whatever tweet the caller names, as long as user.screen_name is the handle. Nothing in the question requires the tweet to be a claim statement for this page market (no mention of Marginalia, the chain, or this contract's address; the 'consumer' field is signing metadata, not an instruction about the tweet's content). Crypto accounts tweet single addresses constantly: token contracts, donation wallets, an exchange deposit address, a scammer they are warning about. For any such tweet, a stranger calls requestClaim with that tweetId, the panel truthfully answers the address in it, and onOracleResult makes it the payee: the whole escrow is transferred there, every later trade's 90% issuer share goes there, and because 'one successful claim per subject ever' is enforced (AlreadyClaimed) the real owner can never correct it. The attacker's 0.5 IMD is reimbursed from the escrow whenever it holds at least the price, so the attack is free against every handle worth attacking. The repository's own probe (jobs/oracle-claim-probe.json) shows the concrete case: tweet 2109295512424009991 by @bddnewstoday names the MARG token contract 0xfa0efea559bde229031c2b0a219472316647759c and the panel answered it 5/5. requestClaim(\"bddnewstoday\", 2109295512424009991) therefore turns that handle's escrow and future fees into IMD sent to a token contract, unrecoverable. Fix: make the question refuse any tweet that is not an explicit claim naming this deployment, e.g. 'answer the address only if the text also contains the exact string <this contract's address> (or a fixed claim phrase plus the chain id); otherwise answer zero', so only a deliberate claim tweet by the handle's owner can set a payee. questionBody already prints address(this); put it in the instruction, not only in the consumer field.","line":256,"path":"src/MarginaliaPages.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {MarginaliaPages, IMarginaliaHookPages} from \"src/MarginaliaPages.sol\";\nimport {IIntake} from \"src/interfaces/IIntake.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\n\n/// @notice The oracle question a claim asks must bind the tweet to THIS page market. As written, the panel is\n/// told to answer \"the single Ethereum address written in the text field\" of ANY tweet by the handle, so every\n/// handle that has ever tweeted one address (a token contract, a donation wallet, a scammer it warned about) can\n/// be claimed by anyone to that address, permanently, for the price of one oracle request that the escrow then\n/// reimburses. The fix is in the question text: the panel must be told to answer zero unless the tweet is a\n/// claim statement that names this contract (its address, as questionBody already prints it in the consumer\n/// field), so only a deliberate claim tweet can set a payee. This test fails while the question's instruction\n/// does not name the contract, and passes once it does.\ncontract PagesClaimBindingTest is Test {\n    MarginaliaPages pages;\n\n    function setUp() public {\n        pages = new MarginaliaPages(\n            IMarginaliaHookPages(address(0x1111)),\n            IIntake(address(0x2222)),\n            bytes32(\"oracle.request@oracle-1\"),\n            address(0x3333)\n        );\n    }\n\n    /// @dev The instruction the panel follows is the \"question\" string; everything after `\",\"chainId\"` is\n    /// metadata (consumer, guards) the panel does not read as a rule for the tweet's content.\n    function _question(string memory body) internal pure returns (string memory) {\n        bytes memory b = bytes(body);\n        bytes memory start = bytes('\"question\":\"');\n        bytes memory stop = bytes('\",\"chainId\"');\n        uint256 from = _indexOf(b, start, 0);\n        require(from != type(uint256).max, \"no question field\");\n        from += start.length;\n        uint256 to = _indexOf(b, stop, from);\n        require(to != type(uint256).max, \"no end of question\");\n        bytes memory q = new bytes(to - from);\n        for (uint256 i; i < q.length; ++i) {\n            q[i] = b[from + i];\n        }\n        return string(q);\n    }\n\n    function _indexOf(bytes memory hay, bytes memory needle, uint256 start) internal pure returns (uint256) {\n        if (needle.length > hay.length) return type(uint256).max;\n        for (uint256 i = start; i + needle.length <= hay.length; ++i) {\n            bool hit = true;\n            for (uint256 j; j < needle.length; ++j) {\n                if (hay[i + j] != needle[j]) {\n                    hit = false;\n                    break;\n                }\n            }\n            if (hit) return i;\n        }\n        return type(uint256).max;\n    }\n\n    /// @notice The probe tweet 2109295512424009991 by @bddnewstoday names the MARG token contract. With the\n    /// question as written the panel answers that contract address and the handle's escrow and every future\n    /// issuer fee go to a token contract forever. The question must require the tweet to name this contract.\n    function testClaimQuestionBindsTheTweetToThisContract() public view {\n        string memory body = pages.questionBody(\"bddnewstoday\", 2109295512424009991);\n        string memory question = _question(body);\n        bytes memory self = bytes(Strings.toHexString(address(pages)));\n        assertTrue(\n            _indexOf(bytes(question), self, 0) != type(uint256).max,\n            \"the panel's instruction does not require the tweet to name this page market, so any address the handle ever tweeted becomes its payee\"\n        );\n    }\n}","reproduction":"State: handle 'bddnewstoday' has pages bought (escrow >= 0.5 IMD) and is unclaimed. Input: anyone calls requestClaim(\"bddnewstoday\", 2109295512424009991) paying 0.5 IMD. The panel fetches the tweet, user.screen_name matches, the text contains exactly one address (the MARG token contract), so the attestation answers 0xfa0efea559bde229031c2b0a219472316647759c with agreed 5 >= quorum 4. onOracleResult sets subjects[subject].payee to the token contract, pays it the escrow less 0.5 IMD (the 0.5 IMD goes back to the attacker), and every later buy/sell of that subject pays its 90% issuer share to the token contract. Expected: only a tweet in which the handle deliberately claims its Marginalia page can set the payee. Actual: any single address the handle ever tweeted becomes the payee forever. test/scratch/PagesClaimBinding.t.sol fails on this code (the question's instruction never names this contract) and passes once the instruction requires the tweet to name it.","severity":"high","snippet":"                    \" then answer with the single Ethereum address written in the text field. If the document cannot be fetched, the handle differs, or the text names no address or more than one, answer 0x0000000000000000000000000000000000000000.\\\",\\\"chainId\\\":\"","title":"Claim question accepts any address the handle ever tweeted: anyone can permanently set a wrong payee and redirect the escrow and all future issuer fees"},{"citation":"resolved","description":"sell() calls _distributeFee, which calls _burnMarg for 0.5% of the value; unlockCallback performs an exact-input swap and then reverts with UnauthorizedCallback unless the pool consumed exactly imdIn and returned MARG (line 390), and the hook's afterSwap independently reverts PartialFill when the IMD delta is not negative. So the seller's payout, although fully covered by reserveOf[subject] (which fees never touch), is only reachable while the launch pool has liquidity in range for that amount. The hook does not lock the launch position ('no liquidity callbacks restrict seeding, withdrawals or LP fee claims', launch.json notes), so any LP, including the launch position's owner, can withdraw and every page holder is then locked out of their IMD until liquidity returns. The same path blocks a large sell whose burn exceeds what the pool can absorb at the unbounded price limit (the swap stops early, the delta is smaller than imdIn, UnauthorizedCallback), so a big holder must split sells or cannot exit. The promise 'the curve reserve always covers every holder selling out at any depth' therefore does not hold operationally. Buys are blocked in the same states, which is less harmful. Fix: never let the burn block the trade: if the swap cannot run (try/catch on poolManager.unlock, or a liquidity check) keep the burn's IMD in a pendingBurn balance that anyone can later burn with a permissionless call, and pay the seller from the reserve unconditionally. hook.fundPot has the same coupling (it also unlocks the PoolManager) but cannot fail for lack of liquidity.","line":232,"path":"src/MarginaliaPages.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {IHooks} from \"v4-core/src/interfaces/IHooks.sol\";\nimport {IUnlockCallback} from \"v4-core/src/interfaces/callback/IUnlockCallback.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {ModifyLiquidityParams} from \"v4-core/src/types/PoolOperation.sol\";\nimport {BalanceDelta} from \"v4-core/src/types/BalanceDelta.sol\";\nimport {ERC20} from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {SafeERC20} from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport {Marginalia} from \"src/Marginalia.sol\";\nimport {MarginaliaHook} from \"src/MarginaliaHook.sol\";\nimport {MarginaliaRouter} from \"src/MarginaliaRouter.sol\";\nimport {MarginaliaTreasury} from \"src/MarginaliaTreasury.sol\";\nimport {MarginaliaJudge} from \"src/MarginaliaJudge.sol\";\nimport {MarginaliaPricer} from \"src/MarginaliaPricer.sol\";\nimport {MarginaliaImpls} from \"src/MarginaliaImpls.sol\";\nimport {HookFlags} from \"src/HookFlags.sol\";\nimport {MarginaliaPages, IMarginaliaHookPages} from \"src/MarginaliaPages.sol\";\nimport {IIntake} from \"src/interfaces/IIntake.sol\";\n\ncontract ProofERC20 is ERC20 {\n    constructor() ERC20(\"Identity.md\", \"IMD\") {\n        _mint(msg.sender, 1_000_000_000 ether);\n    }\n}\n\ncontract ProofLiquidity is IUnlockCallback {\n    using SafeERC20 for IERC20;\n\n    IPoolManager public immutable manager;\n\n    constructor(IPoolManager m) {\n        manager = m;\n    }\n\n    function add(PoolKey memory key, int24 lower, int24 upper, int256 amount) external {\n        manager.unlock(abi.encode(key, ModifyLiquidityParams(lower, upper, amount, bytes32(0))));\n    }\n\n    function unlockCallback(bytes calldata data) external returns (bytes memory) {\n        require(msg.sender == address(manager));\n        (PoolKey memory key, ModifyLiquidityParams memory p) = abi.decode(data, (PoolKey, ModifyLiquidityParams));\n        (BalanceDelta delta,) = manager.modifyLiquidity(key, p, \"\");\n        _settle(key.currency0, delta.amount0());\n        _settle(key.currency1, delta.amount1());\n        return \"\";\n    }\n\n    function _settle(Currency c, int128 d) private {\n        if (d < 0) {\n            manager.sync(c);\n            IERC20(Currency.unwrap(c)).safeTransfer(address(manager), uint256(-int256(d)));\n            manager.settle();\n        } else if (d > 0) {\n            manager.take(c, address(this), uint256(uint128(d)));\n        }\n    }\n}\n\ncontract ProofIntake is IIntake {\n    function priceOf(bytes32, address) external pure returns (uint256) {\n        return 0.5 ether;\n    }\n\n    function request(bytes32, bytes calldata, Callback calldata, address, uint256)\n        external\n        payable\n        returns (bytes32)\n    {\n        return bytes32(uint256(1));\n    }\n}\n\n/// @notice \"The curve reserve always covers every holder selling out at any depth\" is only true while the launch\n/// pool can absorb the 0.5% MARG buy every trade makes: sell() reverts whenever that swap moves nothing, so the\n/// reserve is intact but unreachable. Here the pool's one position is withdrawn and alice, the only holder,\n/// cannot sell. A fix pays the seller from the reserve regardless of the burn (for example keeps the burn's IMD\n/// aside for a later permissionless burn when the swap cannot run), which is what this test then asserts.\ncontract PagesExitNeedsPoolTest is Test {\n    IPoolManager manager;\n    Marginalia token;\n    ProofERC20 imd;\n    MarginaliaHook hook;\n    PoolKey key;\n    ProofLiquidity liquidity;\n    MarginaliaPages pages;\n    address alice = makeAddr(\"alice\");\n    address carol = makeAddr(\"carol\");\n\n    function _deployHook(IPoolManager m, address t) internal returns (MarginaliaHook) {\n        vm.etch(MarginaliaImpls.ROUTER_IMPL, address(new MarginaliaRouter()).code);\n        vm.etch(MarginaliaImpls.JUDGE_IMPL, address(new MarginaliaJudge()).code);\n        vm.etch(MarginaliaImpls.TREASURY_IMPL, address(new MarginaliaTreasury()).code);\n        vm.etch(MarginaliaImpls.PRICER, address(new MarginaliaPricer()).code);\n        bytes memory code = abi.encodePacked(type(MarginaliaHook).creationCode, abi.encode(m, t, address(this)));\n        bytes32 hash = keccak256(code);\n        for (uint256 i = 0; i < 300_000; ++i) {\n            bytes32 salt = bytes32(i);\n            address predicted =\n                address(uint160(uint256(keccak256(abi.encodePacked(bytes1(0xff), address(this), salt, hash)))));\n            if (!HookFlags.matches(predicted, HookFlags.MARGINALIA)) continue;\n            address deployed;\n            assembly (\"memory-safe\") {\n                deployed := create2(0, add(code, 32), mload(code), salt)\n            }\n            require(deployed == predicted && deployed.code.length > 0, \"deployment failed\");\n            return MarginaliaHook(deployed);\n        }\n        revert(\"mining exhausted\");\n    }\n\n    function setUp() public {\n        vm.warp(1_800_000_000);\n        vm.roll(20_000_000);\n        manager = IPoolManager(address(new PoolManager(address(this))));\n        token = new Marginalia();\n        imd = new ProofERC20();\n        hook = _deployHook(manager, address(token));\n        bool margIs0 = address(token) < address(imd);\n        (address c0, address c1) = margIs0 ? (address(token), address(imd)) : (address(imd), address(token));\n        key = PoolKey(Currency.wrap(c0), Currency.wrap(c1), 12500, 60, IHooks(address(hook)));\n        manager.initialize(key, uint160(1 << 96));\n        liquidity = new ProofLiquidity(manager);\n        token.transfer(address(liquidity), 50_000_000 ether);\n        imd.transfer(address(liquidity), 50_000_000 ether);\n        liquidity.add(key, -6000, 6000, 10_000_000 ether);\n        pages = new MarginaliaPages(\n            IMarginaliaHookPages(address(hook)), new ProofIntake(), bytes32(\"oracle.request@oracle-1\"), address(0x5E7)\n        );\n        imd.transfer(alice, 1_000 ether);\n        vm.prank(alice);\n        imd.approve(address(pages), type(uint256).max);\n    }\n\n    function testHolderCanAlwaysSellOutEvenWhenThePoolIsEmpty() public {\n        bytes32 subject = pages.subjectOf(carol);\n        vm.prank(alice);\n        pages.buy(subject, 5, type(uint256).max);\n        assertEq(pages.pagesOf(subject, alice), 5);\n        (uint256 value, uint256 fee) = pages.sellPrice(subject, 5);\n        assertEq(pages.reserveOf(subject), value, \"the reserve covers alice selling out\");\n        // the launch pool's only position is withdrawn (any LP may do this; nothing in the hook prevents it)\n        liquidity.add(key, -6000, 6000, -10_000_000 ether);\n        uint256 before = imd.balanceOf(alice);\n        vm.prank(alice);\n        pages.sell(subject, 5, 0);\n        assertEq(imd.balanceOf(alice) - before, value - fee, \"alice is paid from the reserve\");\n        assertEq(pages.pagesOf(subject, alice), 0);\n    }\n}","reproduction":"State: alice holds 5 pages of subjectOf(carol) (reserve 1.5 IMD). The pool's only position is withdrawn by its LP (ProofLiquidity.add with a negative amount in the proof; on mainnet the launch position's owner or any LP). Input: alice calls sell(subject, 5, 0). Expected: alice receives 1.5 IMD minus the 0.15 IMD fee from the reserve, which holds exactly that. Actual: the call reverts (PoolManager WrappedError wrapping the hook's PartialFill, or UnauthorizedCallback at line 390 when the swap returns nothing); pagesOf and reserveOf are unchanged and no holder of any subject can sell while the pool is empty. test/scratch/PagesExitNeedsPool.t.sol fails on this code and passes once sell pays the seller regardless of the burn swap.","severity":"medium","snippet":"        if (toBurn > 0) _burnMarg(toBurn);","title":"Every trade, including every sell, requires a successful MARG buy on the launch pool: with no in-range liquidity (or a burn larger than the pool can absorb) sells revert and holders cannot reach the r"},{"citation":"resolved","description":"unlockCallback swaps the burn amount with the price limit at MIN_SQRT_PRICE+1 / MAX_SQRT_PRICE-1 and accepts any MARG output above zero (line 390). A searcher can front-run a large page trade with a MARG buy, let the Pages contract buy at the pushed price, and sell back: the trader is unaffected (they pay value + fee regardless) but the MARG actually burned shrinks to almost nothing and the difference is the searcher's profit. Deep trades make this worth doing: 1000 pages at supply 0 is 50,050 IMD of value, a 250 IMD market buy with no minimum output. Fix: bound the output with a minimum derived from the pool's current price before the swap (e.g. require marg >= imdIn * 1e18 / hook.margPriceInImd() * (1 - maxSlippage)), or accumulate burn IMD and let a keeper burn it with a caller-supplied minOut.","line":384,"path":"src/MarginaliaPages.sol","reproduction":"State: pool at 1 MARG = 1 IMD with the fixture's liquidity. Sequence in one block: (1) searcher buys MARG with 1,000,000 IMD through the pool, moving the price up; (2) alice calls buy(subjectOf(carol), 1000, type(uint256).max): unlockCallback swaps 250.25 IMD for MARG at the pushed price and the Burned event shows far less MARG than the ~247 MARG the same IMD bought before step 1; (3) searcher sells the MARG back for more IMD than it paid. Expected: a bounded burn (revert or deferral when the output is below a floor). Actual: any output above zero is accepted.","severity":"low","snippet":"                zeroForOne, -int256(imdIn), zeroForOne ? TickMath.MIN_SQRT_PRICE + 1 : TickMath.MAX_SQRT_PRICE - 1","title":"The MARG burn swap has no slippage bound: MEV sandwiches capture part of the burn on every trade"},{"citation":"resolved","description":"amount is a uint256 priced with priceOf(supply, amount) and credited to pagesOf[subject][msg.sender] in full, but supply is updated with uint64(amount), which wraps for amount >= 2^64. A buy of exactly 2^64 pages would leave supply unchanged while pagesOf grows by 2^64, breaking the supply/pagesOf/reserve relation sellPrice relies on. It is not reachable in practice (the price of 2^64 pages is about 1.7e55 IMD and the burn swap would have to absorb 5e-4 of it, so the trade reverts long before), so this is a robustness defect, not an exploit, but the cast is unchecked and should be: require(amount <= type(uint64).max) or use SafeCast.toUint64, in both buy and sell.","line":197,"path":"src/MarginaliaPages.sol","reproduction":"Input: buy(subject, 2^64, type(uint256).max) by a caller holding priceOf(0, 2^64) * 1.1 IMD (only possible with a mintable mock, test/scratch/Probe.t.sol::testBuyAmountTruncation). Expected: revert on the unrepresentable amount. Actual on this code: the IMD is pulled, supply stays 0 while pagesOf is 2^64; the trade then happens to revert inside the burn swap (UnauthorizedCallback) because the pool cannot absorb the burn, which is the only thing preventing the inconsistent state.","severity":"low","snippet":"        s.supply += uint64(amount);","title":"buy()/sell() silently truncate amount to uint64 when adding to supply while pagesOf and the price use the full uint256"},{"citation":"resolved","description":"The callback looks up the subject by the Intake's requestId argument, verifies the signature in this contract's domain, and consumes a.requestId (the oracle's UUID), but never checks that a.requestId belongs to that Intake request nor that a.questionHash is the hash of the question this contract built for that subject. Any attestation signed for this contract would be accepted as the answer to whichever pending request the Intake presents it with. With an honest Intake this is not exploitable (the Intake delivers each answer under the request it was bought for, and a request made directly on the Intake naming this contract as callback gets a requestId this contract does not know, so it is refused with UnknownRequest), and the question cannot be hash-pinned because its window is relative, which the Judge documents as the same limitation ('relies on Intake request routing without comparing questionHash'). Recorded so the adapter and the panel treat the Intake as a trusted component of the claim path; a cheap hardening is to store the Intake requestId in the Claim and require the Intake to deliver a.requestId equal to it if the live Intake uses the same id for both.","line":321,"path":"src/MarginaliaPages.sol","reproduction":"Not reproducible against an honest Intake; it is a trust statement. Setup that shows the missing check: two pending claims for subjects S1 and S2; an attestation signed for S1's question (answer W) delivered by the Intake under S2's requestId is accepted and sets S2's payee to W. Expected: refused because a.questionHash does not match S2's question. Actual: accepted.","severity":"info","snippet":"        _consume(a.requestId);","title":"onOracleResult trusts the Intake's routing entirely: the attestation's own requestId and questionHash are never compared with the request being answered"},{"citation":"resolved","description":"Read in full: src/MarginaliaPages.sol, src/OracleAttestation.sol, src/interfaces/IIntake.sol, src/Marginalia.sol, test/Pages.t.sol, test/helpers/Fixture.sol. Read for the paths Pages depends on: src/MarginaliaHook.sol (beforeSwap/afterSwap for a quiet buy, fundPot/_fund and the ACT_FUND unlock branch, getPoolKey) and src/MarginaliaJudge.sol (requestJudging/onOracleResult, the pattern Pages copies). Not read: MarginaliaRouter, MarginaliaTreasury, MarginaliaPricer, MarginaliaTypes, HookFlags, MarginaliaImpls (not on any Pages path), and the live Intake's and IMD token's source (only their on-chain reads). Checks run: forge test --match-path test/Pages.t.sol (12/12 pass); worst-case onOracleResult gas with fresh recipient balances is 145,817 under the 200k stipend (test/scratch/Probe.t.sol); the EIP-712 digest of the protocol's conformance vector and the callback selector match the protocol (test/scratch/Vector.t.sol); runtime is 14,954 bytes with no DELEGATECALL/CALLCODE/SELFDESTRUCT under the protected opcode scan; the constructor makes no external call. Live reads over a public RPC on 2026-10-12: hook 0xf0457dd0...a0cc returns imd() = 0xD34a99Bc...63B7, token() = 0xfA0EfEa5...759c, poolManager() = 0x00000000...8A90, INTAKE() = 0x1397434c...ea56, ORACLE_SIGNER() = 0x5598Aa91...2982 (an EOA, no code), ACTION() = bytes32('oracle.request@oracle-1'), initialized() = true, getPoolKey() = (IMD, MARG, 12500, 60, hook); the Intake's priceOf(action, IMD) is 0.5 IMD, under MAX_PRICE. No Slither or Mythril run. For the manifest step: the bytes32 constructor argument is written as the static word 0x6f7261636c652e72657175657374406f7261636c652d31000000000000000000, and the three addresses as static words (none is $owner).","line":119,"path":"src/MarginaliaPages.sol","reproduction":"Not a defect; the record of what was read and verified.","severity":"info","snippet":"    constructor(IMarginaliaHookPages hook_, IIntake intake_, bytes32 action_, address signer_)","title":"Review scope, launch checks and live-constant verification"}],"hash":"d14e760cc3202a1df8c90820200461b20c944d69cd41244f365baae51ede7661","nodeId":"03a154fc-6a24-43c1-afe0-245603ae6434","outcome":"completed","summary":"The review is complete. No tracked file was changed; the findings are in `.imd-findings.json` at the repository root, and the proof tests live under `test/scratch/`, which is ignored.\n\n**Outcome: one high, one medium, two low, two info findings on MarginaliaPages.** The local suite passes 12/12 and the launch-level checks (runtime size, forbidden opcodes, constructor purity, EIP-712 vector, callback selector, 200k stipend) all pass.\n\n**High: the claim question binds the tweet to nothing.** The panel is asked for \"the single Ethereum address written in the text field\" of any tweet by the handle. Any handle that ever tweeted one address (a token contract, a donation wallet, a scammer it warned about) can be claimed by a stranger to that address, permanently, with the oracle fee reimbursed from escrow. The repository's own probe is the concrete case: the tweet by @bddnewstoday names the MARG token contract, so `requestClaim(\"bddnewstoday\", 2109295512424009991)` sends that handle's escrow and all future issuer fees to a token contract forever. Proof: `test/scratch/PagesClaimBinding.t.sol` (fails now, passes once the question requires the tweet to name this contract).\n\n**Medium: every sell needs a successful MARG buy on the launch pool.** The burn swap must consume exactly its input and return MARG, and the hook's afterSwap reverts on a partial fill. With no in-range liquidity, or a burn larger than the pool absorbs, sells revert while the reserve sits untouched. Nothing locks the launch position. Proof: `test/scratch/PagesExitNeedsPool.t.sol`.\n\n**Low:** the burn swap has no slippage bound (sandwichable on deep trades), and `amount` is silently truncated to uint64 when updating supply (unreachable in practice, but unchecked).\n\n**Info:** the callback trusts the Intake's routing entirely (no `questionHash` or request-id binding, same documented limit as the Judge), plus the scope record.\n\n**Verified live over RPC:** the hook at 0xf0457dd0…a0cc reports the IMD token, MARG, the canonical PoolManager, the Intake, the EOA signer and the action bytes32 exactly as the brief states, its pool is initialized at fee 12500, and the Intake quotes 0.5 IMD, under `MAX_PRICE`.\n\n**Read in full:** MarginaliaPages, OracleAttestation, IIntake, Marginalia, Pages.t.sol, Fixture. **Read on the dependent paths only:** MarginaliaHook (quiet-buy swap callbacks, fundPot, ACT_FUND unlock, getPoolKey) and MarginaliaJudge (oracle request/callback). **Not read:** Router, Treasury, Pricer, Types, HookFlags, Impls, and the live Intake and IMD token sources. No Slither or Mythril was run.","treeHash":null,"usage":{"cachedInputTokens":1603245,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":53063,"runtime":"claude","turns":30,"wallClockMs":1418375}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"9b06782c7559b54c","findings":[{"citation":"resolved","description":"Boundary (sentinel-address branch, Boundary guide step 4): payeeOf(subject) returns address(uint160(subject)) for every subject whose top 96 bits are zero, with no exclusion for address(this), the hook, or any other contract that cannot act on IMD. subjectOf(address(pages)) therefore has payee == address(pages) and _distributeFee does IERC20(imd).safeTransfer(address(this), toIssuer): a self-transfer that leaves 90% of every fee of that subject inside Pages, counted in no reserveOf, no escrow and not in pendingBurn. No function can ever move it (there is no sweep, and the only outflows are the reserve, escrow and pendingBurn paths). subjectOf(address(hook)) sends the 90% to the hook as a raw ERC-20 balance, bypassing fundPot/_accrue: the hook pays pools only from ERC-6909 claims it minted, so that IMD is likewise unreachable (the live hook holds 0 raw IMD today). Impact is bounded to the fee the trader chose to pay on a nonsensical subject, so this is a low, but the invariant the existing fuzz test asserts (balance == sum reserves + escrow + pendingBurn) silently breaks for these subjects. Fix: in payeeOf (or buy/sell) refuse address subjects equal to address(this) and address(hook) (BadClaim), or route them to the escrow/recycle path.","line":233,"path":"src/MarginaliaPages.sol","reproduction":"Local fixture (test/helpers/Fixture.sol), fresh MarginaliaPages on the local hook. (1) subject = pages.subjectOf(address(pages)); pages.payeeOf(subject) == address(pages). (2) alice: pages.buy(subject, 1, max): value 0.1e18, fee 0.01e18, toIssuer 0.009e18, toBurn 0.0005e18, toPools 0.0005e18. Expected: contract IMD balance == reserveOf + escrow + pendingBurn (the invariant test/PagesAudit.t.sol asserts). Actual: imd.balanceOf(pages) = 0.1095e18, reserveOf+pendingBurn = 0.1005e18, 0.009e18 unaccounted. (3) alice: pages.sell(subject, 1, 0): reserve 0, pendingBurn 0.001e18, contract balance 0.019e18: 0.018e18 IMD stranded forever. Same call with subject = pages.subjectOf(address(hook)): hook raw IMD balance +0.009e18, pools (refundPool+thesisPool) only +0.0005e18. Verified with test/scratch/SelfPayee.t.sol (both tests pass on current code, i.e. the stranding happens).","severity":"low","snippet":"            IERC20(imd).safeTransfer(payee, toIssuer);","title":"Issuer share of an address subject that is the Pages contract or the hook is self-transferred and stranded outside every accounted balance"},{"citation":"resolved","description":"Boundary (caller-supplied parameter without an on-chain bound, Boundary guide step 2 item 10). The comment at lines 391-392 says 'The caller chooses a meaningful floor from an independent quote', but the function is permissionless, so the floor is chosen by whoever wants the burn to execute badly: a front-runner who first buys MARG with a large IMD amount, then calls burnPending(pendingBurn, 1), then sells back. The contract has margPriceInImd() on the hook and the pool's slot0 available but never checks the received MARG against them. Measured on the fixture pool (10M liquidity at 1:1, 1.25% LP fee, 3% quiet-sell hook fee), with 2,250.75 IMD pending: an honest burn receives 2,222.12 MARG; after a 2,000,000 IMD front-run it receives 1,549.65 MARG (30% less burned). At this depth the sandwicher loses 103,642 IMD to LP and hook fees, so the attack is pure griefing here; it becomes profitable only when the pending tranche is a few percent of pool depth, and pendingBurn accumulates without bound until someone burns it. Severity low: no reserve, escrow or holder funds are at risk (the IMD still enters the pool), only the amount of MARG actually burned. Fix: bound the output on chain, e.g. require marg >= imdIn * 1e18 / hook.margPriceInImd() * (10_000 - MAX_IMPACT_BPS) / 10_000 inside unlockCallback, and/or cap a tranche relative to pool liquidity.","line":396,"path":"src/MarginaliaPages.sol","reproduction":"Fixture pool; carol's address subject. (1) alice buys 3000 pages: pendingBurn = 2,250.75 IMD. (2) Snapshot: burnPending(2250.75e18, 1) alone burns 2,222.12 MARG (fair). Revert snapshot. (3) bob: plain.swap(key, IMD->MARG, 2_000_000e18) then burnPending(2250.75e18, 1) then plain.swap back: MARG burned = 1,549.65 (expected: close to 2,222; actual: 30% less), bob's IMD delta = -103,642 IMD (griefing cost at this depth). Numbers from test/scratch/BurnSandwich.t.sol logs.","severity":"low","snippet":"        if (minMargOut == 0) revert Slippage();","title":"burnPending's only execution-quality floor is the permissionless caller's minMargOut, so any caller may execute the burn at an arbitrary price (floor 1 wei)"},{"citation":"resolved","description":"Boundary (zero input). The brief says the asker pays 'the Intake's current price ... refused above MAX_PRICE 1 IMD'. The code also refuses price == 0. If the Intake ever prices oracle.request@oracle-1 at 0 for IMD (a promotion, or the action version retired and re-added free), no claim can be requested, escrows keep accumulating and are recycled into the hook's pools after 90 days, and the handle owners never get their share. Today the live Intake returns 0.5e18 for this action and IMD, so this is informational. A zero price needs no transferFrom and no approval; the branch could simply skip them.","line":306,"path":"src/MarginaliaPages.sol","reproduction":"test/Pages.t.sol testPriceGuardAndAddressSubjectsNeedNoClaim already shows it: intake.setPrice(0); carol: pages.requestClaim('pricey', 1) reverts PriceMismatch. Expected per brief: a claim at the Intake's current price (0); actual: refused.","severity":"info","snippet":"        if (price == 0 || price > MAX_PRICE) revert PriceMismatch();","title":"requestClaim refuses a zero Intake price, which the brief does not ask for: a free oracle action makes every handle permanently unclaimable"}],"hash":"e2672db8113049dd167de58201a11d103c85ade6700604027b6220ee55dc37e8","nodeId":"e9cbd83e-293f-4afa-b244-db130bf5964b","outcome":"completed","summary":"The review is complete. The findings file is written and validated, and no tracked files were changed.\n\n**Result: no critical, high or medium defect in the Pages math.** The bonding curve and fee splits are integer-exact: the n-th page price sum a(2s+a+1)/2 is always even, every trade value is a multiple of 0.1 IMD, so the 10% fee and its 90/5/5 split leave zero dust, and the reserve equals priceOf(0, supply) after any sequence of buys and sells. The oracle callback needs 157,579 gas in the worst cold case against an OpenZeppelin-style token, inside the 200k stipend, and the live IMD token's transfer cost matches that model. The live hook at the given address has the same bytecode length as this repository's hook, exposes fundPot and poolManager, and holds the Intake, action and signer constants the brief names, and the Intake prices the action at 0.5 IMD today.\n\nThree findings were recorded in `.imd-findings.json`, all reproduced locally:\n\n- **Low:** an address subject equal to the Pages contract or the hook sends the 90% issuer share to itself or to the hook's raw balance, where no function can ever reach it. Buying one page of the contract's own subject strands 0.009 IMD and breaks the balance invariant the existing fuzz test asserts.\n- **Low:** the burn's only price floor is the permissionless caller's own parameter. A front-run of 2,000,000 IMD cut the burned MARG by 30% in the fixture, though the attacker lost 103,642 IMD to fees at that depth, so it is griefing rather than profit today.\n- **Info:** a zero Intake price is refused although the brief only caps it at 1 IMD, which would make every handle unclaimable if the action were ever free.\n\nCoverage lists all 41 listed entry points plus three invariant rows. Every Pages entry point, the hook's fundPot, unlockCallback, beforeSwap and afterSwap paths that Pages exercises, and the token are traced. The remaining hook, judge, router and treasury functions are marked unreached as they lie outside the assigned area.","treeHash":null,"usage":{"cachedInputTokens":1770858,"inputTokens":450,"model":"claude-fable-5-1","outputTokens":48820,"runtime":"claude","turns":34,"wallClockMs":1133462}},{"artifacts":[],"attempt":2,"bundleHash":"5996c5baea82036842f146013aa37549d3acb74f56d16245ac7ab7fea700de53","device":"de319b702da6aa2e","findings":[],"hash":"fab8838ce9317d5c419da4cfa005ae69d0e8a9d20049cb74f6261b6aec7b6382","nodeId":"0ae19a5b-0de8-4d38-a624-f0912d65a276","outcome":"completed","summary":"I've fixed the reopened burn-sandwich finding, three of the five advisory findings, and answered all six in `.imd-responses.json`. `forge build` passes, and `forge test` gives 285 passed, 0 failed and 2 skipped (the two optional fork suites, which skip without an RPC URL). Nothing is committed.\n\n**Burn sandwich (b28cbca9, medium): reproduced and fixed.** On the reviewer's pool the old code gave the attacker exactly the reported profits: +49.65, +78.76, +102.29 and +126.62 IMD for attacks of 400, 700, 1,000 and 1,400 IMD.\n- **The fix:** `burnPending` now runs at most one burn per block. Its swap stops where MARG's price is 1% (`MAX_BURN_IMPACT_BPS`) above where it started, instead of having no limit. If the band is reached first, the leftover IMD stays queued for a later block.\n- **Why it works:** a sandwich can now gain at most about 1% on its own volume, but pays two 1.25% pool fees plus the hook's 3% sell fee. The same four attacks now lose 17.68, 30.72, 43.62 and 60.60 IMD. A scratch fuzz of 3,000 runs (attacks of 1 to 2,000 IMD, three pool shapes) found no profitable sandwich.\n- **What I ruled out:** my first version let the band restart within a block. My own test showed an attacker could profit (+49.3 IMD) by selling into the burn and triggering it again, so the rule is strictly one burn per block.\n- **What's left:** someone who controls several blocks in a row could stack several 1% bands. Someone can also spend a block's single burn on a tiny amount, which delays the burn but cannot divert the IMD. Both are written up in the README.\n- **Every existing number is unchanged.** The 1% limit is a new constant.\n\n**Advisory findings:**\n- **Claim callback gas (f2228aa4): fixed.** The oracle callback now only checks and records the answer, with no token transfers: 105,843 gas against the 200,000 limit. A new function anyone can call, `settleClaim(subject)`, pays out the escrow minus the refunded oracle price, with the same amounts as before. From the moment the answer lands, trades pay the new payee directly and the escrow can't be recycled. This means a successful claim now takes a second transaction to pay out. Four existing tests now call `settleClaim` before checking balances, with unchanged amounts.\n- **Market/hook as subject (8a9e9350): fixed.** If the subject's address is the Pages contract or the hook, its 90% issuer share now goes into escrow and is later recycled to the pools, instead of being stuck. An oracle answer naming either counts as a failed claim.\n- **Dust burn (e209caca): fixed.** A burn too small to buy any MARG now fails with its own `BurnTooSmall` error instead of the misleading `UnauthorizedCallback`.\n- **Recycle race (0680ae89): disputed, no code change.** It reproduces, but the brief sets the rule: escrow becomes recyclable 90 days after the first buy. The README now tells handle owners to claim early.\n- **Fixed oracle settings (8681a890): disputed as a defect, no code change.** It's accurate, but the brief requires the four stored values and no owner. The consequences of a signer key change or retired oracle action are now in the README.\n\n**Other checks:**\n- **Launch check:** the launch's own deployment check (copied from the task's read-only inputs) passes against the new bytecode with the four constructor arguments. The deployed code is 16,944 bytes, under the 24,576 limit, and has no forbidden opcodes.\n- **Mainnet fork:** the fork tests passed 2/2 against the live hook, IMD and Intake via `https://ethereum-rpc.publicnode.com`. The local RPC used in the first round was no longer running.\n\nThe source change is all in `src/MarginaliaPages.sol`, with the new tests in `test/PagesReview.t.sol`. `ADAPTATION.md` and `README.md` describe the changes.","treeHash":"d3981e86bdcfb6ec87a4cc10efbe607706ace350","usage":{"cachedInputTokens":7432975,"inputTokens":104,"model":"claude-opus-5-5","outputTokens":70105,"runtime":"claude","turns":55,"wallClockMs":2122524}},{"artifacts":[],"attempt":1,"bundleHash":"55d27182db19d604dee3b235ecff31fa5d8262009798f2851c379c880d3e6592","device":"93ca4a1020037bf1","findings":[],"hash":"fda023596c5c4ad236f573c12eb5efc94741462063bcd87642925f816793e48c","nodeId":"6293b162-09df-438e-8474-990ee57d86b6","outcome":"completed","summary":"I've rewritten the notes in `launch.json`. The contract entry and its four constructor arguments are unchanged; the notes now describe the current source. `forge build` passes and `forge test --match-path test/Pages.t.sol` passed 12 of 12. I didn't run the full test suite this round. `launch.json` is the only file changed.\n\n**Why the notes changed:** another contributor revised `src/MarginaliaPages.sol` after my manifest was accepted last round. Three things the old notes didn't cover:\n- **Claim payout:** when the oracle answers, the callback now only records the payee. Anyone then calls `settleClaim` to pay out the escrow, minus the oracle price paid back to whoever asked.\n- **MARG burn:** `burnPending` now runs at most once per block and stops at a 1% price move.\n- **Market and hook as issuers:** if this contract or the hook is the issuer, its 90% share now waits in escrow instead of being paid out.\n\n**What stayed the same:**\n- **One contract:** `MarginaliaPages`.\n- **Constructor:** the source still takes the same four parameters in the same order: `(hook, intake, action, signer)`.\n- **Arguments:** the hook `0xf0457dd0cf526686190e4f057ba19db14d34a0cc`, the Intake `0x1397434cd35e8a9C8aC312A61D3A285EB31dea56`, the action `0x6f7261636c652e72657175657374406f7261636c652d31000000000000000000`, and the signer `0x5598Aa9146215Bc13eb26f2c692Ad1461Fd32982`. I re-checked the action value with `cast --format-bytes32-string`; it is `bytes32('oracle.request@oracle-1')`.\n- **Format:** the file still has only the `kind`, `contracts` and `notes` keys, and the notes are 1,485 characters, under the 4,000 limit.","treeHash":"d560eeb7cd2e53ef648970eae9e43b3956f2d54b","usage":{"cachedInputTokens":308722,"inputTokens":14,"model":"claude-opus-5-5","outputTokens":3117,"runtime":"claude","turns":7,"wallClockMs":563897}}],"verification":[{"checks":[{"durationMs":322207,"exitCode":0,"name":"build","output":"Compiling 127 files with Solc 0.8.26\nSolc 0.8.26 finished in 321.95s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:189:17\n    │\n189 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:284:13\n    │\n284 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:242:9\n    │\n242 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:257:9\n    │\n257 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:273:39\n    │\n273 │             if (s.escrowSince == 0 || block.timestamp >= uint256(s.escrowSince) + CLAIM_WINDOW) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:274:33\n    │\n274 │                 s.escrowSince = uint64(block.timestamp);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:349:21\n    │\n349 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n350 │ ┃             action,\n351 │ ┃             bytes(questionBody(normalized, tweetId)),\n352 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n353 │ ┃             imd,\n354 │ ┃             price\n355 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:360:9\n    │\n360 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:358:63\n    │\n358 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:389:13\n    │\n389 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:398:9\n    │\n398 │         emit Claimed(subject, wallet, owed - reimbursed, reimbursed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:397:55\n    │\n397 │         settlements[subject] = Settlement(c.claimant, uint96(reimbursed));\n    │                                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint96' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:425:13\n    │\n425 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:442:9\n    │\n442 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:437:13\n    │\n437 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:443:9\n    │\n443 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `pendingBurn` is updated\n    ╭▸ src/MarginaliaPages.sol:456:38\n    │\n456 │         (spent, burned) = abi.decode(hook.poolManager().unlock(abi.encode(imdIn)), (uint256, uint256));\n    │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:458:9\n    │\n458 │         emit Burned(spent, burned);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:455:44\n    │\n455 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:455:52\n    │\n455 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:475:50\n    │\n475 │             return l > TickMath.MIN_SQRT_PRICE ? uint160(l) : TickMath.MIN_SQRT_PRICE + 1;\n    │                                                  ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:478:46\n    │\n478 │         return u < TickMath.MAX_SQRT_PRICE ? uint160(u) : TickMath.MAX_SQRT_PRICE - 1;\n    │                                              ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:490:31\n    │\n490 │             burnAnchorBlock = uint64(block.number);\n    │                               ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:495:68\n    │\n495 │         BalanceDelta d = manager.swap(key, SwapParams(zeroForOne, -int256(imdIn), limit), \"\");\n    │                                                                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:498:25\n    │\n498 │         if (inD >= 0 || uint256(-int256(inD)) > imdIn) revert UnauthorizedCallback();\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:500:25\n    │\n500 │         uint256 spent = uint256(-int256(inD));\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:501:24\n    │\n501 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:501:32\n    │\n501 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:506:9\n    │\n506 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:109:25\n    │\n109 │         uint256 start = block.number;\n    │                         ━━━━━━━━━━━━\n    ‡\n113 │             vm.roll(start + blocks);\n    │             ─────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:165:25\n    │\n165 │         assertEq(since, block.timestamp);\n    │                         ━━━━━━━━━━━━━━━\n166 │         vm.warp(block.timestamp + 91 days);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:166:17\n    │\n166 │         vm.warp(block.timestamp + 91 days);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":7687,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 498.33µs (0.00ns CPU time)\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 673.00µs (298.32µs CPU time)\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 968.26µs (0.00ns CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 2.13ms (1.69ms CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 647484)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 4220844)\n[PASS] testColdCallbackPaysTwoFreshBalancesUnderStipendWithDistinctIds() (gas: 357232)\nLogs:\n  delivery gas including mock Intake overhead: 160691\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14307)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 91411)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 704831)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.59ms (4.68ms CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 12.62ms (10.81ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 15.41ms (8.37ms CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 17.98ms (5.02ms CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2679131)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2473717)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 695581)\n[PASS] testCurveIsLinear() (gas: 37654)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 4078061)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 64049)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37676)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 171079)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2378488)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 784018)\n[PASS] testSlippageAndNoCap() (gas: 616990)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1949596)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 21.72ms (17.85ms CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 24.21ms (31.66ms CPU time)\n\nRan 7 tests for test/PagesRevision.t.sol:PagesRevisionTest\n[PASS] testAccrualAfterTheWindowOpensANewWindowInsteadOfBeingRecyclableAtOnce() (gas: 2917756)\n[PASS] testBoundedBurnsAcrossBlocksBurnTheWholeBudgetAtMarket() (gas: 4980668)\n[PASS] testCallbackOnlyVerifiesAndStoresThenAnyoneSettles() (gas: 2541580)\nLogs:\n  delivery gas including the mock Intake's overhead: 153153\n\n[PASS] testDustTrancheIsRefusedByName() (gas: 653765)\n[PASS] testMarketAndHookCannotBeSubjects() (gas: 403498)\n[PASS] testOneBlockOfBurningMovesThePriceAtMostTheBound() (gas: 660282)\n[PASS] testSandwichingTheBurnLosesMoneyAtEverySize() (gas: 2780610)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 25.37ms (13.41ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 13563035)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 33.00ms (32.77ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 84.03ms (69.22ms CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 106.69ms (13.09ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 111.39ms (169.35ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 23636, ~: 21950)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 112.37ms (32.49ms CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 121.24ms (40.85ms CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 121.37ms (16.70ms CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2387844)\n[PASS] testBurnAfterAManipulatedPriceStaysBoundedAndCannotBlockTrading() (gas: 1193420)\n[PASS] testBurnCannotSpendReserveOrEscrow() (gas: 701995)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1151934)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143914)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476975)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1333138)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1213351, ~: 1260235)\nLogs:\n  Bound result 1\n  Bound result 533\n  Bound result 1\n\n[PASS] testOversizedTrancheFillsUpToTheBlockBoundAndResumesNextBlock() (gas: 1197678)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 711336)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 121.36ms (113.24ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 105990, ~: 106118)\nLogs:\n  Bound result 7\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 121.27ms (99.25ms CPU time)\n\nRan 29 tests for test/PagesEdges.t.sol:PagesEdgesTest\n[PASS] testAccrualOneSecondBeforeTheWindowEndsKeepsTheClockAndAtItRestartsIt() (gas: 1507044)\n[PASS] testAnyoneMayAbandonExactlyAtTheDeadlineAndTheAskerIsNotRefunded() (gas: 1555208)\n[PASS] testBurnLimitIsTheAnchorMovedByTheBoundAndTheAnchorIsTheBlocksFirstPrice() (gas: 766793)\n[PASS] testBurnPendingRefusesZeroAndOneWeiOverTheQueue() (gas: 664025)\n[PASS] testCallbackFromTheIntakeForAnotherConsumersRequestIsRefused() (gas: 2082515)\n[PASS] testClaimWithoutAnyEscrowSetsThePayeeAndLaterFeesGoDirect() (gas: 2016430)\n[PASS] testClaimedButUnsettledHandleIsClosedToEveryOtherPathAndFrozen() (gas: 2383458)\n[PASS] testClaimedHandleIsClosedToEveryLaterClaimPath() (gas: 2037174)\n[PASS] testColdClaimAgainstTheRealHookFitsTheStipend() (gas: 2136027)\n[PASS] testConstructorRefusesEveryZeroInput() (gas: 9594)\n[PASS] testEscrowClockSurvivesAFailedClaimAndRecyclingTakesLaterFeesToo() (gas: 2526121)\n[PASS] testEscrowExactlyThePriceReimbursesAndPaysTheOwnerNothing() (gas: 2044566)\n[PASS] testEscrowOneWeiShortOfThePriceGoesWhollyToTheOwner() (gas: 2011873)\n[PASS] testExternalTradePastTheBoundSpendsTheBlocksBudgetByNameUntilTheNextBlock() (gas: 1036896)\n[PASS] testFuzzCurveIsAdditiveAndEachPageCostsBaseTimesItsIndex(uint64,uint32,uint32) (runs: 1000, μ: 54614, ~: 54726)\nLogs:\n  Bound result 69766084518\n  Bound result 4\n  Bound result 1044480\n\n[PASS] testFuzzRoundTripAloneAlwaysLosesExactlyTheFees(uint16,uint16) (runs: 300, μ: 752667, ~: 766638)\nLogs:\n  Bound result 112\n  Bound result 63\n\n[PASS] testHandleLengthAndCharacterBoundaries() (gas: 128077)\n[PASS] testLargerPanelsAndQuorumsAreAccepted() (gas: 1531362)\n[PASS] testOwnerWhoAskedCollectsEscrowAndReimbursementInOneSettlement() (gas: 2008808)\n[PASS] testPanelThresholdsAtTheirBoundaries() (gas: 2294297)\n[PASS] testPriceBoundaryAcceptsExactlyOneImdAndRefusesOneWeiMore() (gas: 1545023)\n[PASS] testPriceOverflowRevertsInsteadOfWrapping() (gas: 66609)\n[PASS] testSellFeeIsSplitExactlyLikeABuyFee() (gas: 591392)\n[PASS] testSellingOutEmptiesTheCurveAndTheNextPageCostsBaseAgain() (gas: 776363)\n[PASS] testStrangersCannotCallTheCallbacksOrMoveValue() (gas: 1954265)\n[PASS] testSubjectsAreIndependentCurves() (gas: 994663)\n[PASS] testUpperCaseRequestClaimsTheLowerCaseSubjectAndAsksAboutTheLowerCaseHandle() (gas: 2019011)\n[PASS] testZeroAddressIssuerEscrowsAndCanOnlyBeRecycled() (gas: 881042)\n[PASS] testZeroAmountsAndOneWeiOfSlippageAreRefused() (gas: 669776)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 121.28ms (123.46ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 121.38ms (24.28ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 122.94ms (93.63ms CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 131135, ~: 114222)\nLogs:\n  Bound result 11\n  Bound result 200000000000000000000000\n  Bound result 999999999999999999999000003716\n  Bound result 999999999999999999999000005032\n  Bound result 999999999999999999999000015115\n  Bound result 999999999999999999999000013185\n  Bound result 70000000000000000000\n  Bound result 999999999999999999999000000007\n  Bound result 999999999999999999999006000001\n  Bound result 3000000000000000000\n  Bound result 100000000000000000000\n  Bound result 999999999999999999999000054773\n  Bound result 999999999999999999999000000026\n  Bound result 999999999999999999999000160001\n  Bound result 1000000000000000000000000000000\n  Bound result 999999999999999999999506375857\n  Bound result 2500000000000000000000\n  Bound result 18446744073709551616\n  Bound result 999999999999999999999000004248\n  Bound result 296858534827628535688329214904\n  Bound result 999999999999999999999000018351\n  Bound result 999999999999999999999000024577\n  Bound result 999999999999999999999000007546\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36918, ~: 36923)\nLogs:\n  Bound result 777045\n  Bound result 6240471\n  Bound result 8\n  Bound result 56349008260501531488273230854\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141493, ~: 141878)\nLogs:\n  Bound result 686531578790202941804409037218\n  Bound result 1101554132695346358921818435279\n  Bound result 12384\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36720, ~: 36831)\nLogs:\n  Bound result 989008\n  Bound result 75\n  Bound result 60\n  Bound result 2285624317\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23219, ~: 21542)\nLogs:\n  Bound result 1461446703485210103287273052103988822378723990655\n  Bound result 54933845692814916411780612294197277208572632\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39413, ~: 38005)\nLogs:\n  Bound result 20312\n  Bound result 9999999999999999999999999999999999998454\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16435, ~: 15159)\nLogs:\n  Bound result 47\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 54163, ~: 51987)\nLogs:\n  Bound result 28708\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36408, ~: 36408)\nLogs:\n  Bound result 7\n  Bound result 4935\n  Bound result 60\n  Bound result 2285624317\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 19179, ~: 16931)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21358, ~: 21299)\nLogs:\n  Bound result 5192296858534827628530496329220095\n  Bound result 1213293946\n  Bound result 1225216\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 63628, ~: 59205)\nLogs:\n  Bound result 5956\n  Bound result 4\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 102476, ~: 93214)\nLogs:\n  Bound result 2\n  Bound result 256546530631155278492801\n  Bound result 414137289091684504572620193548\n  Bound result 395692821902398\n  Bound result 2\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 123.04ms (1.03s CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838167, ~: 838176)\nLogs:\n  Bound result 9750000000000000018\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58959, ~: 58968)\nLogs:\n  Bound result 9750000003858947846\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 127.51ms (204.07ms CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 3)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 223   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 207   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 408   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 220   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 212   | 3       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 217   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 209   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 224   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1\n  Bound result 8453\n  Bound result 15453\n  Bound result 56\n  Bound result 2\n  Bound result 33396766295253\n  Bound result 2782\n  Bound result 1\n  Bound result 19182\n  Bound result 2096\n  Bound result 1\n  Bound result 100000000000000000000\n  Bound result 57\n  Bound result 10\n  Bound result 1\n  Bound result 195436218539537399\n  Bound result 0\n  Bound result 3280\n  Bound result 1\n  Bound result 359072232\n  Bound result 2\n  Bound result 1182413870868355955517\n  Bound result 2480\n  Bound result 85\n  Bound result 2\n  Bound result 36693168062835449717755\n  Bound result 0\n  Bound result 98\n  Bound result 2\n  Bound result 0\n  Bound result 155\n  Bound result 996\n  Bound result 1\n  Bound result 6935\n  Bound result 200\n  Bound result 60\n  Bound result 0\n  Bound result 1\n  Bound result 1000000000000\n  Bound result 229\n  Bound result 1\n  Bound result 3347\n  Bound result 1666\n  Bound result 37\n  Bound result 0\n  Bound result 1010025\n  Bound result 2\n  Bound result 1\n  Bound result 19475001197370473513487\n  Bound result 1\n  Bound result 4600\n  Bound result 0\n  Bound result 2\n  Bound result 3761\n  Bound result 13676\n  Bound result 5\n  Bound result 0\n  Bound result 1302\n  Bound result 22184\n  Bound result 25\n  Bound result 1\n  Bound result 3521\n  Bound result 0\n  Bound result 4465\n  Bound result 52260\n  Bound result 34\n  Bound result 1\n  Bound result 4268\n  Bound result 1\n  Bound result 155\n  Bound result 58193\n  Bound result 12\n  Bound result 0\n  Bound result 16969\n  Bound result 1\n  Bound result 2012259112\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 1819564728518505578419\n  Bound result 50010\n  Bound result 55\n  Bound result 64\n  Bound result 0\n  Bound result 2\n  Bound result 9601\n  Bound result 2\n  Bound result 612342134137401094843\n  Bound result 10003\n  Bound result 95\n  Bound result 2\n  Bound result 2\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 464.47ms (456.69ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2460  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2495  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2446  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2408  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2479  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 20000000\n  Bound result 8396\n  Bound result 122\n  Bound result 8969325026070698970\n  Bound result 10313408094\n  Bound result 109074\n  Bound result 2674363595\n  Bound result 79228162514264337593\n  Bound result 18029673165047288\n  Bound result 2\n  Bound result 240\n  Bound result 2\n  Bound result 108423\n  Bound result 320\n  Bound result 522\n  Bound result 20\n  Bound result 2206\n  Bound result 2215740614845642745028\n  Bound result 3646963005544695008\n  Bound result 184\n  Bound result 30000000000000000000\n  Bound result 107882\n  Bound result 1337181797\n  Bound result 15000\n  Bound result 5000000000000000000\n  Bound result 10500\n  Bound result 6048\n  Bound result 5133346364573191188\n  Bound result 678\n  Bound result 866404161832086345361025\n  Bound result 6961\n  Bound result 231623\n  Bound result 4347\n  Bound result 1550\n  Bound result 11155111\n  Bound result 13\n  Bound result 1000000000000\n  Bound result 24094\n  Bound result 2001\n  Bound result 839509010808422057377684\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.10s (1.10s CPU time)\n\nRan 1 test for test/PagesInvariant.t.sol:PagesInvariantTest\n[PASS]\nPagesInvariantTest invariants:\n[PASS] invariant_burnsNeverPassTheBlocksBound\n[PASS] invariant_claimsAreFinal\n[PASS] invariant_conservation\n[PASS] invariant_feesReachPoolsAndDead\n[PASS] invariant_marketHoldsExactlyWhatItOwes\n[PASS] invariant_reserveCoversEveryHolder\n PagesInvariantTest invariants (runs: 96, calls: 4608, reverts: 0)\n\n╭--------------+--------------+-------+---------+----------╮\n| Contract     | Selector     | Calls | Reverts | Discards |\n+==========================================================+\n| PagesHandler | abandon      | 499   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | answer       | 504   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | burn         | 512   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | buy          | 503   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | recycle      | 536   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | requestClaim | 546   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | sell         | 481   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | settle       | 538   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | warp         | 489   | 0       | 0        |\n╰--------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 17216\n  Bound result 6\n  Bound result 7743999999942756\n  Bound result 2755000000064176\n  Bound result 9203\n  Bound result 10709\n  Bound result 15\n  Bound result 60000000000008922\n  Bound result 1296358\n  Bound result 2674806\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.87s (5.87s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 534   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 535   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 476   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 488   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 514   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 496   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 559   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 488   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 494   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 525   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 497   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 1030  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 537   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 516   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 530   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 477   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 531   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 507   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 506   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 98000000000000013579\n  Bound result 98000000000000000100\n  Bound result 22229\n  Bound result 6\n  Bound result 6\n  Bound result 4\n  Bound result 6\n  Bound result 5\n  Bound result 4023\n  Bound result 8211551929315376338916\n  Bound result 1\n  Bound result 49692822128949970269\n  Bound result 1275672099478816990\n  Bound result 7\n  Bound result 9750000000000008194\n  Bound result 99999020000000000000001\n  Bound result 94888\n  Bound result 6\n  Bound result 2043359509130839133\n  Bound result 1307715542653963504\n  Bound result 23632\n  Bound result 11\n  Bound result 9789272264161486270\n  Bound result 183320\n  Bound result 1\n  Bound result 11\n  Bound result 99999000000003851116468\n  Bound result 9481736242911039292\n  Bound result 99999000000000000003202\n  Bound result 99999000000000000020947\n  Bound result 3941\n  Bound result 99999000000000000011260\n  Bound result 12\n  Bound result 7\n  Bound result 3000000000\n  Bound result 99999000000000000000129\n  Bound result 6\n  Bound result 12\n  Bound result 8\n  Bound result 10\n  Bound result 8\n  Bound result 2\n  Bound result 2\n  Bound result 9999999999999999997\n  Bound result 10\n  Bound result 1\n  Bound result 89826\n  Bound result 220269\n  Bound result 10\n  Bound result 15\n  Bound result 98000000000000005973\n  Bound result 14\n  Bound result 3\n  Bound result 9750000000000000051\n  Bound result 98000000000445331559\n  Bound result 15399\n  Bound result 15\n  Bound result 4\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.55s (7.55s CPU time)\n\nRan 29 test suites in 7.56s (16.67s CPU time): 315 tests passed, 0 failed, 2 skipped (317 total tests)\n","passed":true},{"durationMs":162,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.settleClaim(bytes32)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":610,\"README.md\":289,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":510,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":433,\"test/PagesAudit.t.sol\":318,\"test/PagesDeployment.t.sol\":61,\"test/PagesEdges.t.sol\":760,\"test/PagesInvariant.t.sol\":714,\"test/PagesOracle.t.sol\":168,\"test/PagesRevision.t.sol\":278,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":80,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"0060f368f79ad3c2c44b7762ed2d5f8a41939d0397c390a006da4df75f1fbe62","verifiedTreeHash":"2bc42560dfa819baf5f4f16892b6eafa7c14749a","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":273655,"exitCode":0,"name":"build","output":"Compiling 125 files with Solc 0.8.26\nSolc 0.8.26 finished in 273.42s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:191:17\n    │\n191 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:286:13\n    │\n286 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:244:9\n    │\n244 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:259:9\n    │\n259 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:275:39\n    │\n275 │             if (s.escrowSince == 0 || block.timestamp >= uint256(s.escrowSince) + CLAIM_WINDOW) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:276:33\n    │\n276 │                 s.escrowSince = uint64(block.timestamp);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:351:21\n    │\n351 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n352 │ ┃             action,\n353 │ ┃             bytes(questionBody(normalized, tweetId)),\n354 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n355 │ ┃             imd,\n356 │ ┃             price\n357 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:362:9\n    │\n362 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:360:63\n    │\n360 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:391:13\n    │\n391 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:400:9\n    │\n400 │         emit Claimed(subject, wallet, owed - reimbursed, reimbursed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:399:55\n    │\n399 │         settlements[subject] = Settlement(c.claimant, uint96(reimbursed));\n    │                                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint96' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:427:13\n    │\n427 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:444:9\n    │\n444 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:439:13\n    │\n439 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:445:9\n    │\n445 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `pendingBurn` is updated\n    ╭▸ src/MarginaliaPages.sol:460:38\n    │\n460 │         (spent, burned) = abi.decode(hook.poolManager().unlock(abi.encode(imdIn)), (uint256, uint256));\n    │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:462:9\n    │\n462 │         emit Burned(spent, burned);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:459:44\n    │\n459 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:459:52\n    │\n459 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:480:50\n    │\n480 │             return l > TickMath.MIN_SQRT_PRICE ? uint160(l) : TickMath.MIN_SQRT_PRICE + 1;\n    │                                                  ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:483:46\n    │\n483 │         return u < TickMath.MAX_SQRT_PRICE ? uint160(u) : TickMath.MAX_SQRT_PRICE - 1;\n    │                                              ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:497:27\n    │\n497 │         burnAnchorBlock = uint64(block.number);\n    │                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:501:68\n    │\n501 │         BalanceDelta d = manager.swap(key, SwapParams(zeroForOne, -int256(imdIn), limit), \"\");\n    │                                                                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:504:25\n    │\n504 │         if (inD >= 0 || uint256(-int256(inD)) > imdIn) revert UnauthorizedCallback();\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:506:25\n    │\n506 │         uint256 spent = uint256(-int256(inD));\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:507:24\n    │\n507 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:507:32\n    │\n507 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:512:9\n    │\n512 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:139:43\n    │\n139 │         assertEq(pages.burnAnchorBlock(), block.number);\n    │                                           ━━━━━━━━━━━━\n140 │         vm.roll(block.number + 1);\n    │         ───────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:140:17\n    │\n140 │         vm.roll(block.number + 1);\n    │         ────────━━━━━━━━━━━━───── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:184:25\n    │\n184 │         uint256 start = block.number;\n    │                         ━━━━━━━━━━━━\n    ‡\n188 │             vm.roll(start + blocks);\n    │             ─────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:240:25\n    │\n240 │         assertEq(since, block.timestamp);\n    │                         ━━━━━━━━━━━━━━━\n241 │         vm.warp(block.timestamp + 91 days);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:241:17\n    │\n241 │         vm.warp(block.timestamp + 91 days);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":7302,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 422.92µs (0.00ns CPU time)\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 711.89µs (0.00ns CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 647484)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 4216548)\n[PASS] testColdCallbackPaysTwoFreshBalancesUnderStipendWithDistinctIds() (gas: 357232)\nLogs:\n  delivery gas including mock Intake overhead: 160691\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14307)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 91327)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 704831)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 2.75ms (1.66ms CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 8.93ms (3.58ms CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 12.71ms (6.64ms CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2679131)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2473717)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 695452)\n[PASS] testCurveIsLinear() (gas: 37654)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 4078061)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 64049)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37676)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 171079)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2378488)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 784018)\n[PASS] testSlippageAndNoCap() (gas: 616990)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1949596)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 18.99ms (10.86ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 20.07ms (8.82ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 26.13ms (20.21ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 13546439)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 33.57ms (33.46ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 22345, ~: 20760)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 70.64ms (24.82ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 74.27ms (62.74ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 81.00ms (146.18ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 87.04ms (84.25ms CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 111.96ms (6.57ms CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 116.21ms (73.93ms CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 118.65ms (20.46ms CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 118.55ms (13.75ms CPU time)\n\nRan 9 tests for test/PagesRevision.t.sol:PagesRevisionTest\n[PASS] testASecondBurnInABlockIsRefusedEvenAfterThePriceCameBack() (gas: 1075809)\n[PASS] testAccrualAfterTheWindowOpensANewWindowInsteadOfBeingRecyclableAtOnce() (gas: 2917864)\n[PASS] testBoundedBurnsAcrossBlocksBurnTheWholeBudgetAtMarket() (gas: 3666922)\n[PASS] testBurnSellBurnSandwichIsRefusedAndLosesMoneyAtEverySize() (gas: 3458373)\n[PASS] testCallbackOnlyVerifiesAndStoresThenAnyoneSettles() (gas: 2541688)\nLogs:\n  delivery gas including the mock Intake's overhead: 153153\n\n[PASS] testDustTrancheIsRefusedByName() (gas: 653599)\n[PASS] testMarketAndHookCannotBeSubjects() (gas: 403520)\n[PASS] testOneBlockOfBurningMovesThePriceAtMostTheBound() (gas: 594490)\n[PASS] testSandwichingTheBurnLosesMoneyAtEverySize() (gas: 2507869)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 118.56ms (11.82ms CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2387844)\n[PASS] testBurnAfterAManipulatedPriceStaysBoundedAndCannotBlockTrading() (gas: 1193162)\n[PASS] testBurnCannotSpendReserveOrEscrow() (gas: 701866)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1151676)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143914)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476975)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1333138)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1225234, ~: 1260236)\nLogs:\n  Bound result 1\n  Bound result 274\n  Bound result 0\n\n[PASS] testOversizedTrancheFillsUpToTheBlockBoundAndResumesNextBlock() (gas: 1197074)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 711336)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 118.72ms (118.42ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 105994, ~: 106111)\nLogs:\n  Bound result -60\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 129.88ms (14.47ms CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 129.84ms (1.88ms CPU time)\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 129.89ms (660.08µs CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 124825, ~: 101340)\nLogs:\n  Bound result 11\n  Bound result 999999999999999999999999999998\n  Bound result 999999999999999999999002955430\n  Bound result 981851452503212756294246302653\n  Bound result 610614909360623630163234723070\n  Bound result 689203689300162594211563760936\n  Bound result 673564603495004495867486992726\n  Bound result 664668483330207077888611\n  Bound result 45158852613895067835\n  Bound result 427967247207796960495109289400\n  Bound result 924386971632124336974700619974\n  Bound result 184247944999996061005275614\n  Bound result 592900938932068399516169948585\n  Bound result 999999999999999999999000000013\n  Bound result 9244977195068005175907662\n  Bound result 479960259698360025802930664494\n  Bound result 381624405592715801320106281246\n  Bound result 271793200348744390891659150634\n  Bound result 1000000003\n  Bound result 1000000002\n  Bound result 260673692617735080584968385680\n  Bound result 231613444060314107934889153882\n  Bound result 999999999999999999999000000144\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36937, ~: 36983)\nLogs:\n  Bound result 9992964\n  Bound result 9995876\n  Bound result 14\n  Bound result 999999999999999999999999999997\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141471, ~: 141843)\nLogs:\n  Bound result 1266412660188944021221804081384\n  Bound result 435761409546450643946006704527\n  Bound result 25406\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36722, ~: 36871)\nLogs:\n  Bound result 992964\n  Bound result 27\n  Bound result 14\n  Bound result 999999999999999999999999999997\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23241, ~: 21564)\nLogs:\n  Bound result 1461446703485210103287273052112316144278380124211\n  Bound result 86285900647347751961198810214967923863\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39613, ~: 38728)\nLogs:\n  Bound result 1010025\n  Bound result 9999999999999999999999999999999999997644\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16128, ~: 14283)\nLogs:\n  Bound result 14\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 54102, ~: 51987)\nLogs:\n  Bound result 3780\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36401, ~: 36368)\nLogs:\n  Bound result 3963\n  Bound result 6875\n  Bound result 14\n  Bound result 999999999999999999999999999997\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 18714, ~: 16591)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21351, ~: 21299)\nLogs:\n  Bound result 7409662742394877570018\n  Bound result 6822138842\n  Bound result 111159\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 64164, ~: 60758)\nLogs:\n  Bound result 7289\n  Bound result 4\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 102428, ~: 92008)\nLogs:\n  Bound result 1\n  Bound result 707065332509878845419803535636\n  Bound result 569440214120031543169107288921\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 129.89ms (1.06s CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838160, ~: 838176)\nLogs:\n  Bound result 9750000000000000108\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58953, ~: 58968)\nLogs:\n  Bound result 9750000000000000108\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 129.90ms (192.92ms CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 3)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 217   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 203   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 436   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 234   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 220   | 3       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 199   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 205   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 206   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1\n  Bound result 101\n  Bound result 12000\n  Bound result 40\n  Bound result 2\n  Bound result 200\n  Bound result 49881\n  Bound result 7\n  Bound result 0\n  Bound result 488004682\n  Bound result 0\n  Bound result 0\n  Bound result 604799\n  Bound result 12000\n  Bound result 16\n  Bound result 1\n  Bound result 2000000000000000000000\n  Bound result 50177\n  Bound result 77\n  Bound result 2\n  Bound result 3741\n  Bound result 0\n  Bound result 1040369864902745890445\n  Bound result 52250\n  Bound result 63\n  Bound result 1\n  Bound result 5323\n  Bound result 50282\n  Bound result 27\n  Bound result 2\n  Bound result 18\n  Bound result 0\n  Bound result 1\n  Bound result 1457584007913129639829\n  Bound result 58397\n  Bound result 48\n  Bound result 1\n  Bound result 1\n  Bound result 16777216\n  Bound result 2827\n  Bound result 45\n  Bound result 1\n  Bound result 12059\n  Bound result 57668\n  Bound result 62\n  Bound result 2290\n  Bound result 2\n  Bound result 5000000000000000000000\n  Bound result 2\n  Bound result 1\n  Bound result 7862400\n  Bound result 16\n  Bound result 49\n  Bound result 0\n  Bound result 443066086187300374\n  Bound result 1140\n  Bound result 55\n  Bound result 2\n  Bound result 1084\n  Bound result 50121\n  Bound result 23\n  Bound result 2\n  Bound result 1999999999999999999999\n  Bound result 57400\n  Bound result 15\n  Bound result 0\n  Bound result 14972\n  Bound result 4921\n  Bound result 88\n  Bound result 1000000000000000000000\n  Bound result 0\n  Bound result 0\n  Bound result 13922\n  Bound result 5487\n  Bound result 46\n  Bound result 2\n  Bound result 691200\n  Bound result 1860\n  Bound result 259\n  Bound result 0\n  Bound result 1\n  Bound result 17158\n  Bound result 50078\n  Bound result 89\n  Bound result 2\n  Bound result 2\n  Bound result 1327784376\n  Bound result 0\n  Bound result 461\n  Bound result 55869\n  Bound result 96\n  Bound result 50\n  Bound result 1511\n  Bound result 1\n  Bound result 158227222288099921375\n  Bound result 0\n  Bound result 15965\n  Bound result 0\n  Bound result 2523\n  Bound result 50033\n  Bound result 1\n  Bound result 0\n  Bound result 107\n  Bound result 1\n  Bound result 16\n  Bound result 50161\n  Bound result 64\n  Bound result 0\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 459.70ms (453.21ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2443  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2380  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2471  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2543  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2451  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 1057599768515522267306186232919535850114685401077\n  Bound result 10000000000000000000000000000000000000000\n  Bound result 27522592643676\n  Bound result 919\n  Bound result 2432\n  Bound result 628\n  Bound result 2683\n  Bound result 210396857024506037295690\n  Bound result 3870\n  Bound result 3870\n  Bound result 14\n  Bound result 6656\n  Bound result 8880\n  Bound result 119\n  Bound result 12500\n  Bound result 1000000000000000000000000000\n  Bound result 3858947844\n  Bound result 16976\n  Bound result 2892\n  Bound result 9\n  Bound result 1302\n  Bound result 1945\n  Bound result 43\n  Bound result 300\n  Bound result 11676861573303461902900796701431576452549782254\n  Bound result 60000000000000000\n  Bound result 1825694313\n  Bound result 16916883732308900157886815059974\n  Bound result 79228162514264337593\n  Bound result 37756\n  Bound result 3957377347189744508086464364959\n  Bound result 224195580724520965084582495084398723029839332648\n  Bound result 999001\n  Bound result 500000000000000000\n  Bound result 1461501637330902918203684832716283019655932542973\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.03s (1.03s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 487   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 503   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 514   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 524   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 497   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 545   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 514   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 482   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 526   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 522   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 522   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 1023  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 525   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 486   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 460   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 512   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 531   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 572   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 495   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 4\n  Bound result 2\n  Bound result 9750000000007689601\n  Bound result 5\n  Bound result 6073\n  Bound result 445331560\n  Bound result 3000000000000000000\n  Bound result 58429825091939839759\n  Bound result 9750000001359182280\n  Bound result 1\n  Bound result 3\n  Bound result 5\n  Bound result 5\n  Bound result 7\n  Bound result 7\n  Bound result 98000000000000018509\n  Bound result 99999000000000000008282\n  Bound result 6\n  Bound result 99999999999999999960\n  Bound result 5\n  Bound result 98000000000000012533\n  Bound result 9750000000000001888\n  Bound result 6\n  Bound result 77043147648692561763\n  Bound result 8\n  Bound result 8\n  Bound result 50000000000000000000\n  Bound result 8\n  Bound result 1980000000000000000000\n  Bound result 10\n  Bound result 99999000000000000060001\n  Bound result 150\n  Bound result 99999000000000000006932\n  Bound result 9485903715739055267\n  Bound result 1\n  Bound result 8\n  Bound result 98000000000000603000\n  Bound result 98000000000000007903\n  Bound result 2\n  Bound result 1\n  Bound result 27628530496329220096\n  Bound result 3991\n  Bound result 9750000000383708121\n  Bound result 15448\n  Bound result 9750000000000001263\n  Bound result 2\n  Bound result 16\n  Bound result 8\n  Bound result 1\n  Bound result 2\n  Bound result 240\n  Bound result 16\n  Bound result 16\n  Bound result 98000000000000016385\n  Bound result 9750000000000000066\n  Bound result 15765\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.19s (7.19s CPU time)\n\nRan 27 test suites in 7.19s (10.47s CPU time): 287 tests passed, 0 failed, 2 skipped (289 total tests)\n","passed":true},{"durationMs":144,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.settleClaim(bytes32)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":626,\"README.md\":304,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":516,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":433,\"test/PagesAudit.t.sol\":318,\"test/PagesDeployment.t.sol\":61,\"test/PagesOracle.t.sol\":168,\"test/PagesRevision.t.sol\":353,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":80,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":12553,"exitCode":0,"name":"slither","output":"[high/medium] weak-prng at src/MarginaliaPricer.sol:205: MarginaliaPricer.twap(MarginaliaTypes.VenueKind,bool,uint256,uint64,uint256,uint64) (src/MarginaliaPricer.sol#205-229) uses a weak PRNG: \"delta < 0 && delta % int256(dt) != 0 (src/MarginaliaPricer.sol#215)\"\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:287: Reentrancy in MarginaliaRouter._pull(address,uint256) (src/MarginaliaRouter.sol#287-292):\n[high/high] uninitialized-state at src/MarginaliaHook.sol:536: MarginaliaHook.observations (src/MarginaliaHook.sol#106) is never initialized. It is used in:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:377: MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:299: MarginaliaRouter.unlockCallback(bytes) (src/MarginaliaRouter.sol#299-340) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:294: MarginaliaRouter._checkSubject(MarginaliaRouter.Job) (src/MarginaliaRouter.sol#294-297) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:176: MarginaliaPricer.settlePrice(MarginaliaTypes.Venue,bool,MarginaliaTypes.Observation[]) (src/MarginaliaPricer.sol#176-201) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPages.sol:468: MarginaliaPages.burnLimit() (src/MarginaliaPages.sol#468-475) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:287: MarginaliaRouter._pull(address,uint256) (src/MarginaliaRouter.sol#287-292) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:205: MarginaliaPricer.twap(MarginaliaTypes.VenueKind,bool,uint256,uint64,uint256,uint64) (src/MarginaliaPricer.sol#205-229) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaTreasury.sol:42: MarginaliaTreasury.drip() (src/MarginaliaTreasury.sol#42-52) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaHook.sol:579: MarginaliaHook._broken(MarginaliaTypes.Note,uint256) (src/MarginaliaHook.sol#579-582) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaHook.sol:919: MarginaliaHook._unlock(uint8,address,uint256,uint256) (src/MarginaliaHook.sol#919-928) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaTreasury.sol:42: MarginaliaTreasury.drip() (src/MarginaliaTreasury.sol#42-52) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPages.sol:486: MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#486-515) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:135: MarginaliaPricer.postPrice(IPoolManager,MarginaliaTypes.Venue,address,bool,MarginaliaTypes.PriceWindow) (src/MarginaliaPricer.sol#135-155) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:242: MarginaliaRouter._run(bool,uint256,uint256,uint256,MarginaliaRouter.XTrade,MarginaliaTypes.NoteParams,PoolKey) (src/MarginaliaRouter.sol#242-284) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:457: Reentrancy in MarginaliaPages.burnPending(uint256) (src/MarginaliaPages.sol#457-463):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:603: Reentrancy in MarginaliaHook.settle(bytes32) (src/MarginaliaHook.sol#603-652):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:855: Reentrancy in MarginaliaHook.payJudged(uint32,bytes32[3]) (src/MarginaliaHook.sol#855-874):\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:229: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#229-245):\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:336: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#336-363):\n[medium/medium] reentrancy-no-eth at src/MarginaliaJudge.sol:203: Reentrancy in MarginaliaJudge.requestJudging(uint32) (src/MarginaliaJudge.sol#203-226):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:679: Reentrancy in MarginaliaHook.retract(bytes32,string) (src/MarginaliaHook.sol#679-695):\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:179: MarginaliaRouter.sellWithNote(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256).noX (src/MarginaliaRouter.sol#179) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:127: MarginaliaJudge.questionBody(uint32).allow (src/MarginaliaJudge.sol#127) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaHook.sol:611: MarginaliaHook.settle(bytes32).settlePrice (src/MarginaliaHook.sol#611) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:166: MarginaliaRouter.note(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256).noX (src/MarginaliaRouter.sol#166) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:257: MarginaliaRouter._run(bool,uint256,uint256,uint256,MarginaliaRouter.XTrade,MarginaliaTypes.NoteParams,PoolKey).job (src/MarginaliaRouter.sol#257) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:113: MarginaliaJudge.eligibleTheses(uint32).n (src/MarginaliaJudge.sol#113) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:205: MarginaliaRouter.validateVenue(MarginaliaTypes.NoteParams,PoolKey).t1 (src/MarginaliaRouter.sol#205) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:272: MarginaliaJudge.judgedOf(uint32).dup (src/MarginaliaJudge.sol#272) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:268: MarginaliaJudge.judgedOf(uint32).kept (src/MarginaliaJudge.sol#268) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaHook.sol:862: MarginaliaHook.payJudged(uint32,bytes32[3]).paidAmounts (src/MarginaliaHook.sol#862) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:168: MarginaliaJudge._dec(uint256).n (src/MarginaliaJudge.sol#168) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:204: MarginaliaRouter.validateVenue(MarginaliaTypes.NoteParams,PoolKey).t0 (src/MarginaliaRouter.sol#204) is a local variable never initialized\n[medium/medium] unused-return at src/MarginaliaPricer.sol:255: MarginaliaPricer._quoteSpot(IPoolManager,address,address) (src/MarginaliaPricer.sol#255-264) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(HUB_POOL_ID)) (src/MarginaliaPricer.sol#260)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (r0,r1,None) = IUniswapV2PairOracle(ref).getReserves() (src/MarginaliaPricer.sol#245)\n[medium/medium] unused-return at src/MarginaliaPages.sol:468: MarginaliaPages.burnLimit() (src/MarginaliaPages.sol#468-475) ignores return value by (current,None,None,None) = manager.getSlot0(key.toId()) (src/MarginaliaPages.sol#472)\n[medium/medium] unused-return at src/MarginaliaHook.sol:930: MarginaliaHook.unlockCallback(bytes) (src/MarginaliaHook.sol#930-950) ignores return value by poolManager.settle() (src/MarginaliaHook.sol#945)\n[medium/medium] unused-return at src/MarginaliaHook.sol:294: MarginaliaHook.margPriceInImd() (src/MarginaliaHook.sol#294-297) ignores return value by (sqrtP,None,None,None) = poolManager.getSlot0(poolId) (src/MarginaliaHook.sol#295)\n[medium/medium] unused-return at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) ignores return value by (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (sqrtP_scope_0,None,None,None,None,None,None) = IUniswapV3PoolOracle(ref).slot0() (src/MarginaliaPricer.sol#241)\n[medium/medium] unused-return at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) ignores return value by (r0,r1,None) = pair.getReserves() (src/MarginaliaRouter.sol#426)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:267: MarginaliaPricer._v3Cumulative(address) (src/MarginaliaPricer.sol#267-271) ignores return value by (cum,None) = IUniswapV3PoolOracle(pool).observe(ago) (src/MarginaliaPricer.sol#269)\n[medium/medium] unused-return at src/MarginaliaPages.sol:486: MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#486-515) ignores return value by (current,None,None,None) = manager.getSlot0(key.toId()) (src/MarginaliaPages.sol#493)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(v.ref)) (src/MarginaliaPricer.sol#237)\n[medium/medium] unused-return at src/MarginaliaPages.sol:486: MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#486-515) ignores return value by manager.settle() (src/MarginaliaPages.sol#512)\n[low/high] shadowing-local at src/MarginaliaHook.sol:859: MarginaliaHook.payJudged(uint32,bytes32[3]).pool (src/MarginaliaHook.sol#859) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.noteMeta(bytes32).week (src/MarginaliaJudge.sol#19) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.thesesOfWeek(uint32).week (src/MarginaliaJudge.sol#15) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.thesisPool(uint32).week (src/MarginaliaJudge.sol#12) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.drawForJudging(uint32,uint256,bool).week (src/MarginaliaJudge.sol#21) shadows:\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:266: MarginaliaJudge.judgedOf(uint32) (src/MarginaliaJudge.sol#266-279) has external calls inside a loop: (author,noteWeek,thesis,hasChild) = hook.noteMeta(ranked[i]) (src/MarginaliaJudge.sol#270)\n[low/medium] calls-loop at src/MarginaliaHook.sol:919: MarginaliaHook._unlock(uint8,address,uint256,uint256) (src/MarginaliaHook.sol#919-928) has external calls inside a loop: out = poolManager.unlock(data) (src/MarginaliaHook.sol#925)\n[low/medium] calls-loop at src/MarginaliaHook.sol:658: MarginaliaHook._settlementPrice(MarginaliaTypes.Note,MarginaliaTypes.Observation[]) (src/MarginaliaHook.sol#658-676) has external calls inside a loop: p = pricer().settlePrice(n.venue,buy,sample) (src/MarginaliaHook.sol#669-674)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:91: MarginaliaJudge.convertForfeits() (src/MarginaliaJudge.sol#91-106) has external calls inside a loop: out = hook.sellPotMarg(marg) (src/MarginaliaJudge.sol#96-100)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:266: MarginaliaJudge.judgedOf(uint32) (src/MarginaliaJudge.sol#266-279) has external calls inside a loop: (author,noteWeek,thesis,hasChild) = hook.noteMeta(ranked[i]) (src/MarginaliaJudge.sol#270)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:336: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#336-363):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:263: Reentrancy in MarginaliaPages._distributeFee(bytes32,MarginaliaPages.Subject,uint256) (src/MarginaliaPages.sol#263-288):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:722: Reentrancy in MarginaliaHook._forfeit(MarginaliaTypes.Note,address) (src/MarginaliaHook.sol#722-729):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:785: Reentrancy in MarginaliaHook._fund(uint256) (src/MarginaliaHook.sol#785-789):\n[low/medium] reentrancy-benign at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:229: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#229-245):\n[low/medium] reentrancy-events at src/MarginaliaHook.sol:722: Reentrancy in MarginaliaHook._forfeit(Marginalia","passed":true},{"durationMs":789,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/MarginaliaPages.sol:179: `abi.encodePacked()` Hash Collision (2 places)\n[high] eth-send-unchecked-address at src/MarginaliaHook.sol:779: ETH transferred without address checks (3 places)\n[high] reentrancy-state-change at src/MarginaliaHook.sol:224: Reentrancy: State change after external call (23 places)\n[high] storage-array-memory-edit at src/MarginaliaHook.sol:556: Storage Array Edited with Memory\n[high] unsafe-casting at src/MarginaliaHook.sol:936: Unsafe Casting of integers\n[low] costly-loop at src/MarginaliaHook.sol:864: Costly operations inside loop (2 places)\n[low] internal-function-used-once at src/HookFlags.sol:26: Internal Function Used Only Once (3 places)\n[low] large-numeric-literal at src/Marginalia.sol:10: Large Numeric Literal (25 places)\n[low] literal-instead-of-constant at src/MarginaliaHook.sol:355: Literal Instead of Constant (62 places)\n[low] local-variable-shadowing at src/MarginaliaHook.sol:859: Local Variable Shadows State Variable\n[low] require-revert-in-loop at src/MarginaliaHook.sol:864: Loop Contains `require`/`revert` (2 places)\n[low] state-change-without-event at src/MarginaliaHook.sol:835: State Change Without Event (7 places)\n[low] state-no-address-check at src/MarginaliaRouter.sol:135: Address State Variable Set Without Checks\n[low] unchecked-return at src/MarginaliaHook.sol:718: Unchecked Return (7 places)\n[low] uninitialized-local-variable at src/MarginaliaHook.sol:667: Uninitialized Local Variable (3 places)\n[low] unused-import at src/MarginaliaHook.sol:10: Unused Import\n[low] unused-public-function at src/MarginaliaHook.sol:294: Public Function Not Used Internally (4 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"04326df014fca469a56cb4a6af328324facebfa0f60048516de38be784c8f002","verifiedTreeHash":"c398d0a2d18d882b24e8cab868f07cf7038861e6","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":279611,"exitCode":0,"name":"build","output":"Compiling 124 files with Solc 0.8.26\nSolc 0.8.26 finished in 279.32s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:158:17\n    │\n158 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:244:13\n    │\n244 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:206:9\n    │\n206 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:221:9\n    │\n221 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:235:53\n    │\n235 │             if (s.escrowSince == 0) s.escrowSince = uint64(block.timestamp);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:309:21\n    │\n309 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n310 │ ┃             action,\n311 │ ┃             bytes(questionBody(normalized, tweetId)),\n312 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n313 │ ┃             imd,\n314 │ ┃             price\n315 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:320:9\n    │\n320 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:318:63\n    │\n318 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:346:13\n    │\n346 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:359:9\n    │\n359 │         emit Claimed(subject, wallet, owed, reimbursed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:367:13\n    │\n367 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:384:9\n    │\n384 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:379:13\n    │\n379 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:385:9\n    │\n385 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:398:9\n    │\n398 │         hook.poolManager().unlock(abi.encode(imdIn, minMargOut));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:395:44\n    │\n395 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:395:52\n    │\n395 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:398:9\n    │\n398 │         hook.poolManager().unlock(abi.encode(imdIn, minMargOut));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:428:9\n    │\n428 │         emit Burned(imdIn, marg);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:412:18\n    │\n412 │                 -int256(imdIn),\n    │                  ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:419:38\n    │\n419 │         if (inD >= 0 || outD <= 0 || uint256(-int256(inD)) != imdIn) revert UnauthorizedCallback();\n    │                                      ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:420:24\n    │\n420 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:420:32\n    │\n420 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:426:9\n    │\n426 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":8136,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 705.28µs (0.00ns CPU time)\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 923.77µs (0.00ns CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 9.99ms (4.04ms CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 17.49ms (9.60ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 12065711)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 18.23ms (18.09ms CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 19.44ms (11.62ms CPU time)\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 21.44ms (665.11µs CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2662900)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2411734)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 668941)\n[PASS] testCurveIsLinear() (gas: 37344)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 3935373)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 63979)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37561)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 170731)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2377793)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 782680)\n[PASS] testSlippageAndNoCap() (gas: 615462)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1888094)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 43.89ms (9.28ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 47.43ms (29.35ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 22518, ~: 20080)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 47.40ms (36.37ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 83.91ms (83.43ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 92.98ms (82.39ms CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 101.82ms (56.36ms CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 101.88ms (7.58ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 112.32ms (7.56ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 112.40ms (187.40ms CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 667767)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 3878569)\n[PASS] testColdCallbackPaysTwoFreshBalancesUnderStipendWithDistinctIds() (gas: 282027)\nLogs:\n  delivery gas including mock Intake overhead: 203394\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14297)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 86052)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 742292)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 112.45ms (1.77ms CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838159, ~: 838176)\nLogs:\n  Bound result 250000000000000001\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58952, ~: 58968)\nLogs:\n  Bound result 250000000000000000\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 120.34ms (219.18ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 106008, ~: 106118)\nLogs:\n  Bound result 126\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 130.91ms (22.88ms CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 147.05ms (1.77ms CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 147.23ms (46.04ms CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2386917)\n[PASS] testBurnCannotSpendReserveOrEscrowAndRejectsZeroFloor() (gas: 705180)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1433838)\n[PASS] testBurnUsesCallerFloorAndManipulatedPriceCannotBlockTrading() (gas: 1017958)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143720)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476847)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1331251)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1219766, ~: 1257765)\nLogs:\n  Bound result 538\n  Bound result 788\n  Bound result 125\n\n[PASS] testPartialFillBurnRollsBackAndSmallerTranchesWork() (gas: 1297340)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 709869)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 147.12ms (141.05ms CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 130274, ~: 114658)\nLogs:\n  Bound result 16\n  Bound result 55613496089736688059\n  Bound result 264464191761863364130556460149\n  Bound result 966899090549794557\n  Bound result 851482182690440310177734957821\n  Bound result 333122696851384976005972299073\n  Bound result 649469263348983895549412\n  Bound result 647690298290650732698916240820\n  Bound result 29633376231344588896252309336\n  Bound result 160581219811887313314\n  Bound result 249680645377327\n  Bound result 21120665568091046\n  Bound result 1000000002\n  Bound result 106328323999074610728254\n  Bound result 840150811820758320542681639280\n  Bound result 389885335291734633067138516095\n  Bound result 999999999999999999999116437743\n  Bound result 664585839013950695257979097524\n  Bound result 14916610829\n  Bound result 102308102838493022371240261901\n  Bound result 120566026434478511969518850153\n  Bound result 797962289540374902419107465904\n  Bound result 281836751954644188618634494820\n  Bound result 999999999999999999999000001844\n  Bound result 49291105447986568407392977423\n  Bound result 164613033719334311245207057841\n  Bound result 36084860899551454245511\n  Bound result 169142291684465350023123776349\n  Bound result 172800416859096867448794154432\n  Bound result 999999999999999999999000000044\n  Bound result 999999999999999999999999999998\n  Bound result 503957353327339085977208561235\n  Bound result 946958530943013882311065913382\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36909, ~: 36938)\nLogs:\n  Bound result 115275\n  Bound result 11002\n  Bound result 41\n  Bound result 2400630265122203703687383\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141536, ~: 141885)\nLogs:\n  Bound result 687247697784139853184544418216\n  Bound result 1266412660322236585699451273204\n  Bound result 14213\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36752, ~: 36897)\nLogs:\n  Bound result 989119\n  Bound result 12\n  Bound result 2\n  Bound result 40393601615777331857018981\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23255, ~: 21542)\nLogs:\n  Bound result 1461446703485210103287273052103988822378723976689\n  Bound result 39614081257132168796771975168\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39606, ~: 38884)\nLogs:\n  Bound result 3085662557869407456901501805330143530183\n  Bound result 3675335185387145398576662629718278298157\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16165, ~: 14502)\nLogs:\n  Bound result 178\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 53890, ~: 51987)\nLogs:\n  Bound result 5332\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36415, ~: 36397)\nLogs:\n  Bound result 118\n  Bound result 5292\n  Bound result 2\n  Bound result 40393601615777331857018981\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 18886, ~: 16591)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21367, ~: 21299)\nLogs:\n  Bound result 5048\n  Bound result 12296\n  Bound result 6864\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 63495, ~: 60538)\nLogs:\n  Bound result 6000\n  Bound result 3\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 100777, ~: 91838)\nLogs:\n  Bound result 1\n  Bound result 1\n  Bound result 1218626021010801080364452\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 147.18ms (1.12s CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 3)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 209   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 218   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 440   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 210   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 209   | 3       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 205   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 212   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 217   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1620\n  Bound result 1\n  Bound result 2000000000000000000000\n  Bound result 4096\n  Bound result 90\n  Bound result 1\n  Bound result 0\n  Bound result 1152921504606846975\n  Bound result 59139\n  Bound result 5\n  Bound result 0\n  Bound result 1269\n  Bound result 1\n  Bound result 50000000000000000000\n  Bound result 4973\n  Bound result 1\n  Bound result 1\n  Bound result 1261\n  Bound result 0\n  Bound result 37708281716\n  Bound result 3876\n  Bound result 29\n  Bound result 1\n  Bound result 0\n  Bound result 30000000000000000000\n  Bound result 8838\n  Bound result 40\n  Bound result 5000000000000000000000\n  Bound result 0\n  Bound result 112305878086378464\n  Bound result 0\n  Bound result 0\n  Bound result 11000\n  Bound result 2\n  Bound result 1\n  Bound result 2\n  Bound result 6449\n  Bound result 9000\n  Bound result 76\n  Bound result 0\n  Bound result 100000000000000000000\n  Bound result 33081\n  Bound result 79\n  Bound result 0\n  Bound result 13555\n  Bound result 55001\n  Bound result 16\n  Bound result 3\n  Bound result 0\n  Bound result 1\n  Bound result 15655\n  Bound result 2\n  Bound result 228\n  Bound result 2\n  Bound result 3183\n  Bound result 20149\n  Bound result 91\n  Bound result 1\n  Bound result 1000000000000000\n  Bound result 50257\n  Bound result 10\n  Bound result 0\n  Bound result 600\n  Bound result 2\n  Bound result 2\n  Bound result 2001\n  Bound result 2\n  Bound result 117300739\n  Bound result 3008\n  Bound result 0\n  Bound result 2975\n  Bound result 1\n  Bound result 10938\n  Bound result 1\n  Bound result 6745\n  Bound result 1548\n  Bound result 0\n  Bound result 155\n  Bound result 14566\n  Bound result 35\n  Bound result 0\n  Bound result 200180672591497932024\n  Bound result 50109\n  Bound result 0\n  Bound result 1\n  Bound result 7585\n  Bound result 50013\n  Bound result 43\n  Bound result 0\n  Bound result 212\n  Bound result 58569\n  Bound result 49\n  Bound result 0\n  Bound result 53\n  Bound result 1000\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 531.58ms (523.37ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2540  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2430  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2394  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2437  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2487  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 281\n  Bound result 67487\n  Bound result 13\n  Bound result 999999999999999999999999\n  Bound result 1666\n  Bound result 400000\n  Bound result 6000\n  Bound result 3167\n  Bound result 6931\n  Bound result 320\n  Bound result 384\n  Bound result 6142\n  Bound result 8745248984154165900885334782585\n  Bound result 6750\n  Bound result 1\n  Bound result 70\n  Bound result 1\n  Bound result 5698\n  Bound result 22685814125989351599235923974\n  Bound result 4030169805507390064\n  Bound result 976\n  Bound result 112838726185\n  Bound result 84077\n  Bound result 500000000000000001\n  Bound result 80780\n  Bound result 5400\n  Bound result 100000000000000000\n  Bound result 4000000000000000000\n  Bound result 6269\n  Bound result 3883923840\n  Bound result 122\n  Bound result 4831923615514126184\n  Bound result 489\n  Bound result 57468047504936032020328\n  Bound result 1238\n  Bound result 4000000000000000000\n  Bound result 5424\n  Bound result 40\n  Bound result 14373\n  Bound result 124\n  Bound result 1373611828468743159329371216018226462812469038028\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.35s (1.35s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 508   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 532   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 537   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 526   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 538   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 509   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 478   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 501   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 528   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 493   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 499   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 958   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 519   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 564   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 497   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 508   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 513   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 526   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 506   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 3\n  Bound result 99999000000000000000282\n  Bound result 2\n  Bound result 99999000000000000020781\n  Bound result 98000000000000010754\n  Bound result 98000000000000000011\n  Bound result 152933\n  Bound result 19999999999999999980\n  Bound result 1\n  Bound result 1\n  Bound result 98000000000000156244\n  Bound result 8\n  Bound result 5\n  Bound result 6\n  Bound result 98\n  Bound result 1\n  Bound result 8\n  Bound result 99999000000000000000245\n  Bound result 98000000000000002401\n  Bound result 5\n  Bound result 98000000000000000958\n  Bound result 2\n  Bound result 611\n  Bound result 99999000000000000004726\n  Bound result 10\n  Bound result 7\n  Bound result 98000000000000006233\n  Bound result 1\n  Bound result 99999000000000000007567\n  Bound result 6\n  Bound result 99999000000000000018368\n  Bound result 98000000000008565803\n  Bound result 9750000000000007262\n  Bound result 5\n  Bound result 6\n  Bound result 99999000000000000000016\n  Bound result 3865423022304439599\n  Bound result 1\n  Bound result 3\n  Bound result 49999999999999999980\n  Bound result 13\n  Bound result 9\n  Bound result 12\n  Bound result 15\n  Bound result 98000000000000237144\n  Bound result 99999000000000000017501\n  Bound result 7\n  Bound result 12\n  Bound result 16\n  Bound result 16\n  Bound result 9750000000000022579\n  Bound result 12\n  Bound result 89582616721757000017\n  Bound result 15\n  Bound result 13\n  Bound result 7231\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.97s (7.97s CPU time)\n\nRan 26 test suites in 7.98s (11.64s CPU time): 278 tests passed, 0 failed, 2 skipped (280 total tests)\n","passed":true},{"durationMs":171,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256,uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":583,\"README.md\":268,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":431,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":418,\"test/PagesAudit.t.sol\":300,\"test/PagesDeployment.t.sol\":61,\"test/PagesOracle.t.sol\":166,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":79,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":13559,"exitCode":0,"name":"slither","output":"[high/medium] weak-prng at src/MarginaliaPricer.sol:205: MarginaliaPricer.twap(MarginaliaTypes.VenueKind,bool,uint256,uint64,uint256,uint64) (src/MarginaliaPricer.sol#205-229) uses a weak PRNG: \"delta < 0 && delta % int256(dt) != 0 (src/MarginaliaPricer.sol#215)\"\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:287: Reentrancy in MarginaliaRouter._pull(address,uint256) (src/MarginaliaRouter.sol#287-292):\n[high/high] uninitialized-state at src/MarginaliaHook.sol:536: MarginaliaHook.observations (src/MarginaliaHook.sol#106) is never initialized. It is used in:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:377: MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:299: MarginaliaRouter.unlockCallback(bytes) (src/MarginaliaRouter.sol#299-340) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:294: MarginaliaRouter._checkSubject(MarginaliaRouter.Job) (src/MarginaliaRouter.sol#294-297) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:176: MarginaliaPricer.settlePrice(MarginaliaTypes.Venue,bool,MarginaliaTypes.Observation[]) (src/MarginaliaPricer.sol#176-201) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:287: MarginaliaRouter._pull(address,uint256) (src/MarginaliaRouter.sol#287-292) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:205: MarginaliaPricer.twap(MarginaliaTypes.VenueKind,bool,uint256,uint64,uint256,uint64) (src/MarginaliaPricer.sol#205-229) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaTreasury.sol:42: MarginaliaTreasury.drip() (src/MarginaliaTreasury.sol#42-52) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaHook.sol:579: MarginaliaHook._broken(MarginaliaTypes.Note,uint256) (src/MarginaliaHook.sol#579-582) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaHook.sol:919: MarginaliaHook._unlock(uint8,address,uint256,uint256) (src/MarginaliaHook.sol#919-928) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaTreasury.sol:42: MarginaliaTreasury.drip() (src/MarginaliaTreasury.sol#42-52) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:135: MarginaliaPricer.postPrice(IPoolManager,MarginaliaTypes.Venue,address,bool,MarginaliaTypes.PriceWindow) (src/MarginaliaPricer.sol#135-155) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:242: MarginaliaRouter._run(bool,uint256,uint256,uint256,MarginaliaRouter.XTrade,MarginaliaTypes.NoteParams,PoolKey) (src/MarginaliaRouter.sol#242-284) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:294: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#294-321):\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:196: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#196-207):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:603: Reentrancy in MarginaliaHook.settle(bytes32) (src/MarginaliaHook.sol#603-652):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:855: Reentrancy in MarginaliaHook.payJudged(uint32,bytes32[3]) (src/MarginaliaHook.sol#855-874):\n[medium/medium] reentrancy-no-eth at src/MarginaliaJudge.sol:203: Reentrancy in MarginaliaJudge.requestJudging(uint32) (src/MarginaliaJudge.sol#203-226):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:679: Reentrancy in MarginaliaHook.retract(bytes32,string) (src/MarginaliaHook.sol#679-695):\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:179: MarginaliaRouter.sellWithNote(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256).noX (src/MarginaliaRouter.sol#179) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:127: MarginaliaJudge.questionBody(uint32).allow (src/MarginaliaJudge.sol#127) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaHook.sol:611: MarginaliaHook.settle(bytes32).settlePrice (src/MarginaliaHook.sol#611) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:166: MarginaliaRouter.note(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256).noX (src/MarginaliaRouter.sol#166) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:257: MarginaliaRouter._run(bool,uint256,uint256,uint256,MarginaliaRouter.XTrade,MarginaliaTypes.NoteParams,PoolKey).job (src/MarginaliaRouter.sol#257) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:113: MarginaliaJudge.eligibleTheses(uint32).n (src/MarginaliaJudge.sol#113) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:205: MarginaliaRouter.validateVenue(MarginaliaTypes.NoteParams,PoolKey).t1 (src/MarginaliaRouter.sol#205) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:272: MarginaliaJudge.judgedOf(uint32).dup (src/MarginaliaJudge.sol#272) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:268: MarginaliaJudge.judgedOf(uint32).kept (src/MarginaliaJudge.sol#268) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaHook.sol:862: MarginaliaHook.payJudged(uint32,bytes32[3]).paidAmounts (src/MarginaliaHook.sol#862) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:168: MarginaliaJudge._dec(uint256).n (src/MarginaliaJudge.sol#168) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:204: MarginaliaRouter.validateVenue(MarginaliaTypes.NoteParams,PoolKey).t0 (src/MarginaliaRouter.sol#204) is a local variable never initialized\n[medium/medium] unused-return at src/MarginaliaPricer.sol:255: MarginaliaPricer._quoteSpot(IPoolManager,address,address) (src/MarginaliaPricer.sol#255-264) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(HUB_POOL_ID)) (src/MarginaliaPricer.sol#260)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (r0,r1,None) = IUniswapV2PairOracle(ref).getReserves() (src/MarginaliaPricer.sol#245)\n[medium/medium] unused-return at src/MarginaliaPages.sol:401: MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#401-430) ignores return value by manager.settle() (src/MarginaliaPages.sol#426)\n[medium/medium] unused-return at src/MarginaliaHook.sol:930: MarginaliaHook.unlockCallback(bytes) (src/MarginaliaHook.sol#930-950) ignores return value by poolManager.settle() (src/MarginaliaHook.sol#945)\n[medium/medium] unused-return at src/MarginaliaHook.sol:294: MarginaliaHook.margPriceInImd() (src/MarginaliaHook.sol#294-297) ignores return value by (sqrtP,None,None,None) = poolManager.getSlot0(poolId) (src/MarginaliaHook.sol#295)\n[medium/medium] unused-return at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) ignores return value by (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (sqrtP_scope_0,None,None,None,None,None,None) = IUniswapV3PoolOracle(ref).slot0() (src/MarginaliaPricer.sol#241)\n[medium/medium] unused-return at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) ignores return value by (r0,r1,None) = pair.getReserves() (src/MarginaliaRouter.sol#426)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:267: MarginaliaPricer._v3Cumulative(address) (src/MarginaliaPricer.sol#267-271) ignores return value by (cum,None) = IUniswapV3PoolOracle(pool).observe(ago) (src/MarginaliaPricer.sol#269)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(v.ref)) (src/MarginaliaPricer.sol#237)\n[medium/medium] unused-return at src/MarginaliaPages.sol:393: MarginaliaPages.burnPending(uint256,uint256) (src/MarginaliaPages.sol#393-399) ignores return value by hook.poolManager().unlock(abi.encode(imdIn,minMargOut)) (src/MarginaliaPages.sol#398)\n[low/high] shadowing-local at src/MarginaliaHook.sol:859: MarginaliaHook.payJudged(uint32,bytes32[3]).pool (src/MarginaliaHook.sol#859) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.noteMeta(bytes32).week (src/MarginaliaJudge.sol#19) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.thesesOfWeek(uint32).week (src/MarginaliaJudge.sol#15) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.thesisPool(uint32).week (src/MarginaliaJudge.sol#12) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.drawForJudging(uint32,uint256,bool).week (src/MarginaliaJudge.sol#21) shadows:\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:266: MarginaliaJudge.judgedOf(uint32) (src/MarginaliaJudge.sol#266-279) has external calls inside a loop: (author,noteWeek,thesis,hasChild) = hook.noteMeta(ranked[i]) (src/MarginaliaJudge.sol#270)\n[low/medium] calls-loop at src/MarginaliaHook.sol:919: MarginaliaHook._unlock(uint8,address,uint256,uint256) (src/MarginaliaHook.sol#919-928) has external calls inside a loop: out = poolManager.unlock(data) (src/MarginaliaHook.sol#925)\n[low/medium] calls-loop at src/MarginaliaHook.sol:658: MarginaliaHook._settlementPrice(MarginaliaTypes.Note,MarginaliaTypes.Observation[]) (src/MarginaliaHook.sol#658-676) has external calls inside a loop: p = pricer().settlePrice(n.venue,buy,sample) (src/MarginaliaHook.sol#669-674)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:91: MarginaliaJudge.convertForfeits() (src/MarginaliaJudge.sol#91-106) has external calls inside a loop: out = hook.sellPotMarg(marg) (src/MarginaliaJudge.sol#96-100)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:266: MarginaliaJudge.judgedOf(uint32) (src/MarginaliaJudge.sol#266-279) has external calls inside a loop: (author,noteWeek,thesis,hasChild) = hook.noteMeta(ranked[i]) (src/MarginaliaJudge.sol#270)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:225: Reentrancy in MarginaliaPages._distributeFee(bytes32,MarginaliaPages.Subject,uint256) (src/MarginaliaPages.sol#225-246):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:196: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#196-207):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:722: Reentrancy in MarginaliaHook._forfeit(MarginaliaTypes.Note,address) (src/MarginaliaHook.sol#722-729):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:785: Reentrancy in MarginaliaHook._fund(uint256) (src/MarginaliaHook.sol#785-789):\n[low/medium] reentrancy-benign at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:294: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#294-321):\n[low/medium] reentrancy-events at src/MarginaliaPages.sol:401: Reentrancy in MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#401-430):\n[low/medium] reentrancy-events at src/MarginaliaHook.sol:722: Reentrancy in MarginaliaHook._forfeit(MarginaliaTypes.Note,address) (src/MarginaliaHook.sol#722-729):\n[low/medium] reentrancy-events at src/MarginaliaHook.sol:698: Reentrancy in MarginaliaHook.settleThesis(bytes32) (src/MarginaliaHook.sol#698-706):\n[low/medium] reentrancy-events at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-events at src/MarginaliaHook.sol:785: Reentrancy in MarginaliaHook._fund(uint256) (src/MarginaliaHook.sol#785-789):\n[low/medium] reentrancy-events at src/","passed":true},{"durationMs":937,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/MarginaliaPages.sol:146: `abi.encodePacked()` Hash Collision (2 places)\n[high] eth-send-unchecked-address at src/MarginaliaHook.sol:779: ETH transferred without address checks (3 places)\n[high] reentrancy-state-change at src/MarginaliaHook.sol:224: Reentrancy: State change after external call (19 places)\n[high] storage-array-memory-edit at src/MarginaliaHook.sol:556: Storage Array Edited with Memory\n[high] unsafe-casting at src/MarginaliaHook.sol:936: Unsafe Casting of integers\n[low] costly-loop at src/MarginaliaHook.sol:864: Costly operations inside loop (2 places)\n[low] internal-function-used-once at src/HookFlags.sol:26: Internal Function Used Only Once (3 places)\n[low] large-numeric-literal at src/Marginalia.sol:10: Large Numeric Literal (21 places)\n[low] literal-instead-of-constant at src/MarginaliaHook.sol:355: Literal Instead of Constant (56 places)\n[low] local-variable-shadowing at src/MarginaliaHook.sol:859: Local Variable Shadows State Variable\n[low] require-revert-in-loop at src/MarginaliaHook.sol:864: Loop Contains `require`/`revert` (2 places)\n[low] state-change-without-event at src/MarginaliaHook.sol:835: State Change Without Event (7 places)\n[low] state-no-address-check at src/MarginaliaRouter.sol:135: Address State Variable Set Without Checks\n[low] unchecked-return at src/MarginaliaHook.sol:718: Unchecked Return (8 places)\n[low] uninitialized-local-variable at src/MarginaliaHook.sol:667: Uninitialized Local Variable (3 places)\n[low] unused-import at src/MarginaliaHook.sol:10: Unused Import\n[low] unused-public-function at src/MarginaliaHook.sol:294: Public Function Not Used Internally (3 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"0cb45f1d4f5b9bca7dad7ec157ee4fdd8d7929cb4a3cf36cad0279db5fe74c13","verifiedTreeHash":"5e1f46bf23e70cdb5dd088999e3dddfb5f893dd2","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":667895,"exitCode":0,"name":"build","output":"Compiling 125 files with Solc 0.8.26\nSolc 0.8.26 finished in 667.32s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:189:17\n    │\n189 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:284:13\n    │\n284 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:242:9\n    │\n242 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:257:9\n    │\n257 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:273:39\n    │\n273 │             if (s.escrowSince == 0 || block.timestamp >= uint256(s.escrowSince) + CLAIM_WINDOW) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:274:33\n    │\n274 │                 s.escrowSince = uint64(block.timestamp);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:349:21\n    │\n349 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n350 │ ┃             action,\n351 │ ┃             bytes(questionBody(normalized, tweetId)),\n352 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n353 │ ┃             imd,\n354 │ ┃             price\n355 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:360:9\n    │\n360 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:358:63\n    │\n358 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:389:13\n    │\n389 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:398:9\n    │\n398 │         emit Claimed(subject, wallet, owed - reimbursed, reimbursed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:397:55\n    │\n397 │         settlements[subject] = Settlement(c.claimant, uint96(reimbursed));\n    │                                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint96' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:425:13\n    │\n425 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:442:9\n    │\n442 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:437:13\n    │\n437 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:443:9\n    │\n443 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `pendingBurn` is updated\n    ╭▸ src/MarginaliaPages.sol:456:38\n    │\n456 │         (spent, burned) = abi.decode(hook.poolManager().unlock(abi.encode(imdIn)), (uint256, uint256));\n    │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:458:9\n    │\n458 │         emit Burned(spent, burned);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:455:44\n    │\n455 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:455:52\n    │\n455 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:475:50\n    │\n475 │             return l > TickMath.MIN_SQRT_PRICE ? uint160(l) : TickMath.MIN_SQRT_PRICE + 1;\n    │                                                  ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:478:46\n    │\n478 │         return u < TickMath.MAX_SQRT_PRICE ? uint160(u) : TickMath.MAX_SQRT_PRICE - 1;\n    │                                              ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:490:31\n    │\n490 │             burnAnchorBlock = uint64(block.number);\n    │                               ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:495:68\n    │\n495 │         BalanceDelta d = manager.swap(key, SwapParams(zeroForOne, -int256(imdIn), limit), \"\");\n    │                                                                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:498:25\n    │\n498 │         if (inD >= 0 || uint256(-int256(inD)) > imdIn) revert UnauthorizedCallback();\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:500:25\n    │\n500 │         uint256 spent = uint256(-int256(inD));\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:501:24\n    │\n501 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:501:32\n    │\n501 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:506:9\n    │\n506 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:109:25\n    │\n109 │         uint256 start = block.number;\n    │                         ━━━━━━━━━━━━\n    ‡\n113 │             vm.roll(start + blocks);\n    │             ─────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:165:25\n    │\n165 │         assertEq(since, block.timestamp);\n    │                         ━━━━━━━━━━━━━━━\n166 │         vm.warp(block.timestamp + 91 days);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:166:17\n    │\n166 │         vm.warp(block.timestamp + 91 days);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":14945,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 4.92ms (445.56µs CPU time)\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 5.02ms (0.00ns CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 647484)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 4220844)\n[PASS] testColdCallbackPaysTwoFreshBalancesUnderStipendWithDistinctIds() (gas: 357232)\nLogs:\n  delivery gas including mock Intake overhead: 160691\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14307)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 91411)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 704831)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 11.50ms (6.64ms CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 15.39ms (11.47ms CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 26.35ms (7.53ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 28.90ms (12.06ms CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 37.13ms (23.20ms CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2679131)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2473717)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 695581)\n[PASS] testCurveIsLinear() (gas: 37654)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 4078061)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 64049)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37676)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 171079)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2378488)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 784018)\n[PASS] testSlippageAndNoCap() (gas: 616990)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1949596)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 41.38ms (21.40ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 13563035)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 44.47ms (44.26ms CPU time)\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 553.64µs (0.00ns CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 48.58ms (19.78ms CPU time)\n\nRan 7 tests for test/PagesRevision.t.sol:PagesRevisionTest\n[PASS] testAccrualAfterTheWindowOpensANewWindowInsteadOfBeingRecyclableAtOnce() (gas: 2917756)\n[PASS] testBoundedBurnsAcrossBlocksBurnTheWholeBudgetAtMarket() (gas: 4980668)\n[PASS] testCallbackOnlyVerifiesAndStoresThenAnyoneSettles() (gas: 2541580)\nLogs:\n  delivery gas including the mock Intake's overhead: 153153\n\n[PASS] testDustTrancheIsRefusedByName() (gas: 653765)\n[PASS] testMarketAndHookCannotBeSubjects() (gas: 403498)\n[PASS] testOneBlockOfBurningMovesThePriceAtMostTheBound() (gas: 660282)\n[PASS] testSandwichingTheBurnLosesMoneyAtEverySize() (gas: 2780610)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 50.32ms (30.18ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 80.47ms (53.47ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 129.65ms (123.74ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 152.81ms (321.91ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 22847, ~: 20760)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 182.86ms (63.18ms CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 217.36ms (14.42ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 219.51ms (122.31ms CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 223.73ms (109.06ms CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 224.74ms (67.05ms CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838163, ~: 838176)\nLogs:\n  Bound result 9750000000225485028\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58956, ~: 58968)\nLogs:\n  Bound result 7765417045327813001\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 224.79ms (410.35ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 106023, ~: 106088)\nLogs:\n  Bound result 0\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 224.85ms (73.78ms CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 127429, ~: 101851)\nLogs:\n  Bound result 3\n  Bound result 999999999999999999999000013934\n  Bound result 999999999999999999999000003568\n  Bound result 450000000000000000\n  Bound result 1237940039285380274899124224\n  Bound result 999999999999999999999000000125\n  Bound result 1237940039285380274899124224\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36883, ~: 36879)\nLogs:\n  Bound result 6657663\n  Bound result 570069\n  Bound result 34\n  Bound result 155689574321\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141393, ~: 141817)\nLogs:\n  Bound result 1237940039285380274899124225\n  Bound result 1266412660188944021221804091003\n  Bound result 1917\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36740, ~: 36900)\nLogs:\n  Bound result 822648\n  Bound result 5\n  Bound result 34\n  Bound result 155689574321\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23046, ~: 21255)\nLogs:\n  Bound result 1461446703485210103287273052103988822378723981267\n  Bound result 100000000000000000000\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39652, ~: 39068)\nLogs:\n  Bound result 10924\n  Bound result 887220\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16324, ~: 14721)\nLogs:\n  Bound result 1\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 54523, ~: 51987)\nLogs:\n  Bound result 4096\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36410, ~: 36380)\nLogs:\n  Bound result 5664\n  Bound result 3069\n  Bound result 34\n  Bound result 155689574321\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 19196, ~: 17101)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21363, ~: 21299)\nLogs:\n  Bound result 33219\n  Bound result 5192296858534827628530496329220095\n  Bound result 659918\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 63423, ~: 58262)\nLogs:\n  Bound result -60\n  Bound result 13\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 99581, ~: 85072)\nLogs:\n  Bound result 2\n  Bound result 13933\n  Bound result 3567\n  Bound result 450000000000000000\n  Bound result 1237940039285380274899124224\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 224.65ms (1.59s CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2387844)\n[PASS] testBurnAfterAManipulatedPriceStaysBoundedAndCannotBlockTrading() (gas: 1193420)\n[PASS] testBurnCannotSpendReserveOrEscrow() (gas: 701995)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1151934)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143914)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476975)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1333138)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1218055, ~: 1260500)\nLogs:\n  Bound result 1\n  Bound result 1\n  Bound result 0\n\n[PASS] testOversizedTrancheFillsUpToTheBlockBoundAndResumesNextBlock() (gas: 1197678)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 711336)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 229.62ms (214.58ms CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 2)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 176   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 193   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 448   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 213   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 224   | 2       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 221   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 215   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 230   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 2\n  Bound result 129417736293172548851\n  Bound result 0\n  Bound result 1297585623511417305123\n  Bound result 59454\n  Bound result 1\n  Bound result 0\n  Bound result 4123\n  Bound result 2662\n  Bound result 2\n  Bound result 10538130927504095399413\n  Bound result 1198\n  Bound result 1\n  Bound result 5077\n  Bound result 9981\n  Bound result 9\n  Bound result 2\n  Bound result 42\n  Bound result 0\n  Bound result 15\n  Bound result 0\n  Bound result 0\n  Bound result 17961\n  Bound result 1\n  Bound result 1\n  Bound result 150000000000000000\n  Bound result 15222\n  Bound result 16\n  Bound result 0\n  Bound result 1940389979\n  Bound result 1\n  Bound result 0\n  Bound result 202993782792835301376\n  Bound result 50601\n  Bound result 7\n  Bound result 180\n  Bound result 16670\n  Bound result 1\n  Bound result 101\n  Bound result 2\n  Bound result 2\n  Bound result 228\n  Bound result 1\n  Bound result 887220\n  Bound result 4105\n  Bound result 1\n  Bound result 0\n  Bound result 4355\n  Bound result 59711\n  Bound result 35\n  Bound result 4285\n  Bound result 0\n  Bound result 2715\n  Bound result 33760\n  Bound result 20\n  Bound result 0\n  Bound result 16315\n  Bound result 999\n  Bound result 32\n  Bound result 5389\n  Bound result 2\n  Bound result 2\n  Bound result 70000000000000000000\n  Bound result 2\n  Bound result 1\n  Bound result 10350000000000000000\n  Bound result 50100\n  Bound result 9\n  Bound result 2\n  Bound result 7211\n  Bound result 2\n  Bound result 0\n  Bound result 9438\n  Bound result 0\n  Bound result 57057350374175801344\n  Bound result 50056\n  Bound result 7\n  Bound result 2\n  Bound result 64\n  Bound result 1\n  Bound result 179\n  Bound result 9990\n  Bound result 61\n  Bound result 0\n  Bound result 499999999999999999998\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 976.82ms (959.13ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2484  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2572  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2473  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2391  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2368  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 6104\n  Bound result 545900801549170687173510\n  Bound result 2048\n  Bound result 3660\n  Bound result 5000000000000000000\n  Bound result 38377\n  Bound result 502\n  Bound result 127\n  Bound result 4242102453\n  Bound result 2684\n  Bound result 6205\n  Bound result 6766\n  Bound result 1461501637330902918203684832716283019655932542972\n  Bound result 12\n  Bound result 50\n  Bound result 179\n  Bound result 4482\n  Bound result 1315\n  Bound result 48879\n  Bound result 1000000000000000000000000000000\n  Bound result 1267650600228229401496703205376\n  Bound result 7996\n  Bound result 526\n  Bound result 45\n  Bound result 160920\n  Bound result 4686\n  Bound result 7340070532018637917941\n  Bound result 1752\n  Bound result 1461501637330902918203684832716283019655932542972\n  Bound result 360\n  Bound result 731\n  Bound result 18918\n  Bound result 8757765680553123732\n  Bound result 6\n  Bound result 5794\n  Bound result 38464521114330985274356621662871\n  Bound result 160\n  Bound result 686\n  Bound result 5801714891867603188\n  Bound result 6931\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.25s (2.24s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 536   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 506   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 506   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 514   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 509   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 519   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 527   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 473   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 507   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 524   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 497   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 1017  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 515   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 492   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 504   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 532   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 522   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 528   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 512   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 9750000000000011436\n  Bound result 3762\n  Bound result 5\n  Bound result 1249999999999999995\n  Bound result 4\n  Bound result 22779942241758518337\n  Bound result 1\n  Bound result 100000000000000000000\n  Bound result 9750000000000003413\n  Bound result 138890\n  Bound result 41628477513708214638\n  Bound result 98000000000000024577\n  Bound result 2\n  Bound result 53266754396703429526770\n  Bound result 9000000000000000000\n  Bound result 160\n  Bound result 7\n  Bound result 99999000000000000000138\n  Bound result 68093493365227025499\n  Bound result 9750000000000008454\n  Bound result 12\n  Bound result 98000000000000010001\n  Bound result 13\n  Bound result 7\n  Bound result 10500\n  Bound result 94874225880375783563384\n  Bound result 2000000000000000000\n  Bound result 251661364\n  Bound result 10\n  Bound result 3749999999999959385\n  Bound result 901608467706887191\n  Bound result 1\n  Bound result 9750000000000009580\n  Bound result 98000000000000259201\n  Bound result 9750000000000012019\n  Bound result 18\n  Bound result 7\n  Bound result 17\n  Bound result 1\n  Bound result 17077\n  Bound result 98000000000000009529\n  Bound result 2\n  Bound result 12\n  Bound result 5\n  Bound result 20\n  Bound result 601012500000000000000\n  Bound result 16\n  Bound result 9750000000000887221\n  Bound result 3\n  Bound result 19\n  Bound result 6\n  Bound result 5071\n  Bound result 12\n  Bound result 9750000003786714986\n  Bound result 4\n  Bound result 6\n  Bound result 318823\n  Bound result 7619011467826048672\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 14.68s (14.67s CPU time)\n\nRan 27 test suites in 14.69s (20.56s CPU time): 285 tests passed, 0 failed, 2 skipped (287 total tests)\n","passed":true},{"durationMs":335,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.settleClaim(bytes32)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":610,\"README.md\":289,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":510,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":433,\"test/PagesAudit.t.sol\":318,\"test/PagesDeployment.t.sol\":61,\"test/PagesOracle.t.sol\":168,\"test/PagesRevision.t.sol\":278,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":80,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":27550,"exitCode":0,"name":"slither","output":"[high/medium] weak-prng at src/MarginaliaPricer.sol:205: MarginaliaPricer.twap(MarginaliaTypes.VenueKind,bool,uint256,uint64,uint256,uint64) (src/MarginaliaPricer.sol#205-229) uses a weak PRNG: \"delta < 0 && delta % int256(dt) != 0 (src/MarginaliaPricer.sol#215)\"\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:287: Reentrancy in MarginaliaRouter._pull(address,uint256) (src/MarginaliaRouter.sol#287-292):\n[high/high] uninitialized-state at src/MarginaliaHook.sol:536: MarginaliaHook.observations (src/MarginaliaHook.sol#106) is never initialized. It is used in:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:377: MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPages.sol:463: MarginaliaPages.burnLimit() (src/MarginaliaPages.sol#463-470) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:299: MarginaliaRouter.unlockCallback(bytes) (src/MarginaliaRouter.sol#299-340) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:294: MarginaliaRouter._checkSubject(MarginaliaRouter.Job) (src/MarginaliaRouter.sol#294-297) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:176: MarginaliaPricer.settlePrice(MarginaliaTypes.Venue,bool,MarginaliaTypes.Observation[]) (src/MarginaliaPricer.sol#176-201) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:287: MarginaliaRouter._pull(address,uint256) (src/MarginaliaRouter.sol#287-292) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:205: MarginaliaPricer.twap(MarginaliaTypes.VenueKind,bool,uint256,uint64,uint256,uint64) (src/MarginaliaPricer.sol#205-229) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaTreasury.sol:42: MarginaliaTreasury.drip() (src/MarginaliaTreasury.sol#42-52) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaHook.sol:579: MarginaliaHook._broken(MarginaliaTypes.Note,uint256) (src/MarginaliaHook.sol#579-582) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaHook.sol:919: MarginaliaHook._unlock(uint8,address,uint256,uint256) (src/MarginaliaHook.sol#919-928) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaTreasury.sol:42: MarginaliaTreasury.drip() (src/MarginaliaTreasury.sol#42-52) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:135: MarginaliaPricer.postPrice(IPoolManager,MarginaliaTypes.Venue,address,bool,MarginaliaTypes.PriceWindow) (src/MarginaliaPricer.sol#135-155) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:242: MarginaliaRouter._run(bool,uint256,uint256,uint256,MarginaliaRouter.XTrade,MarginaliaTypes.NoteParams,PoolKey) (src/MarginaliaRouter.sol#242-284) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:227: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#227-243):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:603: Reentrancy in MarginaliaHook.settle(bytes32) (src/MarginaliaHook.sol#603-652):\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:334: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#334-361):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:855: Reentrancy in MarginaliaHook.payJudged(uint32,bytes32[3]) (src/MarginaliaHook.sol#855-874):\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:453: Reentrancy in MarginaliaPages.burnPending(uint256) (src/MarginaliaPages.sol#453-459):\n[medium/medium] reentrancy-no-eth at src/MarginaliaJudge.sol:203: Reentrancy in MarginaliaJudge.requestJudging(uint32) (src/MarginaliaJudge.sol#203-226):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:679: Reentrancy in MarginaliaHook.retract(bytes32,string) (src/MarginaliaHook.sol#679-695):\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:179: MarginaliaRouter.sellWithNote(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256).noX (src/MarginaliaRouter.sol#179) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:127: MarginaliaJudge.questionBody(uint32).allow (src/MarginaliaJudge.sol#127) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaHook.sol:611: MarginaliaHook.settle(bytes32).settlePrice (src/MarginaliaHook.sol#611) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:166: MarginaliaRouter.note(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256).noX (src/MarginaliaRouter.sol#166) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:257: MarginaliaRouter._run(bool,uint256,uint256,uint256,MarginaliaRouter.XTrade,MarginaliaTypes.NoteParams,PoolKey).job (src/MarginaliaRouter.sol#257) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:113: MarginaliaJudge.eligibleTheses(uint32).n (src/MarginaliaJudge.sol#113) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:205: MarginaliaRouter.validateVenue(MarginaliaTypes.NoteParams,PoolKey).t1 (src/MarginaliaRouter.sol#205) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:272: MarginaliaJudge.judgedOf(uint32).dup (src/MarginaliaJudge.sol#272) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:268: MarginaliaJudge.judgedOf(uint32).kept (src/MarginaliaJudge.sol#268) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaHook.sol:862: MarginaliaHook.payJudged(uint32,bytes32[3]).paidAmounts (src/MarginaliaHook.sol#862) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:168: MarginaliaJudge._dec(uint256).n (src/MarginaliaJudge.sol#168) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:204: MarginaliaRouter.validateVenue(MarginaliaTypes.NoteParams,PoolKey).t0 (src/MarginaliaRouter.sol#204) is a local variable never initialized\n[medium/medium] unused-return at src/MarginaliaPricer.sol:255: MarginaliaPricer._quoteSpot(IPoolManager,address,address) (src/MarginaliaPricer.sol#255-264) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(HUB_POOL_ID)) (src/MarginaliaPricer.sol#260)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (r0,r1,None) = IUniswapV2PairOracle(ref).getReserves() (src/MarginaliaPricer.sol#245)\n[medium/medium] unused-return at src/MarginaliaPages.sol:481: MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#481-509) ignores return value by manager.settle() (src/MarginaliaPages.sol#506)\n[medium/medium] unused-return at src/MarginaliaPages.sol:481: MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#481-509) ignores return value by (current,None,None,None) = manager.getSlot0(key.toId()) (src/MarginaliaPages.sol#488)\n[medium/medium] unused-return at src/MarginaliaHook.sol:930: MarginaliaHook.unlockCallback(bytes) (src/MarginaliaHook.sol#930-950) ignores return value by poolManager.settle() (src/MarginaliaHook.sol#945)\n[medium/medium] unused-return at src/MarginaliaHook.sol:294: MarginaliaHook.margPriceInImd() (src/MarginaliaHook.sol#294-297) ignores return value by (sqrtP,None,None,None) = poolManager.getSlot0(poolId) (src/MarginaliaHook.sol#295)\n[medium/medium] unused-return at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) ignores return value by (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (sqrtP_scope_0,None,None,None,None,None,None) = IUniswapV3PoolOracle(ref).slot0() (src/MarginaliaPricer.sol#241)\n[medium/medium] unused-return at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) ignores return value by (r0,r1,None) = pair.getReserves() (src/MarginaliaRouter.sol#426)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:267: MarginaliaPricer._v3Cumulative(address) (src/MarginaliaPricer.sol#267-271) ignores return value by (cum,None) = IUniswapV3PoolOracle(pool).observe(ago) (src/MarginaliaPricer.sol#269)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(v.ref)) (src/MarginaliaPricer.sol#237)\n[medium/medium] unused-return at src/MarginaliaPages.sol:463: MarginaliaPages.burnLimit() (src/MarginaliaPages.sol#463-470) ignores return value by (current,None,None,None) = manager.getSlot0(key.toId()) (src/MarginaliaPages.sol#467)\n[low/high] shadowing-local at src/MarginaliaHook.sol:859: MarginaliaHook.payJudged(uint32,bytes32[3]).pool (src/MarginaliaHook.sol#859) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.noteMeta(bytes32).week (src/MarginaliaJudge.sol#19) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.thesesOfWeek(uint32).week (src/MarginaliaJudge.sol#15) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.thesisPool(uint32).week (src/MarginaliaJudge.sol#12) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.drawForJudging(uint32,uint256,bool).week (src/MarginaliaJudge.sol#21) shadows:\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:266: MarginaliaJudge.judgedOf(uint32) (src/MarginaliaJudge.sol#266-279) has external calls inside a loop: (author,noteWeek,thesis,hasChild) = hook.noteMeta(ranked[i]) (src/MarginaliaJudge.sol#270)\n[low/medium] calls-loop at src/MarginaliaHook.sol:919: MarginaliaHook._unlock(uint8,address,uint256,uint256) (src/MarginaliaHook.sol#919-928) has external calls inside a loop: out = poolManager.unlock(data) (src/MarginaliaHook.sol#925)\n[low/medium] calls-loop at src/MarginaliaHook.sol:658: MarginaliaHook._settlementPrice(MarginaliaTypes.Note,MarginaliaTypes.Observation[]) (src/MarginaliaHook.sol#658-676) has external calls inside a loop: p = pricer().settlePrice(n.venue,buy,sample) (src/MarginaliaHook.sol#669-674)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:91: MarginaliaJudge.convertForfeits() (src/MarginaliaJudge.sol#91-106) has external calls inside a loop: out = hook.sellPotMarg(marg) (src/MarginaliaJudge.sol#96-100)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:266: MarginaliaJudge.judgedOf(uint32) (src/MarginaliaJudge.sol#266-279) has external calls inside a loop: (author,noteWeek,thesis,hasChild) = hook.noteMeta(ranked[i]) (src/MarginaliaJudge.sol#270)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:334: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#334-361):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:722: Reentrancy in MarginaliaHook._forfeit(MarginaliaTypes.Note,address) (src/MarginaliaHook.sol#722-729):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:785: Reentrancy in MarginaliaHook._fund(uint256) (src/MarginaliaHook.sol#785-789):\n[low/medium] reentrancy-benign at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:227: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#227-243):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:261: Reentrancy in MarginaliaPages._distributeFee(bytes32,MarginaliaPages.Subject,uint256) (src/MarginaliaPages.sol#261-286):\n[low/medium] reentrancy-events at src/MarginaliaHook.sol:722: Reentrancy in MarginaliaHook._forfeit(MarginaliaTypes.Note,address) (src/MarginaliaHook.sol#722-729):\n[low/medium] reentrancy-events at src/MarginaliaHook.sol:698: Reentrancy in MarginaliaHook.settleThesis(bytes32) (src","passed":true},{"durationMs":1594,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/MarginaliaPages.sol:177: `abi.encodePacked()` Hash Collision (2 places)\n[high] eth-send-unchecked-address at src/MarginaliaHook.sol:779: ETH transferred without address checks (3 places)\n[high] reentrancy-state-change at src/MarginaliaHook.sol:224: Reentrancy: State change after external call (23 places)\n[high] storage-array-memory-edit at src/MarginaliaHook.sol:556: Storage Array Edited with Memory\n[high] unsafe-casting at src/MarginaliaHook.sol:936: Unsafe Casting of integers\n[low] costly-loop at src/MarginaliaHook.sol:864: Costly operations inside loop (2 places)\n[low] internal-function-used-once at src/HookFlags.sol:26: Internal Function Used Only Once (3 places)\n[low] large-numeric-literal at src/Marginalia.sol:10: Large Numeric Literal (25 places)\n[low] literal-instead-of-constant at src/MarginaliaHook.sol:355: Literal Instead of Constant (62 places)\n[low] local-variable-shadowing at src/MarginaliaHook.sol:859: Local Variable Shadows State Variable\n[low] require-revert-in-loop at src/MarginaliaHook.sol:864: Loop Contains `require`/`revert` (2 places)\n[low] state-change-without-event at src/MarginaliaHook.sol:835: State Change Without Event (7 places)\n[low] state-no-address-check at src/MarginaliaRouter.sol:135: Address State Variable Set Without Checks\n[low] unchecked-return at src/MarginaliaHook.sol:718: Unchecked Return (7 places)\n[low] uninitialized-local-variable at src/MarginaliaHook.sol:667: Uninitialized Local Variable (3 places)\n[low] unused-import at src/MarginaliaHook.sol:10: Unused Import\n[low] unused-public-function at src/MarginaliaHook.sol:294: Public Function Not Used Internally (4 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"19938d50ccac28ea353fe795296a906188b1839cb22fe54067bd587932d73775","verifiedTreeHash":"1f36488555d900aa68726945cc64c0c2852737a4","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":277754,"exitCode":0,"name":"build","output":"Compiling 125 files with Solc 0.8.26\nSolc 0.8.26 finished in 277.50s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:191:17\n    │\n191 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:286:13\n    │\n286 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:244:9\n    │\n244 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:259:9\n    │\n259 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:275:39\n    │\n275 │             if (s.escrowSince == 0 || block.timestamp >= uint256(s.escrowSince) + CLAIM_WINDOW) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:276:33\n    │\n276 │                 s.escrowSince = uint64(block.timestamp);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:351:21\n    │\n351 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n352 │ ┃             action,\n353 │ ┃             bytes(questionBody(normalized, tweetId)),\n354 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n355 │ ┃             imd,\n356 │ ┃             price\n357 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:362:9\n    │\n362 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:360:63\n    │\n360 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:391:13\n    │\n391 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:400:9\n    │\n400 │         emit Claimed(subject, wallet, owed - reimbursed, reimbursed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:399:55\n    │\n399 │         settlements[subject] = Settlement(c.claimant, uint96(reimbursed));\n    │                                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint96' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:427:13\n    │\n427 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:444:9\n    │\n444 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:439:13\n    │\n439 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:445:9\n    │\n445 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `pendingBurn` is updated\n    ╭▸ src/MarginaliaPages.sol:460:38\n    │\n460 │         (spent, burned) = abi.decode(hook.poolManager().unlock(abi.encode(imdIn)), (uint256, uint256));\n    │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:462:9\n    │\n462 │         emit Burned(spent, burned);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:459:44\n    │\n459 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:459:52\n    │\n459 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:480:50\n    │\n480 │             return l > TickMath.MIN_SQRT_PRICE ? uint160(l) : TickMath.MIN_SQRT_PRICE + 1;\n    │                                                  ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:483:46\n    │\n483 │         return u < TickMath.MAX_SQRT_PRICE ? uint160(u) : TickMath.MAX_SQRT_PRICE - 1;\n    │                                              ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:497:27\n    │\n497 │         burnAnchorBlock = uint64(block.number);\n    │                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:501:68\n    │\n501 │         BalanceDelta d = manager.swap(key, SwapParams(zeroForOne, -int256(imdIn), limit), \"\");\n    │                                                                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:504:25\n    │\n504 │         if (inD >= 0 || uint256(-int256(inD)) > imdIn) revert UnauthorizedCallback();\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:506:25\n    │\n506 │         uint256 spent = uint256(-int256(inD));\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:507:24\n    │\n507 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:507:32\n    │\n507 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:512:9\n    │\n512 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:139:43\n    │\n139 │         assertEq(pages.burnAnchorBlock(), block.number);\n    │                                           ━━━━━━━━━━━━\n140 │         vm.roll(block.number + 1);\n    │         ───────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:140:17\n    │\n140 │         vm.roll(block.number + 1);\n    │         ────────━━━━━━━━━━━━───── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:184:25\n    │\n184 │         uint256 start = block.number;\n    │                         ━━━━━━━━━━━━\n    ‡\n188 │             vm.roll(start + blocks);\n    │             ─────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:240:25\n    │\n240 │         assertEq(since, block.timestamp);\n    │                         ━━━━━━━━━━━━━━━\n241 │         vm.warp(block.timestamp + 91 days);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:241:17\n    │\n241 │         vm.warp(block.timestamp + 91 days);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":7215,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 422.51µs (0.00ns CPU time)\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 495.76µs (0.00ns CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 939.14µs (1.61ms CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 647484)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 4216548)\n[PASS] testColdCallbackPaysTwoFreshBalancesUnderStipendWithDistinctIds() (gas: 357232)\nLogs:\n  delivery gas including mock Intake overhead: 160691\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14307)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 91327)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 704831)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 4.01ms (2.43ms CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 7.01ms (6.06ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 13546439)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 15.09ms (14.95ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 16.35ms (7.13ms CPU time)\n\nRan 9 tests for test/PagesRevision.t.sol:PagesRevisionTest\n[PASS] testASecondBurnInABlockIsRefusedEvenAfterThePriceCameBack() (gas: 1075809)\n[PASS] testAccrualAfterTheWindowOpensANewWindowInsteadOfBeingRecyclableAtOnce() (gas: 2917864)\n[PASS] testBoundedBurnsAcrossBlocksBurnTheWholeBudgetAtMarket() (gas: 3666922)\n[PASS] testBurnSellBurnSandwichIsRefusedAndLosesMoneyAtEverySize() (gas: 3458373)\n[PASS] testCallbackOnlyVerifiesAndStoresThenAnyoneSettles() (gas: 2541688)\nLogs:\n  delivery gas including the mock Intake's overhead: 153153\n\n[PASS] testDustTrancheIsRefusedByName() (gas: 653599)\n[PASS] testMarketAndHookCannotBeSubjects() (gas: 403520)\n[PASS] testOneBlockOfBurningMovesThePriceAtMostTheBound() (gas: 594490)\n[PASS] testSandwichingTheBurnLosesMoneyAtEverySize() (gas: 2507869)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 16.60ms (11.41ms CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2679131)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2473717)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 695452)\n[PASS] testCurveIsLinear() (gas: 37654)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 4078061)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 64049)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37676)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 171079)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2378488)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 784018)\n[PASS] testSlippageAndNoCap() (gas: 616990)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1949596)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 20.06ms (12.51ms CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 24.19ms (12.29ms CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 22.25ms (10.86ms CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 43.19ms (43.37ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 23189, ~: 21440)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 58.79ms (37.15ms CPU time)\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 79.39ms (575.78µs CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2387844)\n[PASS] testBurnAfterAManipulatedPriceStaysBoundedAndCannotBlockTrading() (gas: 1193162)\n[PASS] testBurnCannotSpendReserveOrEscrow() (gas: 701866)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1151676)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143914)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476975)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1333138)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1221645, ~: 1260233)\nLogs:\n  Bound result 151\n  Bound result 702\n  Bound result 109\n\n[PASS] testOversizedTrancheFillsUpToTheBlockBoundAndResumesNextBlock() (gas: 1197074)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 711336)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 109.53ms (104.67ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 86.53ms (23.74ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 116.03ms (83.89ms CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 120.22ms (4.12ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 120.47ms (78.85ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 125.04ms (174.22ms CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838169, ~: 838176)\nLogs:\n  Bound result 3161409216220502563\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58962, ~: 58968)\nLogs:\n  Bound result 9750000000000040001\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 130.24ms (186.74ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 106009, ~: 106118)\nLogs:\n  Bound result -14626\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 131.61ms (80.00ms CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 128166, ~: 113632)\nLogs:\n  Bound result 2\n  Bound result 999999999999999999999000015001\n  Bound result 1800003600\n  Bound result 999999999999999999999000659919\n  Bound result 999999999999999999999000011000\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36858, ~: 36886)\nLogs:\n  Bound result 583041\n  Bound result 11000\n  Bound result 69\n  Bound result 949956940364074851611255\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141541, ~: 141878)\nLogs:\n  Bound result 158456325028528675187087900672\n  Bound result 1266412660188944021221804097829\n  Bound result 28800\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36723, ~: 36849)\nLogs:\n  Bound result 11000\n  Bound result 12\n  Bound result 15\n  Bound result 32\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23218, ~: 21542)\nLogs:\n  Bound result 1461446703485210103287273052176402869109084400016\n  Bound result 1461446703485210103287273052103988822379037671153\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39194, ~: 38092)\nLogs:\n  Bound result 10001\n  Bound result 9999999999999999999999999999999999990245\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16137, ~: 14538)\nLogs:\n  Bound result 0\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 53898, ~: 51987)\nLogs:\n  Bound result 31\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36442, ~: 36404)\nLogs:\n  Bound result 1\n  Bound result 140\n  Bound result 15\n  Bound result 32\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 18883, ~: 16591)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21353, ~: 21299)\nLogs:\n  Bound result 8884\n  Bound result 5192296858534827628530496329220095\n  Bound result 17078\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 63799, ~: 60676)\nLogs:\n  Bound result 17153\n  Bound result 9\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 98456, ~: 83837)\nLogs:\n  Bound result 7\n  Bound result 8\n  Bound result 6367\n  Bound result 203684832716283019655932542975\n  Bound result 42\n  Bound result 3737465505\n  Bound result 3000000000000000000000000\n  Bound result 237684487542793012780631851008\n  Bound result 500000000000000000\n  Bound result 18051\n  Bound result 54000000000000000\n  Bound result 255\n  Bound result 806583589928461891782872549115\n  Bound result 20000000000000000\n  Bound result 2010000000000000000000\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 131.60ms (1.21s CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 131.75ms (35.54ms CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 3)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 213   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 237   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 421   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 210   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 230   | 3       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 221   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 193   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 195   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 4545\n  Bound result 1\n  Bound result 4235\n  Bound result 32766\n  Bound result 47\n  Bound result 0\n  Bound result 57057350374171575842\n  Bound result 0\n  Bound result 55051546096536484860947\n  Bound result 2\n  Bound result 412780012061501423616\n  Bound result 10769\n  Bound result 20\n  Bound result 0\n  Bound result 120\n  Bound result 12345\n  Bound result 35\n  Bound result 0\n  Bound result 18446744073709551616\n  Bound result 44785\n  Bound result 50\n  Bound result 0\n  Bound result 1024\n  Bound result 50071\n  Bound result 25\n  Bound result 2\n  Bound result 21343\n  Bound result 50015\n  Bound result 56\n  Bound result 4008\n  Bound result 4371\n  Bound result 2\n  Bound result 917224734\n  Bound result 50100\n  Bound result 57\n  Bound result 2\n  Bound result 17543684059633157601738\n  Bound result 4862\n  Bound result 0\n  Bound result 2\n  Bound result 911307494\n  Bound result 1\n  Bound result 125\n  Bound result 1\n  Bound result 2000000000000000000000\n  Bound result 2615712498429058655945\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 4361\n  Bound result 51000\n  Bound result 62\n  Bound result 2\n  Bound result 8819\n  Bound result 3319\n  Bound result 1\n  Bound result 20538\n  Bound result 57989\n  Bound result 92\n  Bound result 0\n  Bound result 2\n  Bound result 2\n  Bound result 1\n  Bound result 2\n  Bound result 5\n  Bound result 53341\n  Bound result 21\n  Bound result 1\n  Bound result 1445\n  Bound result 10360\n  Bound result 99\n  Bound result 2883\n  Bound result 487793730332534585927\n  Bound result 0\n  Bound result 659918\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 14174\n  Bound result 1\n  Bound result 1581197095\n  Bound result 51667\n  Bound result 22\n  Bound result 2\n  Bound result 294110671520741839\n  Bound result 2\n  Bound result 1\n  Bound result 40000\n  Bound result 1\n  Bound result 0\n  Bound result 5685\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 447.68ms (438.95ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2502  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2454  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2492  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2436  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2404  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 3000\n  Bound result 10000000000000000000\n  Bound result 5944\n  Bound result 50000\n  Bound result 346084774187750486968393\n  Bound result 6819476402333376272\n  Bound result 109617\n  Bound result 314478716634879026220257614069371425083788840836\n  Bound result 988\n  Bound result 839\n  Bound result 12500\n  Bound result 55\n  Bound result 1000000000\n  Bound result 93137967851565394639860398260735\n  Bound result 1800000000\n  Bound result 8375\n  Bound result 40000\n  Bound result 9004436776734949376\n  Bound result 1353\n  Bound result 1461501637330902918203684832716283019655932542973\n  Bound result 25086\n  Bound result 400000\n  Bound result 169988\n  Bound result 3059\n  Bound result 1630\n  Bound result 172558\n  Bound result 167896\n  Bound result 10000000\n  Bound result 345600\n  Bound result 3184\n  Bound result 935705970\n  Bound result 562903372451216425\n  Bound result 164751942458008984599459\n  Bound result 7057350374175801344\n  Bound result 10000000000000000000\n  Bound result 48003\n  Bound result 111000000000000000000000\n  Bound result 162514264337593543871108\n  Bound result 500\n  Bound result 12345\n  Bound result 81423\n  Bound result 6635307553923823458\n  Bound result 240545\n  Bound result 5412\n  Bound result 4294261761851473131\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.03s (1.03s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 513   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 496   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 500   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 517   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 484   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 522   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 504   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 536   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 485   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 534   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 510   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 1028  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 539   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 510   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 492   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 519   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 503   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 544   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 504   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 97650000000014699950\n  Bound result 99999000000000000000028\n  Bound result 7684787338105002479\n  Bound result 2\n  Bound result 1800000000\n  Bound result 45137708652533764938949\n  Bound result 98000000000000010973\n  Bound result 4\n  Bound result 98000000000000012311\n  Bound result 99999000000000011155112\n  Bound result 99999000000000000001223\n  Bound result 22742\n  Bound result 2\n  Bound result 9750000000000003601\n  Bound result 2\n  Bound result 8\n  Bound result 78528675185470999397\n  Bound result 99999000000000000345601\n  Bound result 8\n  Bound result 1\n  Bound result 7\n  Bound result 98000000000000008672\n  Bound result 99999010000000000000001\n  Bound result 9\n  Bound result 6\n  Bound result 9\n  Bound result 7\n  Bound result 10\n  Bound result 10\n  Bound result 67360088344389043959687\n  Bound result 22606\n  Bound result 9750000000000000202\n  Bound result 1\n  Bound result 10\n  Bound result 1662\n  Bound result 99999000000000000006619\n  Bound result 9750000000000002401\n  Bound result 12\n  Bound result 345597\n  Bound result 9900000000000000001\n  Bound result 10\n  Bound result 3\n  Bound result 1\n  Bound result 9750000000001000001\n  Bound result 4\n  Bound result 9750000000000001458\n  Bound result 31687303715884105727\n  Bound result 98000000000000002212\n  Bound result 10\n  Bound result 114991\n  Bound result 13865\n  Bound result 99999000000000000000051\n  Bound result 15056483611514029309\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.10s (7.10s CPU time)\n\nRan 27 test suites in 7.10s (10.09s CPU time): 287 tests passed, 0 failed, 2 skipped (289 total tests)\n","passed":true},{"durationMs":171,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.settleClaim(bytes32)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":626,\"README.md\":304,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"launch.json\":15,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":516,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":433,\"test/PagesAudit.t.sol\":318,\"test/PagesDeployment.t.sol\":61,\"test/PagesOracle.t.sol\":168,\"test/PagesRevision.t.sol\":353,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":80,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"36b15b4a7454fab599e03e51b5323222192b9f22870abd4ffe132b7dfaa52957","verifiedTreeHash":"a374d1aa9a4d1a4587d2494e10242f492c29380d","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":254602,"exitCode":0,"name":"build","output":"Compiling 124 files with Solc 0.8.26\nSolc 0.8.26 finished in 254.37s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:158:17\n    │\n158 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:244:13\n    │\n244 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:206:9\n    │\n206 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:221:9\n    │\n221 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:235:53\n    │\n235 │             if (s.escrowSince == 0) s.escrowSince = uint64(block.timestamp);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:309:21\n    │\n309 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n310 │ ┃             action,\n311 │ ┃             bytes(questionBody(normalized, tweetId)),\n312 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n313 │ ┃             imd,\n314 │ ┃             price\n315 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:320:9\n    │\n320 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:318:63\n    │\n318 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:346:13\n    │\n346 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:359:9\n    │\n359 │         emit Claimed(subject, wallet, owed, reimbursed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:367:13\n    │\n367 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:384:9\n    │\n384 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:379:13\n    │\n379 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:385:9\n    │\n385 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:398:9\n    │\n398 │         hook.poolManager().unlock(abi.encode(imdIn, minMargOut));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:395:44\n    │\n395 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:395:52\n    │\n395 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:398:9\n    │\n398 │         hook.poolManager().unlock(abi.encode(imdIn, minMargOut));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:428:9\n    │\n428 │         emit Burned(imdIn, marg);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:412:18\n    │\n412 │                 -int256(imdIn),\n    │                  ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:419:38\n    │\n419 │         if (inD >= 0 || outD <= 0 || uint256(-int256(inD)) != imdIn) revert UnauthorizedCallback();\n    │                                      ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:420:24\n    │\n420 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:420:32\n    │\n420 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:426:9\n    │\n426 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":7162,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 529.05µs (0.00ns CPU time)\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 715.54µs (0.00ns CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 3.59ms (1.89ms CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 667767)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 3878569)\n[PASS] testColdCallbackPaysTwoFreshBalancesUnderStipendWithDistinctIds() (gas: 282027)\nLogs:\n  delivery gas including mock Intake overhead: 203394\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14297)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 86052)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 742292)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 7.43ms (4.33ms CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 15.39ms (14.37ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 18.73ms (6.26ms CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 20.65ms (8.40ms CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 21.97ms (4.34ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 12065711)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 28.29ms (28.06ms CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 28.92ms (12.29ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 21863, ~: 20080)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 35.72ms (36.71ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 57.15ms (58.07ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 61.63ms (56.97ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 96.97ms (28.89ms CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2386917)\n[PASS] testBurnCannotSpendReserveOrEscrowAndRejectsZeroFloor() (gas: 705180)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1433838)\n[PASS] testBurnUsesCallerFloorAndManipulatedPriceCannotBlockTrading() (gas: 1017958)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143720)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476847)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1331251)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1209989, ~: 1258082)\nLogs:\n  Bound result 2\n  Bound result 5\n  Bound result 0\n\n[PASS] testPartialFillBurnRollsBackAndSmallerTranchesWork() (gas: 1297340)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 709869)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 104.56ms (96.90ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 105971, ~: 106113)\nLogs:\n  Bound result -11438\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 116.26ms (119.56ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 117.70ms (152.79ms CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 117.82ms (36.28ms CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 121.05ms (78.91ms CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2662900)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2411734)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 668941)\n[PASS] testCurveIsLinear() (gas: 37344)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 3935373)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 63979)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37561)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 170731)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2377793)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 782680)\n[PASS] testSlippageAndNoCap() (gas: 615462)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1888094)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 121.14ms (10.75ms CPU time)\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 121.25ms (510.88µs CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838166, ~: 838176)\nLogs:\n  Bound result 9750000000000000086\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58959, ~: 58968)\nLogs:\n  Bound result 9750000000000000319\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 126.84ms (215.37ms CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 128124, ~: 101845)\nLogs:\n  Bound result 4\n  Bound result 147530491195717072705658862629\n  Bound result 266089656772766543552057192539\n  Bound result 413567450346554648772191154736\n  Bound result 956970646055824511486275032660\n  Bound result 884718792784862078\n  Bound result 770300264960786895806654727512\n  Bound result 252274625570527139677059352229\n  Bound result 999999999999999999999000000202\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36927, ~: 36996)\nLogs:\n  Bound result 9992003\n  Bound result 11000\n  Bound result 1\n  Bound result 552691790224321108210492048537\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141443, ~: 141832)\nLogs:\n  Bound result 830729559070812284840438075833\n  Bound result 290472660253308476603606068057\n  Bound result 12009\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36741, ~: 36876)\nLogs:\n  Bound result 13320\n  Bound result 1\n  Bound result 20\n  Bound result 28800\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23251, ~: 21542)\nLogs:\n  Bound result 100000000000000000001\n  Bound result 1461446703485210103287273052103988822378723975094\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39551, ~: 39004)\nLogs:\n  Bound result 5557425729203426461259519600097268560812\n  Bound result 1917088554149\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16091, ~: 14429)\nLogs:\n  Bound result 165\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 53743, ~: 51987)\nLogs:\n  Bound result 997\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36415, ~: 36404)\nLogs:\n  Bound result 4320\n  Bound result 1000\n  Bound result 20\n  Bound result 28800\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 18681, ~: 16761)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21346, ~: 21299)\nLogs:\n  Bound result 5192296858534827628530496329220095\n  Bound result 5192296858534827628530496329220095\n  Bound result 4659\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 62735, ~: 58038)\nLogs:\n  Bound result 61396\n  Bound result 16\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 100233, ~: 91671)\nLogs:\n  Bound result 1\n  Bound result 662692669726061643139652125654\n  Bound result 252\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 126.85ms (1.20s CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 3)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 241   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 205   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 418   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 211   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 195   | 3       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 217   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 212   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 221   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1\n  Bound result 1374255301884990083034\n  Bound result 53585\n  Bound result 44\n  Bound result 2\n  Bound result 252\n  Bound result 49601\n  Bound result 12\n  Bound result 0\n  Bound result 0\n  Bound result 1470548450400182098972\n  Bound result 57787\n  Bound result 11\n  Bound result 2\n  Bound result 8192\n  Bound result 50056\n  Bound result 4\n  Bound result 1\n  Bound result 13079\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 1\n  Bound result 13\n  Bound result 2\n  Bound result 75000000000000000000\n  Bound result 2\n  Bound result 9954\n  Bound result 2\n  Bound result 500000000000000000000\n  Bound result 2\n  Bound result 10000\n  Bound result 56193\n  Bound result 86\n  Bound result 1\n  Bound result 14100\n  Bound result 0\n  Bound result 1390054571271235490\n  Bound result 31956\n  Bound result 13\n  Bound result 1\n  Bound result 2\n  Bound result 0\n  Bound result 1\n  Bound result 600\n  Bound result 50016\n  Bound result 24\n  Bound result 1\n  Bound result 0\n  Bound result 23937420551000397919735\n  Bound result 2\n  Bound result 400000\n  Bound result 13923\n  Bound result 26\n  Bound result 4872\n  Bound result 1\n  Bound result 43563350896162705710252\n  Bound result 120\n  Bound result 1\n  Bound result 2109295512424009991\n  Bound result 2\n  Bound result 0\n  Bound result 125\n  Bound result 77\n  Bound result 4\n  Bound result 0\n  Bound result 1540\n  Bound result 2\n  Bound result 7656\n  Bound result 4767\n  Bound result 48\n  Bound result 2\n  Bound result 40470119486054760199303\n  Bound result 1860\n  Bound result 1\n  Bound result 900\n  Bound result 54184\n  Bound result 3\n  Bound result 3368671859121715175794\n  Bound result 1\n  Bound result 0\n  Bound result 16436\n  Bound result 2\n  Bound result 1\n  Bound result 10000\n  Bound result 2\n  Bound result 654082465424432199891\n  Bound result 7\n  Bound result 5\n  Bound result 1\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 466.22ms (450.63ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2418  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2410  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2448  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2461  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2551  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 856\n  Bound result 868\n  Bound result 16777216\n  Bound result 168658\n  Bound result 2307\n  Bound result 15\n  Bound result 9285380274899124224\n  Bound result 6090\n  Bound result 8936\n  Bound result 103969\n  Bound result 5780\n  Bound result 64\n  Bound result 5707\n  Bound result 1000000000000000000000000\n  Bound result 500000000000000000000\n  Bound result 172558\n  Bound result 600\n  Bound result 10\n  Bound result 5009\n  Bound result 2903807060280344574\n  Bound result 9379\n  Bound result 1829332848658377190\n  Bound result 8\n  Bound result 5270\n  Bound result 240\n  Bound result 10000000000000000000000000\n  Bound result 2748\n  Bound result 7035\n  Bound result 108118959529514860835200\n  Bound result 2755\n  Bound result 8294\n  Bound result 757\n  Bound result 255\n  Bound result 3450829853099908082\n  Bound result 1945371970366175622662\n  Bound result 12517\n  Bound result 1450945\n  Bound result 259199\n  Bound result 6455\n  Bound result 3241218212765563463\n  Bound result 826074470\n  Bound result 49811\n  Bound result 887220\n  Bound result 6931\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.06s (1.05s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 494   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 483   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 476   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 526   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 534   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 482   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 538   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 520   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 532   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 487   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 516   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 1010  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 513   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 516   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 534   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 513   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 517   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 552   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 497   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 259200\n  Bound result 2\n  Bound result 4\n  Bound result 60480000\n  Bound result 176307\n  Bound result 2\n  Bound result 2499999999999999990\n  Bound result 420000\n  Bound result 9750000004294988131\n  Bound result 36762445033683717132\n  Bound result 9750000000000005972\n  Bound result 7\n  Bound result 156081\n  Bound result 2\n  Bound result 1\n  Bound result 3\n  Bound result 98000000000000000065\n  Bound result 3\n  Bound result 6\n  Bound result 12285\n  Bound result 3\n  Bound result 8\n  Bound result 99999999999999999950\n  Bound result 15581\n  Bound result 9750000000000000095\n  Bound result 98000000000000023234\n  Bound result 7\n  Bound result 9750000000000019936\n  Bound result 8\n  Bound result 32\n  Bound result 2\n  Bound result 1234547799\n  Bound result 2\n  Bound result 9750000000000008372\n  Bound result 8423\n  Bound result 100000000000000000000000\n  Bound result 4\n  Bound result 4027\n  Bound result 16905\n  Bound result 7\n  Bound result 63999999999999998868\n  Bound result 4\n  Bound result 7739467576259600406\n  Bound result 10\n  Bound result 821\n  Bound result 99999000000000000015373\n  Bound result 98000000000000020718\n  Bound result 16628\n  Bound result 99999000000000000100001\n  Bound result 9750000000000000012\n  Bound result 24441864674355041054\n  Bound result 9750000000000015804\n  Bound result 997\n  Bound result 20207\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.05s (7.05s CPU time)\n\nRan 26 test suites in 7.05s (10.04s CPU time): 278 tests passed, 0 failed, 2 skipped (280 total tests)\n","passed":true},{"durationMs":179,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256,uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":583,\"README.md\":268,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"launch.json\":15,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":431,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":418,\"test/PagesAudit.t.sol\":300,\"test/PagesDeployment.t.sol\":61,\"test/PagesOracle.t.sol\":166,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":79,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"578a448cb84ac2a402ca388c24acf88716618f1e200362295e05750273455012","verifiedTreeHash":"5957da2b802546459ebc82101194199dad0984aa","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":283760,"exitCode":0,"name":"build","output":"Compiling 125 files with Solc 0.8.26\nSolc 0.8.26 finished in 283.51s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:189:17\n    │\n189 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:284:13\n    │\n284 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:242:9\n    │\n242 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:257:9\n    │\n257 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:273:39\n    │\n273 │             if (s.escrowSince == 0 || block.timestamp >= uint256(s.escrowSince) + CLAIM_WINDOW) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:274:33\n    │\n274 │                 s.escrowSince = uint64(block.timestamp);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:349:21\n    │\n349 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n350 │ ┃             action,\n351 │ ┃             bytes(questionBody(normalized, tweetId)),\n352 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n353 │ ┃             imd,\n354 │ ┃             price\n355 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:360:9\n    │\n360 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:358:63\n    │\n358 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:389:13\n    │\n389 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:398:9\n    │\n398 │         emit Claimed(subject, wallet, owed - reimbursed, reimbursed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:397:55\n    │\n397 │         settlements[subject] = Settlement(c.claimant, uint96(reimbursed));\n    │                                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint96' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:425:13\n    │\n425 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:442:9\n    │\n442 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:437:13\n    │\n437 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:443:9\n    │\n443 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `pendingBurn` is updated\n    ╭▸ src/MarginaliaPages.sol:456:38\n    │\n456 │         (spent, burned) = abi.decode(hook.poolManager().unlock(abi.encode(imdIn)), (uint256, uint256));\n    │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:458:9\n    │\n458 │         emit Burned(spent, burned);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:455:44\n    │\n455 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:455:52\n    │\n455 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:475:50\n    │\n475 │             return l > TickMath.MIN_SQRT_PRICE ? uint160(l) : TickMath.MIN_SQRT_PRICE + 1;\n    │                                                  ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:478:46\n    │\n478 │         return u < TickMath.MAX_SQRT_PRICE ? uint160(u) : TickMath.MAX_SQRT_PRICE - 1;\n    │                                              ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:490:31\n    │\n490 │             burnAnchorBlock = uint64(block.number);\n    │                               ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:495:68\n    │\n495 │         BalanceDelta d = manager.swap(key, SwapParams(zeroForOne, -int256(imdIn), limit), \"\");\n    │                                                                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:498:25\n    │\n498 │         if (inD >= 0 || uint256(-int256(inD)) > imdIn) revert UnauthorizedCallback();\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:500:25\n    │\n500 │         uint256 spent = uint256(-int256(inD));\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:501:24\n    │\n501 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:501:32\n    │\n501 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:506:9\n    │\n506 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:109:25\n    │\n109 │         uint256 start = block.number;\n    │                         ━━━━━━━━━━━━\n    ‡\n113 │             vm.roll(start + blocks);\n    │             ─────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:165:25\n    │\n165 │         assertEq(since, block.timestamp);\n    │                         ━━━━━━━━━━━━━━━\n166 │         vm.warp(block.timestamp + 91 days);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:166:17\n    │\n166 │         vm.warp(block.timestamp + 91 days);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":7477,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 540.74µs (0.00ns CPU time)\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 685.14µs (0.00ns CPU time)\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 1.12ms (594.60µs CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 647484)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 4220844)\n[PASS] testColdCallbackPaysTwoFreshBalancesUnderStipendWithDistinctIds() (gas: 357232)\nLogs:\n  delivery gas including mock Intake overhead: 160691\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14307)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 91411)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 704831)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 4.76ms (2.91ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 9.61ms (5.07ms CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 12.39ms (10.97ms CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 12.90ms (4.67ms CPU time)\n\nRan 7 tests for test/PagesRevision.t.sol:PagesRevisionTest\n[PASS] testAccrualAfterTheWindowOpensANewWindowInsteadOfBeingRecyclableAtOnce() (gas: 2917756)\n[PASS] testBoundedBurnsAcrossBlocksBurnTheWholeBudgetAtMarket() (gas: 4980668)\n[PASS] testCallbackOnlyVerifiesAndStoresThenAnyoneSettles() (gas: 2541580)\nLogs:\n  delivery gas including the mock Intake's overhead: 153153\n\n[PASS] testDustTrancheIsRefusedByName() (gas: 653765)\n[PASS] testMarketAndHookCannotBeSubjects() (gas: 403498)\n[PASS] testOneBlockOfBurningMovesThePriceAtMostTheBound() (gas: 660282)\n[PASS] testSandwichingTheBurnLosesMoneyAtEverySize() (gas: 2780610)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 15.96ms (11.28ms CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 17.58ms (34.00ms CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 22.35ms (8.50ms CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 28.45ms (15.81ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 13563035)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 28.39ms (28.28ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 33.25ms (28.56ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 21658, ~: 17955)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 42.76ms (33.26ms CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 50.77ms (2.43ms CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 54.75ms (51.16ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 82.92ms (71.61ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 122.91ms (102.46ms CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2679131)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2473717)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 695581)\n[PASS] testCurveIsLinear() (gas: 37654)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 4078061)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 64049)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37676)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 171079)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2378488)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 784018)\n[PASS] testSlippageAndNoCap() (gas: 616990)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1949596)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 123.02ms (10.25ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 127.28ms (149.85ms CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838165, ~: 838176)\nLogs:\n  Bound result 9000000000000000000\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58957, ~: 58968)\nLogs:\n  Bound result 7335025479415151467\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 127.88ms (225.38ms CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2387844)\n[PASS] testBurnAfterAManipulatedPriceStaysBoundedAndCannotBlockTrading() (gas: 1193420)\n[PASS] testBurnCannotSpendReserveOrEscrow() (gas: 701995)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1151934)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143914)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476975)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1333138)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1211693, ~: 1260236)\nLogs:\n  Bound result 532\n  Bound result 190\n  Bound result 73\n\n[PASS] testOversizedTrancheFillsUpToTheBlockBoundAndResumesNextBlock() (gas: 1197678)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 711336)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 132.57ms (128.33ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 105962, ~: 106088)\nLogs:\n  Bound result 13\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 132.78ms (51.22ms CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 128590, ~: 113649)\nLogs:\n  Bound result 3\n  Bound result 851903343555042765663828993643\n  Bound result 315944280303482421497886886770\n  Bound result 12794573865159\n  Bound result 9108976276210\n  Bound result 1000000000\n  Bound result 1000000002\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36914, ~: 36935)\nLogs:\n  Bound result 9989011\n  Bound result 9989007\n  Bound result 9\n  Bound result 65116\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141506, ~: 141881)\nLogs:\n  Bound result 1267650600227075352991603096572\n  Bound result 1266422281714048856750717242047\n  Bound result 3913\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36741, ~: 36834)\nLogs:\n  Bound result 963327\n  Bound result 5\n  Bound result 12\n  Bound result 338320035701572043128045195762\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23340, ~: 21564)\nLogs:\n  Bound result 100000000000000000000\n  Bound result 1461446703485210103287273052103988822378723973343\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39388, ~: 39200)\nLogs:\n  Bound result 16777216\n  Bound result 9999999999999999999999999999999999993001\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16422, ~: 14794)\nLogs:\n  Bound result 163\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 53811, ~: 51987)\nLogs:\n  Bound result 15157\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36392, ~: 36356)\nLogs:\n  Bound result 1502\n  Bound result 5293\n  Bound result 14\n  Bound result 1000000000000000000000000000000\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 18749, ~: 16336)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21387, ~: 21299)\nLogs:\n  Bound result 17371\n  Bound result 23009\n  Bound result 692\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 62292, ~: 58011)\nLogs:\n  Bound result 23097\n  Bound result 7\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 100915, ~: 91618)\nLogs:\n  Bound result 12\n  Bound result 101531487983127833042304\n  Bound result 336347228406671486245017641512\n  Bound result 789293926566966503203681861298\n  Bound result 580393561792893558349963419614\n  Bound result 192996\n  Bound result 700840922670453877163276325886\n  Bound result 13031\n  Bound result 382800882185362732593810524394\n  Bound result 970209\n  Bound result 9558638991710423500926234954\n  Bound result 696153308517316987366949422549\n  Bound result 871420259487791455201917946555\n  Bound result 23081\n  Bound result 1811801513\n  Bound result 23271562402055262152827677290\n  Bound result 401549303965369280484463306889\n  Bound result 53856958937289200166\n  Bound result 12155\n  Bound result 576564195568088377740587560414\n  Bound result 367339366413374729274948780667\n  Bound result 1\n  Bound result 692096322758939980173186275361\n  Bound result 214\n  Bound result 1\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 132.80ms (1.17s CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 4)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 208   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 204   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 417   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 192   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 221   | 4       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 250   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 213   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 215   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 2\n  Bound result 4191\n  Bound result 2\n  Bound result 5099\n  Bound result 1\n  Bound result 1608\n  Bound result 5377\n  Bound result 0\n  Bound result 4503599627370495\n  Bound result 52557\n  Bound result 18\n  Bound result 0\n  Bound result 130\n  Bound result 19847\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 200128569845183926910\n  Bound result 10001\n  Bound result 69\n  Bound result 0\n  Bound result 2000000000000000000000\n  Bound result 39427\n  Bound result 24\n  Bound result 1\n  Bound result 562988655177746107100\n  Bound result 20\n  Bound result 13\n  Bound result 0\n  Bound result 280\n  Bound result 0\n  Bound result 47421366572471789\n  Bound result 10002\n  Bound result 91\n  Bound result 1\n  Bound result 16126\n  Bound result 2348\n  Bound result 2\n  Bound result 27787128555632444980282\n  Bound result 0\n  Bound result 13814\n  Bound result 10155\n  Bound result 60\n  Bound result 2\n  Bound result 721\n  Bound result 3672351521635008841994\n  Bound result 1\n  Bound result 2\n  Bound result 1457584007913129639836\n  Bound result 16400\n  Bound result 47\n  Bound result 0\n  Bound result 8604\n  Bound result 50013\n  Bound result 91\n  Bound result 2\n  Bound result 100000000000000\n  Bound result 27113\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 1\n  Bound result 0\n  Bound result 0\n  Bound result 1669\n  Bound result 10003\n  Bound result 49\n  Bound result 1\n  Bound result 160\n  Bound result 13214\n  Bound result 31\n  Bound result 0\n  Bound result 4750\n  Bound result 2467\n  Bound result 43\n  Bound result 0\n  Bound result 2544\n  Bound result 2\n  Bound result 2440\n  Bound result 8836\n  Bound result 32\n  Bound result 0\n  Bound result 3843\n  Bound result 2\n  Bound result 1\n  Bound result 8\n  Bound result 8\n  Bound result 64\n  Bound result 1793\n  Bound result 0\n  Bound result 2\n  Bound result 15615\n  Bound result 21770\n  Bound result 46\n  Bound result 0\n  Bound result 1000000000000000000\n  Bound result 2499\n  Bound result 77\n  Bound result 2\n  Bound result 1000\n  Bound result 20\n  Bound result 22\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 465.59ms (454.55ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2415  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2424  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2490  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2516  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2443  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 3000000000000000000000000\n  Bound result 1203\n  Bound result 7250\n  Bound result 1143\n  Bound result 3882737816892\n  Bound result 169\n  Bound result 3600\n  Bound result 20000000\n  Bound result 123448\n  Bound result 96\n  Bound result 1722548055995041\n  Bound result 100000000000000000000000\n  Bound result 13708810239082\n  Bound result 391144060527419430244745632122\n  Bound result 55\n  Bound result 7862\n  Bound result 47218170938390617378625\n  Bound result 401\n  Bound result 358\n  Bound result 1255\n  Bound result 108256\n  Bound result 175519\n  Bound result 6000000\n  Bound result 59240\n  Bound result 6000000\n  Bound result 6392\n  Bound result 6931\n  Bound result 167950\n  Bound result 28800\n  Bound result 10000000000000000000\n  Bound result 201829\n  Bound result 20875603693289984230260013614213250\n  Bound result 60566400\n  Bound result 1\n  Bound result 4503239959059473026\n  Bound result 1285837909010165195727170108129823579620436949808\n  Bound result 999999999999999999999998\n  Bound result 100137\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.08s (1.08s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 522   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 507   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 517   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 502   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 505   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 566   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 493   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 514   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 502   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 495   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 518   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 1056  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 469   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 511   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 499   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 530   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 529   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 479   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 526   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 98000000000000005095\n  Bound result 1\n  Bound result 4\n  Bound result 9750000000000345601\n  Bound result 1\n  Bound result 1212\n  Bound result 4\n  Bound result 6\n  Bound result 2491849847384688631\n  Bound result 69389053265727982474\n  Bound result 6\n  Bound result 1\n  Bound result 1\n  Bound result 19999999999999999980\n  Bound result 9750000000000015001\n  Bound result 34101869646713468193817\n  Bound result 255\n  Bound result 2\n  Bound result 5\n  Bound result 172793\n  Bound result 4\n  Bound result 6238055466126887014\n  Bound result 120\n  Bound result 30613697286732572179\n  Bound result 7\n  Bound result 1\n  Bound result 10350000000000000000\n  Bound result 9025\n  Bound result 9982812971699239908\n  Bound result 10\n  Bound result 4788\n  Bound result 87483840348532862489\n  Bound result 6\n  Bound result 8195\n  Bound result 470161005\n  Bound result 10\n  Bound result 13485177964076406385\n  Bound result 11934\n  Bound result 6\n  Bound result 4\n  Bound result 9750000000000659919\n  Bound result 8\n  Bound result 4\n  Bound result 10\n  Bound result 6\n  Bound result 9222463958108211808\n  Bound result 10\n  Bound result 9750000000000000326\n  Bound result 1000000000000\n  Bound result 98000000000000691201\n  Bound result 98000000000375292465\n  Bound result 5\n  Bound result 99999000000000000015215\n  Bound result 168308\n  Bound result 15\n  Bound result 73224698474967402230\n  Bound result 4\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.36s (7.36s CPU time)\n\nRan 27 test suites in 7.37s (10.23s CPU time): 285 tests passed, 0 failed, 2 skipped (287 total tests)\n","passed":true},{"durationMs":192,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.settleClaim(bytes32)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":610,\"README.md\":289,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"launch.json\":15,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":510,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":433,\"test/PagesAudit.t.sol\":318,\"test/PagesDeployment.t.sol\":61,\"test/PagesOracle.t.sol\":168,\"test/PagesRevision.t.sol\":278,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":80,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"698d174ced06600cb34cd11944687725892f9502abd9902f8bd7657946d237f8","verifiedTreeHash":"faad1ce58d0305e7528a255ecbbe4b71d625eb67","verifierVersion":"0.1.0+fb8278c5"},{"checks":[],"detail":"start commit produces tree e94cb54fe6ce but its accepted dependencies produce 2a6c69f12bd0","evaluation":"checks","profile":"foundry","status":"rejected","submissionHash":"7c895bda997d2480b17a6eed398b680af9f8175cb4ddc0358c6c2e37d86729b5","verifiedTreeHash":"c71dfe01d833356e3f9416d6dcb8178d38ae67af","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":279724,"exitCode":0,"name":"build","output":"Compiling 125 files with Solc 0.8.26\nSolc 0.8.26 finished in 279.47s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/PagesRevision.t.sol:66:5:\n   |\n66 |     function _floorRate() internal view returns (uint256) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:196:17\n    │\n196 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:292:13\n    │\n292 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:247:9\n    │\n247 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:262:9\n    │\n262 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:281:33\n    │\n281 │                 s.escrowSince = uint64(block.timestamp);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:283:30\n    │\n283 │                 e.recentAt = uint64(block.timestamp);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:357:21\n    │\n357 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n358 │ ┃             action,\n359 │ ┃             bytes(questionBody(normalized, tweetId)),\n360 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n361 │ ┃             imd,\n362 │ ┃             price\n363 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:368:9\n    │\n368 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:366:63\n    │\n366 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:394:13\n    │\n394 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:402:9\n    │\n402 │         emit ClaimAnswered(subject, requestId, wallet);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:431:13\n    │\n431 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:453:9\n    │\n453 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:445:13\n    │\n445 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:454:9\n    │\n454 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:473:21\n    │\n473 │         uint40 at = uint40(block.timestamp);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint40' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:497:13\n    │\n497 │         if (span == 0) return (a.tick, 0);\n    │             ━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:501:26\n    │\n501 │         if (delta < 0 && delta % int256(span) != 0) avg -= 1; // floor\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:498:65\n    │\n498 │         int256 cumNow = int256(l.cumulative) + int256(l.tick) * int256(block.timestamp - l.at);\n    │                                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:500:30\n    │\n500 │         int256 avg = delta / int256(span);\n    │                              ━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:501:34\n    │\n501 │         if (delta < 0 && delta % int256(span) != 0) avg -= 1; // floor\n    │                                  ━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:502:16\n    │\n502 │         tick = int24(avg);\n    │                ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `latestObs` is updated\n    ╭▸ src/MarginaliaPages.sol:539:9\n    │\n539 │         hook.poolManager().unlock(abi.encode(imdIn, minMargOut, limit));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:488:9\n    │\n488 │         emit Observed(spot);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:533:44\n    │\n533 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:533:52\n    │\n533 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:539:9\n    │\n539 │         hook.poolManager().unlock(abi.encode(imdIn, minMargOut, limit));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:565:9\n    │\n565 │         emit Burned(spent, marg);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:550:68\n    │\n550 │         BalanceDelta d = manager.swap(key, SwapParams(zeroForOne, -int256(imdIn), limit), \"\");\n    │                                                                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:553:36\n    │\n553 │         if (inD > 0 || outD < 0 || uint256(-int256(inD)) > imdIn) revert UnauthorizedCallback();\n    │                                    ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:554:25\n    │\n554 │         uint256 spent = uint256(-int256(inD));\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:555:24\n    │\n555 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:555:32\n    │\n555 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:563:9\n    │\n563 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":7167,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 403.43µs (0.00ns CPU time)\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 488.95µs (0.00ns CPU time)\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 641.48µs (277.74µs CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 625503)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 4644092)\n[PASS] testColdCallbackPaysTwoFreshBalancesUnderStipendWithDistinctIds() (gas: 353419)\nLogs:\n  delivery gas including mock Intake overhead: 115581\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14319)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 98052)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 678906)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 4.33ms (2.32ms CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 12.09ms (4.94ms CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2685591)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2487849)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 973863)\n[PASS] testCurveIsLinear() (gas: 37674)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 4072224)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 64133)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37960)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 171039)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2375263)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 784453)\n[PASS] testSlippageAndNoCap() (gas: 617349)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1963995)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 14.11ms (7.88ms CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 15.05ms (10.33ms CPU time)\n\nRan 1 test for test/PagesRevision.t.sol:PagesOrientationTest\n[PASS] testBurnBoundHoldsWithImdAsCurrencyZero() (gas: 1698815)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 15.68ms (1.37ms CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 15.68ms (8.69ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 15044462)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 17.98ms (17.82ms CPU time)\n\nRan 7 tests for test/PagesRevision.t.sol:PagesRevisionTest\n[PASS] testADustTrancheIsRefusedByName() (gas: 823769)\n[PASS] testAnsweredClaimPaysDirectlyAtOnceAndSettlesTheEscrowLater() (gas: 2536404)\n[PASS] testBurnSandwichIsRefusedOrUnprofitableWhateverFloorTheCallerPasses() (gas: 3663638)\n[PASS] testBurnWaitsForTheAverageAfterARiseAndFillsAfterAFall() (gas: 2518038)\n[PASS] testPromotedBucketWaitsFromItsLastDeposit() (gas: 1306797)\n[PASS] testRecycleTakesOnlyEscrowThatWaitedTheWindow() (gas: 3076874)\n[PASS] testTheMarketAndTheHookCannotBeSubjectsOrPayees() (gas: 2461337)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 18.73ms (10.36ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 22.25ms (9.75ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 22000, ~: 20080)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 27.88ms (22.42ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 63.30ms (58.45ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 105955, ~: 106105)\nLogs:\n  Bound result 13121\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 81.00ms (24.57ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 88.17ms (161.48ms CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 90.29ms (38.36ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 118.37ms (23.58ms CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838163, ~: 838176)\nLogs:\n  Bound result 9750000000000004756\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58956, ~: 58968)\nLogs:\n  Bound result 9750000000000003151\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 118.41ms (199.12ms CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 118.42ms (14.18ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 118.55ms (65.72ms CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 118.49ms (70.94ms CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2411974)\n[PASS] testBurnCannotSpendReserveOrEscrowAndRejectsZeroFloor() (gas: 900706)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1339037)\n[PASS] testBurnUsesCallerFloorAndManipulatedPriceCannotBlockTrading() (gas: 1264592)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143984)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476935)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1333783)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1258900, ~: 1305877)\nLogs:\n  Bound result 977\n  Bound result 533\n  Bound result 462\n\n[PASS] testOversizedTrancheFillsOnlyToTheLimitAndTheRestWaits() (gas: 1361322)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 711472)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 118.47ms (115.84ms CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 118.57ms (1.43ms CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 129163, ~: 114002)\nLogs:\n  Bound result 4\n  Bound result 999999999999999999999000000043\n  Bound result 999999999999999999999000000095\n  Bound result 999999999999999999999011155112\n  Bound result 999999999999999999999000000014\n  Bound result 350000000000000000\n  Bound result 999999999999999999999000000449\n  Bound result 999999999999999999999000022413\n  Bound result 999999999999999999999000007289\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36953, ~: 37007)\nLogs:\n  Bound result 9989023\n  Bound result 3566234\n  Bound result 59\n  Bound result 502334948543925448794870060220\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141494, ~: 141832)\nLogs:\n  Bound result 1266412660188944021221804094478\n  Bound result 1266412660188944021221804200398\n  Bound result 26447\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36732, ~: 36838)\nLogs:\n  Bound result 990394\n  Bound result 5\n  Bound result 5\n  Bound result 4366\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23270, ~: 21542)\nLogs:\n  Bound result 1461446703485210103287273052103988822378723972700\n  Bound result 1461446703485210103287273052103988822378723974322\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39810, ~: 39506)\nLogs:\n  Bound result 3660579323406009969433125101615251906560\n  Bound result 4223522518321706902843778350233308535719\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16189, ~: 14611)\nLogs:\n  Bound result 0\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 53981, ~: 51987)\nLogs:\n  Bound result 4989\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36407, ~: 36412)\nLogs:\n  Bound result 1393\n  Bound result 2255\n  Bound result 5\n  Bound result 4366\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 18804, ~: 16591)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21375, ~: 21299)\nLogs:\n  Bound result 21344\n  Bound result 428202278563176310\n  Bound result 67137\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 64301, ~: 60431)\nLogs:\n  Bound result -3\n  Bound result 5\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 104063, ~: 94603)\nLogs:\n  Bound result 1\n  Bound result 732114252730904817091313663572\n  Bound result 220069144149213557362615885889\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 118.52ms (954.18ms CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 3)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 219   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 205   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 405   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 229   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 202   | 3       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 205   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 223   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 232   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1\n  Bound result 8827\n  Bound result 2\n  Bound result 18008498570563585878453\n  Bound result 0\n  Bound result 0\n  Bound result 1\n  Bound result 2435\n  Bound result 7002\n  Bound result 60\n  Bound result 1\n  Bound result 200000000000000000000\n  Bound result 51667\n  Bound result 30\n  Bound result 2\n  Bound result 127\n  Bound result 10701\n  Bound result 2\n  Bound result 0\n  Bound result 399996995111363752754\n  Bound result 53992\n  Bound result 46\n  Bound result 2\n  Bound result 3737465504\n  Bound result 242\n  Bound result 73\n  Bound result 0\n  Bound result 15978\n  Bound result 44185\n  Bound result 50\n  Bound result 56\n  Bound result 2\n  Bound result 2\n  Bound result 512\n  Bound result 50073\n  Bound result 50\n  Bound result 2\n  Bound result 16449\n  Bound result 2\n  Bound result 270780985266670324121\n  Bound result 47735\n  Bound result 24\n  Bound result 0\n  Bound result 1629\n  Bound result 1\n  Bound result 0\n  Bound result 2341217399430058620\n  Bound result 2\n  Bound result 24576\n  Bound result 57201\n  Bound result 97\n  Bound result 2\n  Bound result 2001\n  Bound result 0\n  Bound result 2\n  Bound result 1641359156386401\n  Bound result 1\n  Bound result 1\n  Bound result 350000000000000000\n  Bound result 11022\n  Bound result 32\n  Bound result 2\n  Bound result 22168\n  Bound result 56340\n  Bound result 35\n  Bound result 2\n  Bound result 201\n  Bound result 50018\n  Bound result 2\n  Bound result 3411\n  Bound result 2\n  Bound result 5377\n  Bound result 0\n  Bound result 329799204237579\n  Bound result 0\n  Bound result 1031166609000651144072\n  Bound result 56213\n  Bound result 52\n  Bound result 2413\n  Bound result 658\n  Bound result 1\n  Bound result 412\n  Bound result 1\n  Bound result 1\n  Bound result 400122303202102190075\n  Bound result 1\n  Bound result 8278\n  Bound result 50051\n  Bound result 12\n  Bound result 1\n  Bound result 122\n  Bound result 8453\n  Bound result 45\n  Bound result 94\n  Bound result 1\n  Bound result 32\n  Bound result 100\n  Bound result 49\n  Bound result 2\n  Bound result 12481\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 440.12ms (432.55ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2424  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2448  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2497  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2408  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2511  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 2592000\n  Bound result 1666\n  Bound result 818455347861275938710826107459787285848594276320\n  Bound result 9000000000000000\n  Bound result 600188384167819282\n  Bound result 48\n  Bound result 3741\n  Bound result 160920\n  Bound result 18000\n  Bound result 8380807591351116644\n  Bound result 209138\n  Bound result 732\n  Bound result 2037090744\n  Bound result 5973\n  Bound result 764164552314827638269516\n  Bound result 7754086986564470931\n  Bound result 6391\n  Bound result 1490\n  Bound result 604800\n  Bound result 102056577256128148919\n  Bound result 2000000000000000000000\n  Bound result 6139\n  Bound result 1529\n  Bound result 251532389\n  Bound result 100000\n  Bound result 1663\n  Bound result 882\n  Bound result 6851\n  Bound result 1531\n  Bound result 517440285\n  Bound result 192752\n  Bound result 30000000000000000\n  Bound result 222558\n  Bound result 216341\n  Bound result 7584007913129639829\n  Bound result 1150787775983167832211393394602437307275927111717\n  Bound result 3053315955\n  Bound result 111\n  Bound result 2496\n  Bound result 347\n  Bound result 224122\n  Bound result 200736\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.07s (1.07s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 511   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 538   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 537   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 513   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 518   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 524   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 497   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 485   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 499   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 528   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 474   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 1074  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 488   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 504   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 476   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 544   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 507   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 533   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 490   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 9750000000000009514\n  Bound result 5\n  Bound result 1800\n  Bound result 5\n  Bound result 3\n  Bound result 9750000000000005106\n  Bound result 9750000000000010501\n  Bound result 7\n  Bound result 8\n  Bound result 5\n  Bound result 8\n  Bound result 7\n  Bound result 8\n  Bound result 5\n  Bound result 99999000000000000000126\n  Bound result 99999000000000000259201\n  Bound result 8\n  Bound result 99999150000000000000001\n  Bound result 8\n  Bound result 9750000000000000051\n  Bound result 99999350000000000000001\n  Bound result 279147\n  Bound result 96000000000000000000\n  Bound result 98650000000000000001\n  Bound result 10\n  Bound result 73583951849546495875152\n  Bound result 1\n  Bound result 19941953730169134164925\n  Bound result 9008\n  Bound result 98000000002264141857\n  Bound result 9750000000000020321\n  Bound result 4\n  Bound result 6220\n  Bound result 6\n  Bound result 3\n  Bound result 1114\n  Bound result 8232\n  Bound result 20959\n  Bound result 99999000000000000000012\n  Bound result 4\n  Bound result 1\n  Bound result 11\n  Bound result 99999000000000000000056\n  Bound result 12\n  Bound result 1\n  Bound result 987500000000000000\n  Bound result 2400\n  Bound result 3246\n  Bound result 10751842658131634624\n  Bound result 3\n  Bound result 7\n  Bound result 98000000000000014146\n  Bound result 10\n  Bound result 36948\n  Bound result 5\n  Bound result 10\n  Bound result 1\n  Bound result 124\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.04s (7.03s CPU time)\n\nRan 28 test suites in 7.04s (9.99s CPU time): 286 tests passed, 0 failed, 2 skipped (288 total tests)\n","passed":true},{"durationMs":152,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256,uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.observe()\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.settleClaim(bytes32)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":676,\"README.md\":286,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":568,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":436,\"test/PagesAudit.t.sol\":330,\"test/PagesDeployment.t.sol\":61,\"test/PagesOracle.t.sol\":171,\"test/PagesRevision.t.sol\":473,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":81,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":12340,"exitCode":0,"name":"slither","output":"[high/medium] weak-prng at src/MarginaliaPricer.sol:205: MarginaliaPricer.twap(MarginaliaTypes.VenueKind,bool,uint256,uint64,uint256,uint64) (src/MarginaliaPricer.sol#205-229) uses a weak PRNG: \"delta < 0 && delta % int256(dt) != 0 (src/MarginaliaPricer.sol#215)\"\n[high/medium] weak-prng at src/MarginaliaPages.sol:492: MarginaliaPages.twapTick() (src/MarginaliaPages.sol#492-503) uses a weak PRNG: \"delta < 0 && delta % int256(span) != 0 (src/MarginaliaPages.sol#501)\"\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:287: Reentrancy in MarginaliaRouter._pull(address,uint256) (src/MarginaliaRouter.sol#287-292):\n[high/high] uninitialized-state at src/MarginaliaHook.sol:536: MarginaliaHook.observations (src/MarginaliaHook.sol#106) is never initialized. It is used in:\n[medium/high] incorrect-equality at src/MarginaliaPages.sol:492: MarginaliaPages.twapTick() (src/MarginaliaPages.sol#492-503) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:377: MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:299: MarginaliaRouter.unlockCallback(bytes) (src/MarginaliaRouter.sol#299-340) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:294: MarginaliaRouter._checkSubject(MarginaliaRouter.Job) (src/MarginaliaRouter.sol#294-297) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:176: MarginaliaPricer.settlePrice(MarginaliaTypes.Venue,bool,MarginaliaTypes.Observation[]) (src/MarginaliaPricer.sol#176-201) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:287: MarginaliaRouter._pull(address,uint256) (src/MarginaliaRouter.sol#287-292) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:205: MarginaliaPricer.twap(MarginaliaTypes.VenueKind,bool,uint256,uint64,uint256,uint64) (src/MarginaliaPricer.sol#205-229) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaTreasury.sol:42: MarginaliaTreasury.drip() (src/MarginaliaTreasury.sol#42-52) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaHook.sol:579: MarginaliaHook._broken(MarginaliaTypes.Note,uint256) (src/MarginaliaHook.sol#579-582) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaHook.sol:919: MarginaliaHook._unlock(uint8,address,uint256,uint256) (src/MarginaliaHook.sol#919-928) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaTreasury.sol:42: MarginaliaTreasury.drip() (src/MarginaliaTreasury.sol#42-52) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPages.sol:492: MarginaliaPages.twapTick() (src/MarginaliaPages.sol#492-503) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:135: MarginaliaPricer.postPrice(IPoolManager,MarginaliaTypes.Venue,address,bool,MarginaliaTypes.PriceWindow) (src/MarginaliaPricer.sol#135-155) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:242: MarginaliaRouter._run(bool,uint256,uint256,uint256,MarginaliaRouter.XTrade,MarginaliaTypes.NoteParams,PoolKey) (src/MarginaliaRouter.sol#242-284) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:342: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#342-369):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:603: Reentrancy in MarginaliaHook.settle(bytes32) (src/MarginaliaHook.sol#603-652):\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:531: Reentrancy in MarginaliaPages.burnPending(uint256,uint256) (src/MarginaliaPages.sol#531-541):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:855: Reentrancy in MarginaliaHook.payJudged(uint32,bytes32[3]) (src/MarginaliaHook.sol#855-874):\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:234: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#234-248):\n[medium/medium] reentrancy-no-eth at src/MarginaliaJudge.sol:203: Reentrancy in MarginaliaJudge.requestJudging(uint32) (src/MarginaliaJudge.sol#203-226):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:679: Reentrancy in MarginaliaHook.retract(bytes32,string) (src/MarginaliaHook.sol#679-695):\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:179: MarginaliaRouter.sellWithNote(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256).noX (src/MarginaliaRouter.sol#179) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:127: MarginaliaJudge.questionBody(uint32).allow (src/MarginaliaJudge.sol#127) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaHook.sol:611: MarginaliaHook.settle(bytes32).settlePrice (src/MarginaliaHook.sol#611) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:166: MarginaliaRouter.note(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256).noX (src/MarginaliaRouter.sol#166) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:257: MarginaliaRouter._run(bool,uint256,uint256,uint256,MarginaliaRouter.XTrade,MarginaliaTypes.NoteParams,PoolKey).job (src/MarginaliaRouter.sol#257) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:113: MarginaliaJudge.eligibleTheses(uint32).n (src/MarginaliaJudge.sol#113) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:205: MarginaliaRouter.validateVenue(MarginaliaTypes.NoteParams,PoolKey).t1 (src/MarginaliaRouter.sol#205) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:272: MarginaliaJudge.judgedOf(uint32).dup (src/MarginaliaJudge.sol#272) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:268: MarginaliaJudge.judgedOf(uint32).kept (src/MarginaliaJudge.sol#268) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaHook.sol:862: MarginaliaHook.payJudged(uint32,bytes32[3]).paidAmounts (src/MarginaliaHook.sol#862) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:168: MarginaliaJudge._dec(uint256).n (src/MarginaliaJudge.sol#168) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:204: MarginaliaRouter.validateVenue(MarginaliaTypes.NoteParams,PoolKey).t0 (src/MarginaliaRouter.sol#204) is a local variable never initialized\n[medium/medium] unused-return at src/MarginaliaPricer.sol:255: MarginaliaPricer._quoteSpot(IPoolManager,address,address) (src/MarginaliaPricer.sol#255-264) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(HUB_POOL_ID)) (src/MarginaliaPricer.sol#260)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (r0,r1,None) = IUniswapV2PairOracle(ref).getReserves() (src/MarginaliaPricer.sol#245)\n[medium/medium] unused-return at src/MarginaliaPages.sol:531: MarginaliaPages.burnPending(uint256,uint256) (src/MarginaliaPages.sol#531-541) ignores return value by hook.poolManager().unlock(abi.encode(imdIn,minMargOut,limit)) (src/MarginaliaPages.sol#539)\n[medium/medium] unused-return at src/MarginaliaHook.sol:930: MarginaliaHook.unlockCallback(bytes) (src/MarginaliaHook.sol#930-950) ignores return value by poolManager.settle() (src/MarginaliaHook.sol#945)\n[medium/medium] unused-return at src/MarginaliaHook.sol:294: MarginaliaHook.margPriceInImd() (src/MarginaliaHook.sol#294-297) ignores return value by (sqrtP,None,None,None) = poolManager.getSlot0(poolId) (src/MarginaliaHook.sol#295)\n[medium/medium] unused-return at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) ignores return value by (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (sqrtP_scope_0,None,None,None,None,None,None) = IUniswapV3PoolOracle(ref).slot0() (src/MarginaliaPricer.sol#241)\n[medium/medium] unused-return at src/MarginaliaPages.sol:543: MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#543-567) ignores return value by manager.settle() (src/MarginaliaPages.sol#563)\n[medium/medium] unused-return at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) ignores return value by (r0,r1,None) = pair.getReserves() (src/MarginaliaRouter.sol#426)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:267: MarginaliaPricer._v3Cumulative(address) (src/MarginaliaPricer.sol#267-271) ignores return value by (cum,None) = IUniswapV3PoolOracle(pool).observe(ago) (src/MarginaliaPricer.sol#269)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(v.ref)) (src/MarginaliaPricer.sol#237)\n[medium/medium] unused-return at src/MarginaliaPages.sol:465: MarginaliaPages._slot0() (src/MarginaliaPages.sol#465-467) ignores return value by (sqrtPriceX96,tick,None,None) = hook.poolManager().getSlot0(hook.getPoolKey().toId()) (src/MarginaliaPages.sol#466)\n[low/high] shadowing-local at src/MarginaliaHook.sol:859: MarginaliaHook.payJudged(uint32,bytes32[3]).pool (src/MarginaliaHook.sol#859) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.noteMeta(bytes32).week (src/MarginaliaJudge.sol#19) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.thesesOfWeek(uint32).week (src/MarginaliaJudge.sol#15) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.thesisPool(uint32).week (src/MarginaliaJudge.sol#12) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.drawForJudging(uint32,uint256,bool).week (src/MarginaliaJudge.sol#21) shadows:\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:266: MarginaliaJudge.judgedOf(uint32) (src/MarginaliaJudge.sol#266-279) has external calls inside a loop: (author,noteWeek,thesis,hasChild) = hook.noteMeta(ranked[i]) (src/MarginaliaJudge.sol#270)\n[low/medium] calls-loop at src/MarginaliaHook.sol:919: MarginaliaHook._unlock(uint8,address,uint256,uint256) (src/MarginaliaHook.sol#919-928) has external calls inside a loop: out = poolManager.unlock(data) (src/MarginaliaHook.sol#925)\n[low/medium] calls-loop at src/MarginaliaHook.sol:658: MarginaliaHook._settlementPrice(MarginaliaTypes.Note,MarginaliaTypes.Observation[]) (src/MarginaliaHook.sol#658-676) has external calls inside a loop: p = pricer().settlePrice(n.venue,buy,sample) (src/MarginaliaHook.sol#669-674)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:91: MarginaliaJudge.convertForfeits() (src/MarginaliaJudge.sol#91-106) has external calls inside a loop: out = hook.sellPotMarg(marg) (src/MarginaliaJudge.sol#96-100)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:266: MarginaliaJudge.judgedOf(uint32) (src/MarginaliaJudge.sol#266-279) has external calls inside a loop: (author,noteWeek,thesis,hasChild) = hook.noteMeta(ranked[i]) (src/MarginaliaJudge.sol#270)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:266: Reentrancy in MarginaliaPages._distributeFee(bytes32,MarginaliaPages.Subject,uint256) (src/MarginaliaPages.sol#266-294):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:342: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#342-369):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:543: Reentrancy in MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#543-567):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:722: Reentrancy in MarginaliaHook._forfeit(MarginaliaTypes.Note,address) (src/MarginaliaHook.sol#722-729):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:785: Reentrancy in MarginaliaHook._fund(uint256) (src/MarginaliaHook.sol#785-789):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:234: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#234-248):\n[low/medium] reentrancy-benign at src/MarginaliaRouter.sol:377: Reentranc","passed":true},{"durationMs":792,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/MarginaliaPages.sol:184: `abi.encodePacked()` Hash Collision (2 places)\n[high] eth-send-unchecked-address at src/MarginaliaHook.sol:779: ETH transferred without address checks (3 places)\n[high] reentrancy-state-change at src/MarginaliaHook.sol:224: Reentrancy: State change after external call (23 places)\n[high] storage-array-memory-edit at src/MarginaliaHook.sol:556: Storage Array Edited with Memory\n[high] unsafe-casting at src/MarginaliaHook.sol:936: Unsafe Casting of integers (2 places)\n[low] costly-loop at src/MarginaliaHook.sol:864: Costly operations inside loop (2 places)\n[low] internal-function-used-once at src/HookFlags.sol:26: Internal Function Used Only Once (3 places)\n[low] large-numeric-literal at src/Marginalia.sol:10: Large Numeric Literal (21 places)\n[low] literal-instead-of-constant at src/MarginaliaHook.sol:355: Literal Instead of Constant (56 places)\n[low] local-variable-shadowing at src/MarginaliaHook.sol:859: Local Variable Shadows State Variable\n[low] require-revert-in-loop at src/MarginaliaHook.sol:864: Loop Contains `require`/`revert` (2 places)\n[low] state-change-without-event at src/MarginaliaHook.sol:835: State Change Without Event (6 places)\n[low] state-no-address-check at src/MarginaliaRouter.sol:135: Address State Variable Set Without Checks\n[low] unchecked-return at src/MarginaliaHook.sol:718: Unchecked Return (11 places)\n[low] uninitialized-local-variable at src/MarginaliaHook.sol:667: Uninitialized Local Variable (3 places)\n[low] unused-import at src/MarginaliaHook.sol:10: Unused Import\n[low] unused-public-function at src/MarginaliaHook.sol:294: Public Function Not Used Internally (3 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"87ee4bc12b5805697166284443a9c4b86ef7418b80720c9c3b7cd8d2bd6ebba9","verifiedTreeHash":"0814907aa11c86b41fb08997804a051a5de9e9aa","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":311939,"exitCode":0,"name":"build","output":"Compiling 126 files with Solc 0.8.26\nSolc 0.8.26 finished in 311.69s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:158:17\n    │\n158 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:244:13\n    │\n244 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:206:9\n    │\n206 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:221:9\n    │\n221 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:235:53\n    │\n235 │             if (s.escrowSince == 0) s.escrowSince = uint64(block.timestamp);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:309:21\n    │\n309 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n310 │ ┃             action,\n311 │ ┃             bytes(questionBody(normalized, tweetId)),\n312 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n313 │ ┃             imd,\n314 │ ┃             price\n315 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:320:9\n    │\n320 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:318:63\n    │\n318 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:346:13\n    │\n346 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:359:9\n    │\n359 │         emit Claimed(subject, wallet, owed, reimbursed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:367:13\n    │\n367 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:384:9\n    │\n384 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:379:13\n    │\n379 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:385:9\n    │\n385 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:398:9\n    │\n398 │         hook.poolManager().unlock(abi.encode(imdIn, minMargOut));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:395:44\n    │\n395 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:395:52\n    │\n395 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:398:9\n    │\n398 │         hook.poolManager().unlock(abi.encode(imdIn, minMargOut));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:428:9\n    │\n428 │         emit Burned(imdIn, marg);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:412:18\n    │\n412 │                 -int256(imdIn),\n    │                  ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:419:38\n    │\n419 │         if (inD >= 0 || outD <= 0 || uint256(-int256(inD)) != imdIn) revert UnauthorizedCallback();\n    │                                      ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:420:24\n    │\n420 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:420:32\n    │\n420 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:426:9\n    │\n426 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":7233,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 574.79µs (0.00ns CPU time)\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 717.10µs (502.63µs CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 667767)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 3878569)\n[PASS] testColdCallbackPaysTwoFreshBalancesUnderStipendWithDistinctIds() (gas: 282027)\nLogs:\n  delivery gas including mock Intake overhead: 203394\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14297)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 86052)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 742292)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 3.97ms (2.28ms CPU time)\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 3.41ms (0.00ns CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 7.45ms (6.16ms CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 12.94ms (7.27ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 18.04ms (6.69ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 12065711)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 21.69ms (21.49ms CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 25.28ms (17.33ms CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 25.51ms (8.86ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 22599, ~: 20165)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 27.45ms (22.25ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 105881, ~: 106088)\nLogs:\n  Bound result 2357\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 35.90ms (35.57ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 43.95ms (28.60ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 74.56ms (71.56ms CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 80.45ms (47.73ms CPU time)\n\nRan 23 tests for test/PagesEdges.t.sol:PagesEdgesTest\n[PASS] testAnyoneMayAbandonExactlyAtTheDeadlineAndTheAskerIsNotRefunded() (gas: 1554511)\n[PASS] testCallbackFromTheIntakeForAnotherConsumersRequestIsRefused() (gas: 2067158)\n[PASS] testClaimWithoutAnyEscrowSetsThePayeeAndLaterFeesGoDirect() (gas: 1953936)\n[PASS] testClaimedHandleIsClosedToEveryLaterClaimPath() (gas: 2036441)\n[PASS] testColdClaimAgainstTheRealHookFitsTheStipend() (gas: 2043457)\n[PASS] testConstructorRefusesEveryZeroInput() (gas: 9484)\n[PASS] testEscrowClockSurvivesAFailedClaimAndRecyclingTakesLaterFeesToo() (gas: 2524382)\n[PASS] testEscrowExactlyThePriceReimbursesAndPaysTheOwnerNothing() (gas: 1968517)\n[PASS] testEscrowOneWeiShortOfThePriceGoesWhollyToTheOwner() (gas: 1941381)\n[PASS] testFuzzCurveIsAdditiveAndEachPageCostsBaseTimesItsIndex(uint64,uint32,uint32) (runs: 1000, μ: 53890, ~: 54000)\nLogs:\n  Bound result 154395475549\n  Bound result 57713\n  Bound result 12208\n\n[PASS] testFuzzRoundTripAloneAlwaysLosesExactlyTheFees(uint16,uint16) (runs: 300, μ: 752223, ~: 765559)\nLogs:\n  Bound result 136\n  Bound result 1\n\n[PASS] testHandleLengthAndCharacterBoundaries() (gas: 127757)\n[PASS] testLargerPanelsAndQuorumsAreAccepted() (gas: 1516354)\n[PASS] testPanelThresholdsAtTheirBoundaries() (gas: 2293529)\n[PASS] testPriceBoundaryAcceptsExactlyOneImdAndRefusesOneWeiMore() (gas: 1544510)\n[PASS] testPriceOverflowRevertsInsteadOfWrapping() (gas: 66025)\n[PASS] testSellFeeIsSplitExactlyLikeABuyFee() (gas: 590581)\n[PASS] testSellingOutEmptiesTheCurveAndTheNextPageCostsBaseAgain() (gas: 774758)\n[PASS] testStrangersCannotCallTheCallbacksOrMoveValue() (gas: 1953324)\n[PASS] testSubjectsAreIndependentCurves() (gas: 992964)\n[PASS] testUpperCaseRequestClaimsTheLowerCaseSubjectAndAsksAboutTheLowerCaseHandle() (gas: 2018607)\n[PASS] testZeroAddressIssuerEscrowsAndCanOnlyBeRecycled() (gas: 879408)\n[PASS] testZeroAmountsAndOneWeiOfSlippageAreRefused() (gas: 668374)\nSuite result: ok. 23 passed; 0 failed; 0 skipped; finished in 120.11ms (112.32ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 126.62ms (89.43ms CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 128.26ms (45.76ms CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2662900)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2411734)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 668941)\n[PASS] testCurveIsLinear() (gas: 37344)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 3935373)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 63979)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37561)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 170731)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2377793)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 782680)\n[PASS] testSlippageAndNoCap() (gas: 615462)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1888094)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 128.73ms (12.26ms CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2386917)\n[PASS] testBurnCannotSpendReserveOrEscrowAndRejectsZeroFloor() (gas: 705180)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1433838)\n[PASS] testBurnUsesCallerFloorAndManipulatedPriceCannotBlockTrading() (gas: 1017958)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143720)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476847)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1331251)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1224305, ~: 1257740)\nLogs:\n  Bound result 1000\n  Bound result 309\n  Bound result 991\n\n[PASS] testPartialFillBurnRollsBackAndSmallerTranchesWork() (gas: 1297340)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 709869)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 128.84ms (112.33ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 131.30ms (164.84ms CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 131.81ms (1.66ms CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 131524, ~: 115292)\nLogs:\n  Bound result 14\n  Bound result 514264337593623178497920771838\n  Bound result 999999999999999999999000007720\n  Bound result 999999999999999999999000005957\n  Bound result 999999999999999999999000012273\n  Bound result 999999999999999999999000027038\n  Bound result 999999999999999999999000005555\n  Bound result 999999999999999999999000000836\n  Bound result 999999999999999999999000012472\n  Bound result 999999999999999999999000048880\n  Bound result 1099511627776\n  Bound result 999999999999999999999000031991\n  Bound result 907951651594334741017051742135\n  Bound result 999999999999999999999000000043\n  Bound result 999999999999999999999000023270\n  Bound result 999999999999999999999000003933\n  Bound result 2000000000000000000\n  Bound result 999999999999999999999000004380\n  Bound result 999999999999999999999000000009\n  Bound result 999999999999999999999000024236\n  Bound result 999999999999999999999000012501\n  Bound result 30000000000000000\n  Bound result 999999999999999999999000011540\n  Bound result 999999999999999999999000400001\n  Bound result 296858534827628535688329214903\n  Bound result 999999999999999999999000000261\n  Bound result 999999999999999999999000013126\n  Bound result 999999999999999999999000005478\n  Bound result 1064470260\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36956, ~: 37007)\nLogs:\n  Bound result 9990190\n  Bound result 9989114\n  Bound result 2\n  Bound result 36821092777097356904638331009\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141503, ~: 141834)\nLogs:\n  Bound result 1266412668511742066691298552465\n  Bound result 1266412660308741483763937064508\n  Bound result 28796\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36765, ~: 36900)\nLogs:\n  Bound result 989056\n  Bound result 68\n  Bound result 18\n  Bound result 20000000000000000000000\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23271, ~: 21504)\nLogs:\n  Bound result 54933845692814916411780612294197277208572629\n  Bound result 1461446703485210103287273052103988822378724066398\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39478, ~: 38688)\nLogs:\n  Bound result 18430668395868694329365346742799910720\n  Bound result 701440855140002305260163596112033265194\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16347, ~: 14648)\nLogs:\n  Bound result 172\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 53833, ~: 51987)\nLogs:\n  Bound result 27490\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36425, ~: 36409)\nLogs:\n  Bound result 55\n  Bound result 1024\n  Bound result 18\n  Bound result 20000000000000000000000\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 18617, ~: 16591)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21367, ~: 21299)\nLogs:\n  Bound result 5192296858534827628530496329220093\n  Bound result 12772840593649592110673591\n  Bound result 229\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 63628, ~: 60476)\nLogs:\n  Bound result 18200\n  Bound result 8\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 101145, ~: 91975)\nLogs:\n  Bound result 11\n  Bound result 100\n  Bound result 1000000000000000000000000000000\n  Bound result 150000000000000000\n  Bound result 16098\n  Bound result 16432\n  Bound result 1730\n  Bound result 79228162514264337593543950336\n  Bound result 4379\n  Bound result 25000000000000000000000000\n  Bound result 25\n  Bound result 3409\n  Bound result 7121\n  Bound result 864000\n  Bound result 23269\n  Bound result 3595\n  Bound result 1000000000000000000000000\n  Bound result 11000\n  Bound result 5555\n  Bound result 1300000000000000000\n  Bound result 7591\n  Bound result 999999999999999999999999999999\n  Bound result 22654\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 131.75ms (1.21s CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838169, ~: 838176)\nLogs:\n  Bound result 9750000000000000859\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58962, ~: 58968)\nLogs:\n  Bound result 5107948921360346381\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 131.82ms (182.34ms CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 2)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 232   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 234   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 384   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 237   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 224   | 2       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 210   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 191   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 208   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 0\n  Bound result 70\n  Bound result 0\n  Bound result 1\n  Bound result 48832021167430040737722\n  Bound result 1\n  Bound result 1\n  Bound result 1341\n  Bound result 3567\n  Bound result 6\n  Bound result 0\n  Bound result 1\n  Bound result 1184796774\n  Bound result 0\n  Bound result 0\n  Bound result 4096\n  Bound result 50013\n  Bound result 45\n  Bound result 0\n  Bound result 112\n  Bound result 12439\n  Bound result 23\n  Bound result 1\n  Bound result 1\n  Bound result 1733703501335536934730\n  Bound result 2\n  Bound result 23148\n  Bound result 16448\n  Bound result 0\n  Bound result 4325465634695161230826\n  Bound result 1\n  Bound result 2\n  Bound result 1\n  Bound result 1972971872141599964102\n  Bound result 7149\n  Bound result 15\n  Bound result 1\n  Bound result 0\n  Bound result 6931\n  Bound result 2\n  Bound result 2000000000000000000000\n  Bound result 50033\n  Bound result 7\n  Bound result 2\n  Bound result 12462\n  Bound result 2764\n  Bound result 1\n  Bound result 1\n  Bound result 904\n  Bound result 1\n  Bound result 2\n  Bound result 34827629454932861907436\n  Bound result 1\n  Bound result 385\n  Bound result 50071\n  Bound result 2\n  Bound result 1\n  Bound result 1020836872769517884543\n  Bound result 4467\n  Bound result 89\n  Bound result 3589\n  Bound result 2\n  Bound result 832792102268038764140\n  Bound result 4997\n  Bound result 30\n  Bound result 5217\n  Bound result 4079\n  Bound result 1000000000000\n  Bound result 0\n  Bound result 0\n  Bound result 12415\n  Bound result 13967\n  Bound result 98\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 3083\n  Bound result 55577\n  Bound result 11\n  Bound result 0\n  Bound result 500000000000000000000\n  Bound result 334\n  Bound result 0\n  Bound result 500000000000000000000\n  Bound result 0\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 498.29ms (484.91ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2470  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2401  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2454  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2464  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2499  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 1490\n  Bound result 150362\n  Bound result 81257132168796771935554\n  Bound result 205\n  Bound result 224838\n  Bound result 13181092222551990251\n  Bound result 1345\n  Bound result 6737\n  Bound result 2074101769\n  Bound result 6000\n  Bound result 1800003600\n  Bound result 10000000000000000000\n  Bound result 3182973417968015266\n  Bound result 517440284\n  Bound result 1\n  Bound result 3124842406\n  Bound result 259199\n  Bound result 1046363172\n  Bound result 1040\n  Bound result 88042\n  Bound result 1000000000000\n  Bound result 23291559431389482\n  Bound result 203399661\n  Bound result 8461891782872549115\n  Bound result 3806\n  Bound result 2542\n  Bound result 123754\n  Bound result 1714\n  Bound result 1666\n  Bound result 210446\n  Bound result 8351\n  Bound result 80\n  Bound result 309254644812393708\n  Bound result 59600000000000000000\n  Bound result 300\n  Bound result 6191\n  Bound result 10000000000000000000\n  Bound result 242\n  Bound result 15\n  Bound result 1218686167626409700561913727245687294636522415155\n  Bound result 2144\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.08s (1.08s CPU time)\n\nRan 1 test for test/PagesInvariant.t.sol:PagesInvariantTest\n[PASS]\nPagesInvariantTest invariants:\n[PASS] invariant_claimsAreFinal\n[PASS] invariant_conservation\n[PASS] invariant_feesReachPoolsAndDead\n[PASS] invariant_marketHoldsExactlyWhatItOwes\n[PASS] invariant_reserveCoversEveryHolder\n PagesInvariantTest invariants (runs: 96, calls: 4608, reverts: 0)\n\n╭--------------+--------------+-------+---------+----------╮\n| Contract     | Selector     | Calls | Reverts | Discards |\n+==========================================================+\n| PagesHandler | abandon      | 574   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | answer       | 594   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | burn         | 559   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | buy          | 600   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | recycle      | 554   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | requestClaim | 558   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | sell         | 564   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | warp         | 605   | 0       | 0        |\n╰--------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 23748\n  Bound result 40\n  Bound result 306070\n  Bound result 39\n  Bound result 462061283478691461\n  Bound result 22178\n  Bound result 337937720568138789\n  Bound result 379694\n  Bound result 6\n  Bound result 445546\n  Bound result 993705\n  Bound result 1982064\n  Bound result 39\n  Bound result 517499996953169751\n  Bound result 34\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.41s (5.40s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 513   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 510   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 522   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 572   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 508   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 463   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 520   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 485   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 498   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 496   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 537   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 1027  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 539   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 516   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 533   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 510   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 458   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 527   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 506   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 4\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 1\n  Bound result 4\n  Bound result 99999999999999999969\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 3\n  Bound result 40000\n  Bound result 99999000000000000006220\n  Bound result 83269986535294967434317\n  Bound result 338421\n  Bound result 2\n  Bound result 7776000\n  Bound result 4\n  Bound result 113735\n  Bound result 4\n  Bound result 78687401120522810512205\n  Bound result 9750000000000000026\n  Bound result 5\n  Bound result 2\n  Bound result 1\n  Bound result 2163258443\n  Bound result 3\n  Bound result 19774\n  Bound result 9750000000000020152\n  Bound result 99999000000000000008194\n  Bound result 9750000000000000740\n  Bound result 99999000000000000000010\n  Bound result 7\n  Bound result 3\n  Bound result 98000000000000002983\n  Bound result 1048576\n  Bound result 18143\n  Bound result 8\n  Bound result 7\n  Bound result 11675\n  Bound result 11000000000000000000\n  Bound result 2\n  Bound result 999\n  Bound result 8\n  Bound result 1\n  Bound result 7619943654654645805\n  Bound result 1\n  Bound result 6\n  Bound result 86124583988652836764\n  Bound result 5\n  Bound result 1\n  Bound result 4\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.10s (7.10s CPU time)\n\nRan 28 test suites in 7.11s (15.63s CPU time): 302 tests passed, 0 failed, 2 skipped (304 total tests)\n","passed":true},{"durationMs":166,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256,uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":583,\"README.md\":268,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":431,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":418,\"test/PagesAudit.t.sol\":300,\"test/PagesDeployment.t.sol\":61,\"test/PagesEdges.t.sol\":568,\"test/PagesInvariant.t.sol\":598,\"test/PagesOracle.t.sol\":166,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":79,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"aabe5943cb273647aaff6181cb400ecea1e8dbfe1604b2cea106b7e2d18b4813","verifiedTreeHash":"d38a982b8af5f96ef8273eb7374faeaf4bb763df","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":306236,"exitCode":0,"name":"build","output":"Compiling 127 files with Solc 0.8.26\nSolc 0.8.26 finished in 305.98s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2519): This declaration shadows an existing declaration.\n   --> test/PagesInvariant.t.sol:504:13:\n    |\n504 |             uint256 poolBefore = imd.balanceOf(manager);\n    |             ^^^^^^^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/PagesInvariant.t.sol:546:9:\n    |\n546 |         uint256 poolBefore = imd.balanceOf(manager);\n    |         ^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:191:17\n    │\n191 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:286:13\n    │\n286 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:244:9\n    │\n244 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:259:9\n    │\n259 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:275:39\n    │\n275 │             if (s.escrowSince == 0 || block.timestamp >= uint256(s.escrowSince) + CLAIM_WINDOW) {\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:276:33\n    │\n276 │                 s.escrowSince = uint64(block.timestamp);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:351:21\n    │\n351 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n352 │ ┃             action,\n353 │ ┃             bytes(questionBody(normalized, tweetId)),\n354 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n355 │ ┃             imd,\n356 │ ┃             price\n357 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:362:9\n    │\n362 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:360:63\n    │\n360 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:391:13\n    │\n391 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:400:9\n    │\n400 │         emit Claimed(subject, wallet, owed - reimbursed, reimbursed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:399:55\n    │\n399 │         settlements[subject] = Settlement(c.claimant, uint96(reimbursed));\n    │                                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint96' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:427:13\n    │\n427 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:444:9\n    │\n444 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:439:13\n    │\n439 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:445:9\n    │\n445 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `pendingBurn` is updated\n    ╭▸ src/MarginaliaPages.sol:460:38\n    │\n460 │         (spent, burned) = abi.decode(hook.poolManager().unlock(abi.encode(imdIn)), (uint256, uint256));\n    │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:462:9\n    │\n462 │         emit Burned(spent, burned);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:459:44\n    │\n459 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:459:52\n    │\n459 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:480:50\n    │\n480 │             return l > TickMath.MIN_SQRT_PRICE ? uint160(l) : TickMath.MIN_SQRT_PRICE + 1;\n    │                                                  ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:483:46\n    │\n483 │         return u < TickMath.MAX_SQRT_PRICE ? uint160(u) : TickMath.MAX_SQRT_PRICE - 1;\n    │                                              ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:497:27\n    │\n497 │         burnAnchorBlock = uint64(block.number);\n    │                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:501:68\n    │\n501 │         BalanceDelta d = manager.swap(key, SwapParams(zeroForOne, -int256(imdIn), limit), \"\");\n    │                                                                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:504:25\n    │\n504 │         if (inD >= 0 || uint256(-int256(inD)) > imdIn) revert UnauthorizedCallback();\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:506:25\n    │\n506 │         uint256 spent = uint256(-int256(inD));\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:507:24\n    │\n507 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:507:32\n    │\n507 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:512:9\n    │\n512 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesEdges.t.sol:662:47\n    │\n662 │         assertTrue(pages.burnAnchorBlock() != block.number, \"no anchor before the block's burn\");\n    │                                               ━━━━━━━━━━━━\n    ‡\n686 │         vm.roll(block.number + 1);\n    │         ───────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesEdges.t.sol:670:43\n    │\n670 │         assertEq(pages.burnAnchorBlock(), block.number);\n    │                                           ━━━━━━━━━━━━\n    ‡\n686 │         vm.roll(block.number + 1);\n    │         ───────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesEdges.t.sol:686:17\n    │\n686 │         vm.roll(block.number + 1);\n    │         ────────━━━━━━━━━━━━───── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:139:43\n    │\n139 │         assertEq(pages.burnAnchorBlock(), block.number);\n    │                                           ━━━━━━━━━━━━\n140 │         vm.roll(block.number + 1);\n    │         ───────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:140:17\n    │\n140 │         vm.roll(block.number + 1);\n    │         ────────━━━━━━━━━━━━───── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/PagesRevision.t.sol:184:25\n    │\n184 │         uint256 start = block.number;\n    │                         ━━━━━━━━━━━━\n    ‡\n188 │             vm.roll(start + blocks);\n    │             ─────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:240:25\n    │\n240 │         assertEq(since, block.timestamp);\n    │                         ━━━━━━━━━━━━━━━\n241 │         vm.warp(block.timestamp + 91 days);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PagesRevision.t.sol:241:17\n    │\n241 │         vm.warp(block.timestamp + 91 days);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":7158,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 425.72µs (0.00ns CPU time)\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 586.44µs (241.62µs CPU time)\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 668.73µs (0.00ns CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 647484)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 4216548)\n[PASS] testColdCallbackPaysTwoFreshBalancesUnderStipendWithDistinctIds() (gas: 357232)\nLogs:\n  delivery gas including mock Intake overhead: 160691\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14307)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 91327)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 704831)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 5.36ms (3.57ms CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 9.04ms (3.83ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 13.37ms (6.08ms CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 14.06ms (4.77ms CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 18.10ms (12.25ms CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 19.10ms (8.03ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 105914, ~: 106118)\nLogs:\n  Bound result -6000\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 21.13ms (21.07ms CPU time)\n\nRan 9 tests for test/PagesRevision.t.sol:PagesRevisionTest\n[PASS] testASecondBurnInABlockIsRefusedEvenAfterThePriceCameBack() (gas: 1075809)\n[PASS] testAccrualAfterTheWindowOpensANewWindowInsteadOfBeingRecyclableAtOnce() (gas: 2917864)\n[PASS] testBoundedBurnsAcrossBlocksBurnTheWholeBudgetAtMarket() (gas: 3666922)\n[PASS] testBurnSellBurnSandwichIsRefusedAndLosesMoneyAtEverySize() (gas: 3458373)\n[PASS] testCallbackOnlyVerifiesAndStoresThenAnyoneSettles() (gas: 2541688)\nLogs:\n  delivery gas including the mock Intake's overhead: 153153\n\n[PASS] testDustTrancheIsRefusedByName() (gas: 653599)\n[PASS] testMarketAndHookCannotBeSubjects() (gas: 403520)\n[PASS] testOneBlockOfBurningMovesThePriceAtMostTheBound() (gas: 594490)\n[PASS] testSandwichingTheBurnLosesMoneyAtEverySize() (gas: 2507869)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 24.28ms (11.70ms CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2679131)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2473717)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 695452)\n[PASS] testCurveIsLinear() (gas: 37654)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 4078061)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 64049)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37676)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 171079)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2378488)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 784018)\n[PASS] testSlippageAndNoCap() (gas: 616990)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1949596)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 26.16ms (11.28ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 13546439)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 31.28ms (31.08ms CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 49.69ms (26.89ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 51.36ms (30.72ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 87.20ms (73.49ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 93.11ms (112.90ms CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 112.89ms (109.34ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 122.14ms (133.84ms CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838164, ~: 838176)\nLogs:\n  Bound result 9750000000000022693\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58957, ~: 58968)\nLogs:\n  Bound result 9750000000000000361\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 122.33ms (184.10ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 22362, ~: 20080)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 122.97ms (23.90ms CPU time)\n\nRan 29 tests for test/PagesEdges.t.sol:PagesEdgesTest\n[PASS] testABlockThatBurnedRefusesAgainAfterAnExternalPushAndTheNextBlockAnchorsAtThePushedPrice() (gas: 1036235)\n[PASS] testAccrualOneSecondBeforeTheWindowEndsKeepsTheClockAndAtItRestartsIt() (gas: 1507044)\n[PASS] testAnyoneMayAbandonExactlyAtTheDeadlineAndTheAskerIsNotRefunded() (gas: 1555208)\n[PASS] testBurnLimitIsTheAnchorMovedByTheBoundAndABlockBurnsOnce() (gas: 964901)\n[PASS] testBurnPendingRefusesZeroAndOneWeiOverTheQueue() (gas: 663918)\n[PASS] testCallbackFromTheIntakeForAnotherConsumersRequestIsRefused() (gas: 2082537)\n[PASS] testClaimWithoutAnyEscrowSetsThePayeeAndLaterFeesGoDirect() (gas: 2016430)\n[PASS] testClaimedButUnsettledHandleIsClosedToEveryOtherPathAndFrozen() (gas: 2383458)\n[PASS] testClaimedHandleIsClosedToEveryLaterClaimPath() (gas: 2037196)\n[PASS] testColdClaimAgainstTheRealHookFitsTheStipend() (gas: 2136027)\n[PASS] testConstructorRefusesEveryZeroInput() (gas: 9616)\n[PASS] testEscrowClockSurvivesAFailedClaimAndRecyclingTakesLaterFeesToo() (gas: 2526143)\n[PASS] testEscrowExactlyThePriceReimbursesAndPaysTheOwnerNothing() (gas: 2044566)\n[PASS] testEscrowOneWeiShortOfThePriceGoesWhollyToTheOwner() (gas: 2011873)\n[PASS] testFuzzCurveIsAdditiveAndEachPageCostsBaseTimesItsIndex(uint64,uint32,uint32) (runs: 1000, μ: 54610, ~: 54726)\nLogs:\n  Bound result 451143482031\n  Bound result 17342\n  Bound result 310\n\n[PASS] testFuzzRoundTripAloneAlwaysLosesExactlyTheFees(uint16,uint16) (runs: 300, μ: 749484, ~: 766638)\nLogs:\n  Bound result 1\n  Bound result 155\n\n[PASS] testHandleLengthAndCharacterBoundaries() (gas: 128077)\n[PASS] testLargerPanelsAndQuorumsAreAccepted() (gas: 1531384)\n[PASS] testOwnerWhoAskedCollectsEscrowAndReimbursementInOneSettlement() (gas: 2008830)\n[PASS] testPanelThresholdsAtTheirBoundaries() (gas: 2294297)\n[PASS] testPriceBoundaryAcceptsExactlyOneImdAndRefusesOneWeiMore() (gas: 1545045)\n[PASS] testPriceOverflowRevertsInsteadOfWrapping() (gas: 66609)\n[PASS] testSellFeeIsSplitExactlyLikeABuyFee() (gas: 591392)\n[PASS] testSellingOutEmptiesTheCurveAndTheNextPageCostsBaseAgain() (gas: 776385)\n[PASS] testStrangersCannotCallTheCallbacksOrMoveValue() (gas: 1954265)\n[PASS] testSubjectsAreIndependentCurves() (gas: 994663)\n[PASS] testUpperCaseRequestClaimsTheLowerCaseSubjectAndAsksAboutTheLowerCaseHandle() (gas: 2019011)\n[PASS] testZeroAddressIssuerEscrowsAndCanOnlyBeRecycled() (gas: 881042)\n[PASS] testZeroAmountsAndOneWeiOfSlippageAreRefused() (gas: 669798)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 123.02ms (123.97ms CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2387844)\n[PASS] testBurnAfterAManipulatedPriceStaysBoundedAndCannotBlockTrading() (gas: 1193162)\n[PASS] testBurnCannotSpendReserveOrEscrow() (gas: 701866)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1151676)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143914)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476975)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1333138)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1213150, ~: 1260233)\nLogs:\n  Bound result 554\n  Bound result 976\n  Bound result 305\n\n[PASS] testOversizedTrancheFillsUpToTheBlockBoundAndResumesNextBlock() (gas: 1197074)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 711336)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 131.83ms (119.36ms CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 128485, ~: 113783)\nLogs:\n  Bound result 11\n  Bound result 999999999999999999999000001917\n  Bound result 999999999999999999999000000201\n  Bound result 16000000000000000000\n  Bound result 16000000000000000000\n  Bound result 999999999999999999999000005429\n  Bound result 999999999999999999999000000250\n  Bound result 999999999999999999999000000201\n  Bound result 296858534827628535688329214904\n  Bound result 999999999999999999999000016422\n  Bound result 999999999999999999999000016824\n  Bound result 999999999999999999999000887221\n  Bound result 999999999999999999999000018268\n  Bound result 999999999999999999999000016537\n  Bound result 999999999999999999999000002956\n  Bound result 999999999999999999999000016362\n  Bound result 999999999999999999999000002012\n  Bound result 999999999999999999999000006542\n  Bound result 999999999999999999999000036479\n  Bound result 999999999999999999999000006962\n  Bound result 999999999999999999999000011000\n  Bound result 999999999999999999999000021847\n  Bound result 999999999999999999999000021762\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36938, ~: 36984)\nLogs:\n  Bound result 9685863\n  Bound result 252208\n  Bound result 3\n  Bound result 129420009912056910918\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141517, ~: 141885)\nLogs:\n  Bound result 1266412660188944021251926264291\n  Bound result 1237940039285380274899124225\n  Bound result 17831\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36769, ~: 36902)\nLogs:\n  Bound result 989101\n  Bound result 3\n  Bound result 21\n  Bound result 9\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23264, ~: 21542)\nLogs:\n  Bound result 56033804487513053289791982375695\n  Bound result 500192444381763456631\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39830, ~: 39528)\nLogs:\n  Bound result 9999999999999999999999999999999999992005\n  Bound result 500000\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16211, ~: 14794)\nLogs:\n  Bound result 1\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 54116, ~: 51987)\nLogs:\n  Bound result 2225\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36405, ~: 36366)\nLogs:\n  Bound result 6203\n  Bound result 7053\n  Bound result 35\n  Bound result 1300000000000000000\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 19333, ~: 17101)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21356, ~: 21299)\nLogs:\n  Bound result 19543\n  Bound result 16204\n  Bound result 17372\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 64346, ~: 61151)\nLogs:\n  Bound result 0\n  Bound result 3\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 98635, ~: 91281)\nLogs:\n  Bound result 16\n  Bound result 6639\n  Bound result 24236\n  Bound result 42\n  Bound result 9999\n  Bound result 4855\n  Bound result 7372\n  Bound result 20460\n  Bound result 5000\n  Bound result 12915\n  Bound result 4899\n  Bound result 75000000000000000000\n  Bound result 360\n  Bound result 9840\n  Bound result 1000000000000000000000\n  Bound result 9960\n  Bound result 1000000\n  Bound result 8808\n  Bound result 77\n  Bound result 86400\n  Bound result 5943\n  Bound result 10022\n  Bound result 8396\n  Bound result 5391\n  Bound result 4835\n  Bound result 6894\n  Bound result 4295128739\n  Bound result 1088\n  Bound result 17399\n  Bound result 5351\n  Bound result 864000\n  Bound result 21104\n  Bound result 250000000000000000\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 131.98ms (1.10s CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 132.18ms (921.21µs CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 2)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 215   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 243   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 422   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 199   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 215   | 2       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 216   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 190   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 220   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 4439\n  Bound result 2\n  Bound result 2857\n  Bound result 97\n  Bound result 1\n  Bound result 10000000\n  Bound result 1\n  Bound result 448383916526443751334\n  Bound result 1\n  Bound result 357961699067676830607\n  Bound result 402\n  Bound result 1\n  Bound result 0\n  Bound result 0\n  Bound result 5000000000000000000000\n  Bound result 2\n  Bound result 1511\n  Bound result 2\n  Bound result 0\n  Bound result 21689\n  Bound result 53333\n  Bound result 64\n  Bound result 1\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 10635\n  Bound result 50101\n  Bound result 55\n  Bound result 1\n  Bound result 1988584318786873181274\n  Bound result 50663\n  Bound result 96\n  Bound result 2\n  Bound result 19290\n  Bound result 5576\n  Bound result 9\n  Bound result 8863\n  Bound result 1\n  Bound result 86400\n  Bound result 1\n  Bound result 1\n  Bound result 4661\n  Bound result 10005\n  Bound result 40\n  Bound result 1\n  Bound result 1001582335294962060439\n  Bound result 31396\n  Bound result 83\n  Bound result 2\n  Bound result 70000000000000000000\n  Bound result 1\n  Bound result 17586\n  Bound result 0\n  Bound result 12\n  Bound result 2\n  Bound result 1\n  Bound result 10005\n  Bound result 0\n  Bound result 1\n  Bound result 0\n  Bound result 1571\n  Bound result 50124\n  Bound result 98\n  Bound result 1\n  Bound result 2\n  Bound result 60000000000000000\n  Bound result 1530\n  Bound result 4051920982716015181259\n  Bound result 0\n  Bound result 2\n  Bound result 5040\n  Bound result 0\n  Bound result 2\n  Bound result 1\n  Bound result 10286\n  Bound result 0\n  Bound result 4394\n  Bound result 0\n  Bound result 994189088806961825942\n  Bound result 12713\n  Bound result 0\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 474.15ms (458.17ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2480  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2465  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2454  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2401  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2488  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 3740\n  Bound result 1\n  Bound result 27373294\n  Bound result 7\n  Bound result 7616\n  Bound result 172800\n  Bound result 6133\n  Bound result 670362373798978666222781949328009602871019782396\n  Bound result 44337\n  Bound result 795986460211990997\n  Bound result 9000\n  Bound result 280\n  Bound result 130\n  Bound result 7942\n  Bound result 10000000000000000000\n  Bound result 48879\n  Bound result 8453\n  Bound result 1793079072\n  Bound result 587\n  Bound result 6268\n  Bound result 96\n  Bound result 612245086112921471978347\n  Bound result 172800\n  Bound result 2420737339867642122\n  Bound result 333285401399403049248780\n  Bound result 6\n  Bound result 5961\n  Bound result 12500\n  Bound result 1300000000000000000000000\n  Bound result 40\n  Bound result 925612501686372618950762190912688373763603265593\n  Bound result 898\n  Bound result 1300000000000000000\n  Bound result 1550\n  Bound result 1206107831224059603348081560799811221883834135735\n  Bound result 676\n  Bound result 243377\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.09s (1.08s CPU time)\n\nRan 1 test for test/PagesInvariant.t.sol:PagesInvariantTest\n[PASS]\nPagesInvariantTest invariants:\n[PASS] invariant_burnsNeverPassTheBlocksBound\n[PASS] invariant_claimsAreFinal\n[PASS] invariant_conservation\n[PASS] invariant_feesReachPoolsAndDead\n[PASS] invariant_marketHoldsExactlyWhatItOwes\n[PASS] invariant_reserveCoversEveryHolder\n PagesInvariantTest invariants (runs: 96, calls: 4608, reverts: 0)\n\n╭--------------+--------------+-------+---------+----------╮\n| Contract     | Selector     | Calls | Reverts | Discards |\n+==========================================================+\n| PagesHandler | abandon      | 497   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | answer       | 533   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | burn         | 546   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | buy          | 493   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | recycle      | 501   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | requestClaim | 524   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | sell         | 470   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | settle       | 530   | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| PagesHandler | warp         | 514   | 0       | 0        |\n╰--------------+--------------+-------+---------+----------╯\n\nLogs:\n  Bound result 2675825\n  Bound result 40\n  Bound result 1151864\n  Bound result 14608\n  Bound result 409999000371636864\n  Bound result 6400\n  Bound result 40\n  Bound result 40\n  Bound result 2329381574012630134\n  Bound result 328570\n  Bound result 2384013\n  Bound result 90054978474703714\n  Bound result 38\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.60s (5.59s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 524   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 541   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 492   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 491   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 516   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 516   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 508   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 500   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 514   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 527   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 527   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 1020  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 494   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 549   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 511   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 481   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 545   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 469   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 515   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 3\n  Bound result 4\n  Bound result 4\n  Bound result 1\n  Bound result 2478893114\n  Bound result 2\n  Bound result 98000000000000015581\n  Bound result 3\n  Bound result 104611\n  Bound result 2\n  Bound result 3\n  Bound result 5\n  Bound result 4\n  Bound result 1\n  Bound result 54772\n  Bound result 2\n  Bound result 5\n  Bound result 4\n  Bound result 1\n  Bound result 13715\n  Bound result 9750000000000012168\n  Bound result 5\n  Bound result 9750000000000000016\n  Bound result 10350000000000000000\n  Bound result 3\n  Bound result 3\n  Bound result 2983880640491367952\n  Bound result 98000000000000000123\n  Bound result 9750000000000006932\n  Bound result 8\n  Bound result 5497\n  Bound result 10\n  Bound result 108083\n  Bound result 9750000000000020899\n  Bound result 234435\n  Bound result 4\n  Bound result 10\n  Bound result 98000000000000001984\n  Bound result 99999001000000000000001\n  Bound result 17361012247227961072540\n  Bound result 12\n  Bound result 3833140316341833922\n  Bound result 20000000000000000000\n  Bound result 98000000000010283209\n  Bound result 98000000000000000131\n  Bound result 8\n  Bound result 9750000000000000311\n  Bound result 17163\n  Bound result 16\n  Bound result 8575\n  Bound result 12\n  Bound result 99999000000000000003001\n  Bound result 16\n  Bound result 3\n  Bound result 11572\n  Bound result 97\n  Bound result 8226868914329533998\n  Bound result 16\n  Bound result 188368\n  Bound result 18\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.04s (7.05s CPU time)\n\nRan 29 test suites in 7.04s (15.67s CPU time): 317 tests passed, 0 failed, 2 skipped (319 total tests)\n","passed":true},{"durationMs":199,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.settleClaim(bytes32)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":626,\"README.md\":304,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":516,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":433,\"test/PagesAudit.t.sol\":318,\"test/PagesDeployment.t.sol\":61,\"test/PagesEdges.t.sol\":780,\"test/PagesInvariant.t.sol\":746,\"test/PagesOracle.t.sol\":168,\"test/PagesRevision.t.sol\":353,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":80,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"bd6dffedc1ff15aed661964235ed3f43d241bc191b02d88547e722540cd8c46c","verifiedTreeHash":"487110a063ebae913bfcb886825a7824571cb208","verifierVersion":"0.1.0+fb8278c5"},{"checks":[{"durationMs":285682,"exitCode":0,"name":"build","output":"Compiling 125 files with Solc 0.8.26\nSolc 0.8.26 finished in 285.43s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> src/MarginaliaHook.sol:859:9:\n    |\n859 |         uint256 pool = thesisPool[w];\n    |         ^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/MarginaliaHook.sol:99:5:\n   |\n99 |     PoolKey private pool;\n   |     ^^^^^^^^^^^^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to view\n   --> src/MarginaliaHook.sol:299:5:\n    |\n299 |     function beforeSwap(address sender, PoolKey calldata key, SwapParams calldata params, bytes calldata data)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> test/helpers/Fixture.sol:114:5:\n    |\n114 |     function priceOf(bytes32, address) external view returns (uint256) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2018): Function state mutability can be restricted to pure\n  --> test/fork/MainnetLaunch.t.sol:78:5:\n   |\n78 |     function _mine(bytes memory hookCode) internal view returns (bytes32 salt) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/MarginaliaPricer.sol:85:13\n   │\n85 │             n += 1;\n   │             ━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarginaliaTreasury.sol:51:9\n   │\n51 │         emit Dripped(day, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-events-access-control]: `jobHash` is changed without an event but is used for access control\n    ╭▸ src/MarginaliaRouter.sol:303:16\n    │\n303 │         delete jobHash;\n    │                ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaTreasury.sol:43:22\n   │\n43 │         uint32 day = uint32(block.timestamp / 1 days);\n   │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:120:33\n    │\n120 │         if (w.startedAt == 0 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE) {\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:34\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:121:59\n    │\n121 │             return T.PriceWindow(uint64(block.timestamp), uint64(block.number), x, x, x, q, q);\n    │                                                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:142:20\n    │\n142 │                 || block.timestamp < uint256(w.startedAt) + POST_MIN_SPAN\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPricer.sol:143:20\n    │\n143 │                 || block.timestamp > uint256(w.startedAt) + POST_MAX_AGE\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:173:17\n    │\n173 │                 revert BadHandle();\n    │                 ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:149:69\n    │\n149 │             x = twap(v.kind, v.xIsToken0, w.xStart, w.startedAt, x, uint64(block.timestamp));\n    │                                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:168:55\n    │\n168 │         else if (v.kind == T.VenueKind.UniV3) xRead = uint256(_v3Cumulative(ref));\n    │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:28\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                            ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:213:41\n    │\n213 │             int256 delta = int256(c2) - int256(c1);\n    │                                         ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:214:35\n    │\n214 │             int256 mean = delta / int256(dt);\n    │                                   ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:215:38\n    │\n215 │             if (delta < 0 && delta % int256(dt) != 0) mean -= 1; // round toward negative infinity, as v3 does\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:217:57\n    │\n217 │             return fromSqrt(TickMath.getSqrtPriceAtTick(int24(mean)), xIsToken0);\n    │                                                         ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:241:37\n    │\n241 │             (uint160 sqrtP,,,,,,) = IUniswapV3PoolOracle(ref).slot0();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:245:41\n    │\n245 │             (uint112 r0, uint112 r1,) = IUniswapV2PairOracle(ref).getReserves();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPricer.sol:269:33\n    │\n269 │         (int56[] memory cum,) = IUniswapV3PoolOracle(pool).observe(ago);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPricer.sol:279:24\n    │\n279 │         uint32 nowTs = uint32(block.timestamp);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:263:13\n    │\n263 │             hook.fundPot(toPools);\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:225:9\n    │\n225 │         emit Trade(subject, msg.sender, true, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/MarginaliaHook.sol:84:38\n   │\n84 │     bytes32 public constant ACTION = bytes32(\"oracle.request@oracle-1\");\n   │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'bytes32' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:240:9\n    │\n240 │         emit Trade(subject, msg.sender, false, amount, value, fee, s.supply);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/MarginaliaJudge.sol:96:17\n   │\n96 │             try hook.sellPotMarg(marg) returns (uint256 out) {\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:114:47\n    │\n114 │         for (uint256 i = 0; i < all.length && n < MAX_JUDGED; ++i) {\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaJudge.sol:115:35\n    │\n115 │             (,,, bool hasChild) = hook.noteMeta(all[i]);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:170:15\n    │\n170 │             ++n;\n    │               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:174:33\n    │\n174 │             out[i - 1] = bytes1(uint8(48 + v % 10));\n    │                                 ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:186:52\n    │\n186 │         return eligibleTheses(week).length == 0 || block.timestamp >= (uint256(week) + 1) * 7 days + 28 days;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:194:32\n    │\n194 │         if (judgedSet[week] || block.timestamp < requestedAt[week] + ANSWER_DEADLINE) {\n    │                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:254:53\n    │\n254 │             if (s.escrowSince == 0) s.escrowSince = uint64(block.timestamp);\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:214:9\n    │\n214 │         hook.drawForJudging(day, price, retry);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `requestOf` is updated\n    ╭▸ src/MarginaliaJudge.sol:217:21\n    │\n217 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n218 │ ┃             action, body, IIntake.Callback(address(this), this.onOracleResult.selector), imd, price\n219 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaJudge.sol:206:41\n    │\n206 │         if (judgedSet[day] || (retry && block.timestamp < requestedAt[day] + ANSWER_DEADLINE)) {\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:225:9\n    │\n225 │         emit Requested(day, requestId, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `claims` is updated\n    ╭▸ src/MarginaliaPages.sol:328:21\n    │\n328 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n329 │ ┃             action,\n330 │ ┃             bytes(questionBody(normalized, tweetId)),\n331 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n332 │ ┃             imd,\n333 │ ┃             price\n334 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaJudge.sol:223:28\n    │\n223 │         requestedAt[day] = uint64(block.timestamp);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:339:9\n    │\n339 │         emit ClaimRequested(subject, requestId, msg.sender, tweetId);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:337:63\n    │\n337 │         claims[subject] = Claim(requestId, msg.sender, price, uint64(block.timestamp));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:366:13\n    │\n366 │             emit ClaimFailed(subject, requestId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:374:9\n    │\n374 │         emit ClaimAccepted(subject, requestId, wallet);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaJudge.sol:255:9\n    │\n255 │ ┏         emit Judged(\n256 │ ┃             day,\n257 │ ┃             [\n258 │ ┃                 count > 0 ? ranked[0] : bytes32(0),\n    ‡ ┃\n262 │ ┃         );\n    │ ┗━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:402:13\n    │\n402 │         if (block.timestamp < uint256(c.requestedAt) + ANSWER_DEADLINE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:419:9\n    │\n419 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:414:13\n    │\n414 │         if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:420:9\n    │\n420 │         emit Recycled(subject, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:269:50\n    │\n269 │         for (uint256 i = 0; i < ranked.length && kept < 3; ++i) {\n    │                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaJudge.sol:276:17\n    │\n276 │             if (dup) continue;\n    │                 ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaJudge.sol:270:77\n    │\n270 │             (address author, uint32 noteWeek, bool thesis, bool hasChild) = hook.noteMeta(ranked[i]);\n    │                                                                             ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:442:9\n    │\n442 │         manager.unlock(abi.encode(imdIn, minMargOut, zeroForOne, limit));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:431:44\n    │\n431 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:431:52\n    │\n431 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) revert InsufficientBurn();\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaJudge.sol:288:9\n    │\n288 │         hook.payJudged(day, top);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:442:9\n    │\n442 │         manager.unlock(abi.encode(imdIn, minMargOut, zeroForOne, limit));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaRouter.sol:251:13\n    │\n251 │         if (block.timestamp > deadline) revert Expired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:450:54\n    │\n450 │             return lower > TickMath.MIN_SQRT_PRICE ? uint160(lower) : TickMath.MIN_SQRT_PRICE + 1;\n    │                                                      ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:41\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:252:49\n    │\n252 │         if (amountIn == 0 || amountIn > uint256(uint128(type(int128).max))) revert InvalidSwap();\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:453:50\n    │\n453 │         return upper < TickMath.MAX_SQRT_PRICE ? uint160(upper) : TickMath.MAX_SQRT_PRICE - 1;\n    │                                                  ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:476:9\n    │\n476 │         emit Burned(spent, marg);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:462:68\n    │\n462 │         BalanceDelta d = manager.swap(key, SwapParams(zeroForOne, -int256(imdIn), limit), \"\");\n    │                                                                    ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:466:25\n    │\n466 │         uint256 spent = uint256(-int256(inD));\n    │                         ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:467:24\n    │\n467 │         uint256 marg = uint256(uint128(outD));\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:467:32\n    │\n467 │         uint256 marg = uint256(uint128(outD));\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:473:9\n    │\n473 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:338:9\n    │\n338 │         emit Noted(job.payer, job.sellMarg, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:320:18\n    │\n320 │                 -int256(job.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:25\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:328:33\n    │\n328 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:28\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:329:36\n    │\n329 │         uint256 received = uint256(uint128(outputDelta));\n    │                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:373:9\n    │\n373 │         emit XTraded(payer, X_V4, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:355:18\n    │\n355 │                 -int256(x.amountIn),\n    │                  ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:25\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:363:33\n    │\n363 │         uint256 spent = uint256(uint128(-inputDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:20\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:364:28\n    │\n364 │         received = uint256(uint128(outputDelta));\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:403:9\n    │\n403 │         emit XTraded(payer, X_V3, xIn, xOut, spent, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:394:13\n    │\n394 │             int256(x.amountIn),\n    │             ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:399:25\n    │\n399 │         uint256 spent = uint256(zeroForOne ? a0 : a1);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:409:78\n    │\n409 │         if (amount0Delta > 0) IERC20(pool.token0()).safeTransfer(msg.sender, uint256(amount0Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaRouter.sol:410:78\n    │\n410 │         if (amount1Delta > 0) IERC20(pool.token1()).safeTransfer(msg.sender, uint256(amount1Delta));\n    │                                                                              ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaRouter.sol:438:9\n    │\n438 │         emit XTraded(payer, X_V2, xIn, xOut, actualIn, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaRouter.sol:426:37\n    │\n426 │         (uint112 r0, uint112 r1,) = pair.getReserves();\n    │                                     ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:312:49\n    │\n312 │                 specifiedTake = STAMP + _bondOf(uint256(-params.amountSpecified));\n    │                                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:389:9\n    │\n389 │         emit Accrued(day, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:471:17\n    │\n471 │                 emit Revealed(id, hash);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:495:9\n    │\n495 │         emit NotePosted(id, author, p.x, class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:348:13\n    │\n348 │             emit SwapFee(true, author, poolImd, 0, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:361:13\n    │\n361 │             emit SwapFee(false, author, poolImd, fee - STAMP, STAMP);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:372:9\n    │\n372 │         emit SwapFee(false, tx.origin, poolImd, quietFee, 0);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:33\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:41\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                         ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:63\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:335:71\n    │\n335 │         uint256 poolImd = buy ? uint256(uint128(-imdDelta)) : uint256(uint128(imdDelta));\n    │                                                                       ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:340:36\n    │\n340 │             uint256 bond = _bondOf(uint256(-params.amountSpecified));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:31\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:342:39\n    │\n342 │             uint256 margOut = uint256(uint128(margDelta));\n    │                                       ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:17\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:450:60\n    │\n450 │             if (weekTheses[w].length >= MAX_WEEK_THESES || thesesPerAuthor[w][author] >= MAX_AUTHOR_THESES) {\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:465:26\n    │\n465 │             if (bound && age < SEAL_MIN) revert TooEarly(); // the head start is the key holders', not the public's\n    │                          ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:466:26\n    │\n466 │             if (bound && age <= SEAL_MAX) {\n    │                          ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:484:32\n    │\n484 │ …                     || block.timestamp > uint256(parent.postedAt) + THESIS_GRACE\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:442:22\n    │\n442 │         n.postedAt = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:540:13\n    │\n540 │         if (block.timestamp < end) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:541:13\n    │\n541 │         if (block.timestamp > end + SETTLE_WINDOW) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:554:47\n    │\n554 │                     || (len == OBS_MAX - 1 && block.timestamp < uint256(obs[0].timestamp) + OBS_MIN_SPAN))\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:562:9\n    │\n562 │         emit Observed(id, xRead, balance);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:27\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:546:52\n    │\n546 │             T.Observation(uint64(block.timestamp), uint64(block.number), xRead, quoteRead, balance);\n    │                                                    ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:570:13\n    │\n570 │             x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.balanceOf.selector, who));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaHook.sol:651:35\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │                                   ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:607:13\n    │\n607 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:736:13\n    │\n736 │             emit ThesisReleased(n.parentId);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:651:9\n    │\n651 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:634:26\n    │\n634 │             scoreDelta = int256(_difficulty(n));\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:639:27\n    │\n639 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:641:27\n    │\n641 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:645:27\n    │\n645 │             scoreDelta = -int256(_difficulty(n));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:669:17\n    │\n669 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:683:13\n    │\n683 │         if (block.timestamp >= horizonEnd(id)) revert TooLate();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:693:9\n    │\n693 │         emit Retracted(id, text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:694:9\n    │\n694 │         emit Settled(id, T.Status.Retracted, 0, scoreDelta, address(0));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:687:30\n    │\n687 │         int256 scoreDelta = -int256(_difficulty(n) / 2);\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:702:13\n    │\n702 │         if (block.timestamp <= uint256(n.postedAt) + THESIS_GRACE) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:705:9\n    │\n705 │         emit ThesisForfeited(id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:719:9\n    │\n719 │         emit DepositClaimed(id, n.author, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaHook.sol:749:13\n    │\n749 │             n.x.staticcall{gas: BALANCE_READ_GAS}(abi.encodeWithSelector(IERC20.totalSupply.selector));\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:758:16\n    │\n758 │         return uint32(block.timestamp / 1 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:762:16\n    │\n762 │         return uint32(block.timestamp / 7 days);\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:782:9\n    │\n782 │         emit PotFunded(_today(), amount, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `seals` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:816:25\n    │\n816 │         if ((at != 0 && block.timestamp - at <= SEAL_MAX) || x == address(0) || hash == bytes32(0)) {\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:830:9\n    │\n830 │         emit Sealed(hash, msg.sender, x, venue.ref);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:824:13\n    │\n824 │             uint64(block.timestamp),\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:837:23\n    │\n837 │         if (!retry && block.timestamp < (uint256(w) + 1) * 7 days + THESIS_GRACE) revert TooEarly();\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:851:27\n    │\n851 │         return (n.author, uint32(uint256(n.postedAt) / 7 days), n.targetBps == 0, n.children > 0);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `thesisPool` is updated\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaHook.sol:925:28\n    │\n925 │         bytes memory out = poolManager.unlock(data);\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:873:9\n    │\n873 │         emit JudgedPaid(w, paidAmounts);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaHook.sol:926:39\n    │\n926 │         if (unlockHash != bytes32(0)) revert InvalidUnlock();\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:880:13\n    │\n880 │         if (n.day >= _today()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaHook.sol:890:9\n    │\n890 │         emit RefundClaimed(id, msg.sender, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:888:30\n    │\n888 │         notesPerDay[n.day] = uint32(count - 1);\n    │                              ━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:899:17\n    │\n899 │             if (block.timestamp < (uint256(epoch) + 1) * 1 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaHook.sol:903:17\n    │\n903 │             if (block.timestamp < (uint256(epoch) + 1) * 7 days + SWEEP_AFTER) revert TooEarly();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaHook.sol:936:40\n    │\n936 │             address currency = address(uint160(extra));\n    │                                        ━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint160' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaHook.sol:945:13\n    │\n945 │             poolManager.settle();\n    │             ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n   ╭▸ test/AuditFindings.t.sol:19:30\n   │\n19 │         uint256 startBlock = block.number;\n   │                              ━━━━━━━━━━━━\n   ‡\n23 │             vm.roll(startBlock + 25 * (i + 1));\n   │             ────────────────────────────────── `vm.roll` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockNumber()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/AuditFindings.t.sol:20:27\n   │\n20 │         uint256 startTs = block.timestamp;\n   │                           ━━━━━━━━━━━━━━━\n   ‡\n24 │             vm.warp(startTs + 31 minutes * (i + 1));\n   │             ─────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:18:9\n    │\n 18 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/AuditFindings.t.sol:65:9\n    │\n 65 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookBoundaries.t.sol:347:9\n    │\n347 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:82:9\n    │\n 82 │         vm.warp(deadline - 1 hours);\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:193:9\n    │\n193 │         vm.warp(weekEnd - 1 hours);\n    │         ────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/HookReview.t.sol:195:9\n    │\n195 │         vm.warp(weekEnd + 1);\n    │         ──────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:148:9\n    │\n148 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:149:30\n    │\n149 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n153 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:150:27\n    │\n150 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n154 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:176:9\n    │\n176 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:177:30\n    │\n177 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n181 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:178:27\n    │\n178 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n182 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:203:9\n    │\n203 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:204:30\n    │\n204 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n208 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:205:27\n    │\n205 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n209 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:302:9\n    │\n302 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:357:9\n    │\n357 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:358:30\n    │\n358 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n363 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:359:27\n    │\n359 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n364 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:421:9\n    │\n421 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:488:9\n    │\n488 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:489:30\n    │\n489 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n492 │         vm.roll(startBlock + 25);\n    │         ──────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:490:27\n    │\n490 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n493 │         vm.warp(startTs + 30 minutes);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:512:9\n    │\n512 │         vm.warp(hook.horizonEnd(id));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:513:30\n    │\n513 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n517 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:514:27\n    │\n514 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n518 │             vm.warp(startTs + 10 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:554:9\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:538:49\n    │\n538 │         router.note(rebuttal, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:554:17\n    │\n554 │         vm.warp(block.timestamp + hook.THESIS_GRACE() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/Lifecycle.t.sol:583:9\n    │\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:575:49\n    │\n575 │         router.note(sameSide, key, 10 ether, 1, block.timestamp + 1);\n    │                                                 ━━━━━━━━━━━━━━━\n    ‡\n583 │         vm.warp(hook.horizonEnd(a));\n    │         ─────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.number` may be reused across `vm.roll`\n    ╭▸ test/Lifecycle.t.sol:584:30\n    │\n584 │         uint256 startBlock = block.number;\n    │                              ━━━━━━━━━━━━\n    ‡\n589 │             vm.roll(startBlock + 25 * (i + 1));\n    │             ────────────────────────────────── `vm.roll` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockNumber()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:585:27\n    │\n585 │         uint256 startTs = block.timestamp;\n    │                           ━━━━━━━━━━━━━━━\n    ‡\n590 │             vm.warp(startTs + 30 minutes * (i + 1));\n    │             ─────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:629:22\n    │\n629 │         assertEq(at, block.timestamp);\n    │                      ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:634:42\n    │\n634 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:638:17\n    │\n638 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:653:17\n    │\n653 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:657:42\n    │\n657 │         router.note(p, key, 10 ether, 1, block.timestamp + 1);\n    │                                          ━━━━━━━━━━━━━━━\n    ‡\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:663:17\n    │\n663 │         vm.warp(block.timestamp + hook.SEAL_MIN());\n    │         ────────━━━━━━━━━━━━━━━─────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:679:17\n    │\n679 │         vm.warp(block.timestamp + hook.SEAL_MAX() + 1);\n    │         ────────━━━━━━━━━━━━━━━─────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/Lifecycle.t.sol:682:17\n    │\n682 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/RevisionFindings.t.sol:199:17\n    │\n199 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/Fixture.sol:266:50\n    │\n266 │         received = router.note(p, key, imdIn, 1, block.timestamp + 1);\n    │                                                  ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/RevisionFindings.t.sol:267:9\n    │\n267 │         vm.warp((uint256(w) + 1) * 7 days + hook.THESIS_GRACE());\n    │         ──────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Round3Findings.t.sol:67:17\n   │\n67 │         vm.warp(block.timestamp + 1 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":7284,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/PagesMainnet.t.sol:PagesMainnetTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 447.60µs (0.00ns CPU time)\n\nRan 1 test for test/fork/MainnetLaunch.t.sol:MainnetLaunchTest\n[SKIP: skipped] setUp() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 576.52µs (0.00ns CPU time)\n\nRan 6 tests for test/PagesOracle.t.sol:PagesOracleTest\n[PASS] testAbandonBoundaryInvalidatesOldRoutingAndAllowsRetry() (gas: 621316)\n[PASS] testAnswersForUnrequestedIdsAndOtherConsumersAreRefused() (gas: 4054971)\n[PASS] testColdCallbackStoresUnderStipendAndSettlePaysTwoFreshBalances() (gas: 390194)\nLogs:\n  delivery gas including mock Intake overhead: 120590\n\n[PASS] testDigestMatchesProtocolVector() (gas: 14319)\n[PASS] testProtocolSignatureVerifiesUnchanged() (gas: 89418)\n[PASS] testSignedUuidCannotReplayAgainstAnotherPendingIntakeId() (gas: 678742)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 3.22ms (1.92ms CPU time)\n\nRan 7 tests for test/JudgeOracle.t.sol:JudgeOracleTest\n[PASS] testEmptySignedRankingIsAnExecutableNoWinnerResult() (gas: 248153)\n[PASS] testFiveIdsWithEoaSignatureFitStipend() (gas: 554052)\n[PASS] testFullRankingWithEoaSignatureFitsStipend() (gas: 633672)\n[PASS] testProtocolDigestSignatureAndSelectorConformanceOnClone() (gas: 3322442)\n[PASS] testRejectedAnswersDoNotConsumeThePendingRequest() (gas: 892875)\n[PASS] testRequestedHeadIsFilteredAndDeduplicatedWithoutPromotingTheTail() (gas: 250679)\n[PASS] testTimeoutRetryInvalidatesOldIntakeRequest() (gas: 523953)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 6.64ms (5.54ms CPU time)\n\nRan 6 tests for test/AuditFindings.t.sol:AuditFindingsTest\n[PASS] testEmptyV4ObservationIsRefused() (gas: 918993)\n[PASS] testExpiredBaselineRejectsPostWithoutTakingFunds() (gas: 601798)\n[PASS] testHeadOfThreeFitsIntakeStipendAndAFullRankingIsRetried() (gas: 2111077)\n[PASS] testSameBlockDumpPostUnwindDoesNotWinBuy() (gas: 1822381)\n[PASS] testSameBlockPumpPostUnwindDoesNotWinSell() (gas: 1691295)\n[PASS] testUnpayableRankingRollsTheWholePoolForward() (gas: 2384827)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 11.08ms (5.26ms CPU time)\n\nRan 14 tests for test/CompanionFailures.t.sol:RouterFailuresTest\n[PASS] testExpiredDeadlineTakesNothing() (gas: 668139)\n[PASS] testExpiredWindowRefusesPostsUntilAFreshCheckpointMatures() (gas: 1756378)\n[PASS] testInitRequiresAManagerWithCode() (gas: 4169863)\n[PASS] testSlippageFloorRefundsEverything() (gas: 639941)\n[PASS] testStrangersCannotEnterTheCallbacks() (gas: 133302)\n[PASS] testTradeAndNoteRefusesNoTradeZeroTradeAndNativeInput() (gas: 290673)\n[PASS] testTradedNoteMustBeAboutTheTokenTraded() (gas: 980650)\n[PASS] testTradedV4LegUnderAForeignHookOrEmptyPoolIsRefused() (gas: 396113)\n[PASS] testUnapprovedOrUnfundedAuthorIsRefused() (gas: 224265)\n[PASS] testV4VenueUnderAForeignHookIsRefused() (gas: 69759)\n[PASS] testV4VenueWithoutLiquidityIsRefused() (gas: 134961)\n[PASS] testVenueFieldsAreDerivedFromThePoolNotTheCaller() (gas: 48554)\n[PASS] testVenueKindNoneIsRefusedForAPricedCall() (gas: 116223)\n[PASS] testZeroAndOversizedAmountsAreRefused() (gas: 138593)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 13.12ms (5.32ms CPU time)\n\nRan 7 tests for test/PagesReview.t.sol:PagesReviewTest\n[PASS] testCallbackOnlyStoresAndSettleClaimPays() (gas: 2444231)\nLogs:\n  callback gas, no token transfer: 105843\n\n[PASS] testDustTrancheHasItsOwnError() (gas: 666181)\n[PASS] testHonestBurnMovesThePriceAtMostOnePercentPerBlock() (gas: 923951)\n[PASS] testMarketAndHookSubjectsEscrowInsteadOfStranding() (gas: 1224649)\n[PASS] testOracleNamingTheMarketOrHookIsAFailedClaim() (gas: 2306626)\n[PASS] testRepeatedSandwichInOneBlockLosesMoney() (gas: 1580067)\n[PASS] testSandwichingTheBurnLosesMoneyAtEverySize() (gas: 3660469)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 13.23ms (7.30ms CPU time)\n\nRan 8 tests for test/LaunchAuditFindings.t.sol:LaunchAuditFindingsTest\n[PASS] testAHugeSupplyBooksTierOneInsteadOfOverflowing() (gas: 2461200)\n[PASS] testALapsedSealCanBeSealedAgain() (gas: 703279)\n[PASS] testARetractedNoteLeavesTheDaysRefundSplit() (gas: 1382965)\n[PASS] testARetractionAfterTheRefundClaimDoesNotDoubleCount() (gas: 1359071)\n[PASS] testARevertingTotalSupplyDoesNotBlockARetraction() (gas: 1932201)\n[PASS] testARevertingTotalSupplyStillSettlesWrongAndPaysTheKeeper() (gas: 2554573)\n[PASS] testAStrangersSealNeitherBlocksNorPricesTheAuthorsNote() (gas: 2518397)\n[PASS] testAnAuthorsSealOnAnotherVenueDoesNotPriceTheNote() (gas: 2235395)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 14.19ms (7.76ms CPU time)\n\nRan 28 tests for test/CompanionFailures.t.sol:JudgeFailuresTest\n[PASS] testAJudgedWeekCannotBeAbandoned() (gas: 1257630)\n[PASS] testAbandonNeedsALiveRequestPastItsDeadline() (gas: 1190393)\n[PASS] testAbandonTakesNothingAndTheRetryDrawsAgain() (gas: 1467522)\n[PASS] testAnswerAtTheExactExpiryStillCountsAndOneSecondLaterDoesNot() (gas: 1257046)\n[PASS] testAnswerForAWeekAlreadyJudgedIsRefused() (gas: 1320679)\n[PASS] testAnswerSignedByAnotherKeyIsRefused() (gas: 1069433)\n[PASS] testAnswerSignedForAnotherConsumerIsRefused() (gas: 3952788)\n[PASS] testConvertForfeitsWithAnEmptyPotIsANoOp() (gas: 236930)\n[PASS] testConvertNeverSellsMoreThanThePot() (gas: 236488)\n[PASS] testConvertSellsTheLargestHalvingThePoolAbsorbs() (gas: 275386)\n[PASS] testConvertTriesExactlyNineTranchesDownToOneTwoHundredFiftySixth() (gas: 363686)\n[PASS] testCurrentAndFutureWeeksCannotBeRequested() (gas: 128617)\n[PASS] testEligibleThesesAreCappedAtTheJudgedMaximum() (gas: 14217218)\n[PASS] testImplementationHasAPlaceholderSignerAndCannotBeConfigured() (gas: 2726709)\n[PASS] testInitRequiresEveryConfigurationValue() (gas: 2953442)\n[PASS] testIntakeReturningAnIdAlreadyPendingIsRefused() (gas: 1599187)\n[PASS] testJudgedOfFiltersWrongWeekShortFormAndChildlessIds() (gas: 1439829)\n[PASS] testJudgedWeekCannotBeRequestedAgainEvenAfterTheDeadline() (gas: 1242650)\n[PASS] testMalformedAnswerBytesAreRefused() (gas: 1067354)\n[PASS] testOnlyTheHeadOfThreeIsStoredAndTheTailNeverPromotes() (gas: 1221812)\n[PASS] testPayBeforeAnAnswerReverts() (gas: 1064318)\n[PASS] testPayIsPermissionlessAndOnce() (gas: 1438634)\n[PASS] testQuestionBodyNamesTheConsumerChainAndEligibleIdsOnly() (gas: 2516225)\n[PASS] testRepeatRequestBeforeTheDeadlineIsRefused() (gas: 1419149)\n[PASS] testRequestDrawsExactlyThePriceAndKeepsNothing() (gas: 1028228)\n[PASS] testWeekClosedStates() (gas: 1940695)\n[PASS] testWeekWithoutEligibleThesesCannotBeRequested() (gas: 244665)\n[PASS] testZeroAndExcessiveOraclePricesAreRefused() (gas: 1345941)\nSuite result: ok. 28 passed; 0 failed; 0 skipped; finished in 19.01ms (32.70ms CPU time)\n\nRan 1 test for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testFactoryDeploysOnlyPagesWithoutExistingChainState() (gas: 12962623)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 26.95ms (26.75ms CPU time)\n\nRan 10 tests for test/Round3Findings.t.sol:Round3FindingsTest\n[PASS] testABuyCallStillBreaksWhenTheAuthorSells() (gas: 1669522)\n[PASS] testAGiftOfAnySizeDoesNotVoidACorrectSellCall() (gas: 1584170)\n[PASS] testAGiftWorthTheDepositDoesNotVoidACorrectSellCall() (gas: 1663423)\n[PASS] testALaunchPoolCallScoresTheSameWay() (gas: 1417891)\n[PASS] testASelfPricedVenueBooksReputationOnlyAndNoPoolPaysForIt() (gas: 3007470)\n[PASS] testAWrongCallOnAnotherVenueStillForfeitsAndBooksANegativeScore() (gas: 2707061)\n[PASS] testAWrongSellCallStillForfeits() (gas: 1395988)\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 256, μ: 22989, ~: 20590)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 28.95ms (23.03ms CPU time)\n\nRan 31 tests for test/Lifecycle.t.sol:LifecycleTest\n[PASS] testAttestedClassCannotBeSelfDeclared() (gas: 294892)\n[PASS] testCallbackSelectorPinned() (gas: 3383)\n[PASS] testCounterCallDuel() (gas: 3589375)\n[PASS] testCounterThesisEntersTheJudgedSet() (gas: 2688706)\n[PASS] testFakeVenueIsRefused() (gas: 382766)\n[PASS] testFlagsAndBinding() (gas: 56048)\n[PASS] testForfeitsAreImdAndNeedNoConversion() (gas: 861195)\n[PASS] testNoDataRefunds() (gas: 880570)\n[PASS] testNoteTooSmall() (gas: 1644543)\n[PASS] testNotedBuyTakesStampAndDeposit() (gas: 729443)\n[PASS] testNotedSellPaysOnePercentPlusStamp() (gas: 988516)\n[PASS] testObservationsMustSpanAnHour() (gas: 1384019)\n[PASS] testPlainBuyTakesNothing() (gas: 211688)\n[PASS] testQuietSellPaysThreePercent() (gas: 295440)\n[PASS] testQuietThesisPoolSweeps() (gas: 300271)\n[PASS] testRetract() (gas: 866644)\n[PASS] testRightCallReturnsDeposit() (gas: 1623568)\n[PASS] testScoreIsReputationAndAccrualsSplitSeventyThirty() (gas: 2887924)\n[PASS] testSealedBuyMustKeepItsPositionFromTheSeal() (gas: 2165657)\n[PASS] testSealedNoteRevealsAgainstTheSealBaseline() (gas: 1770762)\n[PASS] testSellingEarlyBreaksTheCall() (gas: 1678252)\n[PASS] testThesisParentChild() (gas: 1362912)\n[PASS] testThesisWithoutChildForfeits() (gas: 828214)\n[PASS] testTreasuryDrip() (gas: 320866)\n[PASS] testTwoBlockPumpObserveUnwindSettlesWrong() (gas: 1692826)\n[PASS] testUnansweredWeekCanBeRetried() (gas: 2356119)\n[PASS] testUnrevealedSealIsNotAFreeOptionAndLapses() (gas: 1361008)\n[PASS] testUpOnlyIsRefused() (gas: 291916)\n[PASS] testWeeklyThesisJudging() (gas: 3728190)\n[PASS] testWriterRefundCappedAtStamp() (gas: 1589580)\n[PASS] testWrongCallForfeitsWithKeeperReward() (gas: 1511685)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 35.58ms (29.90ms CPU time)\n\nRan 10 tests for test/RevisionFindings.t.sol:RevisionFindingsTest\n[PASS] testABuyBackNoLongerVoidsASellCallItSettlesOnPrice() (gas: 1599565)\n[PASS] testADustPricedV4VenueCannotBePostedOn() (gas: 1574208)\n[PASS] testARevertingBalanceOfVoidsTheCallAsSoldNotAsNoData() (gas: 2592032)\n[PASS] testAStrangersDustTransferDoesNotVoidASellCall() (gas: 1564471)\n[PASS] testAnAttestationAboutAnotherChainIsRefused() (gas: 2243391)\n[PASS] testAnEmptyCanonicalV3PoolIsRefusedAsAVenue() (gas: 567783)\n[PASS] testHonestObserverOverwritesAPumpObserveUnwindInTheNextBlock() (gas: 3639686)\n[PASS] testPricerRefusesAPriceThatRoundsToZeroInBothOrientations() (gas: 58756)\n[PASS] testSweepNeedsTheStaleRequestAbandonedAndALateAnswerIsThenRefused() (gas: 2379400)\n[PASS] testTheHundredAndTwentyFirstThesisOfAWeekIsRefusedBeforePayment() (gas: 68883218)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 110.55ms (76.98ms CPU time)\n\nRan 13 tests for test/LaunchBinding.t.sol:LaunchBindingTest\n[PASS] testCompanionsAreThePinnedImmutableMinimalProxies() (gas: 30808)\n[PASS] testConstructorWorksWithoutCompanionOrManagerCode() (gas: 55770870)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyOne() (gas: 43621657)\n[PASS] testExactFeeAccountingWhenImdIsCurrencyZero() (gas: 43621441)\n[PASS] testHookAndTokenHaveNoCommonAdminOrWithdrawalSurface() (gas: 533665)\n[PASS] testLiquidityFeesAndFullWithdrawalRemainAvailable() (gas: 753870)\n[PASS] testNativeAndCodelessPairsAreRefused() (gas: 18139513)\n[PASS] testNotedBuyOnFreshManagerSeededOnlyWithMarg() (gas: 42084867)\n[PASS] testOnlyTheSuppliedFactoryCanInitializeAndFailureDoesNotConsumeBinding() (gas: 18283610)\n[PASS] testPermissionsEnableOnlyTheFiveRequiredFlags() (gas: 14213)\n[PASS] testPoolCannotBeReadOrSwappedBeforeBinding() (gas: 18067221)\n[PASS] testPoolMustContainTheConstructorToken() (gas: 18069867)\n[PASS] testWrongFeeIsRefusedBeforeCorrectFeeBinds() (gas: 18253068)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 115.17ms (146.93ms CPU time)\n\nRan 18 tests for test/HookReview.t.sol:HookReviewTest\n[PASS] testBuyCallOnImdRefusedBeforeTakingBond() (gas: 695548)\n[PASS] testBuySettlementUsesSameObservationForBothLegs() (gas: 2194208)\n[PASS] testChildAtExactlyGraceDeadlineReleasesThesis() (gas: 1501471)\n[PASS] testDustReplacementsCannotMonopolizeObservationWindow() (gas: 30914015)\n[PASS] testJudgingWaitsForEveryThesisChildGrace() (gas: 3710217)\n[PASS] testLateChildCannotRescueThesis() (gas: 1480370)\n[PASS] testOneAuthorCannotFillTheWeeklyThesisSet() (gas: 43417988)\n[PASS] testOneHostileReadingRemainsAdverseAfterPriceRecovers() (gas: 2182461)\n[PASS] testReplacementCannotLeaveAFullSeriesShortOfOneHour() (gas: 4017959)\n[PASS] testReplacementDoesNotRestartTwentyBlockGap() (gas: 1296953)\n[PASS] testSealOnImdRefusedBeforeTakingStamp() (gas: 389434)\n[PASS] testSellCallOnImdRefusedBeforeTakingBond() (gas: 695149)\n[PASS] testSellSettlementUsesSameObservationForBothLegs() (gas: 2196149)\n[PASS] testSingleSidedLiquidityExitPaysNoHookSwapFee() (gas: 1189966)\n[PASS] testV2AliasPostRefused() (gas: 2486105)\n[PASS] testV2AliasSealRefused() (gas: 2230883)\n[PASS] testV3AliasPostRefused() (gas: 2323854)\n[PASS] testV3AliasSealRefused() (gas: 2067752)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 115.25ms (62.76ms CPU time)\n\nRan 10 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonCannotReenterATrade() (gas: 2387030)\n[PASS] testBurnCannotSpendReserveOrEscrowAndRejectsZeroFloor() (gas: 733775)\n[PASS] testBurnFailureKeepsFundsAndCanResumeAfterLiquidityReturns() (gas: 1160005)\n[PASS] testBurnUsesCallerFloorAndManipulatedPriceCannotBlockTrading() (gas: 1073063)\n[PASS] testClaimInstructionChangesAcrossDeploymentsAndChains() (gas: 143742)\n[PASS] testClaimInstructionRequiresThisDeploymentAndChain() (gas: 3476869)\n[PASS] testEveryHolderCanExitAfterAllLiquidityIsWithdrawn() (gas: 1331958)\n[PASS] testFuzzReserveCoversAllHoldersWithQueuedBurns(uint16,uint16,uint16) (runs: 256, μ: 1218839, ~: 1258148)\nLogs:\n  Bound result 816\n  Bound result 1\n  Bound result 802\n\n[PASS] testOversizedBurnFillsOnlyTheBandAndKeepsTheRestPending() (gas: 1035940)\n[PASS] testSupplyAndBalancesDoNotTruncateAboveUint64() (gas: 710238)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 117.34ms (119.49ms CPU time)\n\nRan 7 tests for test/Pricer.t.sol:PricerTest\n[PASS] testQuoteLegIsAdverseEvenUnderAV3Twap() (gas: 28455)\n[PASS] testTwapRefusesZeroSpanAndV4() (gas: 17708)\n[PASS] testV2TwapFromWrappingCumulative() (gas: 9503)\n[PASS] testV3TwapOfAConstantTickIsThatTick() (gas: 15459)\n[PASS] testV3TwapRoundsNegativeMeansDown() (gas: 14848)\n[PASS] testV3TwapWeightsByTime() (gas: 14715)\n[PASS] testV4SettlesOnTheAdverseExtreme() (gas: 26636)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 122.85ms (446.74µs CPU time)\n\nRan 3 tests for test/Implementations.t.sol:ImplementationsTest\n[PASS] testClonesInitializeOnceOnlyFromTheirHook() (gas: 4551335)\n[PASS] testFactoryDeploysAllFourWithoutArgumentsOrExternalDependencies() (gas: 34608585)\nLogs:\n  four implementation CREATE2 deployments (gas): 8829579\n\n[PASS] testImplementationsRejectInitialization() (gas: 81376)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 124.53ms (49.97ms CPU time)\n\nRan 8 tests for test/PriceHistory.t.sol:PriceHistoryTest\n[PASS] testBaselineRequiresMatureFreshHistory() (gas: 188472)\n[PASS] testEmptyVenueAndHubCannotBeCheckpointedObservedOrPriced() (gas: 284549)\n[PASS] testFuzzV4BaselineIsNeverFavourableToTheCall(int24,bool) (runs: 256, μ: 105999, ~: 106113)\nLogs:\n  Bound result -6000\n\n[PASS] testHubBaselineUsesOppositeExtremeFromSettlement() (gas: 180334)\n[PASS] testLiveCheckpointCannotEraseHonestExtremesOrRestartTheClock() (gas: 224282)\n[PASS] testV2BaselineIgnoresSameBlockReservesDumpAndPumpBothOrientations() (gas: 467543)\n[PASS] testV3BaselineIgnoresSameBlockTickChangesBothOrientations() (gas: 418025)\n[PASS] testV3BaselineWeightsElapsedTime() (gas: 371037)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 124.74ms (51.53ms CPU time)\n\nRan 12 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2652061)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2452659)\n[PASS] testBuyPaysTheIssuerQueuesBoundedBurnAndFundsThePools() (gas: 697675)\n[PASS] testCurveIsLinear() (gas: 37439)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 3989722)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 63979)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37567)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 170820)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2351839)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 783131)\n[PASS] testSlippageAndNoCap() (gas: 615936)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 1929209)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 124.83ms (10.46ms CPU time)\n\nRan 31 tests for test/PricerProperties.t.sol:PricerPropertiesTest\n[PASS] testDifficultyAnchors() (gas: 56436)\n[PASS] testDifficultyRefusesAZeroHorizon() (gas: 10063)\n[PASS] testDifficultyTiersStepExactlyAtTheThresholds() (gas: 79314)\n[PASS] testEmptyPoolsAreRefusedOnBothLegs() (gas: 161813)\n[PASS] testEthQuoteIsOnlyPriceableOnMainnet() (gas: 40894)\n[PASS] testFromSqrtRefusesAnEmptyOrUnpriceableReading() (gas: 53891)\n[PASS] testFromSqrtZeroThresholdIsSharpInBothOrientations() (gas: 1024182)\n[PASS] testFuzzAppendingAnObservationNeverHelpsTheCall(uint256[16],uint256[16],uint8) (runs: 1000, μ: 128600, ~: 102338)\nLogs:\n  Bound result 11\n  Bound result 250000000000000000\n  Bound result 1300000000000000000\n  Bound result 999999999999999999999000006772\n  Bound result 999999999999999999999000001551\n  Bound result 12000000000000000000\n  Bound result 999999999999999999999000000123\n  Bound result 4000000000000000000\n  Bound result 357495912450770724810077783388\n  Bound result 999999999999999999999000010695\n  Bound result 999999999999999999999002592001\n  Bound result 999999999999999999999000010971\n  Bound result 999999999999999999999000013802\n  Bound result 999999999999999999999000020662\n  Bound result 650000000000000000\n  Bound result 999999999999999999999000007052\n  Bound result 999999999999999999999000017497\n  Bound result 999999999999999999999000012916\n  Bound result 999999999999999999999000035169\n  Bound result 999999999999999999999000007953\n  Bound result 10000000000000000000\n  Bound result 110999999999999999999999\n  Bound result 1000000000000000000000\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36927, ~: 36977)\nLogs:\n  Bound result 128822\n  Bound result 9989025\n  Bound result 58\n  Bound result 12160605404056370248914808\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141430, ~: 141832)\nLogs:\n  Bound result 79228162514264337593543950336\n  Bound result 1266412660188944021221804085300\n  Bound result 28800\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36751, ~: 36905)\nLogs:\n  Bound result 989049\n  Bound result 21\n  Bound result 35\n  Bound result 1172\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23297, ~: 21564)\nLogs:\n  Bound result 28251539696946608121963328968148103161685350754\n  Bound result 1461446703485210103287273052103988822378754976368\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39186, ~: 38269)\nLogs:\n  Bound result 5026218427241393748684700918000455174069\n  Bound result 2123355462985\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 15814, ~: 14137)\nLogs:\n  Bound result 3\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 54074, ~: 51987)\nLogs:\n  Bound result 28588\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36411, ~: 36401)\nLogs:\n  Bound result 48\n  Bound result 2811\n  Bound result 35\n  Bound result 1172\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 19063, ~: 16931)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21354, ~: 21299)\nLogs:\n  Bound result 1\n  Bound result 1\n  Bound result 3\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 63367, ~: 58182)\nLogs:\n  Bound result 33420\n  Bound result 16\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 99665, ~: 84180)\nLogs:\n  Bound result 1\n  Bound result 1216324693784169155103107041\n  Bound result 7937546768482135347\n\n[PASS] testObserveRefusesUnknownVenuesAndUnpriceableQuotes() (gas: 150448)\n[PASS] testPostPriceRefusesAnEmptyWindow() (gas: 15317)\n[PASS] testPostPriceWhoseProductRoundsToZeroIsRefused() (gas: 293627)\n[PASS] testSellDifficultyRefusesAZeroTarget() (gas: 9518)\n[PASS] testSettlementRefusesAnEmptyOrUnspannedSeries() (gas: 39083)\n[PASS] testSqrtIsExactOnEveryHorizonDifficultyUses() (gas: 903275)\n[PASS] testSqrtPins() (gas: 123131)\n[PASS] testTwapRefusesTimeRunningBackwards() (gas: 9132)\n[PASS] testV2TwapAndSpotOfADustRatioAreRefused() (gas: 220677)\n[PASS] testV3TwapRefusesAMeanTickOutsideTheRange() (gas: 27255)\n[PASS] testV4SeriesWithADustExtremeIsRefusedNotSettledAtZero() (gas: 33519)\nSuite result: ok. 31 passed; 0 failed; 0 skipped; finished in 124.84ms (1.12s CPU time)\n\nRan 12 tests for test/HoldRule.t.sol:HoldRuleTest\n[PASS] testABreachIsNeverReplacedByANonBreachInsideTheGap() (gas: 1653878)\n[PASS] testABreachReplacesANonBreachInsideTheGap() (gas: 1661691)\n[PASS] testABuyCallWithAnUnreadableBalanceIsVoidSold() (gas: 1484869)\n[PASS] testASellAuthorMayDumpTheirWholeRemainingBalance() (gas: 1622310)\n[PASS] testASellAuthorWhoBuysBackTheirWholePostBalanceIsStillRight() (gas: 1717897)\n[PASS] testASellCallWithAnUnreadableBalanceStillSettlesOnPrice() (gas: 1510057)\n[PASS] testASellCallsBalanceIsNeverAnAdverseReading() (gas: 1360897)\n[PASS] testAWrongSellCallForfeitsWhateverTheBalanceDid() (gas: 1426628)\n[PASS] testAnEqualReadingInsideTheGapIsRefused() (gas: 1031930)\n[PASS] testAtTheCapAHigherReadingCannotLiftABuyCallsMinimum() (gas: 3939441)\n[PASS] testAtTheCapOnlyAMoreAdverseReadingGetsIn() (gas: 4186133)\n[PASS] testBuyCallHasNoToleranceDownwards() (gas: 1570913)\nSuite result: ok. 12 passed; 0 failed; 0 skipped; finished in 124.96ms (15.43ms CPU time)\n\nRan 9 tests for test/CompanionFailures.t.sol:TreasuryFailuresTest\n[PASS] testDripFailsWhenTheHookCannotTakeTheFunds() (gas: 673929)\n[PASS] testDripIsPermissionlessAndCompounds() (gas: 518661)\n[PASS] testDripOfDustRoundsToZeroAndReverts() (gas: 258318)\n[PASS] testDripWithNothingHeldReverts() (gas: 54033)\n[PASS] testInitOnlyByTheNamedHookAndOnlyOnce() (gas: 623926)\n[PASS] testInitRefusesTheZeroHook() (gas: 556415)\n[PASS] testNoWithdrawOrAdminSurface() (gas: 274868)\n[PASS] testSecondDripOnTheSameDayRevertsAndTheNextDayWorks() (gas: 372660)\n[PASS] testTreasuryRefusesEth() (gas: 71164)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 125.46ms (1.78ms CPU time)\n\nRan 27 tests for test/HookBoundaries.t.sol:HookBoundariesTest\n[PASS] testAfterSwapRejectsZeroOrWrongSignedOutput() (gas: 120869)\n[PASS] testCallCannotBeAChildOfItsOwnCallOrAClosedThesis() (gas: 2942983)\n[PASS] testChildAtTheSevenDayDeadlineCanReleaseTheThesis() (gas: 1486425)\n[PASS] testChildlessThesisForfeitureBoundaryAndKeeperPayment() (gas: 862151)\n[PASS] testEmptyCallAndThesisTextAreRejectedAtomically() (gas: 841850)\n[PASS] testEveryEnabledCallbackRejectsAStranger() (gas: 130741)\n[PASS] testExactOutputPlainBuyHasNoHookDelta() (gas: 54500)\n[PASS] testExactOutputQuietSellsAndNotedTradesAreRejected() (gas: 120205)\n[PASS] testFactoryCannotBindASecondPool() (gas: 73530)\n[PASS] testForeignPoolRejectedByBothSwapCallbacks() (gas: 85794)\n[PASS] testForgedNoteAndExemptionAreRejected() (gas: 153341)\n[PASS] testFuzzBondRoundTripReturnsOnlyTheBond(uint256) (runs: 1000, μ: 838171, ~: 838176)\nLogs:\n  Bound result 1499999999999999794\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58964, ~: 58968)\nLogs:\n  Bound result 6219629502205629125\n\n[PASS] testHorizonEdgesAndTargetEdges() (gas: 2708698)\n[PASS] testManagerCannotInventAnUnlockOutsideAnActiveOperation() (gas: 43865)\n[PASS] testMissingParentAndSameSideCounterAreRejectedAtomically() (gas: 2534248)\n[PASS] testNoDataBondCannotBeStolenOrClaimedTwice() (gas: 901173)\n[PASS] testObservationAndSettlementWindowExactEdges() (gas: 1479155)\n[PASS] testOnlyJudgeCanDrawOrPayAndZeroFundingIsRefused() (gas: 79405)\n[PASS] testRefundRequiresNextDayAuthorAndSingleUse() (gas: 841825)\n[PASS] testRetractAtHorizonIsTooLateAndBeforeItIsFinal() (gas: 1344006)\n[PASS] testSealMaximumAgeUsesSealedPriceDespiteExpiredPostingCheckpoint() (gas: 1102590)\n[PASS] testSealMinimumAgeIsInclusiveAndFailedRevealPreservesCommitment() (gas: 1553352)\n[PASS] testSealRejectsZeroHashAndDuplicateWithoutTakingAnotherStamp() (gas: 481566)\n[PASS] testSweepBoundaryMovesClaimsWithoutWithdrawingThem() (gas: 308016)\n[PASS] testTextLimitIsInclusiveForBothForms() (gas: 2027590)\n[PASS] testUnknownNotesFailEveryLifecycleEntry() (gas: 164079)\nSuite result: ok. 27 passed; 0 failed; 0 skipped; finished in 130.70ms (212.49ms CPU time)\n\nRan 1 test for test/RouterInvariant.t.sol:RouterInvariantTest\n[PASS]\nRouterInvariantTest invariants:\n[PASS] invariant_bindingsPinned\n[PASS] invariant_everyNoteCameThroughTheRouter\n[PASS] invariant_managerBacksTheHooksClaims\n[PASS] invariant_routerKeepsNothing\n RouterInvariantTest invariants (runs: 48, calls: 1920, reverts: 2)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 210   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 216   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 425   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 231   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 224   | 2       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 192   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 216   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 206   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1\n  Bound result 2\n  Bound result 14883\n  Bound result 0\n  Bound result 500000000000000000000\n  Bound result 4143\n  Bound result 16777216\n  Bound result 2\n  Bound result 1\n  Bound result 300000\n  Bound result 94\n  Bound result 82\n  Bound result 2548542073\n  Bound result 0\n  Bound result 0\n  Bound result 7594\n  Bound result 1666\n  Bound result 10\n  Bound result 2\n  Bound result 2000000000000000000000\n  Bound result 10000\n  Bound result 97\n  Bound result 65\n  Bound result 1\n  Bound result 0\n  Bound result 20\n  Bound result 0\n  Bound result 4231\n  Bound result 13465\n  Bound result 96\n  Bound result 0\n  Bound result 2\n  Bound result 99\n  Bound result 2\n  Bound result 3000000000000000000\n  Bound result 0\n  Bound result 18\n  Bound result 0\n  Bound result 1000000\n  Bound result 10369\n  Bound result 7\n  Bound result 2\n  Bound result 1609\n  Bound result 52049\n  Bound result 76\n  Bound result 1522\n  Bound result 2\n  Bound result 0\n  Bound result 49999999999580971900880\n  Bound result 1000000000000000000000\n  Bound result 1\n  Bound result 2\n  Bound result 5819\n  Bound result 1\n  Bound result 14289117740432\n  Bound result 0\n  Bound result 27\n  Bound result 0\n  Bound result 366331029684209600228\n  Bound result 1\n  Bound result 8434\n  Bound result 2989\n  Bound result 9\n  Bound result 1\n  Bound result 789\n  Bound result 1\n  Bound result 19126\n  Bound result 53601\n  Bound result 96\n  Bound result 1980\n  Bound result 1498142187\n  Bound result 2\n  Bound result 554\n  Bound result 2\n  Bound result 3091\n  Bound result 2\n  Bound result 2\n  Bound result 13056\n  Bound result 15161\n  Bound result 96\n  Bound result 251\n  Bound result 0\n  Bound result 6881\n  Bound result 1\n  Bound result 2\n  Bound result 1677501420145433607463\n  Bound result 56085\n  Bound result 5\n  Bound result 1\n  Bound result 0\n  Bound result 96010562111572294072\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 481.01ms (470.31ms CPU time)\n\nRan 1 test for test/TreasuryInvariant.t.sol:TreasuryInvariantTest\n[PASS]\nTreasuryInvariantTest invariants:\n[PASS] invariant_balanceIsGiftsMinusDrips\n[PASS] invariant_dripNeverExceedsTwoPercent\n[PASS] invariant_holdsNoEth\n[PASS] invariant_hookHoldsExactlyTheDrips\n[PASS] invariant_hookIsPinned\n[PASS] invariant_lastDripDayMatchesTheLastSuccessfulDrip\n TreasuryInvariantTest invariants (runs: 256, calls: 12288, reverts: 0)\n\n╭-----------------+-----------+-------+---------+----------╮\n| Contract        | Selector  | Calls | Reverts | Discards |\n+==========================================================+\n| TreasuryHandler | advance   | 2529  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2450  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2369  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2360  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2580  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 6455\n  Bound result 1319745324\n  Bound result 1710\n  Bound result 3000000000000000000\n  Bound result 177095\n  Bound result 240\n  Bound result 6963\n  Bound result 5911346279424586\n  Bound result 1321\n  Bound result 95884503747043872787054\n  Bound result 2465\n  Bound result 1860\n  Bound result 1337181797\n  Bound result 70000000000000000\n  Bound result 6606\n  Bound result 1086394138\n  Bound result 7885\n  Bound result 86\n  Bound result 128\n  Bound result 24041608\n  Bound result 128\n  Bound result 9348\n  Bound result 9004436776734949377\n  Bound result 43\n  Bound result 659126438197451119346938851064455196655408477541\n  Bound result 387\n  Bound result 27\n  Bound result 3588405958779090970\n  Bound result 400000000000000000000\n  Bound result 1060525612\n  Bound result 983705629143020943990136\n  Bound result 8461891782872549115\n  Bound result 1000000000000000000000000000000\n  Bound result 6000000000000000000000\n  Bound result 6202\n  Bound result 10000\n  Bound result 81507131544982335661065\n  Bound result 2989\n  Bound result 120471\n  Bound result 1009943270\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.07s (1.06s CPU time)\n\nRan 5 tests for test/HookAccountingInvariant.t.sol:HookAccountingInvariantTest\n[PASS] invariant_everyImdClaimHasExactlyOneObligation() (runs: 128, calls: 10240, reverts: 0)\n\n╭-----------------------+-------------------+-------+---------+----------╮\n| Contract              | Selector          | Calls | Reverts | Discards |\n+========================================================================+\n| HookAccountingHandler | abandonJudging    | 506   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 545   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 522   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 504   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 493   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 523   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 509   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 453   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 543   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 499   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 514   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 998   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 518   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 520   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 516   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 511   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 505   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 548   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 513   | 0       | 0        |\n╰-----------------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 250000000000000000\n  Bound result 99999000000000000006949\n  Bound result 51\n  Bound result 5\n  Bound result 700000000000000000\n  Bound result 49241037509312061048\n  Bound result 115788164\n  Bound result 4\n  Bound result 9750000000016635278\n  Bound result 2\n  Bound result 4\n  Bound result 1\n  Bound result 3\n  Bound result 5\n  Bound result 9750000000000000050\n  Bound result 3\n  Bound result 329155\n  Bound result 99999000000000002592001\n  Bound result 8\n  Bound result 93322733520040784981\n  Bound result 7\n  Bound result 1602565295\n  Bound result 5\n  Bound result 237198\n  Bound result 9\n  Bound result 9\n  Bound result 9750000000000016593\n  Bound result 4\n  Bound result 5\n  Bound result 10203\n  Bound result 8\n  Bound result 98000000000000002947\n  Bound result 9\n  Bound result 11\n  Bound result 7\n  Bound result 14760\n  Bound result 6\n  Bound result 20292\n  Bound result 3\n  Bound result 2\n  Bound result 99999999999999999998\n  Bound result 99999000000000000001474\n  Bound result 6135099903364526083\n  Bound result 5\n  Bound result 7\n  Bound result 23598488805786\n  Bound result 3\n  Bound result 8\n  Bound result 8\n  Bound result 13\n\n[PASS] testAccountingHandlerChecksGraceThenAllowsPaidRetry() (gas: 2362804)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n\n[PASS] testAccountingHandlerExercisesPayoutsForfeitsSealsDripsAndSweeps() (gas: 5432494)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1\n  Bound result 1\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 4\n  Bound result 3\n  Bound result 4000000000000000000\n  Bound result 5\n  Bound result 50000000000000000000\n\n[PASS] testAccountingHandlerModelsThesisCapAcrossClosureAndWeekRollover() (gas: 4227583)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n  Bound result 4\n  Bound result 1000000000000000000\n  Bound result 1000000000000000000\n\n[PASS] testAccountingHandlerRefusesChildWhoseCheckpointMaturesAfterGrace() (gas: 2660729)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 2000000000000000000\n  Bound result 3000000000000000000\n  Bound result 3\n  Bound result 10000000000000000000\n  Bound result 2000000000000000000\n  Bound result 5\n  Bound result 5\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.15s (7.15s CPU time)\n\nRan 27 test suites in 7.15s (10.33s CPU time): 285 tests passed, 0 failed, 2 skipped (287 total tests)\n","passed":true},{"durationMs":178,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"MarginaliaHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"MarginaliaHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"MarginaliaHook.claimDeposit(bytes32)\",\"MarginaliaHook.claimRefund(bytes32)\",\"MarginaliaHook.drawForJudging(uint32,uint256,bool)\",\"MarginaliaHook.fundPot(uint256)\",\"MarginaliaHook.observe(bytes32)\",\"MarginaliaHook.payJudged(uint32,bytes32[3])\",\"MarginaliaHook.retract(bytes32,string)\",\"MarginaliaHook.seal(address,(uint8,bytes32,address,bool),bytes32)\",\"MarginaliaHook.settle(bytes32)\",\"MarginaliaHook.settleThesis(bytes32)\",\"MarginaliaHook.sweep(uint8,uint32)\",\"MarginaliaHook.unlockCallback(bytes)\",\"MarginaliaJudge.abandonRequest(uint32)\",\"MarginaliaJudge.convertForfeits()\",\"MarginaliaJudge.init(address,address,bytes32,address)\",\"MarginaliaJudge.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaJudge.payJudged(uint32)\",\"MarginaliaJudge.requestJudging(uint32)\",\"MarginaliaPages.abandonClaim(bytes32)\",\"MarginaliaPages.burnPending(uint256,uint256)\",\"MarginaliaPages.buy(bytes32,uint256,uint256)\",\"MarginaliaPages.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaPages.recycle(bytes32)\",\"MarginaliaPages.requestClaim(string,uint256)\",\"MarginaliaPages.sell(bytes32,uint256,uint256)\",\"MarginaliaPages.settleClaim(bytes32)\",\"MarginaliaPages.unlockCallback(bytes)\",\"MarginaliaRouter.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaRouter.init(address,address)\",\"MarginaliaRouter.note((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.sellWithNote((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256)\",\"MarginaliaRouter.uniswapV3SwapCallback(int256,int256,bytes)\",\"MarginaliaRouter.unlockCallback(bytes)\",\"MarginaliaTreasury.drip()\",\"MarginaliaTreasury.init(address)\"],\"files\":{\".gitignore\":11,\"ADAPTATION.md\":637,\"README.md\":286,\"SPEC.md\":286,\"app/app.js\":286,\"app/index.html\":126,\"app/style.css\":57,\"brand/banner-ledger-1500x500.png\":5801,\"brand/pfp-manicule-400.png\":1390,\"brand/pfp-manicule-800.png\":5292,\"dependencies.json\":28,\"foundry.toml\":21,\"helper/.gitignore\":3,\"helper/package-lock.json\":737,\"helper/package.json\":20,\"helper/public/index.html\":94,\"helper/server.js\":90,\"helper/src/app.js\":257,\"jobs/launch-1-hook.json\":43,\"jobs/launch-2-contracts.json\":38,\"jobs/launch-A-implementations.json\":47,\"jobs/launch-A2-implementations.json\":99,\"jobs/launch-B-hook.json\":98,\"jobs/launch-C-pages.json\":34,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"keeper/.env.example\":27,\"keeper/.nvmrc\":1,\"keeper/.railwayignore\":3,\"keeper/README.md\":24,\"keeper/abi/erc20.json\":1,\"keeper/abi/factory.json\":1,\"keeper/abi/hook.json\":1,\"keeper/abi/judge.json\":1,\"keeper/abi/router.json\":1,\"keeper/package-lock.json\":222,\"keeper/package.json\":16,\"keeper/railway.json\":11,\"keeper/src/chain.js\":104,\"keeper/src/config.js\":53,\"keeper/src/db.js\":76,\"keeper/src/index.js\":89,\"keeper/src/sync.js\":90,\"keeper/src/tasks.js\":194,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":479,\"src/MarginaliaPricer.sol\":305,\"src/MarginaliaRouter.sol\":446,\"src/MarginaliaTreasury.sol\":53,\"src/MarginaliaTypes.sol\":127,\"src/OracleAttestation.sol\":221,\"src/interfaces/IIntake.sol\":15,\"src/interfaces/ILaunchFactory.sol\":49,\"test/ADVERSARIAL_COVERAGE.md\":59,\"test/AuditFindings.t.sol\":156,\"test/CompanionFailures.t.sol\":941,\"test/HoldRule.t.sol\":259,\"test/HookAccountingInvariant.t.sol\":776,\"test/HookBoundaries.t.sol\":475,\"test/HookReview.t.sol\":432,\"test/Implementations.t.sol\":96,\"test/JudgeOracle.t.sol\":270,\"test/LaunchAuditFindings.t.sol\":230,\"test/LaunchBinding.t.sol\":305,\"test/Lifecycle.t.sol\":696,\"test/Pages.t.sol\":422,\"test/PagesAudit.t.sol\":304,\"test/PagesDeployment.t.sol\":61,\"test/PagesOracle.t.sol\":171,\"test/PagesReview.t.sol\":226,\"test/PriceHistory.t.sol\":233,\"test/Pricer.t.sol\":88,\"test/PricerProperties.t.sol\":569,\"test/RevisionFindings.t.sol\":324,\"test/Round3Findings.t.sol\":218,\"test/RouterInvariant.t.sol\":248,\"test/TreasuryInvariant.t.sol\":167,\"test/fork/MainnetLaunch.t.sol\":374,\"test/fork/PagesMainnet.t.sol\":79,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":13217,"exitCode":0,"name":"slither","output":"[high/medium] weak-prng at src/MarginaliaPricer.sol:205: MarginaliaPricer.twap(MarginaliaTypes.VenueKind,bool,uint256,uint64,uint256,uint64) (src/MarginaliaPricer.sol#205-229) uses a weak PRNG: \"delta < 0 && delta % int256(dt) != 0 (src/MarginaliaPricer.sol#215)\"\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:414: Reentrancy in MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439):\n[high/medium] reentrancy-balance at src/MarginaliaRouter.sol:287: Reentrancy in MarginaliaRouter._pull(address,uint256) (src/MarginaliaRouter.sol#287-292):\n[high/high] uninitialized-state at src/MarginaliaHook.sol:536: MarginaliaHook.observations (src/MarginaliaHook.sol#106) is never initialized. It is used in:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:377: MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPages.sol:429: MarginaliaPages.burnPending(uint256,uint256) (src/MarginaliaPages.sol#429-443) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:299: MarginaliaRouter.unlockCallback(bytes) (src/MarginaliaRouter.sol#299-340) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:294: MarginaliaRouter._checkSubject(MarginaliaRouter.Job) (src/MarginaliaRouter.sol#294-297) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:176: MarginaliaPricer.settlePrice(MarginaliaTypes.Venue,bool,MarginaliaTypes.Observation[]) (src/MarginaliaPricer.sol#176-201) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:287: MarginaliaRouter._pull(address,uint256) (src/MarginaliaRouter.sol#287-292) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:205: MarginaliaPricer.twap(MarginaliaTypes.VenueKind,bool,uint256,uint64,uint256,uint64) (src/MarginaliaPricer.sol#205-229) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaTreasury.sol:42: MarginaliaTreasury.drip() (src/MarginaliaTreasury.sol#42-52) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaHook.sol:579: MarginaliaHook._broken(MarginaliaTypes.Note,uint256) (src/MarginaliaHook.sol#579-582) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaHook.sol:919: MarginaliaHook._unlock(uint8,address,uint256,uint256) (src/MarginaliaHook.sol#919-928) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaTreasury.sol:42: MarginaliaTreasury.drip() (src/MarginaliaTreasury.sol#42-52) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:135: MarginaliaPricer.postPrice(IPoolManager,MarginaliaTypes.Venue,address,bool,MarginaliaTypes.PriceWindow) (src/MarginaliaPricer.sol#135-155) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaRouter.sol:242: MarginaliaRouter._run(bool,uint256,uint256,uint256,MarginaliaRouter.XTrade,MarginaliaTypes.NoteParams,PoolKey) (src/MarginaliaRouter.sol#242-284) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/MarginaliaPricer.sol:295: MarginaliaPricer.fromSqrt(uint160,bool) (src/MarginaliaPricer.sol#295-304) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:603: Reentrancy in MarginaliaHook.settle(bytes32) (src/MarginaliaHook.sol#603-652):\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:215: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#215-226):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:855: Reentrancy in MarginaliaHook.payJudged(uint32,bytes32[3]) (src/MarginaliaHook.sol#855-874):\n[medium/medium] reentrancy-no-eth at src/MarginaliaJudge.sol:203: Reentrancy in MarginaliaJudge.requestJudging(uint32) (src/MarginaliaJudge.sol#203-226):\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:313: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#313-340):\n[medium/medium] reentrancy-no-eth at src/MarginaliaHook.sol:679: Reentrancy in MarginaliaHook.retract(bytes32,string) (src/MarginaliaHook.sol#679-695):\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:179: MarginaliaRouter.sellWithNote(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256).noX (src/MarginaliaRouter.sol#179) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:127: MarginaliaJudge.questionBody(uint32).allow (src/MarginaliaJudge.sol#127) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaHook.sol:611: MarginaliaHook.settle(bytes32).settlePrice (src/MarginaliaHook.sol#611) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:166: MarginaliaRouter.note(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256).noX (src/MarginaliaRouter.sol#166) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:257: MarginaliaRouter._run(bool,uint256,uint256,uint256,MarginaliaRouter.XTrade,MarginaliaTypes.NoteParams,PoolKey).job (src/MarginaliaRouter.sol#257) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:113: MarginaliaJudge.eligibleTheses(uint32).n (src/MarginaliaJudge.sol#113) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:205: MarginaliaRouter.validateVenue(MarginaliaTypes.NoteParams,PoolKey).t1 (src/MarginaliaRouter.sol#205) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:272: MarginaliaJudge.judgedOf(uint32).dup (src/MarginaliaJudge.sol#272) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:268: MarginaliaJudge.judgedOf(uint32).kept (src/MarginaliaJudge.sol#268) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaHook.sol:862: MarginaliaHook.payJudged(uint32,bytes32[3]).paidAmounts (src/MarginaliaHook.sol#862) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaJudge.sol:168: MarginaliaJudge._dec(uint256).n (src/MarginaliaJudge.sol#168) is a local variable never initialized\n[medium/medium] uninitialized-local at src/MarginaliaRouter.sol:204: MarginaliaRouter.validateVenue(MarginaliaTypes.NoteParams,PoolKey).t0 (src/MarginaliaRouter.sol#204) is a local variable never initialized\n[medium/medium] unused-return at src/MarginaliaPricer.sol:255: MarginaliaPricer._quoteSpot(IPoolManager,address,address) (src/MarginaliaPricer.sol#255-264) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(HUB_POOL_ID)) (src/MarginaliaPricer.sol#260)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (r0,r1,None) = IUniswapV2PairOracle(ref).getReserves() (src/MarginaliaPricer.sol#245)\n[medium/medium] unused-return at src/MarginaliaPages.sol:429: MarginaliaPages.burnPending(uint256,uint256) (src/MarginaliaPages.sol#429-443) ignores return value by manager.unlock(abi.encode(imdIn,minMargOut,zeroForOne,limit)) (src/MarginaliaPages.sol#442)\n[medium/medium] unused-return at src/MarginaliaHook.sol:930: MarginaliaHook.unlockCallback(bytes) (src/MarginaliaHook.sol#930-950) ignores return value by poolManager.settle() (src/MarginaliaHook.sol#945)\n[medium/medium] unused-return at src/MarginaliaHook.sol:294: MarginaliaHook.margPriceInImd() (src/MarginaliaHook.sol#294-297) ignores return value by (sqrtP,None,None,None) = poolManager.getSlot0(poolId) (src/MarginaliaHook.sol#295)\n[medium/medium] unused-return at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) ignores return value by (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (sqrtP_scope_0,None,None,None,None,None,None) = IUniswapV3PoolOracle(ref).slot0() (src/MarginaliaPricer.sol#241)\n[medium/medium] unused-return at src/MarginaliaRouter.sol:414: MarginaliaRouter._tradeV2(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#414-439) ignores return value by (r0,r1,None) = pair.getReserves() (src/MarginaliaRouter.sol#426)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:267: MarginaliaPricer._v3Cumulative(address) (src/MarginaliaPricer.sol#267-271) ignores return value by (cum,None) = IUniswapV3PoolOracle(pool).observe(ago) (src/MarginaliaPricer.sol#269)\n[medium/medium] unused-return at src/MarginaliaPages.sol:456: MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#456-478) ignores return value by manager.settle() (src/MarginaliaPages.sol#473)\n[medium/medium] unused-return at src/MarginaliaPages.sol:429: MarginaliaPages.burnPending(uint256,uint256) (src/MarginaliaPages.sol#429-443) ignores return value by (spot,None,None,None) = manager.getSlot0(key.toId()) (src/MarginaliaPages.sol#437)\n[medium/medium] unused-return at src/MarginaliaPricer.sol:233: MarginaliaPricer._spotInQuote(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaPricer.sol#233-252) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(v.ref)) (src/MarginaliaPricer.sol#237)\n[low/high] shadowing-local at src/MarginaliaHook.sol:859: MarginaliaHook.payJudged(uint32,bytes32[3]).pool (src/MarginaliaHook.sol#859) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.noteMeta(bytes32).week (src/MarginaliaJudge.sol#19) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.thesesOfWeek(uint32).week (src/MarginaliaJudge.sol#15) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.thesisPool(uint32).week (src/MarginaliaJudge.sol#12) shadows:\n[low/high] shadowing-local at src/MarginaliaJudge.sol:14: IHookJudge.drawForJudging(uint32,uint256,bool).week (src/MarginaliaJudge.sol#21) shadows:\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:266: MarginaliaJudge.judgedOf(uint32) (src/MarginaliaJudge.sol#266-279) has external calls inside a loop: (author,noteWeek,thesis,hasChild) = hook.noteMeta(ranked[i]) (src/MarginaliaJudge.sol#270)\n[low/medium] calls-loop at src/MarginaliaHook.sol:919: MarginaliaHook._unlock(uint8,address,uint256,uint256) (src/MarginaliaHook.sol#919-928) has external calls inside a loop: out = poolManager.unlock(data) (src/MarginaliaHook.sol#925)\n[low/medium] calls-loop at src/MarginaliaHook.sol:658: MarginaliaHook._settlementPrice(MarginaliaTypes.Note,MarginaliaTypes.Observation[]) (src/MarginaliaHook.sol#658-676) has external calls inside a loop: p = pricer().settlePrice(n.venue,buy,sample) (src/MarginaliaHook.sol#669-674)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:91: MarginaliaJudge.convertForfeits() (src/MarginaliaJudge.sol#91-106) has external calls inside a loop: out = hook.sellPotMarg(marg) (src/MarginaliaJudge.sol#96-100)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:266: MarginaliaJudge.judgedOf(uint32) (src/MarginaliaJudge.sol#266-279) has external calls inside a loop: (author,noteWeek,thesis,hasChild) = hook.noteMeta(ranked[i]) (src/MarginaliaJudge.sol#270)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:110: MarginaliaJudge.eligibleTheses(uint32) (src/MarginaliaJudge.sol#110-122) has external calls inside a loop: (None,None,None,hasChild) = hook.noteMeta(all[i]) (src/MarginaliaJudge.sol#115)\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:313: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#313-340):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:215: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#215-226):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:323: Reentrancy in MarginaliaHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/MarginaliaHook.sol#323-374):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:722: Reentrancy in MarginaliaHook._forfeit(MarginaliaTypes.Note,address) (src/MarginaliaHook.sol#722-729):\n[low/medium] reentrancy-benign at src/MarginaliaHook.sol:785: Reentrancy in MarginaliaHook._fund(uint256) (src/MarginaliaHook.sol#785-789):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:244: Reentrancy in MarginaliaPages._distributeFee(bytes32,MarginaliaPages.Subject,uint256) (src/MarginaliaPages.sol#244-265):\n[low/medium] reentrancy-benign at src/MarginaliaRouter.sol:377: Reentrancy in MarginaliaRouter._tradeV3(address,MarginaliaRouter.XTrade) (src/MarginaliaRouter.sol#377-404):\n[low/medium] reentrancy-benign at src/MarginaliaPages.sol:456: Reentrancy in MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#456-478):\n[low/medium] reentrancy-events at src/MarginaliaHook.sol:722: Reentrancy in MarginaliaHook._forfeit(MarginaliaTypes.Note,address) (src/MarginaliaHook.sol#722-729):\n[low/medium] reentrancy-events at src/MarginaliaHook.sol:698: Reentrancy in","passed":true},{"durationMs":909,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/MarginaliaPages.sol:161: `abi.encodePacked()` Hash Collision (2 places)\n[high] eth-send-unchecked-address at src/MarginaliaHook.sol:779: ETH transferred without address checks (3 places)\n[high] reentrancy-state-change at src/MarginaliaHook.sol:224: Reentrancy: State change after external call (29 places)\n[high] storage-array-memory-edit at src/MarginaliaHook.sol:556: Storage Array Edited with Memory\n[high] unsafe-casting at src/MarginaliaHook.sol:936: Unsafe Casting of integers\n[low] costly-loop at src/MarginaliaHook.sol:864: Costly operations inside loop (2 places)\n[low] internal-function-used-once at src/HookFlags.sol:26: Internal Function Used Only Once (3 places)\n[low] large-numeric-literal at src/Marginalia.sol:10: Large Numeric Literal (22 places)\n[low] literal-instead-of-constant at src/MarginaliaHook.sol:355: Literal Instead of Constant (59 places)\n[low] local-variable-shadowing at src/MarginaliaHook.sol:859: Local Variable Shadows State Variable\n[low] require-revert-in-loop at src/MarginaliaHook.sol:864: Loop Contains `require`/`revert` (2 places)\n[low] state-change-without-event at src/MarginaliaHook.sol:835: State Change Without Event (7 places)\n[low] state-no-address-check at src/MarginaliaRouter.sol:135: Address State Variable Set Without Checks\n[low] unchecked-return at src/MarginaliaHook.sol:718: Unchecked Return (8 places)\n[low] uninitialized-local-variable at src/MarginaliaHook.sol:667: Uninitialized Local Variable (3 places)\n[low] unused-import at src/MarginaliaHook.sol:10: Unused Import\n[low] unused-public-function at src/MarginaliaHook.sol:294: Public Function Not Used Internally (3 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"fab8838ce9317d5c419da4cfa005ae69d0e8a9d20049cb74f6261b6aec7b6382","verifiedTreeHash":"d3981e86bdcfb6ec87a4cc10efbe607706ace350","verifierVersion":"0.1.0+fb8278c5"},{"checks":[],"detail":"start commit produces tree 1416ad550f66 but its accepted dependencies produce 0863b8b616ce","evaluation":"checks","profile":"foundry","status":"rejected","submissionHash":"fda023596c5c4ad236f573c12eb5efc94741462063bcd87642925f816793e48c","verifiedTreeHash":"d560eeb7cd2e53ef648970eae9e43b3956f2d54b","verifierVersion":"0.1.0+fb8278c5"}]}