{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"b8def7a9-129f-4bfb-8b4e-e9a4327cf5a9","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"9f0a5a9dd5c939eba46e2d096021e70a227d03aef4880822ea60e621e7be6518","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":"0c03e8f27a5c1a6a5f0edd8afbdc11ebd48090b4419924a852990c839adc325d","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":"a24d05810f422a96da315a6c43ec48bad0fcdb9b3e9e82d4253672bfc4aa9c76","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":"219057aad9a491c338b052cf6aee46c827ae4975f4d1314201b3ed9a3cee399e","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":"353cdaddd10788469fc954fdd907ae13b1661b2b98d9431aa47c8f08c9ae6326","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":"dc7265283d85ee38b8c9223086c283d6500c0166c4fa012f74573e5b0c114066","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":"37b190a19aef9fa25ee4d57f40443e30abe02d58e922fcaded2627e7fc531a65","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":"779bd2797ceb5532d8142280704fbb6a30b9d4a6923cf0973024e98884986538","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"1b1f5ad2f6770d6d9cbf39ce8bafb03213b72088ab297049fce37616db05f223","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 v0.10 (src/MarginaliaPages.sol) on Ethereum mainnet: ONE contract, constructor (address hook, address annex, address intake, bytes32 action, address signer) = (0xf0457dd0cf526686190e4f057ba19db14d34a0cc the live MarginaliaHook of launch 1283, 0xd0c0d97aebe9194606bcc46ce56524eee4615543 the live MarginaliaAnnex of launch 1384, 0x1397434cd35e8a9C8aC312A61D3A285EB31dea56 the IdentityMD Intake, bytes32('oracle.request@oracle-1') the oracle action, 0x5598Aa9146215Bc13eb26f2c692Ad1461Fd32982 the IdentityMD oracle signer) — the same oracle constants the live hook holds as INTAKE, ACTION and ORACLE_SIGNER. This REPLACES the v0.9 Pages deployment of job 0925298b (old constants: 0.1 base, no cap, 90/5/5, no gate), which is not used. What it is: the page market of Marginalia, notes in the margin of every trade. A page of a writer's marginalia is the seat in that writer's room: the site delivers the writer's sealed notes and reasoning to page holders first. Pages are bought and sold against a CAPPED linear bonding curve priced in IMD 0xD34a99Bc0f67aE1bbd63C660e6d0b0dd03E263B7: page n costs min(BASE 0.05 IMD x n, CAP 10 IMD), so the line meets the cap at page CAP_PAGE 200 and every later page costs 10 IMD (priceOf sums the line segment and the flat tail; the curve reserve always covers every holder selling out at any depth). Pages are never transferable (buy and sell on the curve only) and a wallet holds at most MAX_PER_WALLET 10 pages of one subject (TooManyPages). BUY GATE (sell is never gated): eligible(wallet) is true when the wallet holds at least MARG_GATE 10,000 MARG (hook.token(), 0xfa0efea559bde229031c2b0a219472316647759c), OR has posted at least one note on the hook or the annex (the first two words of either contract's records(address) getter: score, posted), OR is on identity.md's settled WhitelistCurator at the fixed address WHITELIST 0xcB0b0531e86A9aC36Fa865cA8e3dbccF047FDA91 (contributedBy(address) > 0, read by staticcall, a failed read counts as not listed); otherwise buy reverts NotEligible. Every trade pays FEE_BPS = 10% of its value: ISSUER_BPS 80% of the fee to the issuer in IMD, BURN_BPS 10% of the fee buys MARG on the launch pool through the hook's PoolManager (a quiet buy, no hook fee; unlockCallback accepts only the PoolManager) and sends it to 0x000000000000000000000000000000000000dEaD, the remaining 10% of the fee goes to the hook's pools through hook.fundPot. 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 80% 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. The constructor reads no chain state (the launcher rehearses constructors in an empty EVM); it stores the five values (annex may be zero: that gate leg is then off). 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 (14 tests against the local hook, a whitelist mock etched at the fixed address, an annex-records mock, a local Intake mock and an EOA signer, incl. the capped curve at 210 pages, the per-wallet limit, every gate leg and ungated selling, the 200k callback stipend and replay/tamper refusals).","parentJobId":null,"planHash":"112ef6152999eacaee6510aa2b236331df48e7e2c24044b69ca8b4c48626bc67","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"b8def7a9-129f-4bfb-8b4e-e9a4327cf5a9","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1467-src-marginaliapages-sol"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51182","feedbackHash":"b625d538cf2c1252271346b8f6597edd345183df8ab9bed6308001d023d06113","nodeKey":"adapt_contract_project","submissionHash":"9f0a5a9dd5c939eba46e2d096021e70a227d03aef4880822ea60e621e7be6518","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52131","feedbackHash":"f88bfa236eca6922081425d108cca00bdee0f91c1e21ae75e2ac5408aab3a835","nodeKey":"audit_economics","submissionHash":"0c03e8f27a5c1a6a5f0edd8afbdc11ebd48090b4419924a852990c839adc325d","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51163","feedbackHash":"5688edada7124fbae4ab40e9ba15df050dcca914bbe3a1e6bcd5d8fe3f4d35fb","nodeKey":"audit_flow","submissionHash":"a24d05810f422a96da315a6c43ec48bad0fcdb9b3e9e82d4253672bfc4aa9c76","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51144","feedbackHash":"876d11082a7648fa8c41452b17d0b5f3687a208232605a2f044d2097ffcdc6a7","nodeKey":"audit_imported_code","submissionHash":"219057aad9a491c338b052cf6aee46c827ae4975f4d1314201b3ed9a3cee399e","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52170","feedbackHash":"7c63db642124aa6d63fd30e638f3b8fea40e05e7b005023f17746a4983013552","nodeKey":"audit_judge","submissionHash":"353cdaddd10788469fc954fdd907ae13b1661b2b98d9431aa47c8f08c9ae6326","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51367","feedbackHash":"e3d0185293c6dae24d5abf3b9b18bf73265ee38e3406cfdd791933748c864d9c","nodeKey":"audit_math","submissionHash":"dc7265283d85ee38b8c9223086c283d6500c0166c4fa012f74573e5b0c114066","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52261","feedbackHash":"ba2d2e7d409a909c2f053bdba497a83f32c8f9cbe9118a7883b6a07d5db4a717","nodeKey":"audit_permissions","submissionHash":"37b190a19aef9fa25ee4d57f40443e30abe02d58e922fcaded2627e7fc531a65","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52708","feedbackHash":"3b8853ff301bab54285e7a84c70608b2b1bda4ed80cdfc1f4e4418faccdd6eed","nodeKey":"manifest","submissionHash":"779bd2797ceb5532d8142280704fbb6a30b9d4a6923cf0973024e98884986538","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51322","feedbackHash":"259f2c769cf8f2ba59f70ed5ca9c6270894d77c84210177d714dbd68ca7b2892","nodeKey":"write_foundry_tests","submissionHash":"1b1f5ad2f6770d6d9cbf39ce8bafb03213b72088ab297049fce37616db05f223","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"352cc782b1b53997be99be75edbe41f60c68a7eb23cf486fd42b30fa2fb3f5aa","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"de319b702da6aa2e","findings":[{"citation":"resolved","description":"Economic Security / Invariant / Flow Gap (periphery x first principles). eligible() checks only the wallet's MARG balance at the instant of buy(); MARG is freely transferable, and buy() (line 275-276: `if (pagesOf[subject][msg.sender] + amount > MAX_PER_WALLET) revert TooManyPages(); if (!eligible(msg.sender)) revert NotEligible();`) records nothing about the MARG that qualified the wallet. So one 10,000 MARG balance qualifies any number of fresh wallets in sequence, even within a single transaction from a contract that deploys child wallets. The contract's stated guarantees are that 'a wallet holds at most MAX_PER_WALLET pages of one writer, so no wallet can corner a room' and that 'Buying is gated so that every room costs a sybil something per wallet' (natspec lines 41-45, 239). On mainnet hook.margPriceInImd() reads 2.9685e13 (IMD per MARG, 1e18 scale) at the time of review, so the whole 10,000 MARG gate costs ~0.297 IMD once, and every additional wallet costs nothing but gas. The per-wallet cap is the only thing that spreads the cheap early pages of the linear segment among many readers; with it bypassed, the writer (whose issuer share of 80% of the fee comes back to them, so their own trades cost 2% instead of 10%) or any insider can take pages 1..200 of a room through 20 throwaway wallets and dump them on later readers.","line":241,"path":"src/MarginaliaPages.sol","reproduction":"Local hook fixture of test/Pages.t.sol (PagesFixture), verified with forge: the writer is address W (subject = pages.subjectOf(W)). W deploys 20 contracts S_i, each funded with 150 IMD; for i in 0..19: W transfers the same 10,000 MARG to S_i, S_i approves IMD and calls pages.buy(subject, 10, max) (eligible via the MARG leg), then S_i transfers the 10,000 MARG back to W. Result: supply 200, all held by W's wallets, for value 1005 IMD + fee 100.5 IMD of which 80.4 IMD returns to W as payee (net ~1025.1 IMD). Six real readers then buy 10 pages each at the cap (pages 201..260): they pay 660 IMD (600 value + 60 fee, 48 of which goes to W). W's wallets sell their 200 pages (supply 260 -> 60): they receive 1362.15 IMD plus 121.08 IMD issuer share. W's net profit: +506.13 IMD (forge log 'writer pnl' -5493.87 IMD includes the 6,000 IMD W sent to fund the six readers). The readers' 60 pages are now pages 1..60 and sellPrice(subject, 60) returns 91.5 value - 9.15 fee = 82.35 IMD for the 660 IMD they paid. Expected: the second wallet, qualified only by MARG the first wallet already used, is not eligible (or the per-wallet cap otherwise holds per actor); actual: all 20 buys succeed. Fix direction (a design decision for the author): make the MARG leg cost something per wallet, e.g. lock/escrow MARG_GATE MARG in the contract per wallet while it holds pages, or drop the MARG leg and keep the whitelist/notes legs.","severity":"medium","snippet":"        if (IERC20(hook.token()).balanceOf(wallet) >= MARG_GATE) return true;","title":"MARG gate leg is reusable across wallets: one ~0.3 IMD stash of 10,000 MARG lets one actor hold unlimited pages of a room, defeating MAX_PER_WALLET and enabling a writer pump-and-dump on their own roo"}],"hash":"0c03e8f27a5c1a6a5f0edd8afbdc11ebd48090b4419924a852990c839adc325d","nodeId":"53f53932-3c08-4fcc-a7f3-c23c00e61c5a","outcome":"completed","summary":"I found one defect in the Pages economics, with a reproduction. It's recorded in `.imd-findings.json` with 53 coverage rows. I changed no files; the scratch tests I used to confirm it are deleted.\n\n**Finding 1 (medium): one 10,000 MARG balance makes any number of wallets eligible, so the 10-pages-per-wallet limit doesn't hold** (`src/MarginaliaPages.sol:241`)\n\n- **Cause:** `eligible()` only checks the wallet's MARG balance at the moment it buys. MARG can be transferred freely, so the same 10,000 MARG can pass the gate for one wallet after another, even inside a single transaction.\n- **Cost:** on mainnet `hook.margPriceInImd()` reads about 2.97e13, so the whole 10,000 MARG costs about 0.3 IMD. After that, each extra wallet costs only gas. That breaks the contract's own promise that \"no wallet can corner a room\" and that every room \"costs a sybil something per wallet\".\n- **Reproduction (run with forge on the local test setup):** a writer uses 20 throwaway wallets and one MARG stash to buy pages 1–200 of their own room, costing about 1,025 IMD after their own 80% fee share comes back. Six real readers then buy pages 201–260 at the 10 IMD cap, paying 660 IMD. The writer sells all 200 pages and makes **+506.13 IMD**. The readers can now get back only **82.35 IMD** for their 60 pages.\n- **Fix:** this is a design call for the author. Options are to lock or escrow 10,000 MARG per wallet while it holds pages, or to drop the MARG route and keep the whitelist and posted-a-note routes.\n\n**What holds:**\n- **Curve reserve:** it always equals the cost of buying every page from zero to the current supply, so the reserve covers every holder selling out at any depth, including past the cap.\n- **IMD accounting:** the contract's IMD always covers reserves plus unclaimed writer shares plus any MARG burns waiting for retry.\n- **Fee split:** each fee divides exactly 80/10/10.\n- **Selling:** it is never gated.\n- **Claim flow:** the oracle callback, escrow refund to the asker, recycling and abandonment all behave as specified.\n- **Live mainnet dependencies:** the hook and annex `records`, the whitelist `contributedBy`, and `hook.token()`, `hook.imd()` and `hook.poolManager()` all answered as expected. The Intake price is 0.5 IMD, under the 1 IMD limit. The oracle signer has no code, so it's a plain wallet key.\n- **Callback gas:** the worst case for a successful claim (a payee and an asker who both start with zero IMD) used about 180k gas in the local mock, measured including the mock's own call overhead. That's under the 200k limit but close, so it's worth watching. A real IMD transfer to a new address costs about the same as the mock token (about 52.8k gas estimated).\n\n**What I looked at and left out:**\n- **Unprotected MARG burn:** each trade's burn and `burn()` buy MARG with no minimum output. A sandwich attack isn't profitable: each trade burns at most 1 IMD, and the attacker pays about 5.5% in pool and hook fees on their own trades.\n- **Blocking the owner's claim:** an attacker can jump ahead of the handle owner's claim request at 0.5 IMD a try, but the owner can avoid that by sending through a private mempool.\n\n**Coverage:** all 9 Pages entry points are traced. So are the hook functions Pages relies on: `fundPot`, `unlockCallback`, and the no-fee MARG buy path through `beforeSwap`/`afterSwap`. All other hook, annex, router, judge and treasury entry points are marked `unreached`, since they are outside this area.\n\nThe working tree has untracked files I didn't create: shell dotfiles, `.claude/`, `.idea`, `.vscode`, `.mcp.json` and a `.gitmodules`. I left them alone, but the rules say never to leave a git submodule, so you may want to remove `.gitmodules` before submitting.","treeHash":null,"usage":{"cachedInputTokens":2951036,"inputTokens":50,"model":"claude-opus-5-5","outputTokens":44365,"runtime":"claude","turns":26,"wallClockMs":590752}},{"artifacts":[],"attempt":1,"bundleHash":"0a5e24ffc9206d64d01095f20ef58c6058cd5db08a4a5c45f972ea942e3fdfda","device":"3ac34bfb544bbc10","findings":[],"hash":"1b1f5ad2f6770d6d9cbf39ce8bafb03213b72088ab297049fce37616db05f223","nodeId":"8804468a-59fd-44e1-a927-d480a602e8d4","outcome":"completed","summary":"Added 28 checks under `test/` covering failure paths, oracle verification, reentrancy, fuzzing, and stateful accounting.\n\n- `forge build`: passed.\n- `forge test`: **373 passed, 0 failed, 2 optional fork suites skipped**.\n- Pages invariant: **24,576 calls**, zero unexpected reverts, successful full withdrawals.\n\nNo confirmed contract defects. Details are in [coverage notes](/home/identitymd6/.identitymd/work/b8def7a9-129f-4bfb-8b4e-e9a4327cf5a9/8804468a-59fd-44e1-a927-d480a602e8d4/test/PAGES_TEST_COVERAGE.md).","treeHash":"ec7e55e54212e6b82919388db90f21fb39a1da68","usage":{"cachedInputTokens":13523328,"inputTokens":218425,"model":"gpt-6-astra","outputTokens":60593,"runtime":"codex","turns":25,"wallClockMs":2867676}},{"artifacts":[],"attempt":2,"bundleHash":null,"device":"91067b3439961e55","findings":[{"citation":"resolved","description":"_distributeFee runs on every trade and unconditionally executes _burnMarg(toBurn), an exact-input IMD->MARG swap on the launch pool with the extreme sqrtPriceLimit (MIN_SQRT_PRICE+1 / MAX_SQRT_PRICE-1) and a strict check that the whole input was consumed and some MARG came out (line 450). Whenever that swap cannot fill, the whole trade reverts: (a) the single-range launch pool sells out of MARG (a large buy runs the standing price to the top of its only position; the PoolManager then reverts PriceLimitAlreadyExceeded, or the hook's afterSwap reverts PartialFill when nothing is filled), or (b) every LP withdraws (the hook's manifest says it never restricts withdrawals; the swap yields zero and the hook reverts PartialFill, wrapped by the PoolManager). The contract holds the full curve reserve (reserveOf) in IMD and the spec promises 'selling is never gated: a holder can always leave', yet sell() cannot pay out because the 10%-of-fee burn is a hard precondition of the payout path. Buys revert too, so the market is frozen for as long as the pool state lasts; nobody needs any privilege to cause it (a whale buy, or LPs leaving). Suggested fix: make the burn best-effort or deferred: accrue the burn share into a pendingBurn balance and let anyone call a separate burn() that performs the swap (with its own revert isolated), so the sell path depends only on the IMD the contract already holds; alternatively wrap _burnMarg in try/catch and keep the IMD for a later burn.","line":292,"path":"src/MarginaliaPages.sol","reproduction":"State: launch pool with one range (as the test fixture: liquidity 10M in [-6000, 6000] at 1 MARG = 1 IMD). alice (holding MARG_GATE) buys 5 pages of subjectOf(carol): reserveOf = 0.75 IMD held by the contract. Then a third party swaps 400,000,000 IMD into MARG on the launch pool (quiet buy, allowed by the hook), running the price to the top of the range. Now alice calls sell(subject, 1, 0). Expected: alice receives 0.25 - 0.025 = 0.225 IMD from the reserve. Actual: revert PriceLimitAlreadyExceeded from PoolManager.swap inside MarginaliaPages.unlockCallback (trace: sell -> _distributeFee -> _burnMarg -> unlock -> unlockCallback -> swap). Variant: instead of the whale buy, the LP removes its 10M liquidity; sell reverts with WrappedError(hook, afterSwap, PartialFill). Buys revert the same way. Proof test: test/scratch/PagesSellLiveness.t.sol, both tests fail on this code.","severity":"medium","snippet":"        if (toBurn > 0) _burnMarg(toBurn);","title":"Every sell and buy reverts while the MARG launch pool cannot fill the fee burn swap: holders cannot exit although the reserve is held"},{"citation":"resolved","description":"requestClaim(handle, tweetId) is permissionless and the question body (lines 308-316) asks the panel for 'the single Ethereum address written in the text field' of any tweet whose user.screen_name is the handle. It does not require the tweet to declare that address as the handle's Marginalia / payout wallet, nor to mention Marginalia, the Pages contract or a claim at all. Any tweet the handle ever posted that quotes one address (a donation address, a contract they discussed, a scammer they warned about, an address of a friend) therefore yields a valid attestation, and onOracleResult makes that address the payee permanently (s.payee = wallet; requestClaim then reverts AlreadyClaimed for ever, line 345), paying it the whole escrow at once and 80% of every future fee. A stranger, including the owner of the quoted address, can submit such a tweet id; the owner of the handle cannot undo it and there is no second claim ('one successful claim per subject ever'). The escrow and all future issuer fees of that handle go to the wrong party. Suggested fix: make the question demand an explicit claim statement (e.g. the tweet must contain a fixed phrase naming this contract / 'marginalia' together with the address, and the panel must answer zero otherwise), include the required phrase in definitions, and consider letting the current payee (not a stranger) re-point via a later attested tweet.","line":391,"path":"src/MarginaliaPages.sol","reproduction":"State: handle 'victim' has 20 pages bought (alice 10, bob 10), escrow 0.84 IMD, payee zero. The handle's owner once tweeted 'do not send funds to 0xSCAM...' (tweet id 777). bob (a stranger) calls requestClaim('victim', 777) paying 0.5 IMD. The panel, following questionBody literally, answers 0xSCAM; the Intake calls onOracleResult(rid, attestation{answer=0xSCAM, panelSize 5, quorum 4, agreed 5}, sig). Expected: the handle's owner controls the payee or can contest. Actual: payeeOf(subject) == 0xSCAM, 0xSCAM receives 0.84 - 0.5 = 0.34 IMD, bob is reimbursed 0.5 from the escrow, every later trade pays 0xSCAM 80% of the fee, and the owner's requestClaim('victim', 778) reverts AlreadyClaimed. Contract-level demonstration (mock intake delivering such an answer): test/scratch/Probe.t.sol::testAnyAnsweredAddressIsPermanent passes on this code, showing the contract accepts and permanently applies any attested address.","severity":"medium","snippet":"        s.payee = wallet;","title":"A handle is bound forever to whatever address any of its tweets ever contained; anyone can trigger it and the real owner is locked out"},{"citation":"resolved","description":"escrowSince is set once, at the first escrowed fee (line 289), and never advanced by later deposits. 90 days after a single tiny first buy, anyone may call recycle(subject) and the entire escrow, including the issuer's share of trades made moments before, goes to the hook's pools. A handle whose room only became active late loses its accrued share to the pools even though no reasonable claim window elapsed for that income, and since recycle is permissionless a bot can do it in the same block as a large buy. This matches the brief's wording ('90 days after the first buy'), so it is reported as a design hazard rather than a deviation; the adapter may want escrowSince to track the latest deposit, or to recycle only escrow older than the window.","line":419,"path":"src/MarginaliaPages.sol","reproduction":"alice buys 1 page of subjectOfHandle('fresh') at t0 (escrow 0.004 IMD, escrowSince = t0). At t0 + 90 days bob buys 10 pages (escrow becomes 0.264 IMD). In the same block anyone calls recycle(subject). Expected (by intent): only escrow that waited 90 days unclaimed is recycled. Actual: all 0.264 IMD is sent to hook.fundPot; escrow is 0 (test/scratch/Probe.t.sol::testRecycleSweepsFreshEscrow logs 'escrow before 264000000000000000 after 0').","severity":"low","snippet":"        if (block.timestamp < uint256(s.escrowSince) + CLAIM_WINDOW) revert TooEarly();","title":"recycle() sweeps escrow deposited seconds earlier, because the 90-day window is measured from the first buy only"},{"citation":"resolved","description":"buy/sell take a raw bytes32 subject and never check that it is an address id (top 96 bits zero, non-zero) or the hash of a normalised handle. For any other id payeeOf returns zero (line 193), so 80% of every fee is escrowed under an id that requestClaim can never target (it only derives ids from a validated handle), and the escrow can only be recycled to the pools after 90 days. A buyer who mis-derives the id (an un-normalised handle hashed off chain, a hash of '@handle', a different prefix, or bytes32(0)) buys pages of a room that no one will ever own, with no revert; the curve reserve is still returnable by selling, but the fee share is unrecoverable by the intended issuer. Suggested fix: refuse ids that are neither an address id nor registered by a prior subjectOfHandle-derived buy (e.g. a `known[subject]` flag set by a `buyHandle(string)` entry point), or at least reject bytes32(0).","line":248,"path":"src/MarginaliaPages.sol","reproduction":"alice (eligible) calls buy(keccak256('not a handle'), 10, max). Expected: revert, the id is not a subject. Actual: succeeds; subjects[id].escrow = 0.44 IMD, payeeOf(id) = 0, requestClaim cannot reach it, only recycle after 90 days. Same with buy(bytes32(0), 1, max): escrow 0.004 IMD, payee zero (test/scratch/Probe.t.sol::testArbitrarySubjectEscrowUnclaimable).","severity":"low","snippet":"    function buy(bytes32 subject, uint256 amount, uint256 maxCost) external nonReentrant {","title":"buy() accepts any bytes32 as a subject; escrow of non-address, non-handle ids (including bytes32(0)) can never be claimed"},{"citation":"resolved","description":"Only one request per subject may be in flight and anyone may open it. A griefer who front-runs the handle owner's requestClaim with a bogus tweet id makes the owner's transaction revert ClaimPending; while the panel has not answered (minutes normally, up to 3 days if the body is refused or the panel splits, since Intake v1 delivers no failure callback) the subject is locked. The cost is the oracle price per round, and the griefer's own price is not reimbursed on a zero answer, so it is bounded, but combined with recycle() it has a loss path: when escrowSince + 90 days has passed and a legitimate claim is pending but late, anyone can call abandonClaim(subject) at requestedAt + 3 days and recycle(subject) in the same transaction, sending the escrow to the pools before the owner can re-request; a late but valid answer is then refused (UnknownRequest) and the owner's 0.5 IMD is lost as well.","line":346,"path":"src/MarginaliaPages.sol","reproduction":"Handle 'quiet' has escrow since day 0. Day 89: owner calls requestClaim('quiet', T). The panel does not deliver within 3 days (refused body, split panel, or withheld). Day 92: a bot sends one tx calling abandonClaim(subject) then recycle(subject). Expected: the owner's pending legitimate claim keeps the escrow safe until answered or until the owner gives up. Actual: both calls succeed (abandonClaim only checks the 3-day deadline, recycle only checks no pending claim and the 90-day window), escrow goes to hook.fundPot, the late attestation is refused, the owner is out the 0.5 IMD price. The existing test testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims exercises exactly this order and asserts recycle succeeds right after abandonment.","severity":"low","snippet":"        if (claims[subject].requestId != bytes32(0)) revert ClaimPending();","title":"A pending claim is a public, 0.5 IMD per round lock on the subject; after ANSWER_DEADLINE anyone may abandon and immediately recycle before the owner retries"},{"citation":"resolved","description":"The callback verifies the signature and performs up to two IMD transfers plus six storage writes. Measured under the test fixture with an EOA signer and an OpenZeppelin ERC20 as IMD, a claimant with zero IMD balance and a fresh zero-balance payee: 145,927 gas of the 200,000 the Intake grants. If the live oracle signer is a contract (SignatureChecker falls back to an isValidSignature staticcall after the ECDSA attempt), or the live IMD token's transfer costs more than a plain ERC20, the headroom shrinks; a callback that runs out of gas is recorded as undelivered and not retried, the 0.5 IMD price is lost and the subject is locked for 3 days, and every retry fails the same way, so the handle could never be claimed. The reference's guidance is to only verify and store in the callback and pay in a later call of the user's own.","line":397,"path":"src/MarginaliaPages.sol","reproduction":"test/scratch/Probe.t.sol::testCallbackGas: 20 pages of 'gasy' bought, asker with 0 IMD after paying, payee a fresh address; intake.deliver with gas 200_000 logs 'ok true gas used 145927'. Replace the EOA signer with an ERC-1271 contract and the mock IMD with a token whose transfer costs ~30k more and the same delivery fails inside the stipend.","severity":"info","snippet":"        if (reimbursed > 0) imd.safeTransfer(c.claimant, reimbursed);","title":"onOracleResult uses ~146k of the 200k callback stipend in the worst local case; an ERC-1271 signer or a heavier IMD transfer narrows the margin"},{"citation":"resolved","description":"The brief pins the IdentityMD Intake version 1 (0x1397...) and the plain request(). The oracle-consumer reference says version 2 is the one to use for anything new and offers requestWithFailure so the consumer learns of a refused body (status 1) or a panel that did not agree (status 2). With v1 such outcomes never reach the contract: the asker's 0.5 IMD is spent, claims[subject] stays set, and the subject cannot be asked about again until abandonClaim after ANSWER_DEADLINE. The body also contains the keys head, guards.sources and consumer whose acceptance by the v1 schema the auditor could not verify offline (the live Judge uses head and guards.allow and is answered, so they are likely accepted). This is spec-conformant and reported for the adapter and the panel; no code change is required by the brief.","line":352,"path":"src/MarginaliaPages.sol","reproduction":"requestClaim('h', id) where the panel splits: no callback arrives. Expected (with v2 failure hook): the contract clears the claim at once. Actual: claims['h'] remains set, requestClaim reverts ClaimPending for 3 days, then anyone must call abandonClaim; the price is gone either way.","severity":"info","snippet":"        requestId = intake.request(","title":"Claims are pinned to Intake v1 request() with no failure callback, so refused bodies or split panels silently cost the price and lock the subject for 3 days"},{"citation":"resolved","description":"Read in full: src/MarginaliaPages.sol (every external/public state-changing function: buy, sell, requestClaim, onOracleResult, abandonClaim, recycle, unlockCallback, plus eligible/priceOf/payeeOf), src/OracleAttestation.sol, src/interfaces/IIntake.sol, test/Pages.t.sol, test/helpers/Fixture.sol, src/Marginalia.sol. Read in part (the parts Pages depends on): src/MarginaliaHook.sol (constructor, beforeInitialize/getPoolKey, beforeSwap/afterSwap quiet-buy path, fundPot/_fund, Record/records), src/MarginaliaAnnex.sol (Record layout), src/MarginaliaJudge.sol (questionBody and onOracleResult for comparison), launch.json. Not reached: the rest of MarginaliaHook, MarginaliaRouter, MarginaliaAnnex, MarginaliaPricer, MarginaliaTreasury (live, not part of this deployment), and the live mainnet bytecode of IMD 0xD34a..., Intake 0x1397..., WhitelistCurator 0xcB0b..., the Annex and the oracle signer (no RPC available; the fork rehearsal needs MAINNET_RPC_URL). Checks run: forge build (MarginaliaPages runtime 16,232 bytes, under EIP-170; no DELEGATECALL/CALLCODE/SELFDESTRUCT, no proxy, no initializer, no owner/pause/mint; constructor reads no chain state), forge test --match-path test/Pages.t.sol (14/14 pass), and the scratch probes in test/scratch. Verified sound: capped-curve arithmetic (exact, no rounding loss), reserve invariant reserveOf == priceOf(0, supply) on every path, fee split 80/10/10 exact for all curve values, per-wallet cap, ungated sell, buy gate legs, PoolManager-only unlockCallback (the manager only calls back its own unlocker), Intake-only callback with EIP-712 domain of this contract, chainId/quorum/panel checks, single consumption of the oracle request id, nonReentrant on every value-moving entry, one request in flight per subject, consistent claims/subjectOfRequest bookkeeping. Nothing launch-forbidden was found.","line":54,"path":"src/MarginaliaPages.sol","reproduction":"Not a defect. Commands: forge build --sizes; forge test --match-path test/Pages.t.sol; forge test --match-path test/scratch/Probe.t.sol -vv; forge test --match-path test/scratch/PagesSellLiveness.t.sol.","severity":"info","snippet":"contract MarginaliaPages is IUnlockCallback, ReentrancyGuard, OracleAttestationConsumer {","title":"Audit scope: contracts read, checks run, and what could not be reached"}],"hash":"219057aad9a491c338b052cf6aee46c827ae4975f4d1314201b3ed9a3cee399e","nodeId":"a0460073-4289-436d-a608-619b90492ce1","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds 8 entries. The working tree has no stray files (the findings file and `test/scratch/` are git-ignored; nothing else changed).\n\n**What I found in MarginaliaPages v0.10**\n\n- **Medium, sell liveness.** Every trade runs a MARG burn swap on the launch pool as a hard precondition. When that pool sells out of MARG or its LPs withdraw, `sell` reverts even though the contract holds the full curve reserve, so holders cannot leave. Buys freeze too. A self-contained proof under `test/scratch/PagesSellLiveness.t.sol` fails on the current code for exactly this reason in both scenarios.\n- **Medium, permanent wrong payee.** The claim question asks for any address written in any tweet by the handle, with no claim intent required. Anyone can submit such a tweet, the answered address becomes the payee forever, takes the escrow, and the real owner's claim reverts AlreadyClaimed.\n- **Low.** The 90-day recycle window runs from the first buy only, so escrow deposited seconds earlier is swept. Arbitrary bytes32 subjects accept buys whose escrow nobody can claim. A pending claim can be griefed, and abandon plus recycle in one transaction can take a late legitimate claimant's escrow.\n- **Info.** Callback uses about 146k of the 200k stipend in the worst local case. Intake v1 gives no failure callback. A scope entry lists what was read and what could not be reached.\n\n**Verified sound:** curve arithmetic and reserve invariant, fee split, per-wallet cap, every buy gate leg, PoolManager-only and Intake-only callbacks, replay and tamper refusals, reentrancy coverage. Nothing launch-forbidden is present: no delegatecall, selfdestruct, proxy, owner or post-deploy initialization, and the runtime is under the EIP-170 limit.\n\n**Not reached:** the live mainnet bytecode of IMD, the Intake, the WhitelistCurator, the Annex and the oracle signer, since no RPC was available, and the Router, Annex, Pricer and Treasury sources beyond the parts Pages depends on.","treeHash":null,"usage":{"cachedInputTokens":2023144,"inputTokens":514,"model":"claude-fable-5-1","outputTokens":48708,"runtime":"claude","turns":33,"wallClockMs":1177865}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"bf4c5b8707945096","findings":[],"hash":"2991c56f83b72c8cceae10099f34b7d5d52c393844022aebbad3de17979123bf","nodeId":"a0460073-4289-436d-a608-619b90492ce1","outcome":"failed","summary":"API Error: 400 Claude Code 2.1.226 does not support this model; version 2.1.251 or newer is required. Run 'claude update', or update the Claude desktop app, then try again.","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"claude","turns":1,"wallClockMs":2181}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fa99051b60a858d6","findings":[{"citation":"resolved","description":"Merged from audit_permissions (low) and audit_economics (medium): same root cause. eligible() returns true on a plain balanceOf snapshot at buy time; buy() (line 275-276) records nothing about the MARG that qualified the caller, and MARG is a plain OpenZeppelin ERC20 (src/Marginalia.sol). So the same 10,000 MARG can be passed wallet to wallet inside one transaction, each wallet buying MAX_PER_WALLET pages, and the actor ends with every page of the room and the bag back. The whitelist and posted-note legs are per wallet; the MARG leg is not. The natspec (lines 41-45, 239) and SPEC.md state 'no wallet can corner a room' and 'each path costs a sybil something per wallet'; the MARG leg costs ~0.25 IMD of capital once (hook.margPriceInImd() read 2.537e13 on mainnet on 2026-10-12, so 10,000 MARG is about 0.25 IMD) and nothing per additional wallet. Severity recalibrated to low: no funds move to a wrong party and nobody who did not choose to trade on the curve loses; the brief itself specifies the gate as a MARG balance, and the same cornering is available through the notes leg at roughly 0.1 IMD per wallet. What is broken is the stated per-wallet guarantee, which the site may rely on for sealed-note delivery. A fix keeping every number: hold MARG_GATE MARG in the contract per wallet while it holds pages, or drop the MARG leg; or correct the natspec/spec so the guarantee is not claimed.","line":241,"path":"src/MarginaliaPages.sol","reproduction":"Local PagesFixture (test/Pages.t.sol). Deploy 10 contract wallets W0..W9; give W0 exactly 10,000 MARG and 2,000 IMD. In one transaction, for i in 0..9: W_i approves IMD to Pages, calls pages.buy(subjectOf(carol), 10, max), then transfers all its MARG and IMD to W_{i+1} (W9 returns them to the actor). Expected under the natspec: a per-wallet cost is paid ten times or the actor cannot exceed 10 pages. Actual: every buy succeeds, subjects(subject).supply == 100, pagesOf(subject, W_i) == 10 for all i, and eligible(W_i) is false for all ten afterwards (no per-wallet cost was ever paid). Reproduced in test/scratch/Repro.t.sol testOneMargBagCornersRoom (passes on the current code, demonstrating the behaviour).","severity":"low","snippet":"        if (IERC20(hook.token()).balanceOf(wallet) >= MARG_GATE) return true;","title":"MARG leg of the buy gate reads a transferable balance: one 10,000 MARG bag qualifies unlimited wallets, so MAX_PER_WALLET does not bound one actor and the 'costs a sybil something per wallet' guarante"},{"citation":"resolved","description":"From audit_permissions. _distributeFee sets escrowSince only on the first accrual; recycle() (line 482, `s.escrowSince = 0;`) zeroes it. After CLAIM_WINDOW from the first buy, every later fee on an unclaimed handle is instantly recyclable (the author's own test testFirstBuyWindowRecyclesEvenRecentlyAccruedFees asserts this and it matches the brief's '90 days after the first buy'). But once anyone recycles, the next accrual restarts a full 90-day window, which the brief does not describe. Two handles with identical trade histories therefore give their issuers different outcomes depending on a third party's action, and whoever benefits from recycling (the hook's pools) can pick the favourable branch by sweeping right after each trade on handles past day 90 and never recycling exactly when it would restart the clock. Low: the amounts are issuer fees on handles nobody claimed in 90 days, the brief allows recycling them, and nothing is paid to a wrong party; the defect is an inconsistent rule. Fix: make the rule explicit and one-sided (never reset escrowSince in recycle, or always restart it on accrual from zero escrow and on recycle).","line":314,"path":"src/MarginaliaPages.sol","reproduction":"Local PagesFixture. Register handles A and B; alice buys 1 page of each at t0 (0.004 IMD escrow each, escrowSince = t0). At t0 + 90 days call recycle(A) (succeeds, escrowSince(A) = 0); do nothing to B. At t0 + 91 days bob buys 10 pages of A and 10 of B (identical 0.26 IMD issuer fee each). Expected: identical treatment. Actual: recycle(B) succeeds immediately (0.264 IMD to the pools) while recycle(A) reverts TooEarly and A's 0.26 IMD is protected until t0 + 181 days. Reproduced in test/scratch/Repro.t.sol testEscrowClockDependsOnStranger (passes on the current code, demonstrating the behaviour).","severity":"low","snippet":"            if (s.escrowSince == 0) s.escrowSince = uint64(block.timestamp);","title":"Escrow clock is one-sided: escrowSince is set only when zero and reset only by recycle(), so whether a handle's newly accrued issuer fees are protected for 90 days or recyclable at once depends on whe"},{"citation":"resolved","description":"From audit_flow. An address subject pays itself without a claim. When the subject is the Pages contract itself, _distributeFee's `IERC20(imd).safeTransfer(payee, toIssuer)` moves IMD from Pages to Pages: the share stays in the contract but is tracked by nothing (not reserveOf, not escrow, not pendingBurn) and can never leave, so the accounting identity the test suite asserts (balance == sum reserve + sum escrow + pendingBurn) no longer holds. The same share is lost for good when the subject is a contract with no way to move IMD (the hook, which only holds IMD as PoolManager claims; the PoolManager; 0xdEaD). Only the buyer loses their own fee share, so low. A one-line refusal of subject == address(this) (and optionally of known sinks), or routing such shares to escrow so recycle() can move them, closes it.","line":214,"path":"src/MarginaliaPages.sol","reproduction":"Local PagesFixture: alice (eligible) calls pages.buy(pages.subjectOf(address(pages)), 1, 1 ether). value 0.05 IMD, fee 0.005, toIssuer 0.004 is safeTransfer'd from Pages to Pages. After the call imd.balanceOf(pages) rose by 0.054e18 while reserveOf(subject) + pendingBurn rose by 0.050e18: 0.004 IMD untracked and unreachable by any function. Expected: the buy is refused or the share is accounted. Reproduced in test/scratch/Repro.t.sol testSelfSubjectStrandsIssuerShare (held 54000000000000000 vs tracked 50000000000000000).","severity":"low","snippet":"        if (uint256(subject) >> 160 == 0 && subject != bytes32(0)) return address(uint160(uint256(subject)));","title":"payeeOf treats any nonzero 20-byte subject as a self-paying issuer, so pages of subjectOf(address(pages)) (or of the hook, the PoolManager, 0xdEaD) strand the 80% issuer share: untracked IMD that no e"},{"citation":"resolved","description":"Merged from audit_flow (info) and two audit_permissions (info) findings: same root. The brief asks for exactly these immutables and no owner, so this is not a code defect; it is the design's liveness dependency, recorded so it is accepted knowingly and stated in the README/site. The oracle-consumer reference says the intake, action, price and signer should be constructor input AND owner-settable, and to use Intake version 2 for anything new; Pages holds all of them immutable (OracleAttestationConsumer exposes _setOracleSigner but nothing wires it). States that permanently disable claims: (a) Intake v1 priceOf(action, IMD) becomes 0 or above 1 IMD, so requestClaim reverts PriceMismatch; (b) Intake v1 stops completing requests, so every claim locks 3 days, is abandoned and costs its asker 0.5 IMD; (c) the signer 0x5598... rotates, so every delivery reverts BadSignature. In each case subjects[handle].payee can never be set and recycle() sends every handle's issuer share to the hook's pools 90 days after its first buy. Mainnet reads on 2026-10-12 confirm the present state is healthy: Intake 0x1397... priceOf returns 500000000000000000, the signer is an EOA, and the live hook's INTAKE/ORACLE_SIGNER equal the constructor arguments. On the callback stipend: the repo's cold-start test fits 200k (author measured 177k), and on a mainnet fork at the latest block (publicnode) a successful delivery against the live IMD token used 147,892 gas; a live IMD transfer to a fresh recipient estimates at 53,017 gas, i.e. a standard ERC20. Headroom is real but there is no retry if the stipend is ever exceeded.","line":405,"path":"src/MarginaliaPages.sol","reproduction":"Deploy with the brief's constants; make intake.priceOf(action, imd) return 0 (the suite's ClaimIntake.setPrice(0) does this locally in testPriceGuardAndAddressSubjectsNeedNoClaim): requestClaim('anyhandle', 1) reverts PriceMismatch. Or rotate the signer: with signer S1 in the constructor and an attestation signed by S2, onOracleResult reverts BadSignature (testWrongSignerAndMalformedSignaturesLeaveClaimOpen). No other path sets a handle's payee, so after escrowSince + 90 days recycle(handle) moves the whole issuer share to hook.fundPot.","severity":"info","snippet":"        uint256 price = intake.priceOf(action, imd);\n        if (price == 0 || price > MAX_PRICE) revert PriceMismatch();","title":"Trust and liveness assumption to document: handle claims are pinned to Intake v1, one action id, one hot signer key and a 200k callback stipend with no rotation path; if any of them changes, no handle"}],"hash":"353cdaddd10788469fc954fdd907ae13b1661b2b98d9431aa47c8f08c9ae6326","nodeId":"32d12e3e-01cb-479d-b1a0-46ba86ae8502","outcome":"completed","summary":"Review complete. The findings file is written at the repository root and every one of the 50 listed entry points has a coverage row.\n\n**What I did**\n\n- Reproduced every specialist finding against the code with scratch tests under `test/scratch/` (all demonstrate the behaviour on the current code) and merged duplicates: the MARG-gate sybil finding reported by two areas became one finding, and the three oracle-pinning notes became one.\n- Ran the full Pages suite (63 tests green), then rehearsed Pages on a mainnet fork at the latest block through the public node: the live hook, live launch pool, live IMD and live Intake price all behave as the contract expects, and the claim callback used about 148k gas, under the 200k stipend.\n- Read the live hook, annex, whitelist, Intake and signer on chain to confirm every ABI Pages depends on exists and matches the constructor arguments.\n- Did my own pass over the contract, the deployment model and the manifest. No new defects surfaced. Size, constructor purity, argument order and the schema of `launch.json` all check out.\n\n**Findings kept (4)**\n\n1. **Low.** The MARG leg of the buy gate reads a transferable balance, so one 10,000 MARG bag qualifies unlimited wallets in a single transaction. The per-wallet cap bounds a wallet, not an actor, and the natspec's \"costs a sybil something per wallet\" does not hold for this leg. Recalibrated from the economics specialist's medium: no funds go to a wrong party, the brief specifies a balance gate, and the same cornering is possible through the notes leg for about 0.1 IMD per wallet.\n2. **Low.** The escrow clock is one-sided. It starts only when zero and is reset only by `recycle`, so identical handles get different protection depending on whether a stranger recycled.\n3. **Low.** Buying pages of the Pages contract's own address, or of a sink like the hook or the dead address, strands the 80% issuer share as untracked IMD.\n4. **Info.** Handle claims are pinned to Intake v1, one action, one signer and the 200k stipend with no rotation path. Not a defect, since the brief asks for exactly this, but a liveness assumption the README should state.\n\n**Coverage**\n\nThe 9 Pages entry points plus the hook, token and treasury functions Pages actually exercises are traced as holds or finding. The 32 entry points of the already-live hook, annex, router and judge that this launch neither deploys nor calls are recorded as unreached, with only their ABI surface verified on mainnet.\n\nNothing blocks deployment. The three low findings are the author's call on design, not fixes required for safety.","treeHash":null,"usage":{"cachedInputTokens":1865816,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":46578,"runtime":"claude","turns":35,"wallClockMs":1040747}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"dedc96e38388cb45","findings":[{"citation":"resolved","description":"Access x asymmetry. The natspec (lines 41-44) promises that 'a wallet holds at most MAX_PER_WALLET pages of one writer, so no wallet can corner a room' and that 'every room costs a sybil something per wallet'. The MARG leg of eligible() is a plain balanceOf snapshot at buy time and MARG is freely transferable, so the 'something' is paid once, not per wallet: an actor funds wallet 1 with exactly MARG_GATE, buys 10 pages, forwards the same MARG to wallet 2, buys 10 more, and so on, all inside one transaction and ending with the bag back in hand. The whitelist and posted-note legs are genuinely per wallet; the MARG leg is not, which is the asymmetry. The cap is also cheap in absolute terms: hook.margPriceInImd() on mainnet reads 29685420564359 (2026-10-12), so 10,000 MARG is about 0.3 IMD. A v4 flash-take of MARG inside an unlock does not work (hook.fundPot's own poolManager.unlock reverts AlreadyUnlocked), but it is not needed. The numbers are the brief's and the gate reads as the brief words it, so this is reported as a broken stated guarantee (low), not a spec violation; the author decides whether 'no wallet can corner a room' is a promise the site relies on (e.g. for sealed-note delivery to page holders). A fix that keeps every number: make the per-wallet cap per issuer-side identity that is not transferable (whitelist or note record), or add a minimal cooldown/age on the MARG balance (e.g. require the MARG to have been held since a previous block, or snapshot via the hook's records).","line":241,"path":"src/MarginaliaPages.sol","reproduction":"State: any subject (here subjectOf(carol)); an actor with exactly MARG_GATE = 10_000e18 MARG and 2,000 IMD. Steps in one transaction: deploy 10 fresh contract wallets; give wallet0 the MARG and IMD; for i in 0..9: wallet_i approves IMD, calls pages.buy(subject, 10, max), then transfers all its MARG and IMD to wallet_{i+1} (the last one returns them to the actor). Expected under the natspec: a per-wallet 'sybil something' is paid 10 times or the actor cannot exceed 10 pages. Actual: all 10 buys succeed, the actor controls 100 pages of the subject (subjects(subject).supply == 100), the full MARG bag is back with the actor, and eligible(wallet_i) is false for all 10 afterwards, proving no per-wallet cost was ever paid. Test testOneMargBagCornersARoomAcrossSybilWallets in the proof passes on the current code (it demonstrates the behaviour).","severity":"low","snippet":"        if (IERC20(hook.token()).balanceOf(wallet) >= MARG_GATE) return true;","title":"MARG leg of the buy gate is a reusable snapshot: one 10,000 MARG bag passes eligible() for unlimited fresh wallets in one transaction, so MAX_PER_WALLET does not stop one actor from cornering a room"},{"citation":"resolved","description":"Asymmetry between the first-time and subsequent branches of escrow accrual, and between recycle() (which sets escrowSince = 0 at line 482) and _distributeFee (which only sets escrowSince when it is 0). After CLAIM_WINDOW from the first buy, every later fee on a still-unclaimed handle is instantly recyclable by anyone (the author's test testFirstBuyWindowRecyclesEvenRecentlyAccruedFees asserts this). But if anyone did call recycle() at day 90, escrowSince is zeroed and the next fee restarts a full 90-day protection. Two handles with identical trade histories therefore give their issuer different outcomes purely on a third party's action: on one the issuer's share can be swept to the pools the block after it accrues, on the other it is safe for 90 more days. Whoever benefits from recycling (the hook's pools pay note writers' refunds) can choose the favourable branch by timing recycle() calls: sweep right after each trade on handles past day 90, and never sweep at exactly day 90 so the clock never restarts. Fix: make the rule one-sided and explicit, e.g. always restart escrowSince on accrual when escrow was zero AND on recycle, or record the window per accrual batch, or simply never reset escrowSince in recycle() so that 'after 90 days from the first buy, unclaimed fees are recyclable' holds in every history.","line":314,"path":"src/MarginaliaPages.sol","reproduction":"State: two registered handles A and B, each with one page bought at t0 (0.004 IMD escrow each). At t0 + 90 days anyone calls recycle(A); nobody touches B. At t0 + 91 days bob buys 10 pages of A and 10 pages of B (identical 0.26 IMD issuer fee each). Expected: identical treatment of identical fees. Actual: recycle(B) succeeds at once (the 0.264 IMD goes to the pools), while recycle(A) reverts TooEarly and A's 0.26 IMD is protected until t0 + 181 days. Test testEscrowClockDependsOnWhetherAStrangerRecycled in the proof passes on the current code (it demonstrates the behaviour).","severity":"low","snippet":"            if (s.escrowSince == 0) s.escrowSince = uint64(block.timestamp);","title":"Escrow clock asymmetry: whether new issuer fees are protected for 90 days or recyclable at once depends on whether a stranger called recycle(), because escrowSince is only reset by recycle and never b"},{"citation":"resolved","description":"Not a code defect; the brief asks for exactly these immutables and no owner. Recorded as the trust gap the design carries, with the concrete states that trigger it. The oracle-consumer reference says version 1 of the Intake is 'still served' but 'use version 2 for anything new' and that intake/action/price/signer should be owner-settable 'so a new action version or a moved price must not need a redeploy'. Here all five are immutable. States that permanently disable claims: (a) Intake v1 priceOf(action, IMD) returns 0 or more than 1e18 -> requestClaim reverts PriceMismatch forever; (b) Intake v1 stops completing requests -> every claim locks 3 days then is abandoned, 0.5 IMD lost per attempt; (c) the oracle signer key 0x5598... rotates -> every attestation reverts BadSignature. In each case escrow of every handle is swept to the hook's pools by recycle() after 90 days and handle issuers are never paid. Mainnet reads on 2026-10-12 confirm the current state is healthy: Intake 0x1397... has code and priceOf returns 500000000000000000; the signer is an EOA; the live hook's INTAKE/ACTION/ORACLE_SIGNER equal the constructor arguments. Suggest stating this in the README and the site so handle issuers know the claim window is also bounded by the oracle's lifetime.","line":406,"path":"src/MarginaliaPages.sol","reproduction":"Deploy with the brief's constants; later have intake.priceOf(action, imd) return 0 (or > 1e18). Call requestClaim('anyhandle', 1): reverts PriceMismatch. No other path can ever set subjects[handle].payee, so after 90 days from the first buy recycle(handle) moves the issuer's whole share to the pools. The Pages test suite's ClaimIntake.setPrice(0) reproduces the revert locally (testPriceGuardAndAddressSubjectsNeedNoClaim).","severity":"info","snippet":"        if (price == 0 || price > MAX_PRICE) revert PriceMismatch();","title":"Trust assumption to document: the whole handle-claim path is pinned to Intake v1, one action id and one hot signer key, with no owner to rotate them; if any of the three changes, handles can never be "},{"citation":"resolved","description":"The callback does signature recovery, consumes the oracle UUID, deletes the claim and request mapping, writes the payee, zeroes the escrow and makes two IMD transfers. Measured with the project's fixture in a separate call after setUp (cold storage and cold hook/IMD accounts) with a zero-IMD payee and a claimant whose IMD balance is zero after paying (both 0 -> nonzero balance writes): 177,208 gas; the zero-answer path 100,313. The live IMD is a LayerZero OFT whose transfer is the OpenZeppelin ERC20 path, the live signer is an EOA, and the hook's imd() is an immutable read, so mainnet should match within a few thousand gas. A callback that runs out of the 200k stipend is 'recorded as not delivered and is not retried': the claim then sits 3 days, is abandoned, and the identical retry fails identically, so the handle could never be claimed. Recommend keeping a test that asserts the cold-start figure stays under e.g. 190k, and considering the reference's pattern (store the attested wallet in the callback, pay out in a separate permissionless call) if anything is added to this function.","line":457,"path":"src/MarginaliaPages.sol","reproduction":"Fixture: deploy Pages against the local hook, register 'coldwallet', alice and bob buy 10 pages each, an asker funded with exactly 0.5 IMD calls requestClaim('coldwallet', 1) in setUp. Test: vm.prank(intake); measure gasleft() around pages.onOracleResult(requestId, attestation(wallet = fresh address with 0 IMD), signature). Observed: 177,208 gas used; intake.deliver with call{gas: 200_000} returns true. A failure would show as deliver returning false and claims(subject) still pending.","severity":"info","snippet":"        if (reimbursed > 0) imd.safeTransfer(c.claimant, reimbursed);","title":"onOracleResult success path measured at 177k gas from a cold start: about 23k under the Intake's 200k callback stipend; headroom, not a defect, but the claim path has no retry if it is ever exceeded"}],"hash":"37b190a19aef9fa25ee4d57f40443e30abe02d58e922fcaded2627e7fc531a65","nodeId":"3112863e-8e49-4679-9542-e0eeac62af78","outcome":"completed","summary":"The review is complete and the findings file is written. The working tree is clean apart from `.imd-findings.json`, which git ignores.\n\n**Outcome.** No critical, high or medium defect found in MarginaliaPages v0.10 within the Access Control, Trust Gap and Asymmetry guides. Four findings are recorded, two low and two informational, each with a concrete state and call sequence. All 52 listed entry points plus two invariants have coverage rows, none unreached.\n\n**Findings written to `.imd-findings.json`:**\n\n- **Low, buy gate at line 241.** The MARG leg of `eligible()` is a balance snapshot and MARG is transferable, so one 10,000 MARG bag passes the gate for unlimited fresh wallets in one transaction. One actor held 100 pages of one subject in my reproduction, with the bag returned afterwards. This contradicts the natspec promise that no wallet can corner a room. On mainnet today 10,000 MARG is worth roughly 0.3 IMD.\n- **Low, escrow clock at line 314.** `escrowSince` is reset only by `recycle()`, never by accrual after the window. Two handles with identical trades end up with one handle's new fees instantly sweepable and the other's protected for 90 more days, depending only on whether a stranger called `recycle()` at day 90.\n- **Info, claim path immutability.** Intake v1, the action id and the signer are immutable with no owner. If the Intake price goes to zero or above 1 IMD, the Intake stops completing, or the signer rotates, handles can never be claimed and all escrow drains to the pools after 90 days.\n- **Info, callback gas.** The success path of `onOracleResult` measured 177k gas from a cold start with zero-balance payee and asker, 23k under the 200k stipend. A failure would be unretriable, so the margin deserves a guarding test.\n\n**What held.** Callback authorization and replay (Intake-only, own request only, this contract's EIP-712 domain, chain id, panel minimums, UUID consumed once), the claim slot and abandon path, recycle guards, the burn retry and `unlockCallback` sender binding, buy/sell storage symmetry and reserve coverage. A v4 flash-take of MARG to pass the gate is blocked because `hook.fundPot` performs its own `unlock`. Live mainnet reads confirmed the hook getters, annex records, whitelist, Intake price of 0.5 IMD and an EOA signer all match what the constructor pins.\n\n**Not reached.** The already-live hook, annex, router, judge and treasury were not re-audited beyond the paths Pages calls; their rows say so.","treeHash":null,"usage":{"cachedInputTokens":2192706,"inputTokens":514,"model":"claude-fable-5-1","outputTokens":55336,"runtime":"claude","turns":39,"wallClockMs":1012561}},{"artifacts":[],"attempt":1,"bundleHash":"7b96185698daf342e0697144a24e5944bcd454f13d5c8a3752bd69268900aac5","device":"d021901979a78997","findings":[],"hash":"779bd2797ceb5532d8142280704fbb6a30b9d4a6923cf0973024e98884986538","nodeId":"f4a70c77-d6a6-44fc-aad2-c7525530b874","outcome":"completed","summary":"Created [launch.json](/home/imd/.identitymd-2/work/b8def7a9-129f-4bfb-8b4e-e9a4327cf5a9/f4a70c77-d6a6-44fc-aad2-c7525530b874/launch.json) for MarginaliaPages v0.10 with the exact five constructor arguments.\n\nValidated the manifest against the compiled ABI and live hook constants. `forge build` passed; `forge test`: 345 passed, zero failures, two optional fork suites skipped.\n\nOnly `launch.json` is changed for submission.","treeHash":"40a4d6b9beeccc2c6380210b3323eded6009384f","usage":{"cachedInputTokens":1205888,"inputTokens":62859,"model":"gpt-6-astra","outputTokens":6170,"runtime":"codex","turns":7,"wallClockMs":294735}},{"artifacts":[],"attempt":1,"bundleHash":"35cb51f3884c65d5ede3bf68ab3d524eba2741a462796f3da14db7fb67e7c12c","device":"d75dd2bcf4a95f45","findings":[],"hash":"9f0a5a9dd5c939eba46e2d096021e70a227d03aef4880822ea60e621e7be6518","nodeId":"b1a92475-ae0c-411a-ac07-cc778998e6aa","outcome":"completed","summary":"Implemented the Pages v0.10 adaptation: deferred burns, validated subjects, and explicit payout-claim tweets. Requested economics remain unchanged.\n\nValidation passed: 345 tests, 2 expected fork skips; both Pages mainnet fork tests and the deployment floor passed.\n\n[ADAPTATION.md](/root/.identitymd/work/b8def7a9-129f-4bfb-8b4e-e9a4327cf5a9/b1a92475-ae0c-411a-ac07-cc778998e6aa/ADAPTATION.md) records changes and audit decisions. Ready for the manifest/deployment step; no mainnet transaction was broadcast.","treeHash":"0ae1ea336583c81bd132fb3161cd1edad219fc95","usage":{"cachedInputTokens":11373184,"inputTokens":203084,"model":"gpt-6-astra","outputTokens":79865,"runtime":"codex","turns":24,"wallClockMs":3116932}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"8af9903f4ad1eed0","findings":[{"citation":"resolved","description":"The brief asks for no owner and the same oracle constants the live hook holds, and the contract follows it: `intake`, `action` and `oracleSigner` are set once in the constructor (OracleAttestationConsumer exposes `_setOracleSigner` but Pages wires nothing to it). The supplied oracle-consumer reference says the opposite for consumers: 'Every one of these is constructor input and owner-settable, never a constant: the intake, ..., the action id, ..., the signer. A new action version (oracle-2) or a moved price must not need a redeploy', and names Intake 0x1397...dea56 as version 1, 'still served' while version 2 is the one for anything new. Pages has no fallback: if IdentityMD rotates the signing key, retires the oracle.request@oracle-1 action on v1, or stops serving v1, `onOracleResult` reverts BadSignature (or never arrives), every requestClaim spends 0.5 IMD for nothing, each attempt locks the subject for ANSWER_DEADLINE, and since recycle is permissionless the issuer share of every handle ends in the hook's pools after 90 days instead of with the writer. This is a design tradeoff the brief chose, not a bug in the control flow; it is reported so the decision is taken knowingly (the README mentions only that the panel and signer are trusted to read the tweet correctly, not that their continuity is a liveness assumption for all handle escrow).","line":433,"path":"src/MarginaliaPages.sol","reproduction":"State: Pages deployed with signer S1; handle 'writer' registered, 20 pages bought (escrow 0.84 IMD). The oracle operator rotates to S2 (attestations now signed by S2). Owner tweets claimMessage(wallet), calls requestClaim('writer', tweetId) paying 0.5 IMD. Intake delivers onOracleResult(requestId, a, sigS2): `_verifyAttestation` -> SignatureChecker.isValidSignatureNow(S1, digest, sigS2) is false -> revert BadSignature; the Intake records the delivery as failed and does not retry. Expected (per the oracle-consumer reference): the consumer can be pointed at the new signer. Actual: no path exists; after 3 days anyone calls abandonClaim and the cycle repeats; at escrowSince + 90 days anyone calls recycle('writer') and the 0.84 IMD goes to hook.fundPot. Same outcome if Intake v1 stops completing requests or the action is renamed (priceOf returns 0 -> PriceMismatch forever).","severity":"info","snippet":"        _verifyAttestation(a, signature);","title":"Oracle signer, Intake and action are pinned with no rotation path: a signer rotation or the retirement of Intake v1 makes every handle claim impossible and sends all handle escrow to the pools"},{"citation":"resolved","description":"An address subject needs no registration and pays itself. When the address is the Pages contract itself, `_distributeFee` does `IERC20(imd).safeTransfer(address(this), toIssuer)`: a no-op transfer that leaves the IMD in the contract but tracked by nothing (not reserveOf, not escrow, not pendingBurn), so the accounting invariant the tests assert (`imd.balanceOf(pages) == sum(reserve) + sum(escrow) + pendingBurn`) no longer holds and the IMD can never leave. The same share is lost for good when the subject is any contract with no way to move IMD (the hook, the PoolManager, 0x...dEaD). Only the buyer loses (their own fee), there is no victim besides the dust, so this is informational: a one-line refusal (subject == address(this), or payeeOf returning zero for this contract so the share goes to escrow/recycle) closes it.","line":214,"path":"src/MarginaliaPages.sol","reproduction":"alice (eligible) calls buy(subjectOf(address(pages)), 1, 1 ether). value 0.05, fee 0.005, toIssuer 0.004 is safeTransfer'd from Pages to Pages. Measured after the call on the local fixture: reserveOf(subject) = 0.05e18, pendingBurn = 0, escrow = 0, but imd.balanceOf(pages) exceeds reserve + escrow + pendingBurn by 0.004e18 (observed 11.394e18 vs 11.39e18 with the fixture's other subject). Expected: either the buy is refused or the share is accounted (escrow) and recyclable. Actual: 0.004 IMD is stuck forever; repeats on every trade of that subject.","severity":"info","snippet":"        if (uint256(subject) >> 160 == 0 && subject != bytes32(0)) return address(uint160(uint256(subject)));","title":"payeeOf treats any nonzero 20-byte subject as a self-paying issuer, so buying pages of address(this) (or the hook, the PoolManager, 0xdEaD) strands the 80% issuer share inside Pages outside reserve, e"}],"hash":"a24d05810f422a96da315a6c43ec48bad0fcdb9b3e9e82d4253672bfc4aa9c76","nodeId":"44b0d74e-e45b-430b-a9fc-999ef7fd3429","outcome":"completed","summary":"The review is complete and `.imd-findings.json` holds the result: two informational findings, no critical, high or medium defects, and a coverage row for every listed entry point.\n\n**What I audited.** The control flow of MarginaliaPages v0.10 against the Execution Trace, Periphery and First Principles guides: every state-changing entry point traced from its checks through state writes, external calls and failure paths, plus the hook paths Pages depends on (fundPot, unlockCallback, the quiet-buy branches of beforeSwap and afterSwap) and the OracleAttestation periphery.\n\n**What held.**\n- **Accounting.** The curve reserve equals the sum of page prices at every supply, the price formula never rounds, and the contract's IMD balance stays equal to reserve plus escrow plus pendingBurn on every buy, sell, claim, recycle and burn path.\n- **Claims.** Only the Intake can deliver, only an open request of Pages' own is accepted, the oracle UUID is consumed once, chain, panel and quorum are checked, abandoned requests refuse late answers, and recycle never runs over a pending claim.\n- **Callback budget.** I measured the delivery with cold state (fresh balances, cold slots, separate transaction) at about 146k gas, under the 200k stipend. The question body stays at 1013 characters and the claim prefix at 116 with the longest possible inputs, inside the Intake's limits.\n- **Periphery.** The OracleAttestation library is byte-identical to the canonical copy in the oracle-consumer reference. The consumer differs only in using the memory variant of the signature check, with the same semantics.\n- **Burn path.** The try/catch around the burn swap cannot be exploited by gas starvation, partial fills roll back cleanly, and `burn` can only spend pendingBurn.\n\n**What I reported, both informational.**\n1. The signer, Intake and action are pinned with no rotation path. The brief asked for this, but the oracle-consumer reference says consumers must be able to repoint them. If the key rotates or Intake v1 stops being served, every handle claim fails and all handle escrow recycles into the pools after 90 days.\n2. Buying pages of an address subject that is a contract unable to move IMD, including Pages itself, strands the issuer share inside the contract outside all accounting. Only the buyer's own fee is lost.\n\n**What I could not verify.** Whether Intake v1 accepts the body keys `head`, `guards.sources` and `consumer` for a scalar address answer cannot be checked offline. The live Judge and Annex use the same key shapes, and the brief prescribes them, so this is recorded as an unreached lead. No launch.json exists in the tree yet, so the manifest row is also marked unreached. The scratch test directory has been removed and no repository file was changed.","treeHash":null,"usage":{"cachedInputTokens":2688652,"inputTokens":578,"model":"claude-fable-5-1","outputTokens":51853,"runtime":"claude","turns":38,"wallClockMs":998200}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"ddfb1efa72fe9a94","findings":[],"hash":"dc7265283d85ee38b8c9223086c283d6500c0166c4fa012f74573e5b0c114066","nodeId":"071d7edf-079a-4f28-8923-fceadd9f0625","outcome":"completed","summary":"The review is complete. The findings file holds zero defects and 55 coverage rows, and the working tree is otherwise unchanged.\n\n**Result: no math defect found in MarginaliaPages.** The areas I covered in depth:\n\n- **Curve arithmetic.** I fuzzed `priceOf` against a per-page reference sum of min(0.05·n, 10) and checked additivity, so the reserve always equals the exact sell-out value at any depth, including the cap edge at pages 199, 200 and 201. The closed-form division by 2 is exact because the product is always even.\n- **Fee split.** Every single-page price gives a fee of exactly one tenth, and the 80/10/10 legs reconcile to the fee with no truncation. The smallest fee is 0.005 IMD, so no leg ever rounds to zero.\n- **Casts and bounds.** The uint64 supply cast is guarded by the per-wallet limit, the burn swap's exact-input check compares the delta word for word, and MARG output at the live price stays far inside int128.\n- **Balance invariant.** Contract IMD equals reserves plus escrow plus deferred burns through buys, sells, deferred and retried burns. A buy from inside a foreign PoolManager unlock reverts entirely, so a v4 flash-taken MARG balance cannot pass the gate.\n- **Live wiring.** Over public RPC I confirmed the hook's token, IMD, poolManager and pool key getters, both records getters, the whitelist contract's `contributedBy`, 18 decimals on IMD and MARG, and an Intake price of 0.5 IMD. The pinned-block fork suite could not run on public RPC, so I ran a scratch copy at the latest block: the live-IMD oracle callback fits the 200k stipend and a real trade against the live hook passes.\n\n**One lead I quantified and dropped.** The automatic burn swap uses a zero minimum output. A sandwich on a thinned pool left the victim's burn deferred rather than lost and cost the attacker about 180 IMD in fees, with gain capped at the burn tranche, so it is not a defect.\n\n**Not reached.** Entry points of the Router, Judge, Treasury and Annex are outside this launch and untouched by the Pages math. They are recorded as holding on that basis, not from an independent trace.","treeHash":null,"usage":{"cachedInputTokens":2347718,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":43257,"runtime":"claude","turns":37,"wallClockMs":1102449}}],"verification":[{"checks":[{"durationMs":458121,"exitCode":0,"name":"build","output":"Compiling 131 files with Solc 0.8.26\nSolc 0.8.26 finished in 457.80s\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/AnnexInvariant.t.sol:530:52:\n    |\n530 |         try annex.requestAdmission(asked) returns (bytes32 r) {\n    |                                                    ^^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/AnnexInvariant.t.sol:557:19:\n    |\n557 |         (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerKey, annex.attestationDigest(a));\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[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/MarginaliaAnnex.sol:489:45\n    │\n489 │         if (!ok || ret.length < 32) return (false, 0);\n    │                                             ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\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[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 `_status` is updated\n    ╭▸ src/MarginaliaAnnex.sol:657:9\n    │\n657 │         hook.poolManager().unlock(abi.encode(imdIn, authorIn, minOut, to));\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/MarginaliaAnnex.sol:253:13\n    │\n253 │         if (block.timestamp > deadline) revert Expired();\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/MarginaliaAnnex.sol:295:9\n    │\n295 │         emit NotePosted(id, author, p.x, n.class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaAnnex.sol:278:22\n    │\n278 │         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[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaAnnex.sol:279:17\n    │\n279 │         n.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[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[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:203:17\n    │\n203 │                 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/MarginaliaAnnex.sol:333:13\n    │\n333 │         if (block.timestamp < end) revert TooEarly();\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/MarginaliaPages.sol:242:29\n    │\n242 │         (, uint32 posted) = IMarginaliaRecords(address(hook)).records(wallet);\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/MarginaliaAnnex.sol:334:13\n    │\n334 │         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/MarginaliaAnnex.sol:345:47\n    │\n345 │                     || (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[unused-return]: return value of an external call is not used\n    ╭▸ src/MarginaliaPages.sol:245:13\n    │\n245 │             (, posted) = annex.records(wallet);\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/MarginaliaAnnex.sol:353:9\n    │\n353 │         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/MarginaliaAnnex.sol:339:27\n    │\n339 │             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/MarginaliaAnnex.sol:339:52\n    │\n339 │             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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaAnnex.sol:439:9\n    │\n439 │         hook.fundPot(amount);\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:320:17\n    │\n320 │             try hook.poolManager().unlock(abi.encode(toBurn, uint256(0))) returns (bytes memory) {}\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:328:13\n    │\n328 │             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/MarginaliaAnnex.sol:398:35\n    │\n398 │         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/MarginaliaAnnex.sol:360:13\n    │\n360 │         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/MarginaliaPages.sol:285:9\n    │\n285 │         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/MarginaliaPages.sol:282:21\n    │\n282 │         s.supply += uint64(amount);\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:300:9\n    │\n300 │         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:296:21\n    │\n296 │         s.supply -= uint64(amount);\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:323:17\n    │\n323 │                 emit BurnDeferred(toBurn);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:314:53\n    │\n314 │             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:409:21\n    │\n409 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n410 │ ┃             action,\n411 │ ┃             bytes(questionBody(normalized, tweetId)),\n412 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n413 │ ┃             imd,\n414 │ ┃             price\n415 │ ┃         );\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:420:9\n    │\n420 │         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:418:63\n    │\n418 │         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:446:13\n    │\n446 │             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:459:9\n    │\n459 │         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:467:13\n    │\n467 │         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:484:9\n    │\n484 │         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:479:13\n    │\n479 │         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:485:9\n    │\n485 │         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:498:9\n    │\n498 │         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:494:44\n    │\n494 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) {\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:494:52\n    │\n494 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) {\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:498:9\n    │\n498 │         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:528:9\n    │\n528 │         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:512:18\n    │\n512 │                 -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:519:38\n    │\n519 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-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:519:46\n    │\n519 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-inD)) != imdIn) revert UnauthorizedCallback();\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:524:9\n    │\n524 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:525:24\n    │\n525 │         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:525:32\n    │\n525 │         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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaAnnex.sol:398:9\n    │\n398 │         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/MarginaliaAnnex.sol:385:30\n    │\n385 │         int256 scoreDelta = -int256(diff);\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/MarginaliaAnnex.sol:388:26\n    │\n388 │             scoreDelta = int256(diff);\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[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/MarginaliaAnnex.sol:405:13\n    │\n405 │         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/MarginaliaAnnex.sol:412:9\n    │\n412 │         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/MarginaliaAnnex.sol:413:9\n    │\n413 │         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/MarginaliaAnnex.sol:407:30\n    │\n407 │         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/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[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaAnnex.sol:452:17\n    │\n452 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaAnnex.sol:488:21\n    │\n488 │         (ok, ret) = x.staticcall{gas: BALANCE_READ_GAS}(data);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaAnnex.sol:612:21\n    │\n612 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n613 │ ┃             action,\n614 │ ┃             bytes(admissionBody(hooks)),\n615 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n616 │ ┃             imd,\n617 │ ┃             price\n618 │ ┃         );\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/MarginaliaAnnex.sol:622:9\n    │\n622 │         emit AdmissionRequested(requestId, msg.sender, hooks, price);\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/MarginaliaAnnex.sol:605:70\n    │\n605 │             if (hooks[i] == address(0) || hooks[i].code.length == 0) revert BadList();\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: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[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-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaAnnex.sol:646:21\n    │\n646 │                     emit HookAdmitted(open[i], requestId);\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/MarginaliaAnnex.sol:657:9\n    │\n657 │         hook.poolManager().unlock(abi.encode(imdIn, authorIn, minOut, to));\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/MarginaliaAnnex.sol:691:13\n    │\n691 │             emit Burned(imdIn - authorIn, marg - authorMarg);\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[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaAnnex.sol:672:18\n    │\n672 │                 -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/MarginaliaAnnex.sol:679:38\n    │\n679 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-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/MarginaliaAnnex.sol:679:46\n    │\n679 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-inD)) != imdIn) revert UnauthorizedCallback();\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/MarginaliaAnnex.sol:680:24\n    │\n680 │         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/MarginaliaAnnex.sol:680:32\n    │\n680 │         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/MarginaliaAnnex.sol:687:9\n    │\n687 │         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.chainid` may be reused across `vm.chainId`\n     ╭▸ test/AnnexAdversarial.t.sol:190:21\n     │\n 190 │         a.chainId = block.chainid;\n     │                     ━━━━━━━━━━━━━\n     ‡\n1088 │         vm.chainId(999);\n     │         ─────────────── `vm.chainId` changes this environment here\n     │\n     ├ help: capture it with `vm.getChainId()` 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/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.chainid` may be reused across `vm.revertToState`\n    ╭▸ test/Pages.t.sol:130:21\n    │\n130 │         a.chainId = block.chainid;\n    │                     ━━━━━━━━━━━━━\n    │\n    ⸬  test/PagesReentrancy.t.sol:129:28\n    │\n129 │                 assertTrue(vm.revertToState(snapshot));\n    │                            ────────────────────────── `vm.revertToState` changes this environment here\n    │\n    ├ help: capture it with `vm.getChainId()` instead\n    ╰ help: https://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":38180,"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 480.86µ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 913.86µs (414.29µ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 1.97ms (0.00ns CPU time)\n\nRan 4 tests for test/PagesDeployment.t.sol:PagesOracleConformanceTest\n[PASS] testAddressAnswerFromVectorKeyDeliveredUnderStipend() (gas: 1648963)\n[PASS] testCallbackSelectorMatchesProtocol() (gas: 3739)\n[PASS] testDigestMatchesPinnedProtocolVector() (gas: 13296)\n[PASS] testVerifiesPinnedProtocolSignature() (gas: 17015)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 3.73ms (976.38µs CPU time)\n\nRan 1 test for test/PagesOracleBoundaries.t.sol:PagesColdCallbackTest\n[PASS] testColdCallbackPaysTwoFreshRecipientsWithin200k() (gas: 320880)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.38ms (220.05µs 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.86ms (4.75ms CPU time)\n\nRan 2 tests for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testConstructorRejectsMissingRequiredValues() (gas: 1742975)\n[PASS] testFactoryDeploysExactlyPagesWithNoDependencyCode() (gas: 13706462)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 19.71ms (19.47ms 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 19.54ms (8.68ms 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 21.46ms (10.93ms 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, μ: 106042, ~: 106118)\nLogs:\n  Bound result -11435\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 27.68ms (27.09ms CPU time)\n\nRan 14 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2898172)\n[PASS] testAnnexLegIsOffWhenUnset() (gas: 4151632)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2904850)\n[PASS] testBuyGateWhitelistMargOrNotes() (gas: 1941906)\n[PASS] testBuyPaysTheIssuerBurnsMargAndFundsThePools() (gas: 562885)\n[PASS] testCurveIsLinearThenCapped() (gas: 103553)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 4731069)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 64454)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37650)\n[PASS] testPerWalletLimitAndTheCap() (gas: 9388256)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 171085)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2603908)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 1021356)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 2111036)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 38.53ms (31.16ms 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, μ: 22619, ~: 20590)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 46.76ms (36.72ms 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 54.12ms (83.11ms CPU time)\n\nRan 29 tests for test/Annex.t.sol:AnnexTest\n[PASS] testAPulledPoolPushedToAnExtremeIsReadAtTheExtreme() (gas: 4898651)\n[PASS] testAdmissionAsksThePanelAndAdmitsOnlyWhatItNamed() (gas: 2491254)\n[PASS] testAdmissionBodyIsStrictJson() (gas: 759446)\n[PASS] testAdmissionRefusesBadAnswersAndBadLists() (gas: 1542625)\n[PASS] testAgentClassForContractAuthors() (gas: 1208062)\n[PASS] testAnAdmittedHookPassesTheDynamicFeeGate() (gas: 1042590)\n[PASS] testBaselineBoundRefusesASandwichedPost() (gas: 3472853)\n[PASS] testBuyCallOnAnUnreadableBalanceIsRefusedLikeTheHook() (gas: 2799765)\n[PASS] testBuyCallOnMargCountsThePurchaseOnce() (gas: 1467516)\n[PASS] testCounterAgainstAHookNoteAndAgainstAnAnnexNote() (gas: 3609075)\n[PASS] testDynamicFeePoolNeedsAdmissionEvenWithoutSwapBits() (gas: 135567)\n[PASS] testEmptiedVenueForfeitsInsteadOfRefunding() (gas: 3126196)\n[PASS] testEmptiedVenueOnASoldBuyCallIsStillVoidSold() (gas: 1677805)\n[PASS] testEmptyTextIsRefusedLikeTheHook() (gas: 54539)\n[PASS] testFullListFitsTheCallbackStipend() (gas: 1851403)\n[PASS] testHeldPriceStillSettlesRightAfterAFailedFlashRead() (gas: 2230314)\n[PASS] testHoldRuleVoidsASoldBuyCall() (gas: 1708364)\n[PASS] testHookBitsDecideWithoutAnOracle() (gas: 98895)\n[PASS] testMargVenueBaselineBoundNeedsRoomForThePostsOwnPurchase() (gas: 1102399)\n[PASS] testNoObservationsVoidAndReturnTheBond() (gas: 734020)\n[PASS] testNoteOfAnUnknownIdReverts() (gas: 23176)\n[PASS] testObservationInsideAnUnlockIsRefused() (gas: 2956772)\n[PASS] testObservationWindowAndSpacing() (gas: 901122)\n[PASS] testPostPaysTheStampBuysMargAndHoldsTheBond() (gas: 857166)\n[PASS] testRefusesWhatTheRouterAlreadyTakesAndBadKeys() (gas: 137269)\n[PASS] testRetractHalvesTheScoreAndForfeitsWithoutAKeeperCut() (gas: 924322)\n[PASS] testRightCallReturnsTheBond() (gas: 1529261)\n[PASS] testSoldOutRangeStillSettlesRight() (gas: 3269214)\n[PASS] testWrongCallForfeitsToThePoolsWithTheSettlerCut() (gas: 1511821)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 55.25ms (44.00ms 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 72.66ms (5.87ms 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 74.22ms (62.52ms CPU time)\n\nRan 1 test for test/PagesReentrancy.t.sol:PagesReentrancyTest\n[PASS] testAllPaymentPathsRejectEveryGuardedReentry() (gas: 189267523)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 88.67ms (78.85ms 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 117.91ms (35.10ms 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 199.14ms (205.45ms CPU time)\n\nRan 29 tests for test/AnnexAdversarial.t.sol:AnnexAdversarialTest\n[PASS] testAdmissionListRulesAndPrice() (gas: 2592651)\n[PASS] testAnEmptyAnswerIsStoredNotReverted() (gas: 1165039)\n[PASS] testAnLpPullCannotTurnAWrongCallIntoARefund() (gas: 1826114)\n[PASS] testAttestationEdgesAreRefusedOneByOne() (gas: 1594187)\n[PASS] testBaselineBoundIsInclusiveAtTheBaselineAndOffAtZero() (gas: 3640042)\n[PASS] testBaselineBoundReadsTheSidesOwnBaseline() (gas: 2452540)\n[PASS] testCallbackGasAtTheFullListStaysUnderTheStipend() (gas: 2110451)\n[PASS] testCheckpointWindowAgesAndExpiresLikeTheRouter() (gas: 4984262)\n[PASS] testConstructorStoresFourValuesWithoutReadingTheChain() (gas: 51698)\n[PASS] testCountersRefuseClosedParentsAndTheses() (gas: 5716846)\n[PASS] testFewerThanThreeStandingReadingsAreStillNoData() (gas: 1584176)\n[PASS] testHoldRuleGiftsCountAsHeldAndAReadFailureAsBroken() (gas: 4206416)\n[PASS] testLifecycleRefusalsOnUnknownClosedAndForeignNotes() (gas: 1869727)\n[PASS] testMoreAdverseReadingReplacesTheLastInTheSameBlock() (gas: 1808241)\n[PASS] testOneOracleUuidServesOneRequestOnly() (gas: 1423863)\n[PASS] testPostBoundariesExactly() (gas: 2254356)\n[PASS] testProtocolVectorDigestSelectorAndSignature() (gas: 1184381)\n[PASS] testScoreIsDifficultyWeightedAndRetractIsHalf() (gas: 4699329)\n[PASS] testSellCallSettlesRightAndMaySellThroughTheHorizon() (gas: 1544132)\n[PASS] testSellCallWrongWhenThePriceRises() (gas: 1597641)\n[PASS] testSettlementTakesTheMostAdverseReading() (gas: 1764967)\n[PASS] testSixteenReadingsAtMostAndTheLastSlotWaitsForTheHour() (gas: 4679743)\n[PASS] testSlippageAndUnfundedAuthorsTakeNothing() (gas: 1560244)\n[PASS] testSoldOutSellCallReturnsItsBond() (gas: 3296468)\n[PASS] testSplitIsExactAndNothingStaysInTheAnnex() (gas: 634423)\n[PASS] testStandingReadingsKeepPriceOrderingAndHoldBreachPriority() (gas: 5443760)\n[PASS] testThreeReadingsInsideAnHourAreNoData() (gas: 1494972)\n[PASS] testUnlockCallbackAcceptsOnlyThePoolManager() (gas: 630742)\n[PASS] testVenueQuoteRule() (gas: 1230415)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 235.88ms (41.87ms CPU time)\n\nRan 15 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonClaimCannotReenterAnotherClaimRequest() (gas: 5038391)\n[PASS] testBurnRetryIsBoundedAtomicAndKeepsEscrowAndReserve() (gas: 2838763)\n[PASS] testClaimQuestionRequiresExactIntentBoundToThisDeployment() (gas: 5589085)\n[PASS] testFirstBuyWindowRecyclesEvenRecentlyAccruedFees() (gas: 1019415)\n[PASS] testFuzzDeferredBurnLiabilities(uint8,uint8,uint8) (runs: 256, μ: 2043747, ~: 2045302)\nLogs:\n  Bound result 1\n  Bound result 6\n  Bound result 1\n\n[PASS] testHealthyTradesLeaveEarlierPendingBurnForExplicitRetry() (gas: 1420408)\n[PASS] testOnlyRegisteredHandlePreimagesOrNonzeroAddressesCanBeBought() (gas: 1084837)\n[PASS] testOracleUuidReplayCannotBindAnotherHandle() (gas: 2152689)\n[PASS] testPartialBurnFillRollsBackOnlyTheSwap() (gas: 1192431)\n[PASS] testRegistrationAndQuestionPreviewRejectMalformedHandles() (gas: 131538)\n[PASS] testRejectedTweetThenExplicitClaimAndDistinctOracleRequestId() (gas: 2874745)\n[PASS] testSoldOutLaunchPoolDoesNotBlockBuyingOrSelling() (gas: 2025544)\n[PASS] testV1MissingAnswerLocksUntilAnyoneAbandonsAtThreeDays() (gas: 2848354)\n[PASS] testWhitelistFailedOrShortReadsCountAsNotListed() (gas: 133255)\n[PASS] testWithdrawnLaunchLiquidityDoesNotBlockBuyingOrSelling() (gas: 2968129)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 294.67ms (303.85ms 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 484.37ms (51.44ms CPU time)\n\nRan 11 tests for test/PagesOracleBoundaries.t.sol:PagesOracleBoundariesTest\n[PASS] testAnotherConsumerDomainCannotAuthorizeThisClaim() (gas: 2488727)\n[PASS] testChainDomainChangeInvalidatesEvenCorrectlyTargetedAnswer() (gas: 2491755)\n[PASS] testClaimBeforeFirstBuyPaysFutureFeesWithoutChangingRegistration() (gas: 2128949)\n[PASS] testEachPanelMinimumIsEnforcedIndependently() (gas: 2613319)\n[PASS] testExpiryIsInclusiveAndFutureToleranceIsBounded() (gas: 3121770)\n[PASS] testFuzzEverySignedFieldRejectsPostSignatureTampering(uint8) (runs: 1000, μ: 2365692, ~: 2365569)\nLogs:\n  Bound result 0\n\n[PASS] testMalformedAddressAnswersDoNotConsumeTheOracleUuid() (gas: 2622750)\n[PASS] testRecyclingBoundaryResetsTheNextEscrowWindow() (gas: 1247281)\n[PASS] testReimbursementUsesThePaidPriceAndEqualityIsEnough() (gas: 2203199)\n[PASS] testRevertingEscrowTransferRollsBackClaimAndConsumption() (gas: 2629822)\n[PASS] testWrongSignerAndMalformedSignaturesLeaveClaimOpen() (gas: 2575109)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 483.41ms (489.00ms 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 484.44ms (1.13ms CPU time)\n\nRan 13 tests for test/PagesProperties.t.sol:PagesPropertiesTest\n[PASS] testCurveEdgesAndUint64SupplyRemainQuoted() (gas: 45555)\n[PASS] testFuzzEveryHandleByteIsValidated(uint8,uint8,uint8) (runs: 1000, μ: 69901, ~: 52118)\nLogs:\n  Bound result 13\n  Bound result 0\n\n[PASS] testFuzzPriceMatchesMarginalSum(uint64,uint16) (runs: 1000, μ: 55080, ~: 45504)\nLogs:\n  Bound result 20\n\n[PASS] testFuzzPricePartitionAcrossCap(uint16,uint16,uint16) (runs: 1000, μ: 36658, ~: 36651)\nLogs:\n  Bound result 20\n  Bound result 128\n  Bound result 0\n\n[PASS] testFuzzRepeatedRoundTripsLoseExactlyTwoFees(uint8,uint8,bool) (runs: 1000, μ: 2874781, ~: 2352663)\nLogs:\n  Bound result 1\n  Bound result 2\n\n[PASS] testFuzzRequestPaysOnlyCurrentPriceAndClearsAllowance(uint96) (runs: 1000, μ: 6531087, ~: 6530958)\nLogs:\n  Bound result 60818226357\n\n[PASS] testHandleLengthBoundariesUseBytes() (gas: 78354)\n[PASS] testIntakeFailureZeroAndCollidingIdsRollBackPayment() (gas: 8463720)\n[PASS] testNoAllowanceOrBalanceCannotMintPages() (gas: 605074)\n[PASS] testOraclePriceCeilingIsInclusive() (gas: 1633575)\n[PASS] testRejectedTradesAreAtomicAndLimitsArePerSubject() (gas: 1963627)\n[PASS] testRevertingIssuerPaymentRollsBackSell() (gas: 929330)\n[PASS] testTransferAndApprovalSelectorsCannotMovePages() (gas: 746349)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 484.62ms (1.89s 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 484.73ms (16.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, μ: 131245, ~: 114289)\nLogs:\n  Bound result 5\n  Bound result 999999999999999999999000014089\n  Bound result 111000000000000000000000\n  Bound result 999999999999999999999000002550\n  Bound result 460469231731857444898713964544\n  Bound result 999999999999999999999000000770\n  Bound result 999999999999999999999000011000\n  Bound result 999999999999999999999000014394\n  Bound result 12000000000000000\n  Bound result 999999999999999999999000021088\n  Bound result 999999999999999999999000000031\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36969, ~: 37015)\nLogs:\n  Bound result 9990700\n  Bound result 5298983\n  Bound result 58\n  Bound result 329380255336738246737851089411\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141493, ~: 141832)\nLogs:\n  Bound result 431696574809736422601521170983\n  Bound result 661193283860529433466765598653\n  Bound result 155\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36775, ~: 36929)\nLogs:\n  Bound result 989413\n  Bound result 7\n  Bound result 49\n  Bound result 648218383736360232378645981106\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23364, ~: 21553)\nLogs:\n  Bound result 723229096705732886764314968629170829005\n  Bound result 587180404029121094528748\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39351, ~: 38620)\nLogs:\n  Bound result 2280748896295146521451286538758787183173\n  Bound result 5102009390828217396630593239651240609257\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16308, ~: 14721)\nLogs:\n  Bound result 144\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 54303, ~: 51987)\nLogs:\n  Bound result 79\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36416, ~: 36393)\nLogs:\n  Bound result 1\n  Bound result 1\n  Bound result 32\n  Bound result 345957166306538189104883798229\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 19324, ~: 17016)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21370, ~: 21299)\nLogs:\n  Bound result 5192296858534827628530496329220093\n  Bound result 157018193832545913\n  Bound result 20393\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 63667, ~: 60580)\nLogs:\n  Bound result -380001\n  Bound result 7\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 101431, ~: 91582)\nLogs:\n  Bound result 5\n  Bound result 14088\n  Bound result 111000000000000000000000\n  Bound result 2549\n  Bound result 460469231731687303715884105727\n  Bound result 769\n  Bound result 10999\n  Bound result 14393\n  Bound result 12000000000000000\n  Bound result 21087\n  Bound result 30\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 486.17ms (2.63s 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, μ: 838161, ~: 838176)\nLogs:\n  Bound result 6436877296269736794\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58954, ~: 58968)\nLogs:\n  Bound result 6436877296269736794\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 486.21ms (964.62ms 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 486.37ms (26.25ms 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        | 200   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 242   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 414   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 214   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 210   | 3       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 205   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 206   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 229   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 0\n  Bound result 712\n  Bound result 6375\n  Bound result 14\n  Bound result 0\n  Bound result 1\n  Bound result 9909\n  Bound result 51812\n  Bound result 73\n  Bound result 91\n  Bound result 0\n  Bound result 0\n  Bound result 2\n  Bound result 0\n  Bound result 3037\n  Bound result 1\n  Bound result 285\n  Bound result 1\n  Bound result 16\n  Bound result 2\n  Bound result 2\n  Bound result 197301988533323260985\n  Bound result 0\n  Bound result 2\n  Bound result 6195747421678387004538\n  Bound result 0\n  Bound result 256\n  Bound result 4167\n  Bound result 4\n  Bound result 1\n  Bound result 900000000000000000\n  Bound result 3639\n  Bound result 32\n  Bound result 2\n  Bound result 98644083138018031249\n  Bound result 2\n  Bound result 3893\n  Bound result 50513\n  Bound result 2\n  Bound result 1\n  Bound result 371636862\n  Bound result 0\n  Bound result 562250537601791219118\n  Bound result 51390\n  Bound result 3\n  Bound result 0\n  Bound result 2748\n  Bound result 16384\n  Bound result 70\n  Bound result 2\n  Bound result 2909659950565625346756\n  Bound result 0\n  Bound result 0\n  Bound result 8094\n  Bound result 9262\n  Bound result 15\n  Bound result 2\n  Bound result 1\n  Bound result 2\n  Bound result 5949\n  Bound result 0\n  Bound result 7600\n  Bound result 999\n  Bound result 32\n  Bound result 1\n  Bound result 2526\n  Bound result 2\n  Bound result 0\n  Bound result 100\n  Bound result 400000000000000000000\n  Bound result 1\n  Bound result 3605\n  Bound result 2\n  Bound result 455909028\n  Bound result 49999\n  Bound result 41\n  Bound result 0\n  Bound result 6197\n  Bound result 54906\n  Bound result 55\n  Bound result 0\n  Bound result 1926656081170292321149\n  Bound result 10001\n  Bound result 31\n  Bound result 777\n  Bound result 0\n  Bound result 10500000000000000000\n  Bound result 1\n  Bound result 2\n  Bound result 5170\n  Bound result 0\n  Bound result 1980000000000000000000\n  Bound result 0\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 577.31ms (564.88ms 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   | 2390  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2448  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2529  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2399  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2522  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 1237940039285380274899124224\n  Bound result 2264\n  Bound result 4102\n  Bound result 84329\n  Bound result 2463\n  Bound result 18000\n  Bound result 67487\n  Bound result 7689600\n  Bound result 229\n  Bound result 337004514156665764396983\n  Bound result 4347871784051176899\n  Bound result 120470\n  Bound result 101\n  Bound result 3541\n  Bound result 119\n  Bound result 4493\n  Bound result 7862400\n  Bound result 70386246634238780428520\n  Bound result 1416879341092899500199889022487264508467915316789\n  Bound result 77074\n  Bound result 1110935227663622346370415093635464355886266559188\n  Bound result 999001\n  Bound result 119\n  Bound result 104\n  Bound result 9330295312427474064\n  Bound result 1329227995784915872903807060280344574\n  Bound result 16383\n  Bound result 979642212813691279225310\n  Bound result 4107\n  Bound result 171750\n  Bound result 5589\n  Bound result 198\n  Bound result 3402\n  Bound result 647419086191140876274011\n  Bound result 42847\n  Bound result 219486\n  Bound result 5030473449968935900\n  Bound result 1105000000000000000000\n  Bound result 2881216526201088891\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.25s (1.25s CPU time)\n\nRan 3 tests for test/AnnexInvariant.t.sol:AnnexInvariantTest\n[PASS]\nAnnexInvariantTest invariants:\n[PASS] invariant_admissionIsPermanent\n[PASS] invariant_bondsConserved\n[PASS] invariant_imdHeldEqualsBondsOwed\n[PASS] invariant_noMargRetained\n[PASS] invariant_recordsCountOutcomes\n[PASS] invariant_statusesAreFinalAndDepositsMatch\n AnnexInvariantTest invariants (runs: 96, calls: 4608, reverts: 0)\n\n╭--------------+-------------------+-------+---------+----------╮\n| Contract     | Selector          | Calls | Reverts | Discards |\n+===============================================================+\n| AnnexHandler | admission         | 333   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | claim             | 332   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | moveX             | 276   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | observe           | 378   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | observeSeries     | 342   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | post              | 322   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | pullOrRefillVenue | 318   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | pushEmptyPrice    | 354   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | retract           | 319   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | settle            | 323   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | strangerClaim     | 315   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | tradeMarg         | 362   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | tradeX            | 295   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | warp              | 339   | 0       | 0        |\n╰--------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 4\n  Bound result 1606\n  Bound result 8111\n  Bound result 299999000000002329596499\n  Bound result 99999000000001889567281\n  Bound result 3\n  Bound result 160057\n  Bound result 4992\n  Bound result 12999999999999999987\n  Bound result 4\n  Bound result -2794\n  Bound result 99999540000000000000001\n  Bound result 9000\n  Bound result 52835455817971155097748\n  Bound result 31024\n  Bound result 1\n  Bound result 9750000000000000044\n  Bound result 8644192058950551563\n  Bound result 299999000000000000001911\n  Bound result 3\n  posts 1 settles 1\n  claimed 9750000000000000044 forfeited to pools 0\n  keeper paid 0 admitted hooks 8\n  bounded posts 0 standing readings 0\n\n[PASS] testHandlerPulledPoolDistinguishesWrongFromMissingObservations() (gas: 4694853)\nLogs:\n  Bound result 12000\n  Bound result 1\n  Bound result 1000000000000000000\n  Bound result 8000\n  Bound result 1\n  Bound result 1000000000000000000\n  Bound result 0\n  Bound result 1800\n\n[PASS] testHandlerStandingPricesCanReturnARightBond() (gas: 2680161)\nLogs:\n  Bound result 12000\n  Bound result 1\n  Bound result 10000000000000000000\n  Bound result 3000\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 2.34s (2.33s 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    | 533   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 508   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 528   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 525   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 481   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 502   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 527   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 506   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 501   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 530   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 533   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 962   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 530   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 510   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 528   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 513   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 530   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 490   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 503   | 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 2\n  Bound result 4\n  Bound result 9750000000000004165\n  Bound result 3\n  Bound result 712\n  Bound result 5\n  Bound result 897\n  Bound result 1\n  Bound result 51978338782969654204\n  Bound result 4\n  Bound result 2\n  Bound result 1\n  Bound result 98350000000000000001\n  Bound result 2\n  Bound result 9496579876970476545\n  Bound result 21173\n  Bound result 13581\n  Bound result 99500000000000000000\n  Bound result 2\n  Bound result 4\n  Bound result 2\n  Bound result 9750000000000300001\n  Bound result 2\n  Bound result 9750000000000009556\n  Bound result 21397\n  Bound result 100000000000000000000\n  Bound result 93548029094435468756\n  Bound result 310470\n  Bound result 99999002500000000000001\n  Bound result 3\n  Bound result 6\n  Bound result 99999000000000000004656\n  Bound result 201\n  Bound result 9\n  Bound result 1\n  Bound result 951359117231665614\n  Bound result 10\n  Bound result 98000000000011155112\n  Bound result 6\n  Bound result 6\n  Bound result 9846774065303830508994\n  Bound result 98750000000000000001\n  Bound result 76676379976990354261770\n  Bound result 11\n  Bound result 61124923001360546395\n  Bound result 8\n  Bound result 10\n  Bound result 6\n  Bound result 200\n  Bound result 29950000000000000000\n  Bound result 98000000000000021821\n  Bound result 317527\n  Bound result 98000000000000003049\n  Bound result 16\n  Bound result 2\n  Bound result 9750000000000009689\n  Bound result 12500\n  Bound result 7729809071511458577\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.65s (7.66s CPU time)\n\nRan 2 tests for test/PagesInvariant.t.sol:PagesInvariantTest\n[PASS] invariant_reservesEscrowFeesAndOwnershipConserved() (runs: 256, calls: 24576, reverts: 0)\n\n╭--------------+-----------------+-------+---------+----------╮\n| Contract     | Selector        | Calls | Reverts | Discards |\n+=============================================================+\n| PagesHandler | abandon         | 1845  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | advanceTime     | 1860  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | answer          | 1934  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | burn            | 1952  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | buy             | 1858  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | donate          | 1950  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | exitWithoutGate | 1928  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | recycle         | 1846  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | request         | 1869  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | roundTrip       | 1834  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | sell            | 1935  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | setGate         | 1881  | 0       | 0        |\n|--------------+-----------------+-------+---------+----------|\n| PagesHandler | setLiquidity    | 1884  | 0       | 0        |\n╰--------------+-----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10732\n  Bound result 5402\n  Bound result 10\n  Bound result 2\n  Bound result 10\n  Bound result 18463\n  Bound result 5\n  Bound result 3\n  Bound result 2\n  Bound result 10\n  Bound result 999001\n  Bound result 11854\n  Bound result 556750000000000000\n  Bound result 1824\n  Bound result 9001\n  Bound result 6372\n  Bound result 9953\n  Bound result 3001\n  Bound result 685\n  Bound result 23449\n  Bound result 5970\n  Bound result 3\n  Bound result 23302\n  Bound result 264337593543950333\n  Bound result 2992\n  Bound result 3728\n  Bound result 3\n  Bound result 3\n  Bound result 93500000000052556\n  Bound result 13861\n  Bound result 3909\n  Bound result 404485983285048186\n  Bound result 705\n  Bound result 4\n  Bound result 299335870152406316\n  Bound result 3\n  Bound result 4\n  Bound result 1022\n  Bound result 1125\n  Bound result 591\n  Bound result 10\n\n[PASS] testHandlerExercisesClaimRecycleBurnAndUngatedExit() (gas: 21525232)\nLogs:\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 10\n  Bound result 5\n  Bound result 3\n  Bound result 500000000000000000\n  Bound result 500000000000000000\n  Bound result 1\n  Bound result 10\n  Bound result 250000000000000000\n  Bound result 259200\n  Bound result 2678400\n  Bound result 2678400\n  Bound result 2678400\n  Bound result 265\n  Bound result 1\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 38.03s (38.05s CPU time)\n\nRan 34 test suites in 38.04s (55.14s CPU time): 373 tests passed, 0 failed, 2 skipped (375 total tests)\n","passed":true},{"durationMs":214,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaAnnex.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaAnnex.claimDeposit(bytes32)\",\"MarginaliaAnnex.observe(bytes32)\",\"MarginaliaAnnex.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaAnnex.post((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256,uint256)\",\"MarginaliaAnnex.requestAdmission(address[])\",\"MarginaliaAnnex.retract(bytes32,string)\",\"MarginaliaAnnex.settle(bytes32)\",\"MarginaliaAnnex.unlockCallback(bytes)\",\"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.burn(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.registerHandle(string)\",\"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\":14,\"ADAPTATION.md\":603,\"AGENTS.md\":128,\"README.md\":295,\"SPEC.md\":298,\"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,\"drafts/thesis-imd.md\":34,\"drafts/thesis-infer.md\":31,\"drafts/thesis-zto.md\":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\":38,\"jobs/launch-D-annex.json\":37,\"jobs/launch-E-pages-v2.json\":36,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"jobs/site-B-v2.json\":27,\"jobs/site-C-v3.json\":26,\"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,\"llms.txt\":27,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaAnnex.sol\":695,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":531,\"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/Annex.t.sol\":1053,\"test/AnnexAdversarial.t.sol\":1322,\"test/AnnexInvariant.t.sol\":775,\"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_TEST_COVERAGE.md\":37,\"test/Pages.t.sol\":542,\"test/PagesAudit.t.sol\":375,\"test/PagesDeployment.t.sol\":186,\"test/PagesInvariant.t.sol\":556,\"test/PagesOracleBoundaries.t.sol\":330,\"test/PagesProperties.t.sol\":377,\"test/PagesReentrancy.t.sol\":133,\"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\":130,\"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":"1b1f5ad2f6770d6d9cbf39ce8bafb03213b72088ab297049fce37616db05f223","verifiedTreeHash":"ec7e55e54212e6b82919388db90f21fb39a1da68","verifierVersion":"0.1.0+aca0ff06"},{"checks":[{"durationMs":720897,"exitCode":0,"name":"build","output":"Compiling 127 files with Solc 0.8.26\nSolc 0.8.26 finished in 720.19s\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/AnnexInvariant.t.sol:530:52:\n    |\n530 |         try annex.requestAdmission(asked) returns (bytes32 r) {\n    |                                                    ^^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/AnnexInvariant.t.sol:557:19:\n    |\n557 |         (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerKey, annex.attestationDigest(a));\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[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/MarginaliaAnnex.sol:489:45\n    │\n489 │         if (!ok || ret.length < 32) return (false, 0);\n    │                                             ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\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:203:17\n    │\n203 │                 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/MarginaliaPages.sol:242:29\n    │\n242 │         (, uint32 posted) = IMarginaliaRecords(address(hook)).records(wallet);\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/MarginaliaPages.sol:245:13\n    │\n245 │             (, posted) = annex.records(wallet);\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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:320:17\n    │\n320 │             try hook.poolManager().unlock(abi.encode(toBurn, uint256(0))) returns (bytes memory) {}\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:328:13\n    │\n328 │             hook.fundPot(toPools);\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/MarginaliaAnnex.sol:657:9\n    │\n657 │         hook.poolManager().unlock(abi.encode(imdIn, authorIn, minOut, to));\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:285:9\n    │\n285 │         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/MarginaliaAnnex.sol:253:13\n    │\n253 │         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:282:21\n    │\n282 │         s.supply += uint64(amount);\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/MarginaliaAnnex.sol:295:9\n    │\n295 │         emit NotePosted(id, author, p.x, n.class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaAnnex.sol:278:22\n    │\n278 │         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[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaAnnex.sol:279:17\n    │\n279 │         n.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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:300:9\n    │\n300 │         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:296:21\n    │\n296 │         s.supply -= uint64(amount);\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/MarginaliaAnnex.sol:333:13\n    │\n333 │         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/MarginaliaAnnex.sol:334:13\n    │\n334 │         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/MarginaliaAnnex.sol:345:47\n    │\n345 │                     || (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/MarginaliaAnnex.sol:353:9\n    │\n353 │         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/MarginaliaAnnex.sol:339:27\n    │\n339 │             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/MarginaliaAnnex.sol:339:52\n    │\n339 │             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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaAnnex.sol:439:9\n    │\n439 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/MarginaliaAnnex.sol:398:35\n    │\n398 │         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/MarginaliaAnnex.sol:360:13\n    │\n360 │         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/MarginaliaAnnex.sol:398:9\n    │\n398 │         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/MarginaliaAnnex.sol:385:30\n    │\n385 │         int256 scoreDelta = -int256(diff);\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/MarginaliaAnnex.sol:388:26\n    │\n388 │             scoreDelta = int256(diff);\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/MarginaliaAnnex.sol:405:13\n    │\n405 │         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/MarginaliaAnnex.sol:412:9\n    │\n412 │         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/MarginaliaAnnex.sol:413:9\n    │\n413 │         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/MarginaliaAnnex.sol:407:30\n    │\n407 │         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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaPages.sol:323:17\n    │\n323 │                 emit BurnDeferred(toBurn);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:314:53\n    │\n314 │             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:409:21\n    │\n409 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n410 │ ┃             action,\n411 │ ┃             bytes(questionBody(normalized, tweetId)),\n412 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n413 │ ┃             imd,\n414 │ ┃             price\n415 │ ┃         );\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:420:9\n    │\n420 │         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:418:63\n    │\n418 │         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[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaAnnex.sol:452:17\n    │\n452 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaAnnex.sol:488:21\n    │\n488 │         (ok, ret) = x.staticcall{gas: BALANCE_READ_GAS}(data);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\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:446:13\n    │\n446 │             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:459:9\n    │\n459 │         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:467:13\n    │\n467 │         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:484:9\n    │\n484 │         hook.fundPot(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/MarginaliaPages.sol:479:13\n    │\n479 │         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:485:9\n    │\n485 │         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/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-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:498:9\n    │\n498 │         hook.poolManager().unlock(abi.encode(imdIn, minMargOut));\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/MarginaliaAnnex.sol:612:21\n    │\n612 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n613 │ ┃             action,\n614 │ ┃             bytes(admissionBody(hooks)),\n615 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n616 │ ┃             imd,\n617 │ ┃             price\n618 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:494:44\n    │\n494 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) {\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:494:52\n    │\n494 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) {\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: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/MarginaliaPages.sol:498:9\n    │\n498 │         hook.poolManager().unlock(abi.encode(imdIn, minMargOut));\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/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-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaAnnex.sol:622:9\n    │\n622 │         emit AdmissionRequested(requestId, msg.sender, hooks, price);\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/MarginaliaAnnex.sol:605:70\n    │\n605 │             if (hooks[i] == address(0) || hooks[i].code.length == 0) revert BadList();\n    │                                                                      ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-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:528:9\n    │\n528 │         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:512:18\n    │\n512 │                 -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:519:38\n    │\n519 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-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:519:46\n    │\n519 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-inD)) != imdIn) revert UnauthorizedCallback();\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:524:9\n    │\n524 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:525:24\n    │\n525 │         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:525:32\n    │\n525 │         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[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-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaAnnex.sol:646:21\n    │\n646 │                     emit HookAdmitted(open[i], requestId);\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/MarginaliaAnnex.sol:657:9\n    │\n657 │         hook.poolManager().unlock(abi.encode(imdIn, authorIn, minOut, to));\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/MarginaliaAnnex.sol:691:13\n    │\n691 │             emit Burned(imdIn - authorIn, marg - authorMarg);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaAnnex.sol:672:18\n    │\n672 │                 -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/MarginaliaAnnex.sol:679:38\n    │\n679 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-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/MarginaliaAnnex.sol:679:46\n    │\n679 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-inD)) != imdIn) revert UnauthorizedCallback();\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/MarginaliaAnnex.sol:680:24\n    │\n680 │         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/MarginaliaAnnex.sol:680:32\n    │\n680 │         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/MarginaliaAnnex.sol:687:9\n    │\n687 │         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: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.chainid` may be reused across `vm.chainId`\n     ╭▸ test/AnnexAdversarial.t.sol:190:21\n     │\n 190 │         a.chainId = block.chainid;\n     │                     ━━━━━━━━━━━━━\n     ‡\n1088 │         vm.chainId(999);\n     │         ─────────────── `vm.chainId` changes this environment here\n     │\n     ├ help: capture it with `vm.getChainId()` 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/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":14130,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\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 7.11ms (3.05ms 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 8.12ms (475.16µs 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 14.45ms (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 14.20ms (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 18.79ms (5.25ms CPU time)\n\nRan 4 tests for test/PagesDeployment.t.sol:PagesOracleConformanceTest\n[PASS] testAddressAnswerFromVectorKeyDeliveredUnderStipend() (gas: 1648963)\n[PASS] testCallbackSelectorMatchesProtocol() (gas: 3739)\n[PASS] testDigestMatchesPinnedProtocolVector() (gas: 13296)\n[PASS] testVerifiesPinnedProtocolSignature() (gas: 17015)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 22.47ms (7.80ms 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 27.13ms (22.07ms 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 39.24ms (14.79ms CPU time)\n\nRan 14 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2898172)\n[PASS] testAnnexLegIsOffWhenUnset() (gas: 4151632)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2904850)\n[PASS] testBuyGateWhitelistMargOrNotes() (gas: 1941906)\n[PASS] testBuyPaysTheIssuerBurnsMargAndFundsThePools() (gas: 562885)\n[PASS] testCurveIsLinearThenCapped() (gas: 103553)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 4731069)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 64454)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37650)\n[PASS] testPerWalletLimitAndTheCap() (gas: 9388256)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 171085)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2603908)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 1021356)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 2111036)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 47.84ms (33.57ms 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 48.07ms (17.61ms 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 51.35ms (26.50ms CPU time)\n\nRan 29 tests for test/AnnexAdversarial.t.sol:AnnexAdversarialTest\n[PASS] testAdmissionListRulesAndPrice() (gas: 2592651)\n[PASS] testAnEmptyAnswerIsStoredNotReverted() (gas: 1165039)\n[PASS] testAnLpPullCannotTurnAWrongCallIntoARefund() (gas: 1826114)\n[PASS] testAttestationEdgesAreRefusedOneByOne() (gas: 1594187)\n[PASS] testBaselineBoundIsInclusiveAtTheBaselineAndOffAtZero() (gas: 3640042)\n[PASS] testBaselineBoundReadsTheSidesOwnBaseline() (gas: 2452540)\n[PASS] testCallbackGasAtTheFullListStaysUnderTheStipend() (gas: 2110451)\n[PASS] testCheckpointWindowAgesAndExpiresLikeTheRouter() (gas: 4984262)\n[PASS] testConstructorStoresFourValuesWithoutReadingTheChain() (gas: 51698)\n[PASS] testCountersRefuseClosedParentsAndTheses() (gas: 5716846)\n[PASS] testFewerThanThreeStandingReadingsAreStillNoData() (gas: 1584176)\n[PASS] testHoldRuleGiftsCountAsHeldAndAReadFailureAsBroken() (gas: 4206416)\n[PASS] testLifecycleRefusalsOnUnknownClosedAndForeignNotes() (gas: 1869727)\n[PASS] testMoreAdverseReadingReplacesTheLastInTheSameBlock() (gas: 1808241)\n[PASS] testOneOracleUuidServesOneRequestOnly() (gas: 1423863)\n[PASS] testPostBoundariesExactly() (gas: 2254356)\n[PASS] testProtocolVectorDigestSelectorAndSignature() (gas: 1184381)\n[PASS] testScoreIsDifficultyWeightedAndRetractIsHalf() (gas: 4699329)\n[PASS] testSellCallSettlesRightAndMaySellThroughTheHorizon() (gas: 1544132)\n[PASS] testSellCallWrongWhenThePriceRises() (gas: 1597641)\n[PASS] testSettlementTakesTheMostAdverseReading() (gas: 1764967)\n[PASS] testSixteenReadingsAtMostAndTheLastSlotWaitsForTheHour() (gas: 4679743)\n[PASS] testSlippageAndUnfundedAuthorsTakeNothing() (gas: 1560244)\n[PASS] testSoldOutSellCallReturnsItsBond() (gas: 3296468)\n[PASS] testSplitIsExactAndNothingStaysInTheAnnex() (gas: 634423)\n[PASS] testStandingReadingsKeepPriceOrderingAndHoldBreachPriority() (gas: 5443760)\n[PASS] testThreeReadingsInsideAnHourAreNoData() (gas: 1494972)\n[PASS] testUnlockCallbackAcceptsOnlyThePoolManager() (gas: 630742)\n[PASS] testVenueQuoteRule() (gas: 1230415)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 99.40ms (85.48ms 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 148.45ms (144.71ms 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 155.39ms (168.00ms 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, μ: 105992, ~: 106115)\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 239.91ms (188.34ms 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 242.42ms (142.41ms CPU time)\n\nRan 2 tests for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testConstructorRejectsMissingRequiredValues() (gas: 1742975)\n[PASS] testFactoryDeploysExactlyPagesWithNoDependencyCode() (gas: 13706462)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 246.33ms (140.78ms 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 255.57ms (83.62ms 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 295.80ms (117.38ms CPU time)\n\nRan 29 tests for test/Annex.t.sol:AnnexTest\n[PASS] testAPulledPoolPushedToAnExtremeIsReadAtTheExtreme() (gas: 4898651)\n[PASS] testAdmissionAsksThePanelAndAdmitsOnlyWhatItNamed() (gas: 2491254)\n[PASS] testAdmissionBodyIsStrictJson() (gas: 759446)\n[PASS] testAdmissionRefusesBadAnswersAndBadLists() (gas: 1542625)\n[PASS] testAgentClassForContractAuthors() (gas: 1208062)\n[PASS] testAnAdmittedHookPassesTheDynamicFeeGate() (gas: 1042590)\n[PASS] testBaselineBoundRefusesASandwichedPost() (gas: 3472853)\n[PASS] testBuyCallOnAnUnreadableBalanceIsRefusedLikeTheHook() (gas: 2799765)\n[PASS] testBuyCallOnMargCountsThePurchaseOnce() (gas: 1467516)\n[PASS] testCounterAgainstAHookNoteAndAgainstAnAnnexNote() (gas: 3609075)\n[PASS] testDynamicFeePoolNeedsAdmissionEvenWithoutSwapBits() (gas: 135567)\n[PASS] testEmptiedVenueForfeitsInsteadOfRefunding() (gas: 3126196)\n[PASS] testEmptiedVenueOnASoldBuyCallIsStillVoidSold() (gas: 1677805)\n[PASS] testEmptyTextIsRefusedLikeTheHook() (gas: 54539)\n[PASS] testFullListFitsTheCallbackStipend() (gas: 1851403)\n[PASS] testHeldPriceStillSettlesRightAfterAFailedFlashRead() (gas: 2230314)\n[PASS] testHoldRuleVoidsASoldBuyCall() (gas: 1708364)\n[PASS] testHookBitsDecideWithoutAnOracle() (gas: 98895)\n[PASS] testMargVenueBaselineBoundNeedsRoomForThePostsOwnPurchase() (gas: 1102399)\n[PASS] testNoObservationsVoidAndReturnTheBond() (gas: 734020)\n[PASS] testNoteOfAnUnknownIdReverts() (gas: 23176)\n[PASS] testObservationInsideAnUnlockIsRefused() (gas: 2956772)\n[PASS] testObservationWindowAndSpacing() (gas: 901122)\n[PASS] testPostPaysTheStampBuysMargAndHoldsTheBond() (gas: 857166)\n[PASS] testRefusesWhatTheRouterAlreadyTakesAndBadKeys() (gas: 137269)\n[PASS] testRetractHalvesTheScoreAndForfeitsWithoutAKeeperCut() (gas: 924322)\n[PASS] testRightCallReturnsTheBond() (gas: 1529261)\n[PASS] testSoldOutRangeStillSettlesRight() (gas: 3269214)\n[PASS] testWrongCallForfeitsToThePoolsWithTheSettlerCut() (gas: 1511821)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 506.67ms (72.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 506.69ms (355.62ms 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, μ: 23075, ~: 21270)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 506.74ms (117.62ms 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, μ: 133673, ~: 114953)\nLogs:\n  Bound result 9\n  Bound result 999999999999999999999717473627\n  Bound result 999999999999999999999000006656\n  Bound result 999999999999999999999000000065\n  Bound result 1980000000000000000000\n  Bound result 999999999999999999999000000211\n  Bound result 500000000000000001\n  Bound result 999999999999999999999000005393\n  Bound result 999999999999999999999000020001\n  Bound result 999999999999999999999000604801\n  Bound result 5000000000000000000000\n  Bound result 999999999999999999999000000008\n  Bound result 999999999999999999999000001569\n  Bound result 999999999999999999999000009872\n  Bound result 50000000000000000\n  Bound result 999999999999999999999000004367\n  Bound result 999999999999999999999000016385\n  Bound result 999999999999999999999000000028\n  Bound result 999999999999999999999000021196\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36946, ~: 36940)\nLogs:\n  Bound result 9994092\n  Bound result 6174901\n  Bound result 50\n  Bound result 18221\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141428, ~: 141832)\nLogs:\n  Bound result 1041173380337149948387876096202\n  Bound result 1267650600227075352991603096573\n  Bound result 21584\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36746, ~: 36900)\nLogs:\n  Bound result 29731\n  Bound result 1\n  Bound result 70\n  Bound result 373718802309406306551031488794\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23436, ~: 21564)\nLogs:\n  Bound result 140582071381663874662\n  Bound result 1461446703485210103287273052103988822379104253408\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39361, ~: 38377)\nLogs:\n  Bound result 1750645909251661292621459641794150\n  Bound result 100434969274553\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16098, ~: 14648)\nLogs:\n  Bound result 26\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 54051, ~: 51987)\nLogs:\n  Bound result 20294\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36408, ~: 36409)\nLogs:\n  Bound result 5091\n  Bound result 5032\n  Bound result 50\n  Bound result 18221\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 18895, ~: 16591)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21354, ~: 21299)\nLogs:\n  Bound result 877997019\n  Bound result 268\n  Bound result 1\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 64532, ~: 61370)\nLogs:\n  Bound result 71196\n  Bound result 5\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 102677, ~: 92669)\nLogs:\n  Bound result 11\n  Bound result 828866445970753928249797025955\n  Bound result 471272522134975874386\n  Bound result 413818175434632331801322797506\n  Bound result 8289598\n  Bound result 167358914458145477976934862\n  Bound result 214222675539708891149027133382\n  Bound result 3247782846972250312820547291\n  Bound result 943092061014301105962775783892\n  Bound result 456933864701668858223847489544\n  Bound result 813186108310340763982911260853\n  Bound result 328127197570302973657459622286\n  Bound result 299536343002591862196462905391\n  Bound result 6712421897844721\n  Bound result 3\n  Bound result 1\n  Bound result 252750181587099696321347612991\n  Bound result 1\n  Bound result 1867975921\n  Bound result 544174553570234783085437480078\n  Bound result 64861891058744542\n  Bound result 5336277\n  Bound result 96296087568018452432536706546\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 508.87ms (2.95s 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, μ: 838161, ~: 838176)\nLogs:\n  Bound result 6521725399258997729\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58954, ~: 58968)\nLogs:\n  Bound result 300000000000000000\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 509.22ms (453.85ms CPU time)\n\nRan 15 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonClaimCannotReenterAnotherClaimRequest() (gas: 5038391)\n[PASS] testBurnRetryIsBoundedAtomicAndKeepsEscrowAndReserve() (gas: 2838763)\n[PASS] testClaimQuestionRequiresExactIntentBoundToThisDeployment() (gas: 5589085)\n[PASS] testFirstBuyWindowRecyclesEvenRecentlyAccruedFees() (gas: 1019415)\n[PASS] testFuzzDeferredBurnLiabilities(uint8,uint8,uint8) (runs: 256, μ: 2043514, ~: 2045065)\nLogs:\n  Bound result 4\n  Bound result 6\n  Bound result 1\n\n[PASS] testHealthyTradesLeaveEarlierPendingBurnForExplicitRetry() (gas: 1420408)\n[PASS] testOnlyRegisteredHandlePreimagesOrNonzeroAddressesCanBeBought() (gas: 1084837)\n[PASS] testOracleUuidReplayCannotBindAnotherHandle() (gas: 2152689)\n[PASS] testPartialBurnFillRollsBackOnlyTheSwap() (gas: 1192431)\n[PASS] testRegistrationAndQuestionPreviewRejectMalformedHandles() (gas: 131538)\n[PASS] testRejectedTweetThenExplicitClaimAndDistinctOracleRequestId() (gas: 2874745)\n[PASS] testSoldOutLaunchPoolDoesNotBlockBuyingOrSelling() (gas: 2025544)\n[PASS] testV1MissingAnswerLocksUntilAnyoneAbandonsAtThreeDays() (gas: 2848354)\n[PASS] testWhitelistFailedOrShortReadsCountAsNotListed() (gas: 133255)\n[PASS] testWithdrawnLaunchLiquidityDoesNotBlockBuyingOrSelling() (gas: 2968129)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 509.40ms (595.05ms 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: 1)\n\n╭---------------+----------------+-------+---------+----------╮\n| Contract      | Selector       | Calls | Reverts | Discards |\n+=============================================================+\n| RouterHandler | advance        | 250   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 225   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 403   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 213   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 235   | 1       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 187   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 193   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 214   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 17035\n  Bound result 2\n  Bound result 4054\n  Bound result 1\n  Bound result 461128853466904807255\n  Bound result 1\n  Bound result 16109\n  Bound result 0\n  Bound result 345600\n  Bound result 1631\n  Bound result 85\n  Bound result 2\n  Bound result 11283\n  Bound result 51051\n  Bound result 2\n  Bound result 1\n  Bound result 3146484516\n  Bound result 10000\n  Bound result 54\n  Bound result 0\n  Bound result 2\n  Bound result 5509\n  Bound result 0\n  Bound result 42\n  Bound result 0\n  Bound result 22226\n  Bound result 0\n  Bound result 500000000000000000000\n  Bound result 0\n  Bound result 0\n  Bound result 5303\n  Bound result 1\n  Bound result 700000000000000000000\n  Bound result 50120\n  Bound result 26\n  Bound result 91\n  Bound result 1\n  Bound result 1\n  Bound result 3199\n  Bound result 1\n  Bound result 15798\n  Bound result 19152\n  Bound result 81\n  Bound result 2\n  Bound result 1050000000000000000\n  Bound result 18\n  Bound result 68\n  Bound result 1\n  Bound result 2\n  Bound result 2000000000000000000000\n  Bound result 6957\n  Bound result 48\n  Bound result 15470\n  Bound result 2\n  Bound result 0\n  Bound result 50000000000000000000\n  Bound result 50229\n  Bound result 27\n  Bound result 1\n  Bound result 33424336708390\n  Bound result 4457\n  Bound result 11\n  Bound result 1\n  Bound result 6154428405244755968\n  Bound result 4436\n  Bound result 1\n  Bound result 1542793012780631851008\n  Bound result 9001\n  Bound result 76\n  Bound result 109\n  Bound result 1\n  Bound result 3652\n  Bound result 2748\n  Bound result 14\n  Bound result 0\n  Bound result 75000000000000000000\n  Bound result 18285\n  Bound result 30\n  Bound result 0\n  Bound result 8019\n  Bound result 4999\n  Bound result 10\n  Bound result 2\n  Bound result 320\n  Bound result 0\n  Bound result 13492\n  Bound result 22875\n  Bound result 0\n  Bound result 362\n  Bound result 1\n  Bound result 2\n  Bound result 15979\n  Bound result 816\n  Bound result 80\n  Bound result 3730\n  Bound result 2\n  Bound result 1943469377589179010483\n  Bound result 11729\n  Bound result 71\n  Bound result 1\n  Bound result 17183\n  Bound result 50051\n  Bound result 37\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.00s (976.93ms 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   | 2441  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2505  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2404  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2409  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2529  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 101\n  Bound result 3000000000000000000\n  Bound result 42896\n  Bound result 194\n  Bound result 172240725962693073438654\n  Bound result 1559\n  Bound result 205792988018905490250\n  Bound result 107\n  Bound result 2500000000000000\n  Bound result 10\n  Bound result 14\n  Bound result 450000000000000000\n  Bound result 5555\n  Bound result 8059\n  Bound result 5836\n  Bound result 94176\n  Bound result 6373213064914128330\n  Bound result 8371\n  Bound result 4079\n  Bound result 210\n  Bound result 1000\n  Bound result 249\n  Bound result 30\n  Bound result 6718\n  Bound result 1687303715884105728\n  Bound result 1886\n  Bound result 9999999999999999999\n  Bound result 807570952\n  Bound result 2246\n  Bound result 5000000000000000000\n  Bound result 6331\n  Bound result 613\n  Bound result 500000000000000000000000\n  Bound result 305372827760294935140524312663691576001438142141\n  Bound result 7806\n  Bound result 627206721492376107\n  Bound result 1052\n  Bound result 2\n  Bound result 8\n  Bound result 20000000000000000\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.73s (2.68s CPU time)\n\nRan 3 tests for test/AnnexInvariant.t.sol:AnnexInvariantTest\n[PASS]\nAnnexInvariantTest invariants:\n[PASS] invariant_admissionIsPermanent\n[PASS] invariant_bondsConserved\n[PASS] invariant_imdHeldEqualsBondsOwed\n[PASS] invariant_noMargRetained\n[PASS] invariant_recordsCountOutcomes\n[PASS] invariant_statusesAreFinalAndDepositsMatch\n AnnexInvariantTest invariants (runs: 96, calls: 4608, reverts: 0)\n\n╭--------------+-------------------+-------+---------+----------╮\n| Contract     | Selector          | Calls | Reverts | Discards |\n+===============================================================+\n| AnnexHandler | admission         | 330   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | claim             | 302   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | moveX             | 344   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | observe           | 321   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | observeSeries     | 333   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | post              | 338   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | pullOrRefillVenue | 307   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | pushEmptyPrice    | 334   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | retract           | 337   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | settle            | 350   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | strangerClaim     | 314   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | tradeMarg         | 347   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | tradeX            | 337   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | warp              | 314   | 0       | 0        |\n╰--------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 37502358588873808528869\n  Bound result 359\n  Bound result 4\n  Bound result 1\n  Bound result 6601\n  Bound result 4\n  Bound result 9750000000000011211\n  Bound result 25600\n  Bound result 11630\n  Bound result 99999000000000000011307\n  Bound result 32733\n  Bound result 2\n  Bound result 9750000000000020341\n  Bound result 4457000165736071418318\n  Bound result 1808166536452345898\n  Bound result 24615\n  Bound result 6536\n  Bound result 5\n  Bound result 250000000000000003\n  Bound result 11000999999999999999999\n  Bound result 3870\n  Bound result 2\n  Bound result 9750000000000010762\n  Bound result 2\n  Bound result 20077\n  Bound result 18565\n  Bound result 99999000000000000010202\n  posts 4 settles 3\n  claimed 9750000000000011211 forfeited to pools 0\n  keeper paid 0 admitted hooks 0\n  bounded posts 2 standing readings 0\n\n[PASS] testHandlerPulledPoolDistinguishesWrongFromMissingObservations() (gas: 4694853)\nLogs:\n  Bound result 12000\n  Bound result 1\n  Bound result 1000000000000000000\n  Bound result 8000\n  Bound result 1\n  Bound result 1000000000000000000\n  Bound result 0\n  Bound result 1800\n\n[PASS] testHandlerStandingPricesCanReturnARightBond() (gas: 2680161)\nLogs:\n  Bound result 12000\n  Bound result 1\n  Bound result 10000000000000000000\n  Bound result 3000\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 4.74s (4.74s 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    | 469   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 482   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 552   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 508   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 525   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 545   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 513   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 532   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 496   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 535   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 514   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 989   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 491   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 548   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 492   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 506   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 489   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 521   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 533   | 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 98000000000000018938\n  Bound result 5\n  Bound result 2\n  Bound result 3600\n  Bound result 4\n  Bound result 5\n  Bound result 4\n  Bound result 2\n  Bound result 5\n  Bound result 11770\n  Bound result 11467\n  Bound result 528497694\n  Bound result 1\n  Bound result 90071497916671591144478\n  Bound result 99999000000000000014046\n  Bound result 9750000000000014827\n  Bound result 488353119742401968\n  Bound result 17521\n  Bound result 40417\n  Bound result 3\n  Bound result 9750000000000017499\n  Bound result 2\n  Bound result 5\n  Bound result 9750000000000005820\n  Bound result 4696\n  Bound result 100000000000000000000000\n  Bound result 8\n  Bound result 8\n  Bound result 8\n  Bound result 8\n  Bound result 8\n  Bound result 100000000000000000\n  Bound result 7\n  Bound result 36191114903625715570522\n  Bound result 1100000000000000000\n  Bound result 30\n  Bound result 99999000000000000012346\n  Bound result 6\n  Bound result 1\n  Bound result 755000000000000000\n  Bound result 9\n  Bound result 9750000000000000058\n  Bound result 10\n  Bound result 98000000000000010000\n  Bound result 3660\n  Bound result 74165248848346733081\n  Bound result 264000000000000000\n  Bound result 12\n  Bound result 8\n  Bound result 99999000000000000002272\n  Bound result 9\n  Bound result 5\n  Bound result 14264337632365749961\n  Bound result 99999000000000000013635\n  Bound result 12\n  Bound result 38929206074730592828\n  Bound result 8\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 13.81s (13.80s CPU time)\n\nRan 29 test suites in 13.82s (27.30s CPU time): 345 tests passed, 0 failed, 2 skipped (347 total tests)\n","passed":true},{"durationMs":371,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaAnnex.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaAnnex.claimDeposit(bytes32)\",\"MarginaliaAnnex.observe(bytes32)\",\"MarginaliaAnnex.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaAnnex.post((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256,uint256)\",\"MarginaliaAnnex.requestAdmission(address[])\",\"MarginaliaAnnex.retract(bytes32,string)\",\"MarginaliaAnnex.settle(bytes32)\",\"MarginaliaAnnex.unlockCallback(bytes)\",\"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.burn(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.registerHandle(string)\",\"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\":14,\"ADAPTATION.md\":603,\"AGENTS.md\":128,\"README.md\":295,\"SPEC.md\":298,\"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,\"drafts/thesis-imd.md\":34,\"drafts/thesis-infer.md\":31,\"drafts/thesis-zto.md\":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\":38,\"jobs/launch-D-annex.json\":37,\"jobs/launch-E-pages-v2.json\":36,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"jobs/site-B-v2.json\":27,\"jobs/site-C-v3.json\":26,\"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\":16,\"llms.txt\":27,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaAnnex.sol\":695,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":531,\"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/Annex.t.sol\":1053,\"test/AnnexAdversarial.t.sol\":1322,\"test/AnnexInvariant.t.sol\":775,\"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\":542,\"test/PagesAudit.t.sol\":375,\"test/PagesDeployment.t.sol\":186,\"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\":130,\"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":"779bd2797ceb5532d8142280704fbb6a30b9d4a6923cf0973024e98884986538","verifiedTreeHash":"40a4d6b9beeccc2c6380210b3323eded6009384f","verifierVersion":"0.1.0+788bb33f"},{"checks":[{"durationMs":625884,"exitCode":0,"name":"build","output":"Compiling 127 files with Solc 0.8.26\nSolc 0.8.26 finished in 625.22s\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/AnnexInvariant.t.sol:530:52:\n    |\n530 |         try annex.requestAdmission(asked) returns (bytes32 r) {\n    |                                                    ^^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/AnnexInvariant.t.sol:557:19:\n    |\n557 |         (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerKey, annex.attestationDigest(a));\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[boolean-cst]: misuse of a boolean constant\n    ╭▸ src/MarginaliaAnnex.sol:489:45\n    │\n489 │         if (!ok || ret.length < 32) return (false, 0);\n    │                                             ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\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[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/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[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: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/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: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[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: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[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[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[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/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/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: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[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/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[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[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/MarginaliaAnnex.sol:657:9\n    │\n657 │         hook.poolManager().unlock(abi.encode(imdIn, authorIn, minOut, to));\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/MarginaliaAnnex.sol:253:13\n    │\n253 │         if (block.timestamp > deadline) revert Expired();\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/MarginaliaAnnex.sol:295:9\n    │\n295 │         emit NotePosted(id, author, p.x, n.class, p.side, p.targetBps, p.horizonDays, p.parentId, p.text);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaAnnex.sol:278:22\n    │\n278 │         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[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[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaAnnex.sol:279:17\n    │\n279 │         n.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[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[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/MarginaliaAnnex.sol:333:13\n    │\n333 │         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/MarginaliaAnnex.sol:334:13\n    │\n334 │         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/MarginaliaAnnex.sol:345:47\n    │\n345 │                     || (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/MarginaliaAnnex.sol:353:9\n    │\n353 │         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/MarginaliaAnnex.sol:339:27\n    │\n339 │             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/MarginaliaAnnex.sol:339:52\n    │\n339 │             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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaAnnex.sol:439:9\n    │\n439 │         hook.fundPot(amount);\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/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/MarginaliaAnnex.sol:398:35\n    │\n398 │         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/MarginaliaAnnex.sol:360:13\n    │\n360 │         if (block.timestamp <= end + SETTLE_WINDOW) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaAnnex.sol:398:9\n    │\n398 │         emit Settled(id, outcome, settlePrice, scoreDelta, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\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[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaAnnex.sol:385:30\n    │\n385 │         int256 scoreDelta = -int256(diff);\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/MarginaliaAnnex.sol:388:26\n    │\n388 │             scoreDelta = int256(diff);\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 `_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/MarginaliaAnnex.sol:405:13\n    │\n405 │         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/MarginaliaAnnex.sol:412:9\n    │\n412 │         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/MarginaliaAnnex.sol:413:9\n    │\n413 │         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/MarginaliaAnnex.sol:407:30\n    │\n407 │         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/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[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/MarginaliaPages.sol:203:17\n    │\n203 │                 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/MarginaliaPages.sol:242:29\n    │\n242 │         (, uint32 posted) = IMarginaliaRecords(address(hook)).records(wallet);\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/MarginaliaPages.sol:245:13\n    │\n245 │             (, posted) = annex.records(wallet);\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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:320:17\n    │\n320 │             try hook.poolManager().unlock(abi.encode(toBurn, uint256(0))) returns (bytes memory) {}\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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaPages.sol:328:13\n    │\n328 │             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/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:285:9\n    │\n285 │         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/MarginaliaPages.sol:282:21\n    │\n282 │         s.supply += uint64(amount);\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: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:300:9\n    │\n300 │         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:296:21\n    │\n296 │         s.supply -= uint64(amount);\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: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[calls-loop]: external call inside a loop\n    ╭▸ src/MarginaliaAnnex.sol:452:17\n    │\n452 │             try pricer().settlePrice(n.venue, buy, sample) returns (uint256 p) {\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/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[return-bomb]: external call with a gas limit may copy unbounded return data\n    ╭▸ src/MarginaliaAnnex.sol:488:21\n    │\n488 │         (ok, ret) = x.staticcall{gas: BALANCE_READ_GAS}(data);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/return-bomb\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/MarginaliaAnnex.sol:612:21\n    │\n612 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n613 │ ┃             action,\n614 │ ┃             bytes(admissionBody(hooks)),\n615 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n616 │ ┃             imd,\n617 │ ┃             price\n618 │ ┃         );\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/MarginaliaAnnex.sol:622:9\n    │\n622 │         emit AdmissionRequested(requestId, msg.sender, hooks, price);\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/MarginaliaAnnex.sol:605:70\n    │\n605 │             if (hooks[i] == address(0) || hooks[i].code.length == 0) revert BadList();\n    │                                                                      ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-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:323:17\n    │\n323 │                 emit BurnDeferred(toBurn);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:314:53\n    │\n314 │             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:409:21\n    │\n409 │           requestId = intake.request(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━┛\n410 │ ┃             action,\n411 │ ┃             bytes(questionBody(normalized, tweetId)),\n412 │ ┃             IIntake.Callback(address(this), this.onOracleResult.selector),\n413 │ ┃             imd,\n414 │ ┃             price\n415 │ ┃         );\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:420:9\n    │\n420 │         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:418:63\n    │\n418 │         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:446:13\n    │\n446 │             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:459:9\n    │\n459 │         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:467:13\n    │\n467 │         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:484:9\n    │\n484 │         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:479:13\n    │\n479 │         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:485:9\n    │\n485 │         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:498:9\n    │\n498 │         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:494:44\n    │\n494 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) {\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:494:52\n    │\n494 │         if (imdIn > pendingBurn || imdIn > uint256(uint128(type(int128).max))) {\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:498:9\n    │\n498 │         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:528:9\n    │\n528 │         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:512:18\n    │\n512 │                 -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:519:38\n    │\n519 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-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:519:46\n    │\n519 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-inD)) != imdIn) revert UnauthorizedCallback();\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:524:9\n    │\n524 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaPages.sol:525:24\n    │\n525 │         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:525:32\n    │\n525 │         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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/MarginaliaAnnex.sol:646:21\n    │\n646 │                     emit HookAdmitted(open[i], requestId);\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/MarginaliaAnnex.sol:657:9\n    │\n657 │         hook.poolManager().unlock(abi.encode(imdIn, authorIn, minOut, to));\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/MarginaliaAnnex.sol:691:13\n    │\n691 │             emit Burned(imdIn - authorIn, marg - authorMarg);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/MarginaliaAnnex.sol:672:18\n    │\n672 │                 -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/MarginaliaAnnex.sol:679:38\n    │\n679 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-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/MarginaliaAnnex.sol:679:46\n    │\n679 │         if (inD >= 0 || outD <= 0 || uint256(uint128(-inD)) != imdIn) revert UnauthorizedCallback();\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/MarginaliaAnnex.sol:680:24\n    │\n680 │         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/MarginaliaAnnex.sol:680:32\n    │\n680 │         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/MarginaliaAnnex.sol:687:9\n    │\n687 │         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.chainid` may be reused across `vm.chainId`\n     ╭▸ test/AnnexAdversarial.t.sol:190:21\n     │\n 190 │         a.chainId = block.chainid;\n     │                     ━━━━━━━━━━━━━\n     ‡\n1088 │         vm.chainId(999);\n     │         ─────────────── `vm.chainId` changes this environment here\n     │\n     ├ help: capture it with `vm.getChainId()` 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/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":13374,"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 10.91ms (418.96µ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 19.24ms (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 19.48ms (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 32.83ms (7.32ms CPU time)\n\nRan 4 tests for test/PagesDeployment.t.sol:PagesOracleConformanceTest\n[PASS] testAddressAnswerFromVectorKeyDeliveredUnderStipend() (gas: 1648963)\n[PASS] testCallbackSelectorMatchesProtocol() (gas: 3739)\n[PASS] testDigestMatchesPinnedProtocolVector() (gas: 13296)\n[PASS] testVerifiesPinnedProtocolSignature() (gas: 17015)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 42.23ms (25.31ms 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, μ: 22874, ~: 20080)\n[PASS] testRetractingACallOnAnotherVenueBooksHalfAWrong() (gas: 1945010)\n[PASS] testSqrtFloorsSmallInputs() (gas: 9204563)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 75.47ms (57.57ms 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, μ: 106053, ~: 106118)\nLogs:\n  Bound result -4615\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 99.73ms (89.49ms CPU time)\n\nRan 29 tests for test/AnnexAdversarial.t.sol:AnnexAdversarialTest\n[PASS] testAdmissionListRulesAndPrice() (gas: 2592651)\n[PASS] testAnEmptyAnswerIsStoredNotReverted() (gas: 1165039)\n[PASS] testAnLpPullCannotTurnAWrongCallIntoARefund() (gas: 1826114)\n[PASS] testAttestationEdgesAreRefusedOneByOne() (gas: 1594187)\n[PASS] testBaselineBoundIsInclusiveAtTheBaselineAndOffAtZero() (gas: 3640042)\n[PASS] testBaselineBoundReadsTheSidesOwnBaseline() (gas: 2452540)\n[PASS] testCallbackGasAtTheFullListStaysUnderTheStipend() (gas: 2110451)\n[PASS] testCheckpointWindowAgesAndExpiresLikeTheRouter() (gas: 4984262)\n[PASS] testConstructorStoresFourValuesWithoutReadingTheChain() (gas: 51698)\n[PASS] testCountersRefuseClosedParentsAndTheses() (gas: 5716846)\n[PASS] testFewerThanThreeStandingReadingsAreStillNoData() (gas: 1584176)\n[PASS] testHoldRuleGiftsCountAsHeldAndAReadFailureAsBroken() (gas: 4206416)\n[PASS] testLifecycleRefusalsOnUnknownClosedAndForeignNotes() (gas: 1869727)\n[PASS] testMoreAdverseReadingReplacesTheLastInTheSameBlock() (gas: 1808241)\n[PASS] testOneOracleUuidServesOneRequestOnly() (gas: 1423863)\n[PASS] testPostBoundariesExactly() (gas: 2254356)\n[PASS] testProtocolVectorDigestSelectorAndSignature() (gas: 1184381)\n[PASS] testScoreIsDifficultyWeightedAndRetractIsHalf() (gas: 4699329)\n[PASS] testSellCallSettlesRightAndMaySellThroughTheHorizon() (gas: 1544132)\n[PASS] testSellCallWrongWhenThePriceRises() (gas: 1597641)\n[PASS] testSettlementTakesTheMostAdverseReading() (gas: 1764967)\n[PASS] testSixteenReadingsAtMostAndTheLastSlotWaitsForTheHour() (gas: 4679743)\n[PASS] testSlippageAndUnfundedAuthorsTakeNothing() (gas: 1560244)\n[PASS] testSoldOutSellCallReturnsItsBond() (gas: 3296468)\n[PASS] testSplitIsExactAndNothingStaysInTheAnnex() (gas: 634423)\n[PASS] testStandingReadingsKeepPriceOrderingAndHoldBreachPriority() (gas: 5443760)\n[PASS] testThreeReadingsInsideAnHourAreNoData() (gas: 1494972)\n[PASS] testUnlockCallbackAcceptsOnlyThePoolManager() (gas: 630742)\n[PASS] testVenueQuoteRule() (gas: 1230415)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 120.02ms (105.04ms CPU time)\n\nRan 2 tests for test/PagesDeployment.t.sol:PagesDeploymentTest\n[PASS] testConstructorRejectsMissingRequiredValues() (gas: 1742975)\n[PASS] testFactoryDeploysExactlyPagesWithNoDependencyCode() (gas: 13706462)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 152.15ms (44.97ms 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 159.08ms (47.52ms CPU time)\n\nRan 29 tests for test/Annex.t.sol:AnnexTest\n[PASS] testAPulledPoolPushedToAnExtremeIsReadAtTheExtreme() (gas: 4898651)\n[PASS] testAdmissionAsksThePanelAndAdmitsOnlyWhatItNamed() (gas: 2491254)\n[PASS] testAdmissionBodyIsStrictJson() (gas: 759446)\n[PASS] testAdmissionRefusesBadAnswersAndBadLists() (gas: 1542625)\n[PASS] testAgentClassForContractAuthors() (gas: 1208062)\n[PASS] testAnAdmittedHookPassesTheDynamicFeeGate() (gas: 1042590)\n[PASS] testBaselineBoundRefusesASandwichedPost() (gas: 3472853)\n[PASS] testBuyCallOnAnUnreadableBalanceIsRefusedLikeTheHook() (gas: 2799765)\n[PASS] testBuyCallOnMargCountsThePurchaseOnce() (gas: 1467516)\n[PASS] testCounterAgainstAHookNoteAndAgainstAnAnnexNote() (gas: 3609075)\n[PASS] testDynamicFeePoolNeedsAdmissionEvenWithoutSwapBits() (gas: 135567)\n[PASS] testEmptiedVenueForfeitsInsteadOfRefunding() (gas: 3126196)\n[PASS] testEmptiedVenueOnASoldBuyCallIsStillVoidSold() (gas: 1677805)\n[PASS] testEmptyTextIsRefusedLikeTheHook() (gas: 54539)\n[PASS] testFullListFitsTheCallbackStipend() (gas: 1851403)\n[PASS] testHeldPriceStillSettlesRightAfterAFailedFlashRead() (gas: 2230314)\n[PASS] testHoldRuleVoidsASoldBuyCall() (gas: 1708364)\n[PASS] testHookBitsDecideWithoutAnOracle() (gas: 98895)\n[PASS] testMargVenueBaselineBoundNeedsRoomForThePostsOwnPurchase() (gas: 1102399)\n[PASS] testNoObservationsVoidAndReturnTheBond() (gas: 734020)\n[PASS] testNoteOfAnUnknownIdReverts() (gas: 23176)\n[PASS] testObservationInsideAnUnlockIsRefused() (gas: 2956772)\n[PASS] testObservationWindowAndSpacing() (gas: 901122)\n[PASS] testPostPaysTheStampBuysMargAndHoldsTheBond() (gas: 857166)\n[PASS] testRefusesWhatTheRouterAlreadyTakesAndBadKeys() (gas: 137269)\n[PASS] testRetractHalvesTheScoreAndForfeitsWithoutAKeeperCut() (gas: 924322)\n[PASS] testRightCallReturnsTheBond() (gas: 1529261)\n[PASS] testSoldOutRangeStillSettlesRight() (gas: 3269214)\n[PASS] testWrongCallForfeitsToThePoolsWithTheSettlerCut() (gas: 1511821)\nSuite result: ok. 29 passed; 0 failed; 0 skipped; finished in 160.80ms (102.98ms CPU time)\n\nRan 14 tests for test/Pages.t.sol:PagesTest\n[PASS] testAbandonAfterDeadlineAndRecycleWaitsForPendingClaims() (gas: 2898172)\n[PASS] testAnnexLegIsOffWhenUnset() (gas: 4151632)\n[PASS] testBogusClaimCostsOnlyTheClaimantAndIsRetriable() (gas: 2904850)\n[PASS] testBuyGateWhitelistMargOrNotes() (gas: 1941906)\n[PASS] testBuyPaysTheIssuerBurnsMargAndFundsThePools() (gas: 562885)\n[PASS] testCurveIsLinearThenCapped() (gas: 103553)\n[PASS] testEscrowThenOracleAttestedClaim() (gas: 4731069)\n[PASS] testHandleIsLowerCasedAndValidated() (gas: 64454)\n[PASS] testOnlyThePoolManagerMayCallBack() (gas: 37650)\n[PASS] testPerWalletLimitAndTheCap() (gas: 9388256)\n[PASS] testPriceGuardAndAddressSubjectsNeedNoClaim() (gas: 171085)\n[PASS] testRejectedAnswersDoNotCloseTheClaim() (gas: 2603908)\n[PASS] testSellReturnsTheCurveLessFeeAndPagesAreNotTransferable() (gas: 1021356)\n[PASS] testSmallEscrowIsPaidWithoutReimbursement() (gas: 2111036)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 212.50ms (134.65ms 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 270.04ms (547.66ms 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 293.65ms (143.85ms 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 293.92ms (12.90ms 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, μ: 838153, ~: 838176)\nLogs:\n  Bound result 9999999999999999998\n\n[PASS] testFuzzNotedInputLeavesExactlyQuarterImdForThePool(uint256) (runs: 1000, μ: 58946, ~: 58968)\nLogs:\n  Bound result 9750000000000000707\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 294.02ms (374.49ms 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 449.47ms (76.08ms 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 511.69ms (132.39ms 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 511.86ms (93.41ms 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 511.91ms (59.60ms 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 511.75ms (125.45ms 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 511.97ms (57.02ms CPU time)\n\nRan 15 tests for test/PagesAudit.t.sol:PagesAuditTest\n[PASS] testAbandonClaimCannotReenterAnotherClaimRequest() (gas: 5038391)\n[PASS] testBurnRetryIsBoundedAtomicAndKeepsEscrowAndReserve() (gas: 2838763)\n[PASS] testClaimQuestionRequiresExactIntentBoundToThisDeployment() (gas: 5589085)\n[PASS] testFirstBuyWindowRecyclesEvenRecentlyAccruedFees() (gas: 1019415)\n[PASS] testFuzzDeferredBurnLiabilities(uint8,uint8,uint8) (runs: 256, μ: 2044125, ~: 2045503)\nLogs:\n  Bound result 4\n  Bound result 2\n  Bound result 1\n\n[PASS] testHealthyTradesLeaveEarlierPendingBurnForExplicitRetry() (gas: 1420408)\n[PASS] testOnlyRegisteredHandlePreimagesOrNonzeroAddressesCanBeBought() (gas: 1084837)\n[PASS] testOracleUuidReplayCannotBindAnotherHandle() (gas: 2152689)\n[PASS] testPartialBurnFillRollsBackOnlyTheSwap() (gas: 1192431)\n[PASS] testRegistrationAndQuestionPreviewRejectMalformedHandles() (gas: 131538)\n[PASS] testRejectedTweetThenExplicitClaimAndDistinctOracleRequestId() (gas: 2874745)\n[PASS] testSoldOutLaunchPoolDoesNotBlockBuyingOrSelling() (gas: 2025544)\n[PASS] testV1MissingAnswerLocksUntilAnyoneAbandonsAtThreeDays() (gas: 2848354)\n[PASS] testWhitelistFailedOrShortReadsCountAsNotListed() (gas: 133255)\n[PASS] testWithdrawnLaunchLiquidityDoesNotBlockBuyingOrSelling() (gas: 2968129)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 511.98ms (442.77ms 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 512.10ms (10.39ms 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, μ: 127143, ~: 113309)\nLogs:\n  Bound result 7\n  Bound result 999999999999999999999000000010\n  Bound result 999999999999999999999000004121\n  Bound result 1000000002\n  Bound result 2856782543\n  Bound result 999999999999999999999000036558\n  Bound result 999999999999999999999000000113\n  Bound result 999999999999999999999008872731\n  Bound result 5000000000000000000000\n  Bound result 999999999999999999999000002442\n  Bound result 2500000000000000000000\n  Bound result 999999999999999999999000005457\n  Bound result 999999999999999999999000008454\n  Bound result 1000000000000000000000000\n  Bound result 999999999999999999999000002828\n\n[PASS] testFuzzBuyDifficultyGrowsWithTheTarget(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36954, ~: 37031)\nLogs:\n  Bound result 265359\n  Bound result 4798670\n  Bound result 1\n  Bound result 8146\n\n[PASS] testFuzzCheckpointKeepsStartAndWidensExtremes(uint160,uint160,uint256) (runs: 512, μ: 141529, ~: 141907)\nLogs:\n  Bound result 1266412660188944021221804091696\n  Bound result 1266412660188944021221804081234\n  Bound result 4\n\n[PASS] testFuzzDifficultyFallsWithTheHorizon(uint32,uint16,uint16,uint256) (runs: 1000, μ: 36753, ~: 36871)\nLogs:\n  Bound result 998002\n  Bound result 1\n  Bound result 83\n  Bound result 1800000000000000000\n\n[PASS] testFuzzFromSqrtIsMonotoneAndInverts(uint160,uint160) (runs: 1000, μ: 23178, ~: 21255)\nLogs:\n  Bound result 1461446703485210103287273052103988822378723990216\n  Bound result 1237940039285380274899124224\n\n[PASS] testFuzzLog2IsBracketedAndMonotone(uint256,uint256) (runs: 1000, μ: 39816, ~: 39424)\nLogs:\n  Bound result 1357391566\n  Bound result 1857093833300285386661768519956606142\n\n[PASS] testFuzzLog2IsExactAtPowersOfTwo(uint8) (runs: 512, μ: 16262, ~: 14502)\nLogs:\n  Bound result 0\n\n[PASS] testFuzzPostPriceWindowBoundaries(uint256,bool) (runs: 512, μ: 54262, ~: 51987)\nLogs:\n  Bound result 21094\n\n[PASS] testFuzzSellDifficultyGrowsAsTheTargetFalls(uint32,uint32,uint16,uint256) (runs: 1000, μ: 36440, ~: 36402)\nLogs:\n  Bound result 7631\n  Bound result 1\n  Bound result 7\n  Bound result 210515984086892929578549207792\n\n[PASS] testFuzzSqrtIsTheIntegerFloor(uint256) (runs: 1000, μ: 19211, ~: 16931)\n[PASS] testFuzzV2TwapOfAConstantRatioIsThatRatio(uint112,uint112,uint32,bool) (runs: 512, μ: 21373, ~: 21299)\nLogs:\n  Bound result 5192296858534827628530496329220095\n  Bound result 1201889553097134778495787175400641\n  Bound result 16204\n\n[PASS] testFuzzV3SettlementIgnoresMiddleReadings(int24,uint256[16],uint8,bool) (runs: 512, μ: 62466, ~: 57611)\nLogs:\n  Bound result 0\n  Bound result 12\n\n[PASS] testFuzzV4SettlesOnTheExtremeOfEveryObservation(uint256[16],uint256[16],uint8) (runs: 1000, μ: 97640, ~: 83058)\nLogs:\n  Bound result 5\n  Bound result 914414351913\n  Bound result 36\n  Bound result 3\n  Bound result 718616864666740863231502899712\n  Bound result 686377251021029851707586994554\n  Bound result 192385174153544312432639388151\n  Bound result 494134206470726463009873928619\n  Bound result 271925150654979583762063763378\n  Bound result 687443462607367104148813472427\n  Bound result 570167360723403707763089343235\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 512.00ms (3.40s 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        | 198   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | checkpoint     | 221   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteBuy        | 465   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | noteSell       | 205   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainBuy       | 193   | 3       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | plainSell      | 208   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | strayCallbacks | 219   | 0       | 0        |\n|---------------+----------------+-------+---------+----------|\n| RouterHandler | thesis         | 211   | 0       | 0        |\n╰---------------+----------------+-------+---------+----------╯\n\nLogs:\n  Bound result 1\n  Bound result 16556\n  Bound result 37581\n  Bound result 33\n  Bound result 1\n  Bound result 2\n  Bound result 210\n  Bound result 50012\n  Bound result 25\n  Bound result 0\n  Bound result 2\n  Bound result 2\n  Bound result 1750433553\n  Bound result 1\n  Bound result 1457584007913129639829\n  Bound result 50081\n  Bound result 33\n  Bound result 2\n  Bound result 356349598227653053488\n  Bound result 10001\n  Bound result 14\n  Bound result 1\n  Bound result 2\n  Bound result 2\n  Bound result 6000000\n  Bound result 46240\n  Bound result 25\n  Bound result 1\n  Bound result 394352780754007441767\n  Bound result 50032\n  Bound result 83\n  Bound result 1076\n  Bound result 2\n  Bound result 2\n  Bound result 10000\n  Bound result 59\n  Bound result 1\n  Bound result 1005000000000000000000\n  Bound result 5691\n  Bound result 16\n  Bound result 1\n  Bound result 262144\n  Bound result 10171\n  Bound result 78\n  Bound result 0\n  Bound result 0\n  Bound result 0\n  Bound result 1879114660\n  Bound result 1\n  Bound result 1\n  Bound result 337\n  Bound result 1\n  Bound result 3660\n  Bound result 257\n  Bound result 856\n  Bound result 0\n  Bound result 2\n  Bound result 1030723334170871059414\n  Bound result 30660\n  Bound result 92\n  Bound result 0\n  Bound result 21600\n  Bound result 0\n  Bound result 1349999999999999999\n  Bound result 17205\n  Bound result 22\n  Bound result 1\n  Bound result 12000000000000000000\n  Bound result 59598\n  Bound result 65\n  Bound result 1\n  Bound result 79228162514264337593\n  Bound result 100\n  Bound result 19\n  Bound result 0\n  Bound result 16461\n  Bound result 0\n  Bound result 4684\n  Bound result 15569\n  Bound result 68\n  Bound result 2061736105657047026901\n  Bound result 0\n  Bound result 2\n  Bound result 8750043977755113263\n  Bound result 53701\n  Bound result 60\n  Bound result 2\n  Bound result 54772\n  Bound result 1\n  Bound result 1980000000000000000000\n  Bound result 19317\n  Bound result 95\n  Bound result 5289\n  Bound result 1\n  Bound result 1731687303715884105728\n  Bound result 58643\n  Bound result 14\n  Bound result 0\n  Bound result 12500\n  Bound result 50007\n  Bound result 95\n  Bound result 2\n  Bound result 54210444304732\n  Bound result 0\n  Bound result 25\n  Bound result 1\n  Bound result 0\n  Bound result 80\n  Bound result 58193\n  Bound result 79\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.03s (995.74ms 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   | 2475  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | drip      | 2480  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | gift      | 2411  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | initAgain | 2500  | 0       | 0        |\n|-----------------+-----------+-------+---------+----------|\n| TreasuryHandler | sendEth   | 2422  | 0       | 0        |\n╰-----------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 186876\n  Bound result 604800\n  Bound result 194\n  Bound result 14\n  Bound result 1000000000000000\n  Bound result 811561655\n  Bound result 86399\n  Bound result 25533640795314381195338909512731\n  Bound result 8317\n  Bound result 97\n  Bound result 9222\n  Bound result 209988\n  Bound result 138676684274577503511045240359540287700662\n  Bound result 5380\n  Bound result 811561654\n  Bound result 124029\n  Bound result 599290588\n  Bound result 755000000000000000\n  Bound result 12000\n  Bound result 3543950336000000000\n  Bound result 80\n  Bound result 2500\n  Bound result 112172147781537216\n  Bound result 360\n  Bound result 2432\n  Bound result 894894938023609378906243\n  Bound result 34\n  Bound result 6454\n  Bound result 5245319239414329845\n  Bound result 477338593233046903194339\n  Bound result 887220\n  Bound result 600000000000000000\n  Bound result 48\n  Bound result 1514690317\n  Bound result 5867401253989\n  Bound result 3531256657077453302\n  Bound result 115546657059\n  Bound result 5000\n  Bound result 2\n  Bound result 240799\n  Bound result 40000\n  Bound result 1000000000000\n  Bound result 24\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.09s (2.07s CPU time)\n\nRan 3 tests for test/AnnexInvariant.t.sol:AnnexInvariantTest\n[PASS]\nAnnexInvariantTest invariants:\n[PASS] invariant_admissionIsPermanent\n[PASS] invariant_bondsConserved\n[PASS] invariant_imdHeldEqualsBondsOwed\n[PASS] invariant_noMargRetained\n[PASS] invariant_recordsCountOutcomes\n[PASS] invariant_statusesAreFinalAndDepositsMatch\n AnnexInvariantTest invariants (runs: 96, calls: 4608, reverts: 0)\n\n╭--------------+-------------------+-------+---------+----------╮\n| Contract     | Selector          | Calls | Reverts | Discards |\n+===============================================================+\n| AnnexHandler | admission         | 306   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | claim             | 319   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | moveX             | 344   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | observe           | 337   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | observeSeries     | 347   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | post              | 320   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | pullOrRefillVenue | 325   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | pushEmptyPrice    | 314   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | retract           | 342   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | settle            | 319   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | strangerClaim     | 327   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | tradeMarg         | 346   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | tradeX            | 341   | 0       | 0        |\n|--------------+-------------------+-------+---------+----------|\n| AnnexHandler | warp              | 321   | 0       | 0        |\n╰--------------+-------------------+-------+---------+----------╯\n\nLogs:\n  Bound result 10525\n  Bound result 4\n  Bound result 848\n  Bound result 75716543158046451961877\n  Bound result 131072\n  Bound result 86976\n  Bound result 107802\n  Bound result 55115629533\n  Bound result 4\n  Bound result 2500000000000000000000\n  Bound result 29121\n  Bound result 1\n  Bound result 9750000000000000702\n  Bound result 4\n  Bound result 23666\n  Bound result 83327201603841552658977\n  Bound result 278826026650018611732576\n  Bound result 2\n  Bound result 299999000000000000002401\n  Bound result 200000999999999999999999\n  Bound result 4\n  Bound result 19291\n  Bound result 3\n  Bound result 9750000003767851072\n  Bound result 22291\n  Bound result 5\n  Bound result 9750000000000000196\n  Bound result 351\n  Bound result 6631\n  Bound result 4\n  Bound result 9750000000000014973\n  Bound result 237907203094597799606561\n  Bound result 500000000000000000000\n  Bound result 99999000000000000017008\n  Bound result 120\n  Bound result 147200\n  Bound result 198954592299406893584979\n  Bound result 96\n  Bound result 1\n  posts 3 settles 0\n  claimed 0 forfeited to pools 0\n  keeper paid 0 admitted hooks 10\n  bounded posts 1 standing readings 0\n\n[PASS] testHandlerPulledPoolDistinguishesWrongFromMissingObservations() (gas: 4694853)\nLogs:\n  Bound result 12000\n  Bound result 1\n  Bound result 1000000000000000000\n  Bound result 8000\n  Bound result 1\n  Bound result 1000000000000000000\n  Bound result 0\n  Bound result 1800\n\n[PASS] testHandlerStandingPricesCanReturnARightBond() (gas: 2680161)\nLogs:\n  Bound result 12000\n  Bound result 1\n  Bound result 10000000000000000000\n  Bound result 3000\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.78s (3.75s 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    | 499   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | advance           | 455   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | answerJudging     | 520   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | child             | 503   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimDeposit      | 510   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | claimRefund       | 497   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | fund              | 506   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | giftAndDrip       | 516   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | notedSell         | 529   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | observeSeries     | 520   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | payJudging        | 505   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | post              | 1034  | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | requestJudging    | 488   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | retract           | 505   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | seal              | 523   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | settle            | 520   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | sweep             | 520   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | trade             | 552   | 0       | 0        |\n|-----------------------+-------------------+-------+---------+----------|\n| HookAccountingHandler | unauthorizedClaim | 538   | 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 9750000000166773741\n  Bound result 15582\n  Bound result 201\n  Bound result 5\n  Bound result 2\n  Bound result 5\n  Bound result 9750000000000000025\n  Bound result 6\n  Bound result 99999000000000000011997\n  Bound result 2\n  Bound result 3005\n  Bound result 4\n  Bound result 345600\n  Bound result 14754\n  Bound result 1260000000000000000\n  Bound result 6\n  Bound result 4\n  Bound result 1\n  Bound result 2\n  Bound result 1\n  Bound result 22038\n  Bound result 1\n  Bound result 99999000000000000015829\n  Bound result 9750000000000014077\n  Bound result 44285397294214253334\n  Bound result 71704970726649291240\n  Bound result 4307\n  Bound result 5\n  Bound result 1\n  Bound result 100000000000000000000\n  Bound result 6\n  Bound result 9750000000000000667\n  Bound result 20000000000000000000000\n  Bound result 43838952742109740415150\n  Bound result 9750000000000008160\n  Bound result 9750000000000017172\n  Bound result 8\n  Bound result 1035320974223101875\n  Bound result 1\n  Bound result 2\n  Bound result 9\n  Bound result 9\n  Bound result 1\n  Bound result 4\n  Bound result 6\n  Bound result 27628530496329220096\n  Bound result 2\n  Bound result 1\n  Bound result 9750000000000000096\n  Bound result 10\n  Bound result 9750000000000007544\n  Bound result 808\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 13.12s (13.10s CPU time)\n\nRan 29 test suites in 13.13s (26.83s CPU time): 345 tests passed, 0 failed, 2 skipped (347 total tests)\n","passed":true},{"durationMs":308,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Marginalia.approve(address,uint256)\",\"Marginalia.transfer(address,uint256)\",\"Marginalia.transferFrom(address,address,uint256)\",\"MarginaliaAnnex.checkpointVenue((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address))\",\"MarginaliaAnnex.claimDeposit(bytes32)\",\"MarginaliaAnnex.observe(bytes32)\",\"MarginaliaAnnex.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"MarginaliaAnnex.post((address,(uint8,bytes32,address,bool),uint8,uint32,uint16,bytes32,uint8,string),(address,address,uint24,int24,address),uint256,uint256,uint256,uint256)\",\"MarginaliaAnnex.requestAdmission(address[])\",\"MarginaliaAnnex.retract(bytes32,string)\",\"MarginaliaAnnex.settle(bytes32)\",\"MarginaliaAnnex.unlockCallback(bytes)\",\"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.burn(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.registerHandle(string)\",\"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\":14,\"ADAPTATION.md\":603,\"AGENTS.md\":128,\"README.md\":295,\"SPEC.md\":298,\"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,\"drafts/thesis-imd.md\":34,\"drafts/thesis-infer.md\":31,\"drafts/thesis-zto.md\":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\":38,\"jobs/launch-D-annex.json\":37,\"jobs/launch-E-pages-v2.json\":36,\"jobs/launch-hook-v3.json\":43,\"jobs/oracle-claim-probe.json\":34,\"jobs/site-A-swarm.json\":27,\"jobs/site-B-v2.json\":27,\"jobs/site-C-v3.json\":26,\"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,\"llms.txt\":27,\"remappings.txt\":4,\"src/HookFlags.sol\":33,\"src/Marginalia.sol\":12,\"src/MarginaliaAnnex.sol\":695,\"src/MarginaliaHook.sol\":975,\"src/MarginaliaImpls.sol\":15,\"src/MarginaliaJudge.sol\":290,\"src/MarginaliaPages.sol\":531,\"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/Annex.t.sol\":1053,\"test/AnnexAdversarial.t.sol\":1322,\"test/AnnexInvariant.t.sol\":775,\"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\":542,\"test/PagesAudit.t.sol\":375,\"test/PagesDeployment.t.sol\":186,\"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\":130,\"test/helpers/Fixture.sol\":285,\"test/mocks/MockERC20.sol\":13},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":30261,"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[high/high] uninitialized-state at src/MarginaliaAnnex.sol:329: MarginaliaAnnex.observations (src/MarginaliaAnnex.sol#105) 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/MarginaliaAnnex.sol:245: MarginaliaAnnex.post(MarginaliaTypes.NoteParams,PoolKey,uint256,uint256,uint256,uint256) (src/MarginaliaAnnex.sol#245-296) 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/MarginaliaAnnex.sol:475: MarginaliaAnnex._broken(MarginaliaTypes.Note,uint256) (src/MarginaliaAnnex.sol#475-478) 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/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:394: Reentrancy in MarginaliaPages.requestClaim(string,uint256) (src/MarginaliaPages.sol#394-421):\n[medium/medium] reentrancy-no-eth at src/MarginaliaPages.sol:270: Reentrancy in MarginaliaPages.buy(bytes32,uint256,uint256) (src/MarginaliaPages.sol#270-286):\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/MarginaliaAnnex.sol:572: MarginaliaAnnex.admissionBody(address[]).named (src/MarginaliaAnnex.sol#572) 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/MarginaliaAnnex.sol:364: MarginaliaAnnex.settle(bytes32).settlePrice (src/MarginaliaAnnex.sol#364) 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/MarginaliaAnnex.sol:571: MarginaliaAnnex.admissionBody(address[]).list (src/MarginaliaAnnex.sol#571) 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/MarginaliaAnnex.sol:511: MarginaliaAnnex._spot(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaAnnex.sol#511-526) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(pid) (src/MarginaliaAnnex.sol#519)\n[medium/medium] unused-return at src/MarginaliaAnnex.sol:511: MarginaliaAnnex._spot(IPoolManager,MarginaliaTypes.Venue) (src/MarginaliaAnnex.sol#511-526) ignores return value by (sqrtP,None,None,None) = manager.getSlot0(PoolId.wrap(HUB_POOL_ID)) (src/MarginaliaAnnex.sol#524)\n[medium/medium] unused-return at src/MarginaliaPages.sol:240: MarginaliaPages.eligible(address) (src/MarginaliaPages.sol#240-252) ignores return value by (None,posted) = IMarginaliaRecords(address(hook)).records(wallet) (src/MarginaliaPages.sol#242)\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/MarginaliaPages.sol:501: MarginaliaPages.unlockCallback(bytes) (src/MarginaliaPages.sol#501-530) ignores return value by manager.settle() (src/MarginaliaPages.sol#524)\n[medium/medium] unused-return at src/MarginaliaPages.sol:492: MarginaliaPages.burn(uint256,uint256) (src/MarginaliaPages.sol#492-499) ignores return value by hook.poolManager().unlock(abi.encode(imdIn,minMargOut)) (src/MarginaliaPages.sol#498)\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:304: MarginaliaPages._distributeFee(bytes32,MarginaliaPages.Subject,uint256) (src/MarginaliaPages.sol#304-330) ignores return value by hook.poolManager().unlock(abi.encode(toBurn,uint256(0))) (src/MarginaliaPages.sol#320-324)\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:240: MarginaliaPages.eligible(address) (src/MarginaliaPages.sol#240-252) ignores return value by (None,posted) = annex.records(wallet) (src/MarginaliaPages.sol#245)\n[medium/medium] unused-return at src/MarginaliaAnnex.sol:656: MarginaliaAnnex._buyMarg(uint256,uint256,uint256,address) (src/MarginaliaAnnex.sol#656-658) ignores return value by hook.poolManager().unlock(abi.encode(imdIn,authorIn,minOut,to)) (src/MarginaliaAnnex.sol#657)\n[medium/medium] unused-return at src/MarginaliaAnnex.sol:660: MarginaliaAnnex.unlockCallback(bytes) (src/MarginaliaAnnex.sol#660-694) ignores return value by manager.settle() (src/MarginaliaAnnex.sol#687)\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/MarginaliaAnnex.sol:443: MarginaliaAnnex._settlementPrice(MarginaliaTypes.Note,MarginaliaTypes.Observation[]) (src/MarginaliaAnnex.sol#443-459) has external calls inside a loop: p = pricer().settlePrice(n.venue,buy,sample) (src/MarginaliaAnnex.sol#452-457)\n[low/medium] calls-loop at src/MarginaliaJudge.sol:91: MarginaliaJudge.convertForfeits() (src/MarginaliaJudge.sol#91-106) has external c","passed":true},{"durationMs":2092,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/MarginaliaPages.sol:179: `abi.encodePacked()` Hash Collision (3 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/MarginaliaAnnex.sol:226: Reentrancy: State change after external call (24 places)\n[high] storage-array-memory-edit at src/MarginaliaAnnex.sol:336: Storage Array Edited with Memory (3 places)\n[high] unsafe-casting at src/MarginaliaHook.sol:936: Unsafe Casting of integers\n[low] costly-loop at src/MarginaliaAnnex.sol:642: Costly operations inside loop (4 places)\n[low] internal-function-used-once at src/HookFlags.sol:26: Internal Function Used Only Once (4 places)\n[low] large-numeric-literal at src/Marginalia.sol:10: Large Numeric Literal (28 places)\n[low] literal-instead-of-constant at src/MarginaliaAnnex.sol:259: Literal Instead of Constant (70 places)\n[low] local-variable-shadowing at src/MarginaliaHook.sol:859: Local Variable Shadows State Variable\n[low] require-revert-in-loop at src/MarginaliaAnnex.sol:573: Loop Contains `require`/`revert` (4 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/MarginaliaAnnex.sol:657: Unchecked Return (10 places)\n[low] uninitialized-local-variable at src/MarginaliaAnnex.sol:450: Uninitialized Local Variable (4 places)\n[low] unused-import at src/MarginaliaHook.sol:10: Unused Import\n[low] unused-public-function at src/MarginaliaAnnex.sol:179: Public Function Not Used Internally (4 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"9f0a5a9dd5c939eba46e2d096021e70a227d03aef4880822ea60e621e7be6518","verifiedTreeHash":"0ae1ea336583c81bd132fb3161cd1edad219fc95","verifierVersion":"0.1.0+788bb33f"}]}