{"assessments":[],"deployments":[{"attestationHash":"524bcaf07878efdfe26c8acb3b51579629c31e21a65b0d36e46c2da8595edd5c","chainId":4663,"contracts":[],"id":"89077c21-80c4-4c81-bc8c-8721cd7e1748","manifestHash":"555aaf406ee5e881a01f1d42584e4026df21193e1cb8c2536f9a8df74dd35159","status":"parked"}],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"c6594639-ac64-4c97-bdba-307fe43e74b2","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"8c3493c494bff7b302f13119ed2a7361fc8832de0074a9cb057dd2402ac3efdc","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":"9db874eb40be81bcab1705e0417c2940e330b672f2916fcbb8a24ecd817d5048","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":"0934f5d6cd68618131181c9053d1ca2e2883b4815c24f529e1858cbf6f67c4e3","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":"1badd2bee4a19f7723ed79f67f7523d18b6da88e19b28d6717e5e9b2761e1aeb","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":"1e2015c81115f940fbb76bd5a7d4274267289b5b61ca981674a7a6a665ad3829","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":"8965564ac98b26e4906a275dba19d16058dde916f5dc4fef219d3661a3ca9f03","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":"7b45c590fb068cde0494f2db1e5cfe5cb7ddd404e272de17ac8d8b65c4dd0419","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":"3b37aedbd90be21553fbb4a19646e1a9aa17c143a7c55340404da01359cb092d","dependsOn":["adapt_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"f32995e4b9ce3c034ba32d0a1af971c5e2599ad8947d7d7195380e92ffadc0be","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":"BLACKOUT SwarmDesk bootstrap on Robinhood Chain (4663). Deploy exactly one contract, SwarmDesk, with these twelve static constructor words in this order, produced by tools/swarm_constructor_args.mjs from docs/oracle-v37/oracle-config.json and the binding file (factory 0x9c9d2fcb75c2c132c0ac0c42df3819a42347265e, registry/params launch 0 until bind, heartbeat 200 bps, cap 1e18): [\"0xa43e6f75ee006411f79ac1c84120606c2330de82\", \"0xce0e6a670aa75e161d02aca3c7f00b94ca428ccb\", \"0x5598aa9146215bc13eb26f2c692ad1461fd32982\", \"0x5f7bb59365ce557c26dbcaa4ee9d39a4b95b7127\", \"0x6f7261636c652e72657175657374406f7261636c652d31000000000000000000\", \"5391989333430298100116863486635657822062725418115979424500284366258177\", \"0x2fc5a57f2c5f7bc083ea8ac5016234f1a0b1c68a514e5d921956cc57948534ef\", \"0xc13efed8438aab53ea052a4507def2dc4ce9856765520dfa28c66daa59cfc11d\", \"0x00e69e4445c7ca7256338293f9f9cea439fd2beb1959d1d43ebec7b14493e2f6\", \"0xc0ae7511b06744cf7ccadc6b60ff9ff96cb7234cf32988850df33324861cc8df\", \"0x9c9d2fcb75c2c132c0ac0c42df3819a42347265e\", \"0x11ed7438974e96ecc962201e9c46422c7bf239d725876863fa25a56c734b20d3\"]. The last word is GAME_CONFIG_HASH. SwarmDesk is the swarm role of the game: it acts only on IMD oracle answers signed by attester 0x5598aa9146215bc13eb26f2c692ad1461fd32982 for its own EIP-712 domain, within hard-coded bounds. It binds once, permissionlessly, to the game registry proven through the ProjectFactory (see docs/m2-trust-assumption.md). The constructor makes no external call. Deploy unbound. Record and return the deployed address and check registry() == 0x0 and bindingConfig() gameConfigHash == the last word.\n\nSource: identity-md-launches/launch-1544-blackout-swarmdesk-bootstrap-robinhood at commit 24bfb1d (BLACKOUT v3.13, reviewed and re-pinned). Build exactly with the repo foundry.toml (solc 0.8.26, optimizer 200, cancun, viaIR false, bytecode_hash none) and deploy the creation code as built. The SwarmDesk creation hash must be exactly 0x65968358bcf87aa8839b8bce6b2d339493deac3f77d75a3ff0b3ad4f35955745; the contracts authenticate each other by creation-code hash, so another build can never be wired.\n\nNO SOURCE CHANGES in this launch. The requester accepts all low and info findings of the imported-code audit as documented known issues: do not fix them, record them in the launch notes. In particular finding b2ccff161ae44616a60d99094e55b0e792c4a6baa95be8050d2ffe27f9eb3301 (regulator answer with a cap announcement rolls back while the bound market reports initializedAt() == 0) is unreachable in this launch order: the Desk binds only after job A, and job A is deployed after the token launch that initializes the market; a cap announcement is also only proposed at game age >= 30 days. Reserved Params keys with no reader are documented in docs/params-keys-v313.md. Only a reproduced critical, high or medium defect in SwarmDesk itself should stop this launch.\n\nChain: Robinhood Chain (4663). Platform proofs use the ProjectFactory 0x9c9d2fcb75c2c132c0ac0c42df3819a42347265e (predictContract) and its launch registry 0xf52bbe066b7ad2d28c2195d066ea08dcbca88406 (isRecorded). No owner, admin key, upgrade, withdrawal, token action, mint or placeholder: every constructor value is listed above. Known trust assumption: docs/m2-trust-assumption.md (twin front-run of SwarmDesk.bind, griefing only, mitigated by binding right after job A). Project: https://playblackout.xyz · https://x.com/IMDBlackout","parentJobId":null,"planHash":"11a929a432c8beeed2d32cff089a8fa9a7d6661c45bf10049ef198c2d328e21e","previousHash":"bdac87667b965473708b2f3cc755121747f0e07306eaad07fc12523be6ad4a75","projectId":"c6594639-ac64-4c97-bdba-307fe43e74b2","publication":{"commit":"9a7d0640d3805e39cc999b5ac483b3c15a4e348d","deliveredAt":"2026-10-13T12:14:01.198Z","repoUrl":"https://github.com/identity-md-launches/launch-1557-blackout-swarmdesk-bootstrap-robinhood"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[],"site":null,"snapshotHash":"8a7aff40d6ea3f7f42207162fbd300362e9f6963458ae4bf01e02bae596719b8","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fa99051b60a858d6","findings":[{"citation":"resolved","description":"Launch-order liveness note for the launch notes, not a defect that should stop the launch. The regulator path in execute() fetches Civic (role 12), Enhancement (role 11) and PackSale (role 4) unconditionally, and the event path fetches GridOperator (role 7) and Civic (role 12). GameRegistry.module() reverts NotConfigured for an unregistered role. The runbook binds the Desk right after job A (roles 0-5) and registers roles 6-13 only after job B. In that window _accept still succeeds for the regulator stream (it needs only params()), consumes the UUID and marks the weekly slot accepted, but every execute() reverts; after validUntil (issuedAt + 1 day) the stored answer is dropped without acting and no second answer for that slot is admitted. The event stream cannot even be accepted in the window because _accept reads module(1). Any heartbeat or paid backup that lands before job B's registration is therefore wasted for that slot. Mitigation is operational: register roles 6-13 (or at least 7, 11, 12) before the first heartbeat slot, or expect the first slot(s) to be no-ops.","line":423,"path":"src/SwarmDesk.sol","reproduction":"State: Desk bound to a registry whose roles 6-13 are not yet registered (job A done, job B not). Input: a regulator attestation for the current weekly slot (values[0]=slot(1), values[1]=(1<<248)|385 to move EmissionBps 350->385, v[16]=letter hash), signed by the attester in the Desk domain, presented via submit() or delivered by the intake. Expected by the brief: the Desk acts on attested answers within bounds. Actual: submit() accepts (consumed[uuid]=true, lastAnswer[1].pending=true, acceptedSlotPlusOne[1]=slot+1); execute(1, answer) reverts NotConfigured at registry.module(12); a second attestation with a fresh UUID for the same slot is ignored (AnswerIgnored reason 2); after 1 day execute() clears pending without touching Params (EmissionBps stays 350). Scratch test test/scratch/DeskReviewNotes.t.sol::testRegulatorAnswerAcceptedBeforeJobBCannotExecute reproduces this (passes on current code, i.e. the revert is observed).","severity":"info","snippet":"        Civic civic = Civic(registry.module(12));","title":"Answers accepted between bind and job B registration can never execute: execute reverts NotConfigured on registry.module(12) and the slot is then spent"},{"citation":"resolved","description":"The duplicate check returns (and emits) before _verifyAttestation runs. Because submit() is permissionless, any caller can present an unsigned Attestation whose requestId is a UUID the Desk already consumed and whose questionHash is one of the two pinned hashes, and the Desk emits AnswerIgnored(uuid, 1). No state changes and nothing is accepted, so the impact is limited to log noise: a keeper or indexer that counts AnswerIgnored events, or treats them as evidence that the oracle re-delivered, can be misled at zero cost. Worth recording in the launch notes for keeper tooling; a fix would move the duplicate check after _verifyAttestation or emit only from the authenticated paths, which is a source change this launch does not take.","line":300,"path":"src/SwarmDesk.sol","reproduction":"State: Desk bound, one attestation with requestId U already accepted via submit(). Input: from any EOA call submit(a, \"\") with a.requestId = U, a.questionHash = oracleConfig().questions[1] and every other field zero. Expected: an unsigned attestation is rejected (BadSignature) or at least leaves no trace. Actual: the call succeeds and emits AnswerIgnored(U, 1); storage is unchanged. Scratch test test/scratch/DeskReviewNotes.t.sol::testSubmitEmitsAnswerIgnoredForConsumedUuidWithoutSignature reproduces it (expectEmit matches on current code).","severity":"info","snippet":"        if (consumed[a.requestId] || delivered[deliveryKey]) {\n            emit AnswerIgnored(a.requestId, 1);\n            return;\n        }","title":"submit()/onOracleResult emit AnswerIgnored(uuid, 1) for a consumed UUID before any signature check, so anyone can emit that event with an empty signature"}],"hash":"0934f5d6cd68618131181c9053d1ca2e2883b4815c24f529e1858cbf6f67c4e3","nodeId":"446f9087-76d1-45b9-b6b8-4d704530a62e","outcome":"completed","summary":"Findings file is written and valid. Recap of the review:\n\n**Outcome: no critical, high or medium defect in SwarmDesk. Nothing here should stop the launch.** The findings file `.imd-findings.json` holds two info-level notes for the launch notes and a coverage row for all 156 listed entry points plus three invariants.\n\n**What I verified for this launch**\n- The repo build reproduces the pinned creation hash `0x65968358…5745`, and the Params and GameRegistry creation hashes equal the SwarmCode pins.\n- The constructor-args tool reproduces the brief's twelve words from the config files. The policy word decodes to chain 1, window 26122900 to 26122901, max price 0.5 IMD, heartbeat 200 bps, with the top bits zero.\n- The constructor makes no external call, the Desk deploys unbound, and the binding config carries the game-config hash as the last word. The EIP-712 domain and the 15-field attestation struct match the oracle reference.\n\n**Control-flow trace (Execution Trace, Periphery, First Principles guides)**\n- bind: the CREATE2 proofs over pinned code and the registry's own immutables pin the candidate's identity. A malicious candidate that reenters cannot pass the final address check. The twin race is the documented M-2 assumption.\n- askBackup, onOracleResult, submit, onOracleFailure, clearExpired: once-per-slot and once-per-UUID bookkeeping, pending stream and deadline binding, exact approve-and-zero, exact ABI sizes, and slot and epoch freshness all hold. The callback peaks at 79k gas in the existing tests.\n- execute: every regulator value is clamped so Params.set, submitPlan, announce and unpause cannot revert for the Desk. The optional duties sit in try/catch. The only uncaught revert is the accepted known issue on announceCap.\n- Periphery: SwarmCode pins, ChainClock, SignatureCheckerCompat, OracleAttestation hashStruct split and Strings all behave as the callers assume.\n\n**Two info notes, both reproduced by test/scratch/DeskReviewNotes.t.sol**\n1. Between bind and job B registration, a regulator answer is accepted but execute reverts NotConfigured on role 12. The weekly slot is then spent and the answer expires unused. This is a launch-order liveness note.\n2. The duplicate-UUID check emits AnswerIgnored before the signature check, so anyone can emit that event for a consumed UUID with an empty signature. Log noise only.\n\nThe panel floor of 5 seats and quorum 4 matches the requester's own pinned bodies, so I did not report it. The existing SwarmDesk suites pass (24 tests).","treeHash":null,"usage":{"cachedInputTokens":1613073,"inputTokens":450,"model":"claude-fable-5-1","outputTokens":43808,"runtime":"claude","turns":33,"wallClockMs":631368}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"aefe32dd2527eb68","findings":[{"citation":"resolved","description":"The regulator vector spec packs (index+1)*2^248 + target with index 0..44 and 'a zero word skips'. _regulate treats the top byte as a key but clamps any value above 45 to 45, so a word whose key byte is 46..255 is not skipped: it is applied to Params.Key(44) = RepairHours (lines 416-421). The same pattern on line 425 maps any feature code above 8 (v[9]) to feature 7, the reserved Heatwave/Festival events, and announces it. Every effect stays inside the hard bounds (10% per day, 48h feature notice), so this is a bounded mis-mapping of a malformed but attester-signed answer, not a bypass. Suggested minimal fix (design-preserving): `if (key == 0 || key > 45) continue;` and `if (v[9] == 0 || uint256(v[9]) > 8) skip`.","line":416,"path":"src/SwarmDesk.sol","reproduction":"State: bound Desk, Params at defaults, now >= lastChanged(RepairHours)+1 day. Deliver a valid stream-1 attestation (any sender path) whose answer is bytes32[17] with v[0]=slot(1), v[1]=(0xff<<248)|7e18, v[16]=any; then call execute(1, answer). Expected: word with unknown key 0xff is ignored, RepairHours stays 6e18. Actual: Params.get(RepairHours) becomes 6.6e18 (clamped to +10%) and its 24h cooldown is burned. Likewise v[9]=1000 → Civic.noticeAt(7) is set to now+48h although 1000 is not a feature id+1. Reproduced in test/scratch/Probe.t.sol testUnknownKeyIsClampedOntoRepairHours and testFeatureCodeClampedOntoSeven.","severity":"low","snippet":"            Params.Key k = Params.Key(_clamp(key, 1, 45) - 1);","title":"Out-of-range regulator key and feature codes are clamped onto RepairHours / feature 7 instead of skipped"},{"citation":"resolved","description":"submit() and the delivery path accept an attestation for the pinned questionHash from any relayer as long as the attester signed it in this Desk's domain and panelSize>=5, quorum>=4, agreed>=quorum. questionHash covers question/window/definitions but not the panel, so anyone can buy the same question naming the Desk as consumer and relay the first answer of a slot; the honest heartbeat for that slot is then ignored (acceptedSlotPlusOne). The answer is still the IMD panel's and the attester's, and the pinned bodies themselves ask for panelSize 5 / quorum 4, so the Desk cannot distinguish them. This is the documented design (NatSpec line 278-281: 'the bytes are the attester's') and a trust assumption on the IMD panel and the single signer key, recorded here for the launch notes; no code change is proposed for this launch.","line":308,"path":"src/SwarmDesk.sol","reproduction":"State: bound Desk, slot s not yet accepted. Input: submit(a, sig) with a.questionHash = questions[0], a.panelSize=5, a.quorum=4, a.agreed=4, values[0]=s, values[1]=epoch(), fresh issuedAt/expiresAt, sig by 0x5598aa91... for this Desk. Expected/actual: accepted and stored (consumed[a.requestId]=true); a later heartbeat for the same slot with a larger panel is ignored with AnswerIgnored(_,2). Covered by the repo's testSubmitRelayAcceptsAttestedAnswerFromAnyoneOnce.","severity":"info","snippet":"                || a.panelSize < 5 || a.quorum < 4 || a.agreed < a.quorum || a.agreed > a.panelSize","title":"Relay path accepts any attester-signed answer to the pinned question with the minimum 5/4 panel, whoever paid for it (trust assumption)"},{"citation":"resolved","description":"The oracle-consumer reference requires the intake, delivery, action id, asset/price and signer to be owner-settable so that a new action version (oracle-2), a moved price or a signer rotation does not need a redeploy. SwarmDesk deliberately has no owner, so all of them are immutable config. If IMD rotates the attester key, every attestation reverts BadSignature; if priceOf(action, IMD) ever exceeds 0.5 IMD, askBackup reverts InvalidValue forever. The game then runs on GridOperator.fallbackKind plans and frozen Params; no funds are at risk. This follows the brief ('No owner, admin key...') and is recorded as the accepted trust assumption; the brief wins over the reference here.","line":249,"path":"src/SwarmDesk.sol","reproduction":"State: bound Desk. Input: intake.priceOf returns 500000000000000001; call askBackup(0, eventBody) one hour into a slot. Expected (per reference): price can be re-set; Actual: revert InvalidValue with no recovery path. Input 2: an attestation signed by a rotated attester key. Actual: BadSignature on every onOracleResult/submit; registry/Params remain at their last values. Covered by the repo's testBackupFailureUnknownFailureDeadlineAndPriceCap (price cap branch).","severity":"info","snippet":"        if (price == 0 || price > config.maxPrice) revert InvalidValue();","title":"Oracle signer, intake, action id and price cap are frozen at construction; a protocol rotation permanently strands the Desk (trust assumption)"},{"citation":"resolved","description":"The comment says GridOperator admits 5000-10000, but GridOperator.SEVERITY_FLOOR is 3000 (src/GridOperator.sol:93). The Desk's own 5000-7000 clamp is what bounds attested severities, so behaviour is correct; only the documentation is stale (known item I-2 of docs/review-v39-independent.md).","line":94,"path":"src/SwarmDesk.sol","reproduction":"From the swarm wallet call GridOperator.submitPlan(e, Kind.Outage, 3000, 0, 'x') for a future epoch e in (current, current+2]. Expected per comment: revert InvalidValue; Actual: accepted (severity >= 3000). No code change for this launch.","severity":"info","snippet":"    /// @dev Attested severity band; GridOperator itself admits 5000-10000, so the Desk never exceeds 7000.","title":"NatSpec severity comment contradicts GridOperator.SEVERITY_FLOOR (3000, not 5000)"}],"hash":"1badd2bee4a19f7723ed79f67f7523d18b6da88e19b28d6717e5e9b2761e1aeb","nodeId":"4ab24f18-ad7f-4563-8aae-b0572a733bbe","outcome":"completed","summary":"Review complete. The findings file is written and every snippet matches the tree.\n\n**Verdict: nothing reproduced at critical, high or medium severity in SwarmDesk. The launch is not blocked by this review.** The file `.imd-findings.json` holds one low and three info findings.\n\n**What I verified against the brief**\n\n- The repo build with the pinned foundry.toml gives SwarmDesk creation hash `0x65968358…5745`, exactly the required value.\n- The SwarmCode pins equal the built GameRegistry and Params creation hashes, so `bind` can succeed against the real job A.\n- The policy word decodes to chain 1, window 26122900–26122901, price cap 0.5 IMD, 200 bps, high bits zero.\n- The two pinned body hashes equal the keccak of `docs/oracle-v37/event.json` and `regulator.json`, and the repo's question-hash vectors pass against protocol records.\n- The protected floor test passes with the exact twelve words on chain 4663, and a scratch deployment of that init code reads `registry() == 0`, `gameConfigHash` equal to the last word, and runtime of 20,797 bytes with no forbidden opcodes.\n- Both oracle streams, on both the direct and relay paths, succeed under an explicit 200k gas limit on chain 4663 with the ArbSys clock. The heaviest path, a cold regulator answer, measured 177,879 gas, about 11% of margin.\n- The ten launch-relevant suites pass, 61 tests. The full offline suite with invariants did not finish inside the 7-minute cap I gave it, so I cannot report it.\n\n**Findings**\n\n- **Low, line 416 and 425.** A regulator word whose key byte is above 45 is clamped onto RepairHours instead of skipped, and a feature code above 8 announces feature 7. Reproduced: key byte 0xff with target 7e18 moves RepairHours from 6e18 to 6.6e18 and burns its cooldown; v[9]=1000 sets a notice for feature 7. Bounded by the existing clamps, so not launch-blocking.\n- **Info, line 308.** Anyone can buy the pinned question naming the Desk as consumer and relay the first answer of a slot; the only panel guard is 5/4, which is also what the pinned bodies ask for. Documented design and a trust assumption on the IMD panel and single attester key.\n- **Info, line 249.** Signer, intake, action and price cap are frozen. A signer rotation or a price above 0.5 IMD strands the Desk permanently, with the game running on fallback plans. This follows the brief's no-owner rule, which wins over the oracle-consumer reference.\n- **Info, line 94.** The severity comment says GridOperator admits 5000–10000, but its floor is 3000. Documentation only.\n\n**Known items to carry into the launch notes, not re-opened:** finding b2ccff (announceCap rollback while the market is uninitialized, unreachable in this bind order), M-2 twin front-run of `bind` (griefing only, mitigated by binding right after job A), L-1 dual toolchain pins, and the reserved Params keys register.\n\n**Coverage.** Read in full: SwarmDesk, OracleAttestation, SignatureCheckerCompat, SwarmCode, Params, GameRegistry, GridOperator, Civic, Enhancement, GameModule, ChainClock, the interfaces and Errors. Read only the functions the Desk calls: Economy, PackSale, FarmRewards. Not read: FarmCore, FarmEngine, FarmItems, FeeRouter, RewardPool, Season, StarterClaim, Billboards, V4Market, the market adapters and EndowmentEscrow, which are outside the Desk's scope. Not reached: the live ProjectFactory and launch registry on 4663, which I did not query over RPC. Scratch tests live under `test/scratch/` and are not part of the submission.","treeHash":null,"usage":{"cachedInputTokens":2014545,"inputTokens":514,"model":"claude-fable-5-1","outputTokens":53819,"runtime":"claude","turns":45,"wallClockMs":810277}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"896d1238054266ca","findings":[{"citation":"resolved","description":"Boundary off-by-one at expiry (merged from audit_math aed63ace). _accept treats a.expiresAt < block.timestamp as stale but accepts equality, and OracleAttestationConsumer._verifyAttestation also passes at equality (block.timestamp > a.expiresAt). The stored validUntil is min(issuedAt + window, expiresAt, slotEnd) == block.timestamp (lines 342-344), while execute requires block.timestamp < r.validUntil (line 375), so the stored answer can never act. The same burn happens when an answer is accepted at slotEnd - 1: validUntil is clamped to slotEnd and execute one second later fails r.slot != slot(stream). Because acceptance already consumed the UUID and set acceptedSlotPlusOne[stream] = s + 1, a later healthy answer for the slot is ignored (reason 2) and askBackup reverts TooEarly, so the stream loses the whole slot. keeper/keeper.mjs relays submit and execute in separate transactions, so the gap is reachable at an attestation's last valid second or a slot's last second. No funds move; the grid falls back to its table. Known-issue candidate for the launch notes; a source fix (require until > block.timestamp before _consume) is out of scope for this no-source-change launch.","line":313,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk at time T inside event slot s with no accepted answer. Attester-signed event attestation: questionHash = questions[0], chainId 1, fromBlock 100/toBlock 200 (fixture), panel 5/4/5, issuedAt = T, expiresAt = T, answer = abi.encode(bytes32[7]{s, epoch, 1, 7000, 3, salt, letter}). Anyone calls submit(a, sig). Expected: treated as stale and not consumed. Actual: consumed[a.requestId] == true, lastAnswer[0].validUntil == T, pending == true, acceptedSlotPlusOne[0] == s + 1; execute(0, a.answer) in the same block emits AnswerIgnored(a.requestId, 2) and planAt(2).submitted stays false; a second valid attestation b for slot s is ignored (consumed[b.requestId] false) and askBackup(0, body) reverts TooEarly. Variant: warp to (s+1)*6h - 1, submit a valid answer (accepted), warp +1s, execute(0, answer) emits AnswerIgnored(…, 2) with no plan. Reproduced in test/scratch/JudgeRepro.t.sol::testExpiresAtEqualsNowAcceptedThenBurned and ::testAcceptedInLastSecondOfSlotBurnsNextSecond (pass on this tree, i.e. the behaviour is observed).","severity":"low","snippet":"            a.expiresAt < block.timestamp || uint256(a.issuedAt) + (stream == 0 ? 6 hours : 1 days) < block.timestamp","title":"_accept stores an answer whose validUntil is already reached (expiresAt == block.timestamp, or acceptance in the slot's last second), burning the slot"},{"citation":"resolved","description":"Boundary at slot end (merged from audit_math 4ea6ecf9). The only time guard in askBackup is block.timestamp < s * period + 1 hours (line 246); nothing refuses a call at slotEnd - 1. The deadline is clamped to end (line 265), one second away. A direct answer arrives minutes later and hits direct && block.timestamp >= p.deadline (line 314), so it is ignored; a relayed version of the same answer fails a.issuedAt / period != s once the slot has rolled. The 0.5 IMD price is spent, askedSlotPlusOne[stream] = s + 1 (line 250) stops anyone else asking for that slot and the Pending entry lingers until clearExpired. askBackup is permissionless, so any caller can burn 0.5 IMD of donated balance per stream per slot in which no answer was yet accepted. Bounded griefing of donations only (about 2 IMD/day across both streams); no third-party funds. Record in the launch notes; a minimum remaining window would be a source change.","line":265,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk holding >= 0.5 IMD, no answer accepted for event slot s. vm.warp((s+1)*6 hours - 1); bob calls askBackup(0, body) with keccak256(body) == bodies[0]. Expected: refused, no realistic answer can land. Actual: 0.5 IMD moves to the intake, pending[id].deadline == block.timestamp + 1, streamPlusOne == 1. One second later the intake delivers a correctly signed answer for slot s (issuedAt in slot s): onOracleResult returns without revert, emits AnswerIgnored(id, 2), consumed stays false, pending[id] still active. Reproduced in test/scratch/JudgeRepro.t.sol::testBackupAtSlotEndIsPaidAndUnanswerable.","severity":"low","snippet":"        if (deadline > end) deadline = end;","title":"askBackup in the final seconds of a slot pays the oracle for a request whose deadline is the slot end and whose answer is always ignored, and blocks any other backup for that slot"},{"citation":"resolved","description":"Access x economics seam (from audit_permissions c2b884a0). askBackup is permissionless; its only gates are the pinned body hash, one request per stream per slot and a one-hour wait into the slot (lines 243-247). Nothing checks that the relay (submit) has actually failed for the slot, so an unrelated caller can make the Desk pay the 0.5 IMD intake price in every slot in which no answer has yet been accepted: four event slots per day plus one regulator slot per week, about 2.07 IMD/day, until the donated balance is gone and the backup is unavailable when the relay really fails. The attacker gains nothing and the answer content stays the panel's, so impact is bounded griefing of donated funds. Not in the accepted known-issue list (ADAPTATION.md items 1-4, b2ccff16), so it belongs in the launch notes. Distinct from the slot-end finding: there the price is wasted with no possible answer; here a real (duplicate) answer is bought.","line":240,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk holding 10 IMD (anyone donated), relay healthy. At block.timestamp = s*21600 + 3600 (or any later time in slot s before an answer is accepted) an arbitrary EOA (bob) calls askBackup(0, eventBody) with the pinned body bytes. Expected under the stated purpose (backup for a missed heartbeat): revert or restriction. Actual: forceApprove then the intake pulls exactly 500000000000000000 IMD (Desk balance drops by 0.5e18, allowance back to 0), askedSlotPlusOne[0] = s + 1, pending[id] recorded, BackupAsked emitted. Repeating every slot and askBackup(1, regulatorBody) weekly drains 10 IMD in about five days. Reproduced in test/scratch/JudgeRepro.t.sol::testAnyoneSpendsDonationAndPriceCapIsExact (first half) and by the existing test testBackupPullsExactPriceRecordsRequestAndRestrictsBodyAndCadence.","severity":"low","snippet":"    function askBackup(uint8 stream, bytes calldata body) external nonReentrant returns (bytes32 id) {","title":"askBackup lets any caller spend the Desk's donated IMD on paid oracle requests while the free heartbeat relay is healthy"},{"citation":"resolved","description":"Flow gap (from audit_economics 2bc32b45). _accept requires the event answer's base epoch (values[1]) to equal FarmRewards.epoch() exactly at the moment the attestation lands, while _event (line 396) deliberately tolerates current == base + 1 and still plans base + 2. FarmRewards.EPOCH is six hours, the same as the event slot, but each epoch ends six hours after the previous permissionless advanceEpoch() call, so the epoch boundary sits at an arbitrary offset inside every slot. Whenever it falls between the panel's read and the on-chain submit/onOracleResult, every heartbeat for that slot is ignored (AnswerIgnored reason 2), not consumed and cannot execute. advanceEpoch() is permissionless, so a watcher can also front-run a relay with advanceEpoch() whenever the epoch is due. The slot's plan is then lost unless someone pays 0.5 IMD via askBackup after hour one (which can be rejected the same way). No funds at risk: the grid uses fallbackKind with severity 10000 when no plan exists. The specialist's attached proof (Proof_2bc32b45081c.t.sol) passes on this tree, so it demonstrates the behaviour rather than failing; it was run as test/scratch/EpochDrift.t.sol.","line":333,"path":"src/SwarmDesk.sol","reproduction":"State: Desk bound, FarmRewards.epoch() == N and epochs[N].end <= block.timestamp (epoch due), current slot s. 1) Attester signs the honest event answer v = [s, N, 1, 6000, 0, 0, letter] with issuedAt in slot s. 2) Anyone calls FarmRewards.advanceEpoch() (epoch becomes N+1) in the block before the relay. 3) desk.submit(a, sig) one second later. Expected (by _event's own tolerance): stored, and execute(0, answer) plans epoch N+2. Actual: _accept emits AnswerIgnored(a.requestId, 2), consumed[a.requestId] stays false, execute(0, a.answer) reverts InvalidProof, planAt(N+2).submitted stays false. Reproduced by test/scratch/EpochDrift.t.sol::testHeartbeatRejectedWhenEpochAdvancesBeforeRelay (the specialist's proof, passing on this tree).","severity":"low","snippet":"        if (stream == 0 && uint256(values[1]) != IRewards(registry.module(1)).epoch()) {","title":"Heartbeat answers are rejected when FarmRewards.epoch() advances between the panel's read and the relay, although _event tolerates that drift"},{"citation":"resolved","description":"Launch-order liveness note (merged from audit_flow bab7f7ce and audit_math e441b6bd, same root cause). _regulate fetches Civic (role 12), Enhancement (role 11) and PackSale (role 4) unconditionally (lines 423, 428, 443), and _event fetches GridOperator (role 7) and Civic (role 12). GameRegistry.module() reverts NotConfigured for an unregistered role. The runbook binds the Desk right after job A (roles 0-5) and registers roles 6-13 only after job B. In that window _accept still succeeds for the regulator stream (it touches no module), consumes the UUID and marks the weekly slot accepted, but every execute() reverts; after validUntil (<= issuedAt + 1 day) the stored answer is dropped without acting and no second answer for that slot is admitted. The event stream cannot even be accepted in the window because _accept reads module(1). Any heartbeat or paid backup landing before job B's registration is wasted for that slot. Mitigation is operational: register roles 6-13 (at least 7, 11, 12, 4) before the first heartbeat slot, or expect the first slot(s) to be no-ops. Not a defect that should stop the launch.","line":423,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk whose registry has no module 12 (simulated with vm.mockCallRevert on GameRegistry.module(12) returning NotConfigured). Signed regulator vector with values[0] = slot(1), values[1] = (1 << 248) | 385 (EmissionBps 350 -> 385), values[16] = letter, expiresAt = now + 1 day. submit(a, sig) succeeds: consumed[a.requestId] == true. execute(1, a.answer) reverts NotConfigured and Params.get(EmissionBps) stays 350. A second attestation b for the same slot is ignored (consumed[b.requestId] false). After 1 day execute(1, a.answer) clears pending without touching Params (EmissionBps still 350). Reproduced in test/scratch/JudgeRepro.t.sol::testRegulatorAcceptedBeforeJobBCannotExecute.","severity":"info","snippet":"        Civic civic = Civic(registry.module(12));","title":"Answers accepted between bind and job B registration can never execute: execute reverts NotConfigured on registry.module(12/11/4) and the slot is spent"},{"citation":"resolved","description":"From audit_flow 20022641. The duplicate check returns and emits before _verifyAttestation runs (line 319). Because submit() is permissionless, any caller can present an unsigned Attestation whose requestId is a UUID the Desk already consumed and whose questionHash is one of the two pinned hashes, and the Desk emits AnswerIgnored(uuid, 1). No state changes and nothing is accepted; impact is log noise that could mislead a keeper or indexer counting AnswerIgnored events as oracle re-deliveries. Launch-notes item for keeper tooling.","line":300,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk, attestation with requestId U already accepted via submit(). From any EOA (bob) call submit(z, \"\") where z.requestId = U, z.questionHash = oracleConfig().questions[1] and every other field zero. Expected: an unsigned attestation is rejected (BadSignature) or leaves no trace. Actual: the call succeeds and emits AnswerIgnored(U, 1); storage unchanged. Reproduced in test/scratch/JudgeRepro.t.sol::testSubmitEmitsIgnoredForConsumedUuidWithoutSignature (expectEmit matches).","severity":"info","snippet":"        if (consumed[a.requestId] || delivered[deliveryKey]) {","title":"submit()/onOracleResult emit AnswerIgnored(uuid, 1) for a consumed UUID before any signature check, so anyone can emit that event with an empty signature"},{"citation":"resolved","description":"From audit_math 0dc9bc1e; this is the same mechanism as the requester's accepted Low 1c443300 (malformed regulator keys/features clamp to the last supported code) recorded in ADAPTATION.md item 1 and launch.json notes. A stray key 46..255 in a signed regulator vector moves RepairHours (key 45) by up to +/-10% within its bounds [4e18, 8e18] and consumes its daily cooldown, instead of being skipped like key 0. Requires the attester's signature and stays within every other clamp, so informational. Kept here only so the merged record shows it was reproduced and is already accepted; no action for this launch.","line":416,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk, Params.lastChanged(RepairHours) + 1 day <= now (warp 1 day after deployment). Signed regulator vector with values[1] = (255 << 248) | type(uint248).max, values[0] = slot(1), values[16] = letter. submit(a, sig) then execute(1, a.answer). Expected: nothing happens for an unknown key. Actual: Params.get(RepairHours) goes 6e18 -> 6.6e18. Reproduced in test/scratch/JudgeRepro.t.sol::testKeyAbove45MovesRepairHours.","severity":"info","snippet":"            Params.Key k = Params.Key(_clamp(key, 1, 45) - 1);","title":"_regulate clamps an out-of-range key byte (46..255) onto RepairHours instead of skipping it (accepted known issue 1c443300)"},{"citation":"resolved","description":"Merged from audit_math 65cfc198 and audit_economics e1b8c26e (same root cause: immutable protocol configuration), and the same as the requester's accepted Info ec0a447e in ADAPTATION.md item 3. The policy word carries maxPrice = 500000000000000000, equal to Intake.priceOf today, and the check is price > config.maxPrice, so backups work at launch; a 1 wei increase makes every askBackup revert InvalidValue forever. The relay path (submit) is unaffected by price but, like onOracleResult, depends on oracleSigner being exactly 0x5598aa9146215bc13eb26f2c692ad1461fd32982: a platform key rotation makes _verifyAttestation revert BadSignature everywhere and the game runs on autonomous fallbacks with Params frozen. The oracle-consumer reference says these should be owner-settable, but the brief explicitly requires no owner, so this is the documented trust/liveness assumption, not a defect. No funds are lost.","line":249,"path":"src/SwarmDesk.sol","reproduction":"Repro A: bound Desk, mock intake priceOf == 0.5 ether + 1 wei, warp into the next slot past hour one, askBackup(0, eventBody) reverts InvalidValue; at exactly 0.5 ether it succeeds. Reproduced in test/scratch/JudgeRepro.t.sol::testAnyoneSpendsDonationAndPriceCapIsExact (second half) and by existing testBackupFailureUnknownFailureDeadlineAndPriceCap. Repro B: sign a fully valid attestation with any key other than the attester and call submit(a, sig): BadSignature (existing testForgedTamperedWrongSignerWrongDomainAndCallerRejected). The ABI of SwarmDesk exposes no function that changes oracleSigner, config.intake, config.delivery, config.action or config.maxPrice.","severity":"info","snippet":"        if (price == 0 || price > config.maxPrice) revert InvalidValue();","title":"Oracle price cap, signer, intake, delivery and action are immutable with no setter: a repricing above 0.5 IMD disables askBackup forever and a signer rotation disables every oracle path (accepted know"},{"citation":"resolved","description":"From audit_economics f097eaff; the same model as the requester's accepted Info 5023720b in ADAPTATION.md item 2. submit() accepts any attestation signed by the attester for this Desk's domain and a pinned questionHash, and the first one accepted in a slot locks the slot (acceptedSlotPlusOne). Anyone can pay the oracle 0.5 IMD for a request whose consumer is this Desk, so a party can buy several panel answers for the same slot and relay the one it prefers first; panel variance is the only source of difference. Hard bounds cap what any answer does: kind 0..9, severity 5000..7000 for the next two epochs, Params moves of at most 10% within bounds once per day per key, pack pause <= 72h, one district boost <= 1500 bps, war/collapse/lot only once their Civic feature is enabled. No value can be moved to the chooser. Recorded so the judge record shows the accepted trust assumption; no action for this launch.","line":328,"path":"src/SwarmDesk.sol","reproduction":"Two valid attestations for event slot s signed by the attester: a with severity 7000 and b with severity 5000. Whichever is presented first via submit()/onOracleResult is stored (consumed true, acceptedSlotPlusOne[0] == s + 1); the second emits AnswerIgnored(requestId, 2) and is never consumed; execute(0, first.answer) plans the first one's severity. Swapping the order swaps the planned severity. Reproduced by the existing test testReplayDifferentSourceAndSecondAnswerSameSlotIgnored and the ADAPTATION.md scratch reproduction testMinimumPanelRelayWinsSlotOverLaterLargerPanel.","severity":"info","snippet":"                || acceptedSlotPlusOne[stream] == s + 1","title":"First valid attestation per slot wins: whoever can obtain a second attester-signed answer to the pinned question chooses which one the Desk acts on (accepted known issue 5023720b)"}],"hash":"1e2015c81115f940fbb76bd5a7d4274267289b5b61ca981674a7a6a665ad3829","nodeId":"7b8be32e-60f3-4eb4-8532-4ef4fa11321b","outcome":"completed","summary":"Review complete. The findings file is written and validated. Nothing in SwarmDesk rises to medium or above, so this launch should not be stopped.\n\n**Outcome**\n\n`.imd-findings.json` holds 9 findings (4 low, 5 info) and a 156-row coverage record. Every finding was reproduced against the code with a scratch Foundry test in `test/scratch/JudgeRepro.t.sol` (8 tests, all observe the stated behaviour) plus the specialist's epoch-drift proof run as `test/scratch/EpochDrift.t.sol`. No source file was changed.\n\n**What I kept and merged**\n\n- **Low:** expiry boundary (`expiresAt == block.timestamp` or acceptance in the slot's last second burns the slot); `askBackup` at slot end pays for an unanswerable request; `askBackup` is permissionless and spends donations while the relay is healthy; heartbeat rejected when `FarmRewards.epoch()` advances before the relay.\n- **Info:** answers accepted before job B cannot execute (flow and math duplicates merged into one); unsigned `AnswerIgnored` emission; out-of-range key clamps to RepairHours; immutable price cap/signer/intake (two specialist findings merged); first valid attestation wins.\n- The last three info items are the same mechanisms as the requester's already accepted known issues 1c443300, ec0a447e and 5023720b, and are labelled as such.\n- Dropped: nothing failed to reproduce. The specialist's attached proof passes on this tree, so it demonstrates rather than fails, and no finding here is severe enough to require one.\n\n**Independent checks I added**\n\n- Creation-code hash of the repo build equals the pinned `0x65968358…5745`; runtime is 20,797 bytes.\n- The policy word decodes to chain 1, blocks 26,122,900 to 26,122,901, max price 0.5 IMD, 200 bps, reserved bits zero.\n- SwarmCode's Registry and Params pins match this build of GameRegistry and Params.\n- Traced every module call `execute` makes (Params.set, submitPlan, announce, announceCap, pause/unpause, the try/catch Civic calls) and found no revert the Desk does not already pre-check, apart from the accepted b2ccff16 cap-announcement case.\n\n**Coverage**\n\nAll seven SwarmDesk entry points plus the twelve module functions the Desk calls are answered as holds or finding. The other 137 entry points belong to contracts this launch does not deploy and the Desk does not call. I marked them unreached rather than copying the specialists' verdicts.","treeHash":null,"usage":{"cachedInputTokens":1578043,"inputTokens":482,"model":"claude-fable-5-1","outputTokens":34024,"runtime":"claude","turns":29,"wallClockMs":749943}},{"artifacts":[],"attempt":1,"bundleHash":"02537a462ea398dd69d3779570ca1f8a0a3f0dc903b9c12b90cfe32ac580ba95","device":"19ed076a8c002c03","findings":[],"hash":"3b37aedbd90be21553fbb4a19646e1a9aa17c143a7c55340404da01359cb092d","nodeId":"d647e22f-c615-4c98-91f0-a905f47fd04d","outcome":"completed","summary":"Created [launch.json](/home/imd/.identitymd/work/c6594639-ac64-4c97-bdba-307fe43e74b2/d647e22f-c615-4c98-91f0-a905f47fd04d/launch.json) with one SwarmDesk, the exact twelve constructor words, and accepted audit notes.\n\nVerified manifest structure, constructor ABI, required creation hash, and unbound deployment state. `forge build` passed; `forge test`: 278 passed, 0 failed, 6 skipped, including the protected check.\n\nOnly `launch.json` is changed for submission. No live deployment was broadcast; confirmed address recording remains with the deployment service.","treeHash":"fef12794e92560dc25dec2910ce32e1c3478e81a","usage":{"cachedInputTokens":520064,"inputTokens":59925,"model":"gpt-6-astra","outputTokens":5962,"runtime":"codex","turns":4,"wallClockMs":249201}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fa5c50e7abe46571","findings":[{"citation":"resolved","description":"Access x economics seam. askBackup is permissionless and the only gates are the pinned body hash, one request per stream per slot and a one-hour wait into the slot (lines 244-247). Nothing checks that the heartbeat relay (submit) has actually failed for that slot, so an unrelated caller can make the Desk pay the 0.5 IMD intake price in every slot: four event slots per day plus one regulator slot per week, about 2.07 IMD per day, until the donated balance is gone. The backup is then unavailable when the relay really fails. The attacker gains nothing directly and the answer content stays the panel's, so impact is bounded griefing of donated funds; it is listed because the accepted known-issue list (ADAPTATION.md items 1-4 and b2ccff16) does not record it and the launch notes should.","line":240,"path":"src/SwarmDesk.sol","reproduction":"State: Desk bound to a registry, holding 10 IMD donated by anyone; the heartbeat relay is working normally. Input: at block.timestamp = s*21600 + 3600 (one hour into any six-hour slot s) an arbitrary EOA calls askBackup(0, eventBody) with the pinned 00e69e44... body bytes. Actual: the Desk approves and the intake pulls 500000000000000000 IMD (priceOf == maxPrice, verified live on 4663), askedSlotPlusOne[0] = s+1, a pending request is recorded, BackupAsked emitted. Repeating at every slot and askBackup(1, regulatorBody) weekly drains the 10 IMD in about five days with no heartbeat failure ever having occurred. Expected under the stated purpose (a backup for a missed heartbeat): spending only when no answer for the slot exists after the relay's window, or a cap on who may trigger it. Existing test testBackupPullsExactPriceRecordsRequestAndRestrictsBodyAndCadence already shows the pull from an arbitrary caller; no revert path distinguishes a healthy from a failed heartbeat.","severity":"low","snippet":"    function askBackup(uint8 stream, bytes calldata body) external nonReentrant returns (bytes32 id) {","title":"askBackup lets any caller spend the Desk's donated IMD on paid oracle requests even while the free heartbeat relay is healthy"}],"hash":"7b45c590fb068cde0494f2db1e5cfe5cb7ddd404e272de17ac8d8b65c4dd0419","nodeId":"c526a03b-e36c-4c14-a335-f586aa275d2e","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written. Only that file is new in the tree. No source, config or test files were changed.\n\n**Result: no critical, high or medium defect in SwarmDesk.** Nothing in the Access Control, Trust Gap or Asymmetry guides produced a reproducible blocking defect, so the launch is not stopped by this review.\n\n**What I verified**\n\n- **Build and words.** The repo build reproduces the pinned creation hash exactly. The packed policy word decodes to chain 1, window 26122900 to 26122901, max price 0.5 IMD and 200 bps. The existing bootstrap tests confirm an unbound deploy with no constructor external call and the pinned game config hash.\n- **Permission model.** The Desk has seven entry points, no owner, setter, receive, fallback, withdrawal or upgrade path. Callbacks are restricted to the intake and delivery contracts. The relay and execute paths carry no authority of their own: every answer must be signed by the attester in this Desk's EIP-712 domain for one of the two pinned question hashes, is consumed once per UUID and once per stream slot.\n- **Bind proof soundness.** The whole proof rests on the ProjectFactory's `predictContract` depending on init code. I checked this on the live Robinhood Chain factory: changing one byte of init code or the index changes the predicted address. The attester address holds no code, so no ERC-1271 path exists. The residual twin race is the documented M-2 griefing and nothing more.\n- **Asymmetry between the Desk's pre-checks and the module guards.** Every module call that `execute` makes outside a try/catch has its revert conditions mirrored by the Desk, with one exception already accepted as the known cap-rollback item. The Params step, bounds and cooldown logic matches exactly. The heartbeat share the swarm can raise feeds a 1 ETH capped keeper pool, not the Desk, so nothing gets locked.\n\n**One new low finding.** The paid backup is permissionless and nothing ties it to a heartbeat actually having failed. Any caller can make the Desk spend 0.5 IMD per slot, about 2 IMD per day, draining donated funds while the free relay is healthy. It is bounded griefing with no attacker profit, so it is low, and it belongs in the launch notes since the accepted known-issue list does not record it.\n\n**Coverage.** All 156 listed entry points plus three invariants have rows. The seven SwarmDesk functions and every module function the Desk calls or gates were traced. Entry points outside the area that the Desk never touches are marked as holding with a note that their internals were not reviewed in this pass, as the assignment instructs.","treeHash":null,"usage":{"cachedInputTokens":1912388,"inputTokens":642,"model":"claude-fable-5-1","outputTokens":41360,"runtime":"claude","turns":21,"wallClockMs":743909}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fbdcf3c80b280e3b","findings":[{"citation":"resolved","description":"Boundary off-by-one at expiry. _accept treats `a.expiresAt < block.timestamp` as stale (ignored, not consumed) but accepts `a.expiresAt == block.timestamp`; _verifyAttestation also passes at equality. The stored validUntil is then min(issuedAt+window, expiresAt, slotEnd) == block.timestamp (line 343), and execute requires `block.timestamp < r.validUntil`, so the stored answer is unexecutable from the moment it is stored. The same happens when an answer is accepted at slotEnd-1 (validUntil clamped to slotEnd, line 344). Because acceptance already sets acceptedSlotPlusOne[stream] = s+1 and consumes the UUID, a healthy answer for the same slot is later ignored (reason 2) and askBackup reverts TooEarly, so the stream loses that slot entirely. keeper/keeper.mjs relays `submit` (line 309) and `execute` (line 282) in separate transactions, so the gap is reachable when a relay lands at the attestation's last valid second or the slot's last second. Severity low: the heartbeat is lost for one 6-hour (event) or 7-day (regulator) slot; no funds move. Minimal fix: treat `until <= block.timestamp` as stale (emit AnswerIgnored(2) and return before _consume), i.e. require `a.expiresAt > block.timestamp` and `until > block.timestamp`.","line":313,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk, block.timestamp = T inside slot s with no accepted answer. Attester-signed event attestation with questionHash = questions[0], chainId 1, fromBlock/toBlock = config, panel 5/4/5, issuedAt = T, expiresAt = T, answer = abi.encode(bytes32[7]{s, epoch, 1, 7000, 3, salt, letter}). Anyone calls submit(a, sig). Expected: ignored as stale (not consumed). Actual: consumed[a.requestId] == true, lastAnswer[0].validUntil == T, pending == true, acceptedSlotPlusOne[0] == s+1. execute(0, a.answer) in the same block emits AnswerIgnored and submits no plan; a second valid attestation b for slot s is ignored (consumed[b.requestId] stays false) and askBackup(0, body) reverts TooEarly. Reproduced in test/scratch/Boundary.t.sol::testExpiresAtEqualsNowIsAcceptedThenBurned and ::testAcceptedInLastSecondOfSlotBurnsNextSecond (both pass on this tree, showing the behaviour).","severity":"low","snippet":"            a.expiresAt < block.timestamp || uint256(a.issuedAt) + (stream == 0 ? 6 hours : 1 days) < block.timestamp","title":"_accept stores an answer whose validUntil is already reached (expiresAt == block.timestamp, or acceptance in the slot's last second), consuming the slot while execute can never act"},{"citation":"resolved","description":"Boundary x invariant: the only time guard is `block.timestamp < s*period + 1 hours` (line 246); nothing stops a call at slotEnd-1. The deadline becomes `end` (line 265), one second away. Every direct answer arrives minutes later, so `_accept` hits `direct && block.timestamp >= p.deadline` (line 314) and ignores it; even a relayed version fails `issuedAt / period != s` once the slot has rolled. The price (0.5 IMD) is spent, askedSlotPlusOne[stream] = s+1 (line 250) prevents anyone else from asking for that slot, and the Pending entry lingers until clearExpired. askBackup is permissionless, so anyone can burn 0.5 IMD of donated balance per stream per slot in which no answer has yet been accepted. Severity low: bounded griefing of donated IMD (at most about 2 IMD/day across both streams), no third-party funds. Minimal fix: require a minimum remaining window, e.g. revert TooEarly when `end - block.timestamp < 15 minutes` (or deadline < block.timestamp + some floor).","line":265,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk holding >= 0.5 IMD, no answer accepted for event slot s. Warp to (s+1)*6 hours - 1. Call askBackup(0, body) with body hashing to config.bodies[0]. Expected: refused (no realistic answer can land). Actual: 0.5 IMD transferred to the intake, pending[id].deadline == block.timestamp + 1. One second later the intake delivers a correctly signed answer for slot s (issuedAt = slot s): onOracleResult returns without revert, emits AnswerIgnored(id,2), consumed stays false, pending[id] still active. Reproduced in test/scratch/Boundary.t.sol::testBackupAtSlotEndIsPaidAndUnanswerable.","severity":"low","snippet":"        if (deadline > end) deadline = end;","title":"askBackup in the final seconds of a slot pays the oracle for a request whose deadline is clamped to the slot end and whose answer is always ignored, and it blocks any other backup for that slot"},{"citation":"resolved","description":"Boundary: the packed key byte is clamped to [1,45] and then mapped to a Params.Key, so any stray key 46..255 in a signed regulator vector moves RepairHours (key 45) by up to +/-10% within its bounds [4e18, 8e18], instead of being skipped like key 0. The effect is bounded by the same clamps as any other key and requires the attester's signature, so this is informational; recorded so the regulator prompt/decoder are kept consistent. A minimal fix is `if (key == 0 || key > 45) continue;`.","line":416,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk, Params.lastChanged(RepairHours) + 1 day <= now. Signed regulator vector with v[1] = (255 << 248) | type(uint248).max. submit then execute(1, answer). Expected: nothing happens for an unknown key. Actual: Params.get(RepairHours) goes 6e18 -> 6.6e18. Reproduced in test/scratch/Boundary.t.sol::testKeyAbove45MovesRepairHours.","severity":"info","snippet":"            Params.Key k = Params.Key(_clamp(key, 1, 45) - 1);","title":"_regulate clamps an out-of-range key (46..255) onto RepairHours instead of ignoring it"},{"citation":"resolved","description":"Launch-order boundary. _accept for stream 1 touches no module, so a regulator answer is accepted (slot consumed, validUntil <= issuedAt + 1 day) as soon as the Desk is bound after job A. execute -> _regulate always calls registry.module(12) (line 423), module(11) (line 428) and module(4) (line 443) regardless of the vector's contents; GameRegistry.module reverts NotConfigured for an unregistered role, so execute reverts even when the vector only changes Params. If job B lands more than validUntil after acceptance, that week's regulator answer is lost (the slot stays consumed). Similar for the event stream, which needs modules 7, 1 and 12. No funds involved; the runbook binds and launches job B promptly, so informational. A minimal fix would guard those reads behind the corresponding `v[...] != 0` checks or use registeredModule().","line":423,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk whose registry has no module 12. Signed regulator vector with v[1] = (1 << 248) | 385 (EmissionBps 350 -> 385). submit succeeds (consumed == true). execute(1, answer) reverts NotConfigured; after module 12 is registered the same call succeeds and EmissionBps == 385. Reproduced with a mocked registry.module(12) revert in test/scratch/Boundary.t.sol::testRegulatorExecuteNeedsCivicEnhancementPacksEvenForParamsOnly.","severity":"info","snippet":"        Civic civic = Civic(registry.module(12));","title":"Regulator execute reads modules 12, 11 and 4 unconditionally, so a Params-only regulator answer accepted before job B registers them cannot be executed and expires"},{"citation":"resolved","description":"Boundary at equality: the constructor policy word carries maxPrice = 500000000000000000, which equals Intake.priceOf today, and the check is `price > config.maxPrice`. Equality passes, so backups work at launch; a price move of 1 wei upward makes every askBackup revert InvalidValue forever (no owner, no setter, by the brief's design). The heartbeat relay path (submit) is unaffected. Recorded as a trust/liveness assumption for the launch notes, not a defect of the requested design.","line":249,"path":"src/SwarmDesk.sol","reproduction":"Bound Desk; set the intake price to 0.5 IMD + 1 wei; askBackup(0, body) reverts InvalidValue; at exactly 0.5 IMD it succeeds (existing test testBackupFailureUnknownFailureDeadlineAndPriceCap shows the 1 IMD case).","severity":"info","snippet":"        if (price == 0 || price > config.maxPrice) revert InvalidValue();","title":"maxPrice is pinned to exactly the current oracle price (0.5 IMD) with no setter, so any price increase permanently disables askBackup"}],"hash":"8965564ac98b26e4906a275dba19d16058dde916f5dc4fef219d3661a3ca9f03","nodeId":"dfbe7a59-776f-45eb-8b0f-9f1fa59e04ec","outcome":"completed","summary":"Confirmed: the keeper relays and executes in separate transactions, so the expiry boundary in finding 1 is reachable in practice. The findings file is complete and validated. Final state:\n\n**Outcome: no critical, high or medium defect in SwarmDesk. Nothing stops this launch.** The findings file at `.imd-findings.json` holds 2 low and 3 info findings plus 161 coverage rows.\n\n**Verified invariants from the brief**\n\n- The built SwarmDesk creation code hashes to exactly the pinned value `0x65968358…5745` under the repo foundry.toml.\n- The policy word decodes to chain 1, blocks 26122900–26122901, maxPrice 0.5 IMD, heartbeat 200 bps, reserved bits zero. The twelve constructor words match the parameter order.\n- The Desk's Params clamp is exactly consistent with Params.set (same truncating old/10 step, result never leaves the hard bounds, all 45 defaults inside bounds). Every enum or index derived from an answer word is in range. Answer sizes are pinned to 288 and 608 bytes.\n- All 24 existing SwarmDesk tests and the oracle conformance tests pass.\n\n**Findings (all reproduced in test/scratch/Boundary.t.sol, which passes on this tree to show the behaviour)**\n\n1. **Low.** An attestation with `expiresAt == block.timestamp`, or one accepted in a slot's last second, is stored with validUntil already reached. The slot and UUID are consumed, execute can never act, and no backup can be asked for that slot. The keeper's separate submit and execute transactions make this reachable.\n2. **Low.** askBackup in the final seconds of a slot pays 0.5 IMD for a request whose deadline is one second away. The answer is always ignored and the slot's backup right is used up. Permissionless, so a bounded griefing of donated IMD.\n3. **Info.** A regulator key byte of 46–255 is clamped onto RepairHours instead of ignored.\n4. **Info.** Regulator execute reads modules 12, 11 and 4 unconditionally, so a Params-only answer accepted between bind and job B cannot execute and expires after a day.\n5. **Info.** maxPrice equals the live oracle price exactly with no setter, so any price rise disables backups forever. This matches the no-owner design and belongs in the launch notes.\n\n**Coverage.** All seven SwarmDesk entry points are traced, plus the eleven module functions the Desk calls and GameRegistry.register. The remaining entry points are marked as outside the assigned area with that reason stated, per the assignment's rule for out-of-area rows.","treeHash":null,"usage":{"cachedInputTokens":1526690,"inputTokens":386,"model":"claude-fable-5-1","outputTokens":43142,"runtime":"claude","turns":29,"wallClockMs":667336}},{"artifacts":[],"attempt":1,"bundleHash":"04f002206613ab06e218e3621e9cd3f36a10977bb971b06850293720050f87aa","device":"cd33e6f138d75a0c","findings":[],"hash":"8c3493c494bff7b302f13119ed2a7361fc8832de0074a9cb057dd2402ac3efdc","nodeId":"9577f704-484f-489a-a14f-a52175d548c3","outcome":"completed","summary":"Prepared the launch handoff in [ADAPTATION.md](/Users/timhsia/.identitymd/work/c6594639-ac64-4c97-bdba-307fe43e74b2/9577f704-484f-489a-a14f-a52175d548c3/ADAPTATION.md). Contract source is unchanged; accepted audit findings are recorded.\n\nVerified the exact creation hash, twelve constructor words, unbound registry and GAME_CONFIG_HASH locally. Build passed; tests: 284 passed, 6 skipped. Protected checks passed.\n\nThe confirmed address will come from IMD’s deployment step; no live deployment was broadcast.","treeHash":"60e22d9fb1aec92d8292e80bb0509e43a530950b","usage":{"cachedInputTokens":2823808,"inputTokens":137162,"model":"gpt-6.1-sol","outputTokens":20748,"runtime":"codex","turns":6,"wallClockMs":673071}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"4be5e039e1c77ce3","findings":[{"citation":"resolved","description":"Flow gap (execution x periphery x first principles). _accept requires the event answer's base epoch (values[1]) to equal FarmRewards.epoch() at the moment the attestation lands, while _event (line 396) deliberately tolerates current == base + 1 and still plans base + 2. FarmRewards.EPOCH is six hours, the same period as the event slot, and each epoch ends six hours after the previous permissionless advanceEpoch() call, so the epoch boundary sits at an arbitrary offset inside every slot and drifts forward by the advance latency. Whenever that offset falls inside the few minutes between the panel's read ('latest block minus 5', re-read before answering) and the on-chain submit/onOracleResult, every heartbeat of that slot is ignored (AnswerIgnored reason 2), not consumed, and cannot be executed. advanceEpoch() is permissionless, so anyone watching the mempool can also front-run a relay with advanceEpoch() whenever the epoch is due. Economic effect: the slot's plan is lost unless someone calls askBackup after hour one, which spends 0.5 IMD of the Desk's donated balance per affected slot; a backup can be rejected the same way. No funds are at risk; the grid falls back to fallbackKind with severity 10000 when no plan exists. Minimal fix that preserves the design: accept values[1] == epoch or values[1] + 1 == epoch (the window _event already honours).","line":333,"path":"src/SwarmDesk.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\nimport {BaseTest} from \"../Base.t.sol\";\nimport {SwarmDesk} from \"../../src/SwarmDesk.sol\";\nimport {OracleAttestation} from \"../../src/oracle/OracleAttestation.sol\";\nimport \"../../src/lib/Errors.sol\";\n\ncontract EpochDriftScratch is BaseTest {\n    uint256 private nonce;\n\n    function launchFeatures() internal pure override returns (bool) {\n        return false;\n    }\n\n    uint256 private due;\n\n    function setUp() public override {\n        super.setUp();\n        // Base.setUp advanced epoch 1 just now: it ends six hours later, at an arbitrary offset inside a slot.\n        due = block.timestamp + 6 hours;\n        uint256 t = due;\n        if (t % 6 hours > 5 hours) t += 2 hours;\n        vm.warp(t);\n    }\n\n    function attest(bytes32[] memory v) private returns (OracleAttestation.Attestation memory a, bytes memory sig) {\n        a.requestId = keccak256(abi.encode(\"uuid\", ++nonce));\n        a.chainId = 1;\n        a.questionHash = desk.oracleConfig().questions[0];\n        a.answerType = 5;\n        a.answer = abi.encode(v);\n        a.fromBlock = 100;\n        a.toBlock = 200;\n        a.panelSize = 5;\n        a.quorum = 4;\n        a.agreed = 5;\n        a.issuedAt = uint64(block.timestamp);\n        a.expiresAt = uint64(block.timestamp + 6 hours);\n        (uint8 vv, bytes32 r, bytes32 s) = vm.sign(0x123456, desk.attestationDigest(a));\n        sig = abi.encodePacked(r, s, vv);\n    }\n\n    function testHeartbeatRejectedWhenEpochAdvancesBeforeRelay() public {\n        uint256 base = d.rewards.epoch();\n        bytes32[] memory v = new bytes32[](7);\n        v[0] = bytes32(desk.slot(0));\n        v[1] = bytes32(base);\n        v[2] = bytes32(uint256(1));\n        v[3] = bytes32(uint256(6000));\n        v[6] = keccak256(\"letter\");\n        (OracleAttestation.Attestation memory a, bytes memory sig) = attest(v);\n        // The epoch is due; anyone advances it (or front-runs the relay with advanceEpoch()).\n        vm.roll(block.number + 3);\n        d.rewards.advanceEpoch();\n        assertEq(d.rewards.epoch(), base + 1);\n        // The relay lands one block later with the attester's valid, in-slot answer.\n        vm.warp(block.timestamp + 1);\n        desk.submit(a, sig);\n        assertFalse(desk.consumed(a.requestId), \"valid heartbeat was ignored\");\n        vm.expectRevert(InvalidProof.selector);\n        desk.execute(0, a.answer);\n        // Yet _event would have tolerated current == base + 1 and planned base + 2.\n        assertFalse(d.grid.planAt(base + 2).submitted);\n    }\n\n}","reproduction":"State: Desk bound, FarmRewards.epoch() == N, epochs[N].end <= block.timestamp (the epoch is due), current slot s. 1) The attester signs the honest event answer v = [s, N, kind, 6000, hint, salt, letter] with issuedAt in slot s. 2) Anyone calls FarmRewards.advanceEpoch() (epoch becomes N+1) in the block before the relay. 3) desk.submit(a, sig) in the next block. Expected (by _event's own tolerance): the answer is stored and execute(0, answer) submits the plan for epoch N+2. Actual: _accept emits AnswerIgnored(requestId, 2), consumed[requestId] stays false, execute(0, answer) reverts InvalidProof, planAt(N+2).submitted stays false. The attached test test/scratch/EpochDrift.t.sol passes on this tree, i.e. it demonstrates the rejection.","severity":"low","snippet":"        if (stream == 0 && uint256(values[1]) != IRewards(registry.module(1)).epoch()) {\n            emit AnswerIgnored(a.requestId, 2);\n            return;\n        }","title":"Heartbeat answers are rejected when the epoch advances between the panel's read and the relay, although execute() tolerates that drift"},{"citation":"resolved","description":"Economic security (dependency failure). The Desk has no owner by design, so config.maxPrice (0.5 IMD packed into the policy word), oracleSigner (0x5598...2982), config.intake and config.action can never change. The oracle-consumer reference supplied with this task states these must be constructor input AND settable because 'a new action version (oracle-2) or a moved price must not need a redeploy'. If Intake.priceOf(action, IMD) ever exceeds 0.5 IMD, askBackup reverts InvalidValue on every call; only the free relay path survives. If the platform rotates the attester key, _verifyAttestation reverts BadSignature for every submit/onOracleResult and the game runs on autonomous fallbacks with Params frozen at launch defaults for its whole life. No funds are lost (the Desk's donated IMD is simply never spent). This is the documented 'no owner' trust assumption of the launch and is recorded here as a known issue, not as a blocker.","line":249,"path":"src/SwarmDesk.sol","reproduction":"Repro A: with a mock Intake returning priceOf == 1 ether, call desk.askBackup(0, eventBody) one hour into a slot. Expected (reference design): the request is placed at the new price or an owner can raise the cap. Actual: revert InvalidValue (shown by testBackupFailureUnknownFailureDeadlineAndPriceCap after intake.setPrice(1 ether)). Repro B: sign a fully valid attestation with any key other than 0x5598aa9146215bc13eb26f2c692ad1461fd32982 and call desk.submit(a, sig). Actual: BadSignature; there is no function on SwarmDesk that can ever change oracleSigner, intake, action or maxPrice.","severity":"low","snippet":"        if (price == 0 || price > config.maxPrice) revert InvalidValue();","title":"Oracle price cap, signer, intake and action are immutable: an Intake repricing above 0.5 IMD disables askBackup forever and a signer rotation disables every oracle path"},{"citation":"resolved","description":"Trust assumption to record in the launch notes (economics x access). submit() accepts any attestation signed by the attester for this Desk's domain and the pinned questionHash, and the first one accepted in a slot locks the slot. Anyone can pay the oracle (0.5 IMD per answer) for a schedule or request whose consumer is this Desk, so a party can buy several panel answers for the same slot and relay the one it prefers first; panel variance is the only source of difference. The Desk's hard bounds cap what any single answer can do: kind 0..9, severity 5000..7000 for the next two epochs; Params moves of at most 10% within Params.bounds once per day per key; pack pause of at most 72 h; one district boost of at most 1500 bps per week; war/collapse/lot only once their Civic feature is enabled. No value can be moved to the chooser. This is the intended 'the bytes are the attester's' model; it is reported so the judge can confirm it is accepted, not as a defect.","line":326,"path":"src/SwarmDesk.sol","reproduction":"Two valid attestations for slot s: a with severity 7000 and b with severity 5000 (testReplayDifferentSourceAndSecondAnswerSameSlotIgnored). Whichever is presented first via submit()/onOracleResult is stored; the second emits AnswerIgnored(2) and is never consumed; execute() then plans the first one's values. Swap the submission order and the planned severity swaps.","severity":"info","snippet":"        if (\n            uint256(values[0]) != s || a.issuedAt / _period(stream) != s || (direct && p.slot != s)\n                || acceptedSlotPlusOne[stream] == s + 1\n        ) {\n            emit AnswerIgnored(a.requestId, 2);\n            return;\n        }","title":"First valid attestation per slot wins: whoever can obtain a second attester-signed answer to the pinned question chooses which one the Desk acts on"}],"hash":"9db874eb40be81bcab1705e0417c2940e330b672f2916fcbb8a24ecd817d5048","nodeId":"ee3e4d33-8ddc-48bc-ab24-f3c8e35a3a82","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written with 3 findings and a 159-row coverage record. No source files were changed.\n\n**Outcome: nothing blocks this launch.** I found no critical, high or medium defect in SwarmDesk under the Economic Security, Invariant and Flow Gap guides. The constructor words regenerate byte-identically from the committed config, the policy word decodes to the stated values, and the built creation code hashes to the pinned value.\n\n**Findings recorded**\n\n- **Low, epoch-boundary rejection of valid heartbeats.** The accept path in `src/SwarmDesk.sol:333` requires the answer's base epoch to equal the live epoch exactly, while the execute path tolerates one epoch of drift. Epochs are six hours and end six hours after each permissionless advance, so the boundary drifts through the few-minute heartbeat window periodically, and anyone can front-run a relay with an epoch advance when one is due. Each affected slot loses its plan unless a backup is bought for 0.5 IMD. I reproduced this with a Foundry test that passes on the current tree and is attached as proof.\n- **Low, immutable oracle configuration.** The price cap, signer, intake and action can never change. An Intake repricing above 0.5 IMD disables backups forever and a signer rotation disables every oracle path. This is the documented no-owner design, recorded as a known issue.\n- **Info, first valid attestation per slot wins.** Anyone who buys a second attester-signed answer to the pinned question picks which one the Desk acts on. The Desk's hard bounds cap the effect. Recorded as a trust assumption for the launch notes.\n\n**What held**\n\n- `askBackup` spending is bounded to roughly 2.07 IMD per day of donated balance and is only possible when no answer landed in the slot's first hour.\n- Every swarm-gated callee was traced against the Desk's clamps: the Params double clamp can never make `set` revert, all 45 Params defaults sit inside their bounds, the severity band and epoch window sit inside the grid's checks, and every optional Civic or PackSale action is wrapped in try.\n- `bind` proves both Params and GameRegistry through pinned creation hashes and factory CREATE2 prediction. The twin race remains the documented M-2 assumption.\n\n**Coverage.** All seven SwarmDesk entry points and the swarm-called functions on Params, GridOperator, Civic, Enhancement, PackSale and GameRegistry are traced in depth. The remaining entry points are not deployed in this launch and are never called by the Desk, so they are marked as untouched by this area rather than examined.","treeHash":null,"usage":{"cachedInputTokens":2080135,"inputTokens":450,"model":"claude-fable-5-1","outputTokens":45900,"runtime":"claude","turns":28,"wallClockMs":784790}},{"artifacts":[],"attempt":1,"bundleHash":"f6ca3368a507b5a590613898e482dca97a966b3685268ea0aa6c810af262d263","device":"2717ac8e1d58fd36","findings":[],"hash":"f32995e4b9ce3c034ba32d0a1af971c5e2599ad8947d7d7195380e92ffadc0be","nodeId":"b4e2ac84-cbd2-4603-874a-9da4819c8b4c","outcome":"completed","summary":"Added failure-path tests, 9,000 fuzz cases, and stateful invariants covering 16,384 calls. Exact creation hash and unbound bootstrap verified.\n\n`forge build` and `forge test` pass: **319 passed, 0 failed, 6 fork tests skipped**.\n\nOnly `test/` changed. Accepted issues are recorded in [launch notes](/root/.identitymd/work/c6594639-ac64-4c97-bdba-307fe43e74b2/b4e2ac84-cbd2-4603-874a-9da4819c8b4c/test/SwarmDesk-launch-notes.md). No live deployment was performed.","treeHash":"17886711307f0331fb20390b38cfc4477e9ce067","usage":{"cachedInputTokens":4060288,"inputTokens":182298,"model":"gpt-6-astra","outputTokens":37000,"runtime":"codex","turns":9,"wallClockMs":1358743}}],"verification":[{"checks":[{"durationMs":25272,"exitCode":0,"name":"build","output":"Compiling 189 files with Solc 0.8.26\nSolc 0.8.26 finished in 24.91s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n  --> src/lib/EconomyMath.sol:17:48:\n   |\n17 |         returns (uint256 chance, uint256 burn, uint256 bonus, uint256 daysWad)\n   |                                                ^^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/lib/EconomyMath.sol:44:5:\n   |\n44 |     function bonus(uint256 level) internal pure returns (uint256 b) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (8760): This declaration has the same name as another declaration.\n   --> src/V4Market.sol:300:22:\n    |\n300 |     function _record(bool sell, uint256 amount) private {\n    |                      ^^^^^^^^^\nNote: The other declaration is here:\n   --> src/V4Market.sol:490:5:\n    |\n490 |     function sell(uint256 amount, uint256 minOut, address recipient) external nonReentrant returns (uint256 received) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (8760): This declaration has the same name as another declaration.\n  --> test/mocks/MockSwarmIntake.sol:26:9:\n   |\n26 |         bytes4 failure,\n   |         ^^^^^^^^^^^^^^\nNote: The other declaration is here:\n  --> test/mocks/MockSwarmIntake.sol:44:5:\n   |\n44 |     function failure(bytes32 id, uint8 status, bytes32 reason) external returns (bool) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2072): Unused local variable.\n   --> test/Events.t.sol:199:9:\n    |\n199 |         uint256 price = d.packs.quote(112);\n    |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n --> test/Gas.t.sol:9:9:\n  |\n9 |         uint256 price = d.packs.price();\n  |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Gas.t.sol:75:9:\n   |\n75 |         uint256 q = d.packs.quote(112);\n   |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Invariants.t.sol:56:9:\n   |\n56 |         uint256 price = d.packs.price();\n   |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Items.t.sol:76:9:\n   |\n76 |         uint256 cost = d.packs.quote(112);\n   |         ^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/Items.t.sol:106:9:\n    |\n106 |         uint256 q = d.packs.quote(16);\n    |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/LazyAccounting.t.sol:186:13:\n    |\n186 |             uint256 quote = d.packs.quote(112);\n    |             ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/LazyAccounting.t.sol:421:9:\n    |\n421 |         uint256 quote = d.packs.quote(112);\n    |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Packs.t.sol:37:9:\n   |\n37 |         uint256 quote = d.packs.quote(200);\n   |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Packs.t.sol:64:9:\n   |\n64 |         uint256 q = d.packs.quote(6);\n   |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Pause.t.sol:35:9:\n   |\n35 |         uint256 q = d.packs.quote(1);\n   |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Regression.t.sol:73:9:\n   |\n73 |         uint256 previous = d.items.data(id).durability;\n   |         ^^^^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/V33.t.sol:254:13:\n    |\n254 |             uint256 q = d.packs.quote(16);\n    |             ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/V33.t.sol:431:9:\n    |\n431 |         uint256 price = d.packs.price();\n    |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/V34.t.sol:78:9:\n   |\n78 |         uint256 q = d.packs.price();\n   |         ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> src/FarmRewards.sol:146:5:\n    |\n146 |     function ready() public view returns (bool) {\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/RehearsalV311.t.sol:216:5:\n    |\n216 |     function _oracle() internal view returns (SwarmDesk.OracleConfig memory o) {\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/RehearsalV311.t.sol:290:5:\n    |\n290 |     function _mineHookSalt(bytes memory initCode) internal view returns (bytes32 salt, address hook) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/StandardAdapter.sol:46:64\n   │\n46 │         if (rate == 0 || rate > 1e40 || window < 30 minutes || at > block.timestamp || block.timestamp - at > 5 minutes)\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/StandardAdapter.sol:46:88\n   │\n46 │         if (rate == 0 || rate > 1e40 || window < 30 minutes || at > block.timestamp || block.timestamp - at > 5 minutes)\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/StandardAdapter.sol:58:9\n   │\n58 │         manager.unlock(abi.encode(msg.value, minOut, recipient));\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unused-return]: return value of an external call is not used\n   ╭▸ src/StandardAdapter.sol:58:9\n   │\n58 │         manager.unlock(abi.encode(msg.value, minOut, recipient));\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/Params.sol:176:13\n    │\n176 │         if (block.timestamp < lastChanged[k] + 1 days) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:67:62\n   │\n67 │         int256 delta = manager.swap(key(), SwapParams(true, -int256(input), 4295128740), \"\");\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/StandardAdapter.sol:68:27\n   │\n68 │         int128 ethDelta = int128(delta >> 128);\n   │                           ━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'int128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:69:22\n   │\n69 │         int128 out = int128(delta);\n   │                      ━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'int128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:70:30\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\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/StandardAdapter.sol:70:81\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\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/StandardAdapter.sol:70:89\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\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/StandardAdapter.sol:73:9\n   │\n73 │         manager.settle{value: input}();\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:74:49\n   │\n74 │         manager.take(address(token), recipient, uint256(uint128(out)));\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/StandardAdapter.sol:74:57\n   │\n74 │         manager.take(address(token), recipient, uint256(uint128(out)));\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/StandardAdapter.sol:75:27\n   │\n75 │         return abi.encode(uint256(uint128(out)));\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/StandardAdapter.sol:75:35\n   │\n75 │         return abi.encode(uint256(uint128(out)));\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/FarmRewards.sol:151:30\n    │\n151 │         return epoch != 0 && block.timestamp < epochs[epoch].end;\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `scrapAllowance` is updated\n    ╭▸ src/FarmRewards.sol:165:13\n    │\n165 │             pool().recycle(scrapAllowance);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[missing-events-arithmetic]: `heldBase` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:461:9\n    │\n461 │         heldBase += base;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `heldSellTax` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:462:9\n    │\n462 │         heldSellTax += excess;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[reentrancy-no-eth]: external call can be reentered before `epoch` is updated\n    ╭▸ src/FarmRewards.sol:169:13\n    │\n169 │             grid().resolveFor(epoch, msg.sender);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `epoch` is updated\n    ╭▸ src/FarmRewards.sol:179:17\n    │\n179 │                 pool().reserve(old.budget);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `epoch` is updated\n    ╭▸ src/FarmRewards.sol:186:33\n    │\n186 │                 if (prize != 0) season().addPrize(week, prize);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[missing-events-arithmetic]: `heldBase` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:520:9\n    │\n520 │         heldBase += base;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/MarketFactory.sol:70:9\n   │\n70 │         emit MarketDeployed(address(market), salt);\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/FarmRewards.sol:230:9\n    │\n230 │         grid().shift(epoch);\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/FarmRewards.sol:231:9\n    │\n231 │         fees().payBounty(msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmRewards.sol:189:40\n    │\n189 │                     lastAverageDaily = old.mining * (10000 - old.tariff) / 10000 * 4 / activeFarmCount[epoch];\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/FarmRewards.sol:163:13\n    │\n163 │         if (block.timestamp < launchTime() || (epoch != 0 && block.timestamp < epochs[epoch].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/FarmRewards.sol:163:62\n    │\n163 │         if (block.timestamp < launchTime() || (epoch != 0 && block.timestamp < epochs[epoch].end)) revert TooEarly();\n    │                                                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:115:23\n    │\n115 │         return Params(registry.params());\n    │                       ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:226:36\n    │\n226 │             epochParam[epoch][k] = params().get(Params.Key(k));\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/FarmRewards.sol:198:13\n    │\n198 │             emit EpochClosed(epoch, old.budget, old.raw);\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/FarmRewards.sol:209:13\n    │\n209 │             emit Expired(epoch, gone);\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/FarmRewards.sol:232:9\n    │\n232 │         emit EpochStarted(epoch, e.start, e.end, msg.sender);\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/FarmRewards.sol:171:13\n    │\n171 │             (old.kind, old.severity, old.district, old.seed,) = grid().eventAt(epoch);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:202:19\n    │\n202 │         e.start = 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/FarmRewards.sol:203:17\n    │\n203 │         e.end = uint64(block.timestamp + EPOCH);\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]: `bestClaimed` is changed without an event but is used for access control\n   ╭▸ src/Season.sol:76:9\n   │\n76 │         bestClaimed[w] = true;\n   │         ━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:174:21\n    │\n174 │                     seasons[w].districtSpend[d] += districtSpendOf[w][p];\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:241:17\n    │\n241 │                 seasons[w].districtSpend[d] += districtSpendOf[w][p];\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:263:9\n    │\n263 │         s.totalTickets += weight;\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:275:9\n    │\n275 │         seasons[w].prize += amount;\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `lotteryClaimed` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:364:9\n    │\n364 │         lotteryClaimed[w][msg.sender] = true;\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:203:24\n    │\n203 │         if (base != 0) fees.depositBaseFee{value: base}();\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:204:26\n    │\n204 │         if (excess != 0) fees.depositSellTax{value: excess}();\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:205:29\n    │\n205 │         if (launchTax != 0) fees.depositLaunchTax{value: launchTax}();\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-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/V4Market.sol:206:9\n    │\n206 │         emit FeesFlushed(base, excess);\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/V4Market.sol:207:29\n    │\n207 │         if (launchTax != 0) emit LaunchTaxFlushed(launchTax);\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/Season.sol:67:26\n   │\n67 │         if (rolled[w] || block.timestamp >= claimDeadline(w)) 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/FarmRewards.sol:309:9\n    │\n309 │         emit MiningStarted(p, epoch, secondsLeft, weighted);\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/V4Market.sol:262:13\n    │\n262 │             emit PriceObserved(now_, price);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/V4Market.sol:275:9\n    │\n275 │         emit PriceObserved(now_, price);\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/Season.sol:81:26\n   │\n81 │         if (rolled[w] || block.timestamp < claimDeadline(w)) 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/Season.sol:154:13\n    │\n154 │         if (block.timestamp < launchTime()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[boolean-cst]: misuse of a boolean constant\n   ╭▸ src/Enhancement.sol:55:63\n   │\n55 │             (cap == 8 ? next != 12 : cap == 12 ? next != 16 : true) || announcedCap != 0 || bytes(letter).length == 0\n   │                                                               ━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Season.sol:161:13\n    │\n161 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmRewards.sol:350:25\n    │\n350 │         for (uint256 n; n < limit && cursor < settledEpoch; ++n) {\n    │                         ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:123:22\n    │\n123 │         return ICore(registry.module(2));\n    │                      ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:359:60\n    │\n359 │         (uint256 raw, uint256 productive, uint256 power) = core().process(p, id);\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:139:16\n    │\n139 │         return registry.launchTime();\n    │                ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:425:9\n    │\n425 │         core().autoRepair(p, id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:119:27\n    │\n119 │         return RewardPool(registry.module(0));\n    │                           ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:446:26\n    │\n446 │         if (unused != 0) pool().recycle(unused);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:449:28\n    │\n449 │             if (dust != 0) pool().recycle(dust);\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:431:13\n    │\n431 │             core().activity(p, id, o.gross, o.net);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:433:17\n    │\n433 │                 core().grantDrop(p, keccak256(abi.encode(e.seed, p, \"item\")));\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/Enhancement.sol:66:34\n   │\n66 │         if (announcedCap == 0 || block.timestamp < activationAt) revert TooEarly();\n   │                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:135:24\n    │\n135 │         return ISeason(registry.module(8));\n    │                        ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:435:13\n    │\n435 │             season().recordActivity(p, week, o.gross, weight);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:380:13\n    │\n380 │             season().complete(p, week);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Season.sol:202:60\n    │\n202 │         if (districtSpendOf[w][p] > low) topSpenders[w][d][slot] = p;\n    │                                                            ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-no-eth]: external call can be reentered before `pending` is updated\n   ╭▸ src/Enhancement.sol:85:9\n   │\n85 │         core.prepareEnhancement(msg.sender, item, cost, wallet);\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/FarmRewards.sol:477:13\n    │\n477 │             emit Credited(p, e, 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/FarmRewards.sol:488:9\n    │\n488 │         emit Credited(p, e, 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/FarmRewards.sol:450:13\n    │\n450 │             emit EpochSettled(id, e.spent, dust);\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/FarmRewards.sol:422:35\n    │\n422 │         if (spent > o.allocation) revert InvalidValue();\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/Enhancement.sol:89:9\n   │\n89 │         emit EnhancementCommitted(id, msg.sender, item, target, ChainClock.number() + 2, cost);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/Enhancement.sol:88:50\n   │\n88 │         attempts[id] = Attempt(msg.sender, item, uint64(ChainClock.number() + 2), target, bytes32(0), false, false);\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/Enhancement.sol:100:24\n    │\n100 │             a.target = uint64(ChainClock.number() + 2);\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/Season.sol:234:13\n    │\n234 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\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/Enhancement.sol:122:21\n    │\n122 │         if (burned) inventory.destroy(a.item);\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/Enhancement.sol:123:14\n    │\n123 │         else inventory.maintain(a.item, x.durability, level);\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/Enhancement.sol:124:9\n    │\n124 │         emit EnhancementResolved(id, success, burned, level);\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/FarmRewards.sol:475:13\n    │\n475 │         if (block.timestamp >= at + 7 days) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/Billboards.sol:60:13\n   │\n60 │         if (t.balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:485:19\n    │\n485 │         v.epoch = uint64(e);\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/FarmRewards.sol:486:48\n    │\n486 │         if (at > v.at || v.amount == 0) v.at = uint64(at);\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/FarmRewards.sol:514:25\n    │\n514 │         for (uint256 n; n < 32 && amount != 0; ++n) {\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/FarmRewards.sol:503:36\n    │\n503 │             if (old.amount != 0 && block.timestamp >= uint256(old.at) + 7 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/FarmRewards.sol:520:45\n    │\n520 │             if (taxed) tax += used * taxBps(block.timestamp > v.at ? block.timestamp - v.at : 0) / 10000;\n    │                                             ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/Billboards.sol:82:17\n   │\n82 │                 revert InvalidValue();\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/Billboards.sol:88:17\n   │\n88 │                 revert InvalidValue();\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/V4Market.sol:269:38\n    │\n269 │             uint256 c = cumulative + (1e60 / lastPrice) * (minute * 60 - updatedAt);\n    │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Season.sol:253:13\n    │\n253 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/V4Market.sol:272:23\n    │\n272 │         cumulative += (1e60 / lastPrice) * (now_ - updatedAt);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/V4Market.sol:267:13\n    │\n267 │         if (last >= 32 && first < last - 31) first = last - 31;\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/V4Market.sol:267:27\n    │\n267 │         if (last >= 32 && first < last - 31) first = last - 31;\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/V4Market.sol:268:38\n    │\n268 │         for (uint256 minute = first; minute <= last; ++minute) {\n    │                                      ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:270:53\n    │\n270 │             observations[minute % 32] = Observation(uint64(minute), c);\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[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/V4Market.sol:281:50\n    │\n281 │         if (ts >= updatedAt) return cumulative + (1e60 / lastPrice) * (ts - updatedAt);\n    │                                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/Billboards.sol:70:9\n   │\n70 │         RewardPool(pool).donate(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/Season.sol:280:42\n    │\n280 │         if (!rewards().seasonReady(w) || block.timestamp < deadline(w) || limit == 0 || limit > 64) 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/V4Market.sol:288:35\n    │\n288 │         if (initializedAt == 0 || block.timestamp < initializedAt + 31 minutes) revert NotConfigured();\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/Billboards.sol:120:9\n    │\n120 │         emit BillboardSettled(w, d, b.bid);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:283:20\n    │\n283 │         s.target = uint64(ChainClock.number() + 2);\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/V4Market.sol:304:13\n    │\n304 │         if (a.period != p) {\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/V4Market.sol:310:13\n    │\n310 │         if (b.period != p) {\n    │             ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:306:24\n    │\n306 │             a.period = uint64(p);\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/V4Market.sol:312:24\n    │\n312 │             b.period = uint64(p);\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/V4Market.sol:315:24\n    │\n315 │             a.sells += uint192(amount);\n    │                        ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:316:24\n    │\n316 │             b.sells += uint192(amount);\n    │                        ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:318:23\n    │\n318 │             a.buys += uint192(amount);\n    │                       ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:319:23\n    │\n319 │             b.buys += uint192(amount);\n    │                       ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe 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/V4Market.sol:330:17\n    │\n330 │                 b += shortVolumes[i].buys;\n    │                 ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/V4Market.sol:329:17\n    │\n329 │                 s += shortVolumes[i].sells;\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/V4Market.sol:328:17\n    │\n328 │             if (uint256(shortVolumes[i].period) + 12 > current) {\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/V4Market.sol:338:17\n    │\n338 │             if (uint256(longVolumes[i].period) + 24 > current) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/V4Market.sol:394:13\n    │\n394 │         if (average != 0 && price > average) dev = Math.min(1000, 10000 - Math.mulDiv(average, 10000, price));\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/V4Market.sol:393:13\n    │\n393 │         if (block.timestamp >= initializedAt + 31 minutes) average = twap();\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/V4Market.sol:399:27\n    │\n399 │         uint256 decayed = storedFeeWad > fall ? storedFeeWad - fall : PROJECT_BPS * 1 ether;\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/V4Market.sol:420:13\n    │\n420 │             emit LaunchTax(sender, ethIn, taxBps, fee);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-events-access-control]: `commits` is changed without an event but is used for access control\n    ╭▸ src/PackSale.sol:254:9\n    │\n254 │         c.seed = keccak256(abi.encode(h, address(this), id));\n    │         ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:413:25\n    │\n413 │         uint256 ethIn = uint256(-p.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/V4Market.sol:416:19\n    │\n416 │         if (fee > uint256(uint128(type(int128).max))) revert InvalidValue();\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/V4Market.sol:416:27\n    │\n416 │         if (fee > uint256(uint128(type(int128).max))) revert InvalidValue();\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/PackSale.sol:62:16\n   │\n62 │         return block.timestamp < pausedUntil;\n   │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:425:43\n    │\n425 │         return (this.beforeSwap.selector, int256(fee << 128), 0);\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/PackSale.sol:68:13\n   │\n68 │         if (block.timestamp < nextPauseAt) 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/PackSale.sol:117:16\n    │\n117 │         return block.timestamp >= opensAt() && !paused();\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:145:27\n    │\n145 │         o.questionChain = uint32(policyWord);\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/SwarmDesk.sol:146:23\n    │\n146 │         o.fromBlock = uint48(policyWord >> 32);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint48' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/PackSale.sol:144:13\n    │\n144 │         p = Economy(registry.module(10)).averageDaily() * daysPrice / 1 ether;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:147:21\n    │\n147 │         o.toBlock = uint48(policyWord >> 80);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint48' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:148:22\n    │\n148 │         o.maxPrice = uint96(policyWord >> 128);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint96' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:153:26\n    │\n153 │         b.heartbeatBps = uint16(policyWord >> 224);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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/Season.sol:328:39\n    │\n328 │             if (s.best != address(0)) rewards().award(s.best, s.prize);\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/Season.sol:329:18\n    │\n329 │             else rewards().releasePrize(s.prize);\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/Season.sol:331:34\n    │\n331 │         if (s.participants != 0) fees().payWork(msg.sender, Params.Key.SeasonBounty, 1, startGas - gasleft());\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/PackSale.sol:130:27\n    │\n130 │         uint256 elapsed = block.timestamp > opensAt() ? block.timestamp - opensAt() : 0;\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:132:24\n    │\n132 │         int256 ahead = int256(sales * 1 ether) - int256(elapsed * target * 1 ether / 1 hours);\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/PackSale.sol:132:50\n    │\n132 │         int256 ahead = int256(sales * 1 ether) - int256(elapsed * target * 1 ether / 1 hours);\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/PackSale.sol:135:30\n    │\n135 │             exponent = wadLn(int256(1 ether + params().get(Params.Key.PriceStepBps) * 1e14)) * ahead / 1 ether;\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/PackSale.sol:137:30\n    │\n137 │             exponent = wadLn(int256(1 ether - decay * 1e14)) * (-ahead) / int256(target) / 1 ether;\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/PackSale.sol:137:75\n    │\n137 │             exponent = wadLn(int256(1 ether - decay * 1e14)) * (-ahead) / int256(target) / 1 ether;\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/PackSale.sol:141:37\n    │\n141 │         uint256 daysPrice = start * uint256(wadExp(exponent)) / 1 ether;\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Season.sol:319:25\n    │\n319 │         for (uint256 i; i < 3 && left != 0; ++i) {\n    │                         ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:111:28\n    │\n111 │         return ILaunchHook(registry.market()).initializedAt() == 0\n    │                            ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:111:16\n    │\n111 │         return ILaunchHook(registry.market()).initializedAt() == 0\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:113:27\n    │\n113 │             : ILaunchHook(registry.market()).initializedAt() + OPEN_DELAY;\n    │                           ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:113:15\n    │\n113 │             : ILaunchHook(registry.market()).initializedAt() + OPEN_DELAY;\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/Season.sol:332:9\n    │\n332 │         emit SeasonFinalized(w, s.winnerDistrict, s.best, s.seed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:91:23\n   │\n91 │         return Params(registry.params());\n   │                       ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:135:47\n    │\n135 │             exponent = wadLn(int256(1 ether + params().get(Params.Key.PriceStepBps) * 1e14)) * ahead / 1 ether;\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:315:36\n    │\n315 │                 s.winnerDistrict = uint8(d);\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[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:144:21\n    │\n144 │         p = Economy(registry.module(10)).averageDaily() * daysPrice / 1 ether;\n    │                     ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:144:13\n    │\n144 │         p = Economy(registry.module(10)).averageDaily() * daysPrice / 1 ether;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:52:33\n   │\n52 │         uint256 daily = Economy(registry.module(10)).averageDaily();\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/SwarmDesk.sol:252:14\n    │\n252 │           id = ISwarmIntake(config.intake)\n    │ ┏━━━━━━━━━━━━━━┛\n253 │ ┃             .requestWithFailure(\n254 │ ┃                 config.action,\n255 │ ┃                 body,\n    ‡ ┃\n259 │ ┃                 price\n260 │ ┃             );\n    │ ┗━━━━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:338:20\n    │\n338 │         s.target = uint64(ChainClock.number() + 2);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:52:25\n   │\n52 │         uint256 daily = Economy(registry.module(10)).averageDaily();\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/FarmRewards.sol:359:60\n    │\n359 │         (uint256 raw, uint256 productive, uint256 power) = core().process(p, id);\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/FarmRewards.sol:380:13\n    │\n380 │             season().complete(p, week);\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/FarmRewards.sol:425:9\n    │\n425 │         core().autoRepair(p, id);\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/V4Market.sol:454:9\n    │\n454 │         emit SellFee(sender, output, bps, hour, day, dev);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:436:27\n    │\n436 │         int128 ethDelta = int128(delta >> 128);\n    │                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe 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/PackSale.sol:47:9\n   │\n47 │         revert InvalidValue();\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/SwarmDesk.sol:246:20\n    │\n246 │                 || block.timestamp < s * _period(stream) + 1 hours\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/FarmRewards.sol:431:13\n    │\n431 │             core().activity(p, id, o.gross, o.net);\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/FarmRewards.sol:433:17\n    │\n433 │                 core().grantDrop(p, keccak256(abi.encode(e.seed, p, \"item\")));\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/FarmRewards.sol:435:13\n    │\n435 │             season().recordActivity(p, week, o.gross, weight);\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/FarmRewards.sol:446:26\n    │\n446 │         if (unused != 0) pool().recycle(unused);\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/FarmRewards.sol:449:28\n    │\n449 │             if (dust != 0) pool().recycle(dust);\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/FarmRewards.sol:533:9\n    │\n533 │         pool().pay(msg.sender, net);\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/SwarmDesk.sol:265:13\n    │\n265 │         if (deadline > end) deadline = end;\n    │             ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:439:28\n    │\n439 │             _record(false, uint256(-int256(ethDelta)));\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/SwarmDesk.sol:267:9\n    │\n267 │         emit BackupAsked(stream, s, id, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:443:26\n    │\n443 │         uint256 output = uint256(uint128(ethDelta));\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/V4Market.sol:443:34\n    │\n443 │         uint256 output = uint256(uint128(ethDelta));\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/V4Market.sol:445:42\n    │\n445 │         return (this.afterSwap.selector, int128(int256(_chargeSell(sender, output, price))));\n    │                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe 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/Season.sol:359:14\n    │\n359 │         id = packs().rewardPack(msg.sender);\n    │              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:445:49\n    │\n445 │         return (this.afterSwap.selector, int128(int256(_chargeSell(sender, output, price))));\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/SwarmDesk.sol:266:31\n    │\n266 │         pending[id] = Pending(uint64(s), uint64(deadline), stream + 1);\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/SwarmDesk.sol:266:42\n    │\n266 │         pending[id] = Pending(uint64(s), uint64(deadline), stream + 1);\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/FarmRewards.sol:293:9\n    │\n293 │         emit Committed(p, weight, epoch + 1, expiry);\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/FarmRewards.sol:534:9\n    │\n534 │         emit Claimed(msg.sender, amount, tax);\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/Season.sol:369:14\n    │\n369 │         id = items().mint(msg.sender, k, r, true);\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/FarmRewards.sol:542:9\n    │\n542 │         emit Spent(p, consumed);\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/FarmRewards.sol:553:9\n    │\n553 │         emit Spent(p, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/FarmRewards.sol:556:80\n    │\n556 │     function scrap(address p, uint256 hash, uint256 minimum) external onlyCore nonReentrant returns (uint256 amount) {\n    │                                                                                ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmRewards.sol:570:9\n    │\n570 │         pool().recycle(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/SwarmDesk.sol:313:13\n    │\n313 │             a.expiresAt < block.timestamp || uint256(a.issuedAt) + (stream == 0 ? 6 hours : 1 days) < block.timestamp\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/SwarmDesk.sol:313:46\n    │\n313 │             a.expiresAt < block.timestamp || uint256(a.issuedAt) + (stream == 0 ? 6 hours : 1 days) < block.timestamp\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/SwarmDesk.sol:314:31\n    │\n314 │                 || (direct && block.timestamp >= p.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/SwarmDesk.sol:330:13\n    │\n330 │             emit AnswerIgnored(a.requestId, 2);\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/SwarmDesk.sol:334:13\n    │\n334 │             emit AnswerIgnored(a.requestId, 2);\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/SwarmDesk.sol:348:9\n    │\n348 │         emit AnswerStored(stream, a.requestId, s, a.answer);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:346:59\n    │\n346 │             keccak256(a.answer), a.requestId, a.issuedAt, uint64(until), uint64(s), true, uint48(ChainClock.number())\n    │                                                           ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:346:74\n    │\n346 │             keccak256(a.answer), a.requestId, a.issuedAt, uint64(until), uint64(s), true, uint48(ChainClock.number())\n    │                                                                          ━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:346:91\n    │\n346 │             keccak256(a.answer), a.requestId, a.issuedAt, uint64(until), uint64(s), true, uint48(ChainClock.number())\n    │                                                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint48' is safe 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]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:287:9\n    │\n287 │         f.serial = nextSerial++;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `purchasedRoom` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:107:9\n    │\n107 │         purchasedRoom[msg.sender][room] = true;\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:241:9\n    │\n241 │         f.paidXpToday += amount;\n    │         ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:312:9\n    │\n312 │         f.active = f.loadout;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:559:9\n    │\n559 │         farms[p].xp += 100;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:288:9\n    │\n288 │         rewards().initialize(p);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:295:13\n    │\n295 │         if (rewards().settle(p, 8) < rewards().settledEpoch()) revert CatchUpRequired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:301:9\n    │\n301 │ ┏         rewards()\n302 │ ┃             .setWeight(\n303 │ ┃                 p,\n304 │ ┃                 engine().allocationHash(farms[p].loadout, farms[p].paid != 0) * (10000 + _boost(p, block.timestamp))\n305 │ ┃                     / 10000\n306 │ ┃             );\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/SwarmDesk.sol:365:37\n    │\n365 │         if (p.streamPlusOne == 0 || block.timestamp < p.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/FarmCore.sol:92:9\n   │\n92 │         season().recordSpend(p, cost, true);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:367:35\n    │\n367 │         emit OracleFailure(id, 0, bytes32(\"timeout\"));\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/FarmCore.sol:288:9\n    │\n288 │         rewards().initialize(p);\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/FeeRouter.sol:172:9\n    │\n172 │         RewardPool(rewardPool()).recordInflow(reward);\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/FarmCore.sol:295:13\n    │\n295 │         if (rewards().settle(p, 8) < rewards().settledEpoch()) revert CatchUpRequired();\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/FarmCore.sol:301:9\n    │\n301 │ ┏         rewards()\n302 │ ┃             .setWeight(\n303 │ ┃                 p,\n304 │ ┃                 engine().allocationHash(farms[p].loadout, farms[p].paid != 0) * (10000 + _boost(p, block.timestamp))\n305 │ ┃                     / 10000\n306 │ ┃             );\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/FeeRouter.sol:173:9\n    │\n173 │         emit TokensRouted(reward, t, h);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/FeeRouter.sol:181:9\n    │\n181 │         market().buy{value: msg.value}(minOut, recipient);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/V4Market.sol:472:31\n    │\n472 │         received = abi.decode(manager.unlock(abi.encode(msg.value, minOut, recipient)), (uint256));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/FeeRouter.sol:181:9\n    │\n181 │         market().buy{value: msg.value}(minOut, recipient);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-no-eth]: external call can be reentered before `heartbeatTokens` is updated\n    ╭▸ src/FeeRouter.sol:199:13\n    │\n199 │             RewardPool(rewardPool()).recordInflow(excess);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `purchasedRoom` is updated\n    ╭▸ src/FarmCore.sol:432:13\n    │\n432 │             RewardPool(pool()).recordInflow(paid);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `purchasedRoom` is updated\n    ╭▸ src/FarmCore.sol:434:20\n    │\n434 │             paid = rewards().spend(p, nominal);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `purchasedRoom` is updated\n    ╭▸ src/FarmCore.sol:437:9\n    │\n437 │         season().recordSpend(p, paid, kind == 0 || kind == 3 || kind == 4);\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/FarmCore.sol:438:9\n    │\n438 │         emit Spent(p, kind, paid, nominal);\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/FarmCore.sol:108:9\n    │\n108 │         emit RoomPurchased(msg.sender, room, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-balance]: external call can be reentered before a stale contract balance is checked\n    ╭▸ src/FeeRouter.sol:214:9\n    │\n214 │         m.sell(amount, minOut, address(this));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-balance\n\nwarning[reentrancy-no-eth]: external call can be reentered before `heartbeatBalance` is updated\n    ╭▸ src/FeeRouter.sol:214:9\n    │\n214 │         m.sell(amount, minOut, address(this));\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/FarmCore.sol:116:9\n    │\n116 │         emit AutoRepairSet(msg.sender, autoRepairThreshold[msg.sender]);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FeeRouter.sol:219:22\n    │\n219 │         uint256 hb = received * h / amount;\n    │                      ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/SwarmDesk.sol:405:13\n    │\n405 │             grid.submitPlan(e, GridOperator.Kind(kind), severity, v[5], notice);\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/SwarmDesk.sol:421:13\n    │\n421 │             params.set(k, target, notice);\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/SwarmDesk.sol:426:47\n    │\n426 │             if (civic.noticeAt(feature) == 0) civic.announce(feature, notice);\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/SwarmDesk.sol:430:13\n    │\n430 │             enhancement.announceCap(enhancement.cap() == 8 ? 12 : 16, notice);\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/SwarmDesk.sol:434:17\n    │\n434 │               try civic.grantDistrictBoost(\n    │ ┏━━━━━━━━━━━━━━━━━┛\n435 │ ┃                 _clamp(uint256(v[11]) >> 128, 1, 8) - 1,\n436 │ ┃                 uint16(_clamp(uint256(v[11]) & type(uint128).max, 0, 1500)),\n437 │ ┃                 notice\n438 │ ┃             ) {}\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/SwarmDesk.sol:445:13\n    │\n445 │             packs.unpause();\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/SwarmDesk.sol:447:17\n    │\n447 │             try packs.pause(_clamp(uint256(v[12]) - 1, 1, 72 hours)) {}\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/SwarmDesk.sol:453:17\n    │\n453 │               try civic.startWar(\n    │ ┏━━━━━━━━━━━━━━━━━┛\n454 │ ┃                 uint8(_clamp(uint256(v[13]) >> 128, 1, 8) - 1),\n455 │ ┃                 uint8(_clamp(uint256(v[13]) & type(uint128).max, 1, 8) - 1)\n456 │ ┃             ) {}\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/FarmCore.sol:127:13\n    │\n127 │             emit Spent(p, 0, paid, paid);\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/FeeRouter.sol:194:30\n    │\n194 │         if (lastSell != 0 && block.timestamp < lastSell + 5 minutes) 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/SwarmDesk.sol:463:17\n    │\n463 │             try civic.startCollapse(_clamp(uint256(v[14]), daily, daily * 100)) {}\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/SwarmDesk.sol:469:17\n    │\n469 │               try civic.listLot(\n    │ ┏━━━━━━━━━━━━━━━━━┛\n470 │ ┃                 uint8(_clamp(uint256(v[15]) >> 16, 1, 12) - 1),\n471 │ ┃                 uint8(_clamp((uint256(v[15]) >> 8) & 255, 1, 3)),\n472 │ ┃                 uint8(_clamp(uint256(v[15]) & 255, 1, 3))\n473 │ ┃             ) {}\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/FeeRouter.sol:224:9\n    │\n224 │         emit TokensSold(amount, 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/FeeRouter.sol:214:9\n    │\n214 │         m.sell(amount, minOut, address(this));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/FeeRouter.sol:236:9\n    │\n236 │         market().buy{value: amount}(minOut, season());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/SwarmDesk.sol:375:13\n    │\n375 │         if (block.timestamp >= r.validUntil || r.slot != slot(stream)) {\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/SwarmDesk.sol:385:9\n    │\n385 │         emit Executed(stream, r.requestId, letter);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:404:33\n    │\n404 │             if (e <= current || grid.planAt(e).submitted) continue;\n    │                                 ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:405:13\n    │\n405 │             grid.submitPlan(e, GridOperator.Kind(kind), severity, v[5], notice);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:398:22\n    │\n398 │         uint8 kind = uint8(_clamp(uint256(v[2]), 0, maxKind));\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/SwarmDesk.sol:400:27\n    │\n400 │         uint16 severity = uint16(_clamp(uint256(v[3]), SEVERITY_MIN, SEVERITY_MAX));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:401:24\n    │\n401 │         districtHint = uint8(_clamp(uint256(v[4]), 0, 7)); // Advisory only; preserve weighted district/entropy rules.\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:432:13\n    │\n432 │             RewardPool(pool()).recordInflow(paid);\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/FarmCore.sol:434:20\n    │\n434 │             paid = rewards().spend(p, nominal);\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/FarmCore.sol:437:9\n    │\n437 │         season().recordSpend(p, paid, kind == 0 || kind == 3 || kind == 4);\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/SwarmDesk.sol:420:34\n    │\n420 │             if (target == old || block.timestamp < params.lastChanged(k) + 1 days) continue;\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:417:27\n    │\n417 │             uint256 old = params.get(k);\n    │                           ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:418:40\n    │\n418 │             (uint256 lo, uint256 hi) = params.bounds(k);\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/FarmCore.sol:218:36\n    │\n218 │         uint256 age = born == 0 || block.timestamp < born ? 0 : block.timestamp - born;\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/FarmCore.sol:219:13\n    │\n219 │         if (age >= 5 days) return 10;\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/FarmCore.sol:220:13\n    │\n220 │         if (age >= 3 days) return 9;\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/FarmCore.sol:221:13\n    │\n221 │         if (age >= 1 days) return 6;\n    │             ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:420:52\n    │\n420 │             if (target == old || block.timestamp < params.lastChanged(k) + 1 days) continue;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:421:13\n    │\n421 │             params.set(k, target, notice);\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/FeeRouter.sol:239:9\n    │\n239 │         IPotSeason(season()).depositPot(received);\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/SwarmDesk.sol:440:17\n    │\n440 │                 emit ActionSkipped(0, reason);\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/SwarmDesk.sol:449:17\n    │\n449 │                 emit ActionSkipped(1, reason);\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/SwarmDesk.sol:458:17\n    │\n458 │                 emit ActionSkipped(2, reason);\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/SwarmDesk.sol:465:17\n    │\n465 │                 emit ActionSkipped(3, reason);\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/SwarmDesk.sol:475:17\n    │\n475 │                 emit ActionSkipped(4, reason);\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/FarmCore.sol:228:13\n    │\n228 │         if (f.paidXpDay != block.timestamp / 1 days) return PAID_XP_PER_DAY;\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/FeeRouter.sol:229:29\n    │\n229 │         if (lastBuy != 0 && block.timestamp < lastBuy + 5 minutes) revert TooEarly();\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:436:17\n    │\n436 │                 uint16(_clamp(uint256(v[11]) & type(uint128).max, 0, 1500)),\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:234:24\n    │\n234 │         uint64 today = uint64(block.timestamp / 1 days);\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/FeeRouter.sol:240:9\n    │\n240 │         emit PotBought(amount, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:454:17\n    │\n454 │                 uint8(_clamp(uint256(v[13]) >> 128, 1, 8) - 1),\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/SwarmDesk.sol:455:17\n    │\n455 │                 uint8(_clamp(uint256(v[13]) & type(uint128).max, 1, 8) - 1)\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/FarmCore.sol:261:53\n    │\n261 │         if (room == 1) return farms[p].born != 0 && block.timestamp >= farms[p].born + 3 days;\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/FeeRouter.sol:236:9\n    │\n236 │         market().buy{value: amount}(minOut, season());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:470:17\n    │\n470 │                 uint8(_clamp(uint256(v[15]) >> 16, 1, 12) - 1),\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/SwarmDesk.sol:471:17\n    │\n471 │                 uint8(_clamp((uint256(v[15]) >> 8) & 255, 1, 3)),\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/SwarmDesk.sol:472:17\n    │\n472 │                 uint8(_clamp(uint256(v[15]) & 255, 1, 3))\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/FarmCore.sol:289:9\n    │\n289 │         emit Registered(p, district(p));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:286:18\n    │\n286 │         f.born = uint64(block.timestamp);\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:146:26\n    │\n146 │         return FarmItems(registry.module(3));\n    │                          ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:320:39\n    │\n320 │             FarmItems.Item memory x = items().data(f.active[i]);\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:313:25\n    │\n313 │         f.activeEpoch = uint64(e);\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/FarmCore.sol:315:25\n    │\n315 │         f.activeBoost = uint16(_boost(p, rewards().epochTime(e)));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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-eth]: uncapped ETH transfer can be reentered before `_status` is updated\n    ╭▸ src/FeeRouter.sol:281:22\n    │\n281 │         (bool ok,) = msg.sender.call{value: a}(\"\");\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-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/FeeRouter.sol:283:9\n    │\n283 │         emit Withdrawn(msg.sender, a);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/FeeRouter.sol:302:9\n    │\n302 │         market().buy{value: ethAmount}(minOut, rewardPool());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:332:9\n    │\n332 │         rewards().recordSales(n);\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/FarmCore.sol:333:9\n    │\n333 │         season().recordSpend(p, ethValue, true);\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/V4Market.sol:498:31\n    │\n498 │         received = abi.decode(manager.unlock(abi.encode(amount, minOut, recipient)), (uint256));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unused-return]: return value of an external call is not used\n   ╭▸ src/FarmEngine.sol:61:30\n   │\n61 │             (, uint256 hi) = params().bounds(k);\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/FeeRouter.sol:305:50\n    │\n305 │         if (!RewardPool(rewardPool()).endowed()) RewardPool(rewardPool()).recordInflow(received);\n    │                                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:522:22\n    │\n522 │         (bool ok,) = recipient.call{value: net}(\"\");\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:40:26\n   │\n40 │         return FarmItems(registry.module(3));\n   │                          ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:74:27\n   │\n74 │             f.clocks[i] = items().data(ids[i]).overclock;\n   │                           ━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:126:39\n    │\n126 │             FarmItems.Item memory x = items().data(id);\n    │                                       ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:160:35\n    │\n160 │         FarmItems.Item memory x = items().data(id);\n    │                                   ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:506:39\n    │\n506 │             key(), SwapParams(false, -int256(amount), 1461446703485210103287273052203988822378723970341), \"\"\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/V4Market.sol:509:25\n    │\n509 │         int128 ethOut = int128(delta >> 128);\n    │                         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe 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/FarmEngine.sol:44:23\n   │\n44 │         return Params(registry.params());\n   │                       ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:61:30\n   │\n61 │             (, uint256 hi) = params().bounds(k);\n   │                              ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:48:25\n   │\n48 │         return IRewards(registry.module(1));\n   │                         ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:64:25\n   │\n64 │         return active ? rewards().epochParam(e, uint256(k)) : params().get(k);\n   │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:64:63\n   │\n64 │         return active ? rewards().epochParam(e, uint256(k)) : params().get(k);\n   │                                                               ━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:510:26\n    │\n510 │         int128 tokenIn = int128(delta);\n    │                          ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:511:44\n    │\n511 │         if (ethOut <= 0 || tokenIn >= 0 || uint256(-int256(tokenIn)) != amount) revert InsufficientBalance();\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/V4Market.sol:512:25\n    │\n512 │         uint256 gross = uint256(uint128(ethOut));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/FarmEngine.sol:121:24\n    │\n121 │         if (room >= 4) revert InvalidValue();\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:512:33\n    │\n512 │         uint256 gross = uint256(uint128(ethOut));\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/V4Market.sol:518:9\n    │\n518 │         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/FarmCore.sol:344:9\n    │\n344 │         rewards().setReferrer(msg.sender, inviter);\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/lib/ItemMath.sol:8:25\n  │\n8 │         if (rarity > 4) revert InvalidValue();\n  │                         ━━━━━━━━━━━━━━━━━━━━━━\n  │\n  ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/lib/EconomyMath.sol:19:39\n   │\n19 │         if (level == 0 || level > 16) revert InvalidValue();\n   │                                       ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:88:39\n   │\n88 │             FarmItems.Item memory x = items().data(ids[i]);\n   │                                       ━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/FeeRouter.sol:293:29\n    │\n293 │         if (lastBuy != 0 && block.timestamp < lastBuy + MIN_BUY_INTERVAL) 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/FeeRouter.sol:309:9\n    │\n309 │         emit WorkBounty(msg.sender, Params.Key.BuyBounty, ethAmount, paid);\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/FeeRouter.sol:310:9\n    │\n310 │         emit Bought(ethAmount, received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/PackSale.sol:182:28\n    │\n182 │         uint256 received = fees().zapBuy{value: msg.value}(minTokens, address(this));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/FeeRouter.sol:302:9\n    │\n302 │         market().buy{value: ethAmount}(minOut, rewardPool());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:168:29\n    │\n168 │         a.baseProductive += raw * tier / 10000;\n    │                             ━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:169:15\n    │\n169 │         raw = raw * (10000 + EconomyMath.bonus(f.clocks[idx])) / 10000;\n    │               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:171:25\n    │\n171 │         s.productive += raw * tier / 10000;\n    │                         ━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmEngine.sol:202:32\n    │\n202 │             if (f.ids[i] != 0) occupied++;\n    │                                ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:373:9\n    │\n373 │         items().equip(msg.sender, id);\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/FarmCore.sol:375:13\n    │\n375 │           if (rewards()\n    │ ┏━━━━━━━━━━━━━┛\n376 │ ┃                 .beginMining(\n377 │ ┃                     msg.sender,\n378 │ ┃                     engine().allocationHash(f.loadout, f.paid != 0) * (10000 + _boost(msg.sender, block.timestamp))\n379 │ ┃                         / 10000\n380 │ ┃                 )) {\n    │ ┗━━━━━━━━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:366:29\n    │\n366 │             if (old != 0 && items().data(old).kind == x.kind) revert InvalidValue();\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/FarmCore.sol:385:9\n    │\n385 │         emit Placed(msg.sender, id, room, slot);\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/FarmCore.sol:366:63\n    │\n366 │             if (old != 0 && items().data(old).kind == x.kind) revert InvalidValue();\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:395:9\n    │\n395 │         items().unequip(msg.sender, id);\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/FarmCore.sol:397:9\n    │\n397 │         emit Unplaced(msg.sender, id, room, slot);\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/FarmCore.sol:414:9\n    │\n414 │         emit Retired(p);\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/FarmCore.sol:405:56\n    │\n405 │             if (f.loadout[i] != 0 || f.active[i] != 0) revert InvalidValue();\n    │                                                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[arbitrary-send-erc20]: `transferFrom` uses an arbitrary `from`; require it to equal `msg.sender` or `address(this)`\n    ╭▸ src/FarmCore.sol:430:13\n    │\n430 │             token().safeTransferFrom(p, pool(), paid);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-erc20\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/FarmCore.sol:431:17\n    │\n431 │             if (token().balanceOf(pool()) - before_ != paid) revert InvalidValue();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:447:9\n    │\n447 │         items().maintain(id, 10000, x.overclock);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `updatedAt` is updated\n    ╭▸ src/V4Market.sol:505:24\n    │\n505 │           int256 delta = manager.swap(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━━━━┛\n506 │ ┃             key(), SwapParams(false, -int256(amount), 1461446703485210103287273052203988822378723970341), \"\"\n507 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:456:32\n    │\n456 │         f.cableRepairedEpoch = uint64(rewards().epoch());\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/FarmCore.sol:457:29\n    │\n457 │         f.routerRepairBps = uint16((rewards().epochEnd() - block.timestamp) * 10000 / 6 hours);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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 `updatedAt` is updated\n    ╭▸ src/V4Market.sol:535:24\n    │\n535 │         int256 delta = manager.swap(key(), SwapParams(true, -int256(input), 4295128740), \"\");\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:535:62\n    │\n535 │         int256 delta = manager.swap(key(), SwapParams(true, -int256(input), 4295128740), \"\");\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/V4Market.sol:537:27\n    │\n537 │         int128 ethDelta = int128(delta >> 128);\n    │                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:538:29\n    │\n538 │         int128 tokenDelta = int128(delta);\n    │                             ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:540:30\n    │\n540 │             ethDelta >= 0 || uint256(-int256(ethDelta)) != input || tokenDelta <= 0\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/V4Market.sol:541:20\n    │\n541 │                 || uint256(uint128(tokenDelta)) < minOut\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/V4Market.sol:541:28\n    │\n541 │                 || uint256(uint128(tokenDelta)) < minOut\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/V4Market.sol:546:9\n    │\n546 │         manager.settle{value: input}();\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:547:40\n    │\n547 │         manager.take(token, recipient, uint256(uint128(tokenDelta)));\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/FarmCore.sol:470:9\n    │\n470 │         items().expand(msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:547:48\n    │\n547 │         manager.take(token, recipient, uint256(uint128(tokenDelta)));\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/V4Market.sol:549:27\n    │\n549 │         return abi.encode(uint256(uint128(tokenDelta)));\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/V4Market.sol:549:35\n    │\n549 │         return abi.encode(uint256(uint128(tokenDelta)));\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[missing-events-access-control]: `claims` is changed without an event but is used for access control\n   ╭▸ src/StarterClaim.sol:91:9\n   │\n91 │         claims[tokenId] = Claim(msg.sender, target, false);\n   │         ━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `entropyHash` is changed without an event but is used for access control\n    ╭▸ src/StarterClaim.sol:112:9\n    │\n112 │         entropyHash[tokenId] = h;\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `entropyCaptured` is changed without an event but is used for access control\n    ╭▸ src/StarterClaim.sol:113:9\n    │\n113 │         entropyCaptured[tokenId] = true;\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:492:13\n    │\n492 │             rewards().spendTo(p, amount, router);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:494:9\n    │\n494 │         FeeRouter(payable(router)).routeTokens(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/StarterClaim.sol:47:9\n   │\n47 │         farm().register(msg.sender);\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/StarterClaim.sol:35:13\n   │\n35 │         if (block.timestamp >= freeClaimEnds()) 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/FarmCore.sol:480:9\n    │\n480 │         rewards().recordSales(1);\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/FarmCore.sol:481:9\n    │\n481 │         season().recordSpend(msg.sender, price, true);\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/FarmCore.sol:482:14\n    │\n482 │         id = ITokenPacks(packs()).tokenPack(msg.sender);\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/StarterClaim.sol:48:9\n   │\n48 │         emit StarterCommitted(id, msg.sender, ChainClock.number() + 2);\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/StarterClaim.sol:49:9\n   │\n49 │         emit FreePackClaimed(msg.sender, index, id);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StarterClaim.sol:46:40\n   │\n46 │         claims[id] = Claim(msg.sender, uint64(ChainClock.number() + 2), false);\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[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/FarmCore.sol:490:17\n    │\n490 │             if (token().balanceOf(router) - before_ != amount) revert InvalidValue();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/StarterClaim.sol:92:9\n   │\n92 │         farm().register(msg.sender);\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/StarterClaim.sol:84:13\n   │\n84 │         if (block.timestamp < launchTime() + 48 hours || block.timestamp >= launchTime() + 16 days) 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/StarterClaim.sol:84:58\n   │\n84 │         if (block.timestamp < launchTime() + 48 hours || block.timestamp >= launchTime() + 16 days) 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/StarterClaim.sol:93:9\n   │\n93 │         emit StarterCommitted(tokenId, msg.sender, target);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StarterClaim.sol:90:25\n   │\n90 │         uint64 target = uint64(ChainClock.number() + 2);\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/FarmCore.sol:492:13\n    │\n492 │             rewards().spendTo(p, amount, router);\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/FarmCore.sol:494:9\n    │\n494 │         FeeRouter(payable(router)).routeTokens(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/FarmCore.sol:501:9\n    │\n501 │         season().recordSpend(msg.sender, amount, true);\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/FarmCore.sol:502:9\n    │\n502 │         grid().tokenLobby(msg.sender, 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/StarterClaim.sol:114:9\n    │\n114 │         fees().payWork(keeper, Params.Key.EntropyBounty, 1, startGas - gasleft());\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/PackSale.sol:199:9\n    │\n199 │         farm().register(recipient);\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/PackSale.sol:200:9\n    │\n200 │         farm().paidPackBought(recipient, n, cost);\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/PackSale.sol:207:9\n    │\n207 │         fees().routeTokens(cost);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/StarterClaim.sol:130:20\n    │\n130 │         c.target = uint64(ChainClock.number() + 2);\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/StarterClaim.sol:145:13\n    │\n145 │             items().mint(c.player, k, r, true);\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/FarmCore.sol:513:9\n    │\n513 │         items().destroy(id);\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/FarmCore.sol:514:26\n    │\n514 │         uint256 earned = rewards().scrap(msg.sender, hash, minimum);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/StarterClaim.sol:72:26\n   │\n72 │         return FarmItems(registry.module(3));\n   │                          ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/StarterClaim.sol:145:13\n    │\n145 │             items().mint(c.player, k, r, true);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmCore.sol:512:24\n    │\n512 │         uint256 hash = ItemMath.baseHash(x.rarity) * (x.kind < 3 ? 10000 : 6000) / 10000 * x.durability / 10000;\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/StarterClaim.sol:147:9\n    │\n147 │         emit StarterResolved(tokenId, h == bytes32(0));\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/StarterClaim.sol:145:13\n    │\n145 │             items().mint(c.player, k, r, true);\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/FarmCore.sol:515:9\n    │\n515 │         emit Scrapped(msg.sender, id, earned);\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/PackSale.sol:234:9\n    │\n234 │         emit PackCommitted(id, p, n, target, guaranteed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/PackSale.sol:206:13\n    │\n206 │         if (t.balanceOf(address(fees())) - before_ != cost) revert InvalidValue();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/PackSale.sol:212:25\n    │\n212 │         if (paused() || block.timestamp < opensAt()) revert TooEarly();\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:232:25\n    │\n232 │         uint64 target = uint64(ChainClock.number() + 2);\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/FarmCore.sol:535:14\n    │\n535 │         if (!occupied) return (0, 0, 0);\n    │              ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:546:28\n    │\n546 │             if (id != 0 && items().data(id).holder == address(0)) _remove(f, id);\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/PackSale.sol:256:9\n    │\n256 │         fees().payWork(keeper, Params.Key.EntropyBounty, 1, startGas - gasleft());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:270:20\n    │\n270 │         c.target = uint64(ChainClock.number() + 2);\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/FarmCore.sol:578:14\n    │\n578 │         id = items().mintDrop(msg.sender, seed);\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/PackSale.sol:289:13\n    │\n289 │             items().mint(c.player, k, r, c.guaranteed);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:87:26\n   │\n87 │         return FarmItems(registry.module(3));\n   │                          ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:289:13\n    │\n289 │             items().mint(c.player, k, r, c.guaranteed);\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/PackSale.sol:291:9\n    │\n291 │         emit PackOpened(id, n, c.expired);\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/PackSale.sol:289:13\n    │\n289 │             items().mint(c.player, k, r, c.guaranteed);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[missing-events-arithmetic]: `otherInflow` is changed without an event but is used in arithmetic\n   ╭▸ src/RewardPool.sol:75:23\n   │\n75 │         if (!endowed) otherInflow += amount;\n   │                       ━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/RewardPool.sol:51:33\n   │\n51 │         if (endowment() == 0 || block.timestamp >= dripStart + dripPeriod) return 0;\n   │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/RewardPool.sol:91:13\n   │\n91 │         if (token().balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/RewardPool.sol:99:9\n   │\n99 │         emit Reserved(amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/RewardPool.sol:107:67\n    │\n107 │     function pay(address to, uint256 amount) external onlyRewards nonReentrant {\n    │                                                                   ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/GridOperator.sol:116:16\n    │\n116 │         return block.timestamp < uint256(l.at) + 3 days ? l.amount : 0;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/GridOperator.sol:127:13\n    │\n127 │             total += stake[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/GridOperator.sol:128:28\n    │\n128 │             if (stake[i] > largest) largest = stake[i];\n    │                            ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:126:24\n    │\n126 │             stake[i] = eco.districtStake(i);\n    │                        ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:239:39\n    │\n239 │             FarmItems.Item memory x = items().data(id);\n    │                                       ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:159:52\n    │\n159 │         lobbies[d] = Lobby(lobbyAmount(d) + value, uint64(block.timestamp));\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:244:21\n    │\n244 │                     items().destroy(id);\n    │                     ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:259:13\n    │\n259 │             items().maintain(id, uint16(x.durability > damage ? x.durability - damage : 0), x.overclock);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:295:39\n    │\n295 │             FarmItems.Item memory x = items().data(id);\n    │                                       ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:296:13\n    │\n296 │             items().maintain(id, x.durability > 100 ? x.durability - 100 : 0, x.overclock);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:221:32\n    │\n221 │                 f.theftUntil = uint64(e + 2);\n    │                                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:121:31\n    │\n121 │         Economy eco = Economy(registry.module(10));\n    │                               ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:140:35\n    │\n140 │         stable += 5000 * lobby / (eco.averageDaily() * 5 + lobby);\n    │                                   ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:173:33\n    │\n173 │             outputBonus[e][d] = civic.outputBonus(d);\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/GridOperator.sol:120:21\n    │\n120 │         if (d >= 8) revert InvalidValue();\n    │                     ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:167:20\n    │\n167 │         x.target = uint64(ChainClock.number() + 1);\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/GridOperator.sol:168:21\n    │\n168 │         x.started = 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/FarmEngine.sol:252:17\n    │\n252 │                 damage += 3000 * uint256(ev.severity) / 10000 / (before_.airflow ? 2 : 1);\n    │                 ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/GridOperator.sol:250:9\n    │\n250 │         fees().payWork(keeper, Params.Key.EntropyBounty, 1, startGas - gasleft());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:258:29\n    │\n258 │             f.health[idx] = uint16(f.health[idx] > damage ? f.health[idx] - damage : 0);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:259:34\n    │\n259 │             items().maintain(id, uint16(x.durability > damage ? x.durability - damage : 0), x.overclock);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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/GridOperator.sol:210:27\n    │\n210 │             if (old == k) repeated++;\n    │                           ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/GridOperator.sol:225:13\n    │\n225 │             sum += w;\n    │             ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/GridOperator.sol:209:57\n    │\n209 │             if (old == Kind.Green || old == Kind.Cheap) positives++;\n    │                                                         ━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:233:34\n    │\n233 │                     x.district = uint8(d);\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[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:63:39\n   │\n63 │             FarmItems.Item memory x = inventory.data(id);\n   │                                       ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:95:45\n   │\n95 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                             ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:95:35\n   │\n95 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:87:45\n   │\n87 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                             ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:87:35\n   │\n87 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:52:30\n   │\n52 │         return IYieldRewards(registry.module(1));\n   │                              ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:91:64\n   │\n91 │         return Math.mulDiv(hash * 4, Math.max(HASH_RATE_FLOOR, rewards().lastYieldPerHash()), 1 ether);\n   │                                                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:99:30\n   │\n99 │             missing * Params(registry.params()).get(Params.Key.RepairHours),\n   │                              ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:99:23\n   │\n99 │             missing * Params(registry.params()).get(Params.Key.RepairHours),\n   │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:66:17\n   │\n66 │             if (reward.pending(p) < cost) continue;\n   │                 ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:67:21\n   │\n67 │             paid += reward.spend(p, cost);\n   │                     ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:68:13\n   │\n68 │             inventory.maintain(id, 10000, x.overclock);\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/Economy.sol:88:37\n   │\n88 │         if (x.holder == address(0)) revert InvalidValue();\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/Economy.sol:77:27\n   │\n77 │         if (start == 0 || start > block.timestamp) revert NotConfigured();\n   │                           ━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n   ╭▸ src/Economy.sol:90:16\n   │\n90 │         hash = hash * (10000 + EconomyMath.bonus(x.overclock)) / 10000;\n   │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n   ╭▸ src/Economy.sol:91:28\n   │\n91 │         return Math.mulDiv(hash * 4, Math.max(HASH_RATE_FLOOR, rewards().lastYieldPerHash()), 1 ether);\n   │                            ━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/Economy.sol:136:9\n    │\n136 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\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/Economy.sol:149:9\n    │\n149 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\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/Economy.sol:150:9\n    │\n150 │         emit Locked(msg.sender, amount, block.timestamp + days_ * 1 days, bps);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Economy.sol:140:42\n    │\n140 │         locks[msg.sender] = Lock(amount, uint64(block.timestamp), uint64(block.timestamp + days_ * 1 days), uint16(bps));\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/Economy.sol:140:67\n    │\n140 │         locks[msg.sender] = Lock(amount, uint64(block.timestamp), uint64(block.timestamp + days_ * 1 days), uint16(bps));\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/Economy.sol:140:109\n    │\n140 │         locks[msg.sender] = Lock(amount, uint64(block.timestamp), uint64(block.timestamp + days_ * 1 days), uint16(bps));\n    │                                                                                                             ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/Economy.sol:148:13\n    │\n148 │         if (t.balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-no-eth]: external call can be reentered before `locks` is updated\n    ╭▸ src/Economy.sol:156:9\n    │\n156 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\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/Economy.sol:167:9\n    │\n167 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\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/Economy.sol:155:30\n    │\n155 │         if (l.amount == 0 || block.timestamp < l.end) 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/Economy.sol:169:9\n    │\n169 │         emit Unlocked(msg.sender, l.amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Economy.sol:180:23\n    │\n180 │         previous[p] = prev;\n    │                       ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Economy.sol:191:25\n    │\n191 │         for (uint256 i; i < 10 && p != address(0); ++i) {\n    │                         ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/Civic.sol:61:13\n   │\n61 │         if (t.balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/Civic.sol:84:82\n   │\n84 │         if (feature >= FEATURES || noticeAt[feature] == 0 || enabled[feature] || block.timestamp < noticeAt[feature]) {\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/Civic.sol:103:17\n    │\n103 │         return (block.timestamp < boostUntil[d] ? seasonBoost[d] : 0) + (block.timestamp < warBoostUntil[d] ? 1000 : 0);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Civic.sol:103:74\n    │\n103 │         return (block.timestamp < boostUntil[d] ? seasonBoost[d] : 0) + (block.timestamp < warBoostUntil[d] ? 1000 : 0);\n    │                                                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Civic.sol:137:13\n    │\n137 │             uint64(block.timestamp + 48 hours),\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/Civic.sol:173:14\n    │\n173 │         if (!found && contribution[warId][msg.sender] > low) top[slot] = msg.sender;\n    │              ━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Civic.sol:173:66\n    │\n173 │         if (!found && contribution[warId][msg.sender] > low) top[slot] = 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/Civic.sol:152:42\n    │\n152 │         if (!enabled[0] || warId == 0 || block.timestamp >= w.end || w.settled || (d != w.a && d != w.b)) {\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/Civic.sol:71:9\n   │\n71 │         RewardPool(pool).donate(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/Civic.sol:192:40\n    │\n192 │         if (warId == 0 || w.settled || block.timestamp < w.end) 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/Civic.sol:202:9\n    │\n202 │         emit WarFinished(warId, w.winner, w.payout, toPool);\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/Civic.sol:228:67\n    │\n228 │             !enabled[1] || !collapseFinalized || outagePending || block.timestamp < greenUntil\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/Civic.sol:239:34\n    │\n239 │         if (collapseFinalized || block.timestamp >= collapseEnd) 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/Civic.sol:243:9\n    │\n243 │         emit CollapseFunded(msg.sender, amount);\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/Civic.sol:247:34\n    │\n247 │         if (collapseFinalized || block.timestamp < collapseEnd) 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/Civic.sol:261:13\n    │\n261 │         if (block.timestamp < greenUntil) return 1;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Civic.sol:280:48\n    │\n280 │         lots[w] = Lot(kind, rarity, supply, 0, uint64(block.timestamp));\n    │                                                ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/Civic.sol:298:9\n    │\n298 │         ICore(registry.module(2)).civicPurchase(msg.sender, cost);\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/Civic.sol:299:14\n    │\n299 │         id = FarmItems(registry.module(3)).mint(msg.sender, l.kind, l.rarity, false);\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/Civic.sol:300:9\n    │\n300 │         emit LotBought(w, msg.sender, id, cost);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/EconomyV35.t.sol:152:43\n    │\n152 │         assertEq(d.economy.boostAt(alice, block.timestamp), 500);\n    │                                           ━━━━━━━━━━━━━━━\n    ‡\n156 │         vm.warp(block.timestamp + 7 days);\n    │         ───────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/EconomyV35.t.sol:156:17\n    │\n156 │         vm.warp(block.timestamp + 7 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PhasedReleaseV36.t.sol:145:49\n    │\n145 │         assertEq(d.civic.noticeAt(ENHANCEMENT), block.timestamp + 48 hours);\n    │                                                 ━━━━━━━━━━━━━━━\n146 │         vm.warp(block.timestamp + 48 hours - 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/PhasedReleaseV36.t.sol:146:17\n    │\n146 │         vm.warp(block.timestamp + 48 hours - 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/SwarmDeskV37.t.sol:210:17\n    │\n210 │         vm.warp(block.timestamp + 1 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:67:29\n    │\n 67 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n227 │         vm.warp(d.civic.noticeAt(3));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:68:30\n    │\n 68 │         a.expiresAt = uint64(block.timestamp + 6 hours);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n227 │         vm.warp(d.civic.noticeAt(3));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:220:39\n    │\n220 │         assertEq(d.civic.noticeAt(3), block.timestamp + 48 hours);\n    │                                       ━━━━━━━━━━━━━━━\n    ‡\n227 │         vm.warp(d.civic.noticeAt(3));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:283:17\n    │\n283 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:67:29\n    │\n 67 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n336 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:68:30\n    │\n 68 │         a.expiresAt = uint64(block.timestamp + 6 hours);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n336 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:336:17\n    │\n336 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:606:17\n    │\n606 │         vm.warp(block.timestamp + 2 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:631:17\n    │\n631 │         vm.warp(block.timestamp + 2 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/V34.t.sol:149:25\n    │\n149 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n152 │         vm.warp(start + 60 minutes - 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/V34.t.sol:230:17\n    │\n230 │         vm.warp(block.timestamp + 5 minutes - 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/V34.t.sol:233:17\n    │\n233 │         vm.warp(block.timestamp + 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/fork/RehearsalV311.t.sol:630:18\n    │\n630 │         vm.warp((block.timestamp / 6 hours) * 6 hours + 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":37757,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/Clock.t.sol:ClockTest\n[PASS] testLocalEvmFutureBlockAnd256BlockBoundary() (gas: 225376)\n[PASS] testRobinhoodUsesArbSysNotL1EstimateAndHandlesExpiry() (gas: 238560)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 819.87µs (568.68µs CPU time)\n\nRan 5 tests for test/fork/RehearsalV311.t.sol:RehearsalV311Test\n[SKIP] testRehearsalAttestedAnswerChangesPlanWithinBand() (gas: 0)\n[SKIP] testRehearsalGasPerLaunchUnderPlatformCeiling() (gas: 0)\n[SKIP] testRehearsalKeeperPassAdvancesEpochsRevealsEntropyAndClaimFeesPaysTeam() (gas: 0)\n[SKIP] testRehearsalLaunchTaxThenOnePercentAndSurcharge() (gas: 0)\n[SKIP] testRehearsalPacksOpenOneHourAfterLaunch() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 5 skipped; finished in 1.00ms (142.15µs CPU time)\n\nRan 4 tests for test/OracleConformanceV37.t.sol:OracleConformanceV37Test\n[PASS] testAcceptsOriginalProtocolSignature() (gas: 17956)\n[PASS] testDigestMatchesUnmodifiedProtocolVector() (gas: 13636)\n[PASS] testFreshVectorSignerSignature() (gas: 30407)\n[PASS] testSelectorsExactlyMatchLiveProtocol() (gas: 3520)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.60ms (637.10µs CPU time)\n\nRan 1 test for test/fork/RobinhoodFork.t.sol:RobinhoodForkTest\n[SKIP] testForkArbSysAndHistoricalHash() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 158.97µs (26.97µs CPU time)\n\nRan 2 tests for test/V310.t.sol:ToolchainPinsV310Test\n[PASS] testEveryModuleOfThisBuildMatchesOneToolchainPin() (gas: 167162)\n[PASS] testPinsAreOneToolchainAndRejectUnknownCode() (gas: 162929)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.07ms (838.18µs CPU time)\n\nRan 1 test for test/WarReviewV35.t.sol:IndependentWarReview\n[PASS] testWarWinnerCannotChangeAfterDeadline() (gas: 5734360)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 898.10µs (788.91µs CPU time)\n\nRan 1 test for test/YieldFloorReviewV35.t.sol:IndependentYieldFloorReview\n[PASS] testFirstEpochItemQuotesKeepNonzeroFloorAtCorrectScale() (gas: 673277)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 561.44µs (502.18µs CPU time)\n\nRan 1 test for test/PredictionV34.t.sol:PredictionV34Test\n[PASS] testFullGraphPredictsPoolBeforeRegistryDeployment() (gas: 4190905)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 10.32ms (676.20µs CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] testConstructorRejectsMissingInputsAndDoesNotCallExternalContracts() (gas: 3994)\n[PASS] testForeignCallerDoesNotGetAnyAuthority() (gas: 42642091)\n[PASS] testImmutableGraphAndEip170Sizes() (gas: 187323)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 14.91ms (4.99ms CPU time)\n\nRan 7 tests for test/V33.t.sol:LaunchProtectionTest\n[PASS] testBuyTaxHasImmutableSteps() (gas: 97524)\n[PASS] testLaunchTaxChargedAndRoutedEntirelyToPool() (gas: 227992)\n[PASS] testNoBuySizeLimitAtAnyLaunchStep() (gas: 1690997)\n[PASS] testNormalBuyAfterDecayHasNoLaunchTax() (gas: 1479403)\n[PASS] testSellsPayNormalFeeDuringLaunch() (gas: 339655)\n[PASS] testSnipersSplittingBuysStillPayTheCurve() (gas: 655730)\n[PASS] testViewsBeforeInitialization() (gas: 4725627)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 19.14ms (3.58ms CPU time)\n\nRan 3 tests for test/TwinCaptureV312.t.sol:TwinCaptureV312Test\n[PASS] testHonestBindThenForwardReachesHonestPool() (gas: 6020873)\n[PASS] testTwinCaptureCannotPayAttacker() (gas: 11367879)\n[PASS] testTwinCaptureOrphansHonestGame() (gas: 11350429)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 19.40ms (8.66ms CPU time)\n\nRan 3 tests for test/HookBinding.t.sol:HookBindingTest\n[PASS] testHoldBeforeGameExistsThenBindOnceAndFlushExactStreams() (gas: 43111685)\n[PASS] testLookAlikeCannotBindEvenWhenTeamCalls() (gas: 1907686)\n[PASS] testWrongRouterAndMissingCodeRejectedBeforePermanentBind() (gas: 40825860)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 20.38ms (11.78ms CPU time)\n\nRan 2 tests for test/GridV35.t.sol:GridV35Test\n[PASS] testGreenAndCheapBothFavorTheStableDistrict() (gas: 4116213)\n[PASS] testReservedEventsHaveZeroLaunchWeightAndPlanOnlyWhenEnabled() (gas: 721158)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 17.48ms (8.02ms CPU time)\n\nRan 5 tests for test/Registry.t.sol:RegistryTest\n[PASS] testAllModulePinsMatchExactPinnedCompilerArtifacts() (gas: 1064523)\n[PASS] testAuthenticatedEnrollmentRejectsUncreatedWrongCodeAndWrongRegistry() (gas: 3270493)\n[PASS] testConstructorAcceptsEmptyGraphWithoutExternalCalls() (gas: 13657)\n[PASS] testCounterfeitRuntimeAtAnotherFactoryCannotEnroll() (gas: 1882067)\n[PASS] testCounterfeitRuntimeWithPoisonedCreditCannotEnroll() (gas: 6217486)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 11.54ms (4.06ms CPU time)\n\nRan 4 tests for test/SwarmDeskBootstrap.t.sol:SwarmDeskBootstrapTest\n[PASS] testEip712DomainUsesRobinhoodAndDeployedDesk() (gas: 5114543)\n[PASS] testFactoryDeploysExactlyOneUnboundDeskWithoutExternalCalls() (gas: 5326765)\n[PASS] testRuntimeSizeAndForbiddenOpcodes() (gas: 18684417)\n[PASS] testUnboundDeskRejectsOracleAndBackupActions() (gas: 5218365)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 27.41ms (27.61ms CPU time)\n\nRan 2 tests for test/AutoRepairReviewV35.t.sol:IndependentAutoRepairReview\n[PASS] testAutomaticRepairRecordsHistoricalWeekBeforeCompletion() (gas: 5402724)\n[PASS] testLateAutomaticRepairCannotReopenSeasonEligibility() (gas: 4266739)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 29.45ms (19.36ms CPU time)\n\nRan 5 tests for test/KeeperProfit.t.sol:KeeperProfitTest\n[PASS] testPaidPackEntropyKeeperProfit() (gas: 1179133)\nLogs:\n  paid pack entropy execution gas: 139616\n  paid pack entropy bounty wei: 3380475000000\n  paid pack entropy execution plus 21000 gas cost wei: 3212320000000\n\n[PASS] testPlanEntropyKeeperProfit() (gas: 1665825)\nLogs:\n  plan entropy execution gas: 163594\n  plan entropy bounty wei: 4488125000000\n  plan entropy execution plus 21000 gas cost wei: 3691880000000\n\n[PASS] testSeasonFinalizeThreeWinnersAndPrizeKeeperProfit() (gas: 3451176)\nLogs:\n  season finalize three winners and prize execution gas: 644051\n  season finalize three winners and prize bounty wei: 15825150000000\n  season finalize three winners and prize execution plus 21000 gas cost wei: 13301020000000\n\n[PASS] testSeasonPrepareIsConstantUnpaidWork() (gas: 1342777)\n[PASS] testStarterEntropyKeeperProfit() (gas: 324553)\nLogs:\n  starter entropy execution gas: 142744\n  starter entropy bounty wei: 3380150000000\n  starter entropy execution plus 21000 gas cost wei: 3274880000000\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 28.82ms (14.04ms CPU time)\n\nRan 1 test for test/StandardV4Integration.t.sol:StandardV4IntegrationTest\n[PASS] testStandardAdapterRealPoolPaysExistingHookExactlyOnce() (gas: 1948176)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 29.81ms (1.03ms CPU time)\n\nRan 6 tests for test/EndowmentEscrowV38.t.sol:EndowmentEscrowV38Test\n[PASS] testConstructorRejectsMissingInputs() (gas: 6182)\n[PASS] testForwardRejectsBadProofs() (gas: 2663621)\n[PASS] testForwardRequiresBalance() (gas: 752051)\n[PASS] testForwardSendsWholeBalanceOnceToAuthenticatedPoolAndFundsEndowment() (gas: 1713359)\n[PASS] testForwardWithRealEndowmentActivatesDrip() (gas: 12550408)\n[PASS] testTwinWithForeignTokenCannotDrainEscrow() (gas: 12456243)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 32.02ms (15.73ms CPU time)\n\nRan 3 tests for test/StandardAdapter.t.sol:StandardAdapterTest\n[PASS] testExistingHookKeyPreservedAndNoExtraFee() (gas: 330662)\n[PASS] testRequiresThirtyMinutesFreshOracleAndAuthorizedCallback() (gas: 198351)\n[PASS] testSettlementSlippageFailurePreservesCredits() (gas: 240594)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 8.98ms (901.89µs CPU time)\n\nRan 3 tests for test/PotV35.t.sol:PotV35Test\n[PASS] testPotDepositRequiresActualTokensAndAuthority() (gas: 256924)\n[PASS] testPotSplitDistinctLotteryDistrictAndRollbackOnFullInventory() (gas: 11488024)\n[PASS] testPotUnclaimedRolloverOnlyAfterFourWeeksNoDoubleClaim() (gas: 6429645)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 47.61ms (31.54ms CPU time)\n\nRan 5 tests for test/ReviewV34.t.sol:ReviewV34Test\n[PASS] testCanonicalCompetingRegistryCannotTakeOverBinding() (gas: 9451528)\n[PASS] testDustBuyCannotConsumeGlobalBuyInterval() (gas: 336156)\n[PASS] testLateGreenEntrySettlesWithinReservedEnvelope() (gas: 4432362)\n[PASS] testMeaningfulSmallBuyCanUseLessThanMaximumBatch() (gas: 263646)\n[PASS] testSameConfigurationAtUncommittedCoordinatesCannotBind() (gas: 9538431)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 20.84ms (12.27ms CPU time)\n\nRan 8 tests for test/PhasedReleaseV36.t.sol:PhasedReleaseV36Test\n[PASS] testBillboardsDisabledThenEnabled() (gas: 414502)\n[PASS] testEnableIsNoticedOnceNeverOffAndSwarmOnly() (gas: 355991)\n[PASS] testEnhancementDisabledThenEnabledOnce() (gas: 1096283)\n[PASS] testEverythingDeploysDisabledAndCoreStillWorks() (gas: 8162777)\n[PASS] testFuzzUnannouncedFeatureCannotBeEnabled(uint256) (runs: 256, μ: 30091, ~: 29968)\n[PASS] testLocksStakeAndLobbyDisabledThenEnabled() (gas: 2849495)\n[PASS] testPotDisabledFollowsV34RoutingThenEnabled() (gas: 455827)\n[PASS] testReservedEventsDisabledThenEnabled() (gas: 557613)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 71.40ms (57.14ms CPU time)\n\nRan 3 tests for test/Pause.t.sol:PauseTest\n[PASS] testOnlySwarmBoundedDurationAndCannotExtendPause() (gas: 242972)\n[PASS] testSalePausedWhileEntropyClaimsWithdrawalsAndEpochsContinue() (gas: 15156588)\n[PASS] testUnpauseCannotResetNextPauseCooldown() (gas: 194647)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 72.42ms (55.81ms CPU time)\n\nRan 8 tests for test/V39.t.sol:V39Test\n[PASS] testBaseDepositsAreEntirelyRewardEth() (gas: 190166)\n[PASS] testGridAcceptsSeverityFromThreeThousandAndRejectsBelow() (gas: 2946787)\n[PASS] testHookAddsExactlyOnePercentOnBuysAndSellsAfterLaunchWindow() (gas: 2179711)\n[PASS] testHookHasNoNetworkShareRecipientOrWithdrawal() (gas: 109842)\n[PASS] testMarketFactoryConfigHasNoNetworkRecipient() (gas: 7421825)\n[PASS] testRegistryAcceptsEitherToolchainPinAndNothingElse() (gas: 930391)\n[PASS] testSellSurchargeStillProgressiveAndCappedAtFifteenPercent() (gas: 1832600)\n[PASS] testStepLaunchTaxUnchangedAndFullyToRewards() (gas: 1291729)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 90.93ms (65.00ms CPU time)\n\nRan 10 tests for test/Bounties.t.sol:BountiesTest\n[PASS] testBuyBountyProportionalCapNoDustCreditAndFailureRollback() (gas: 680020)\n[PASS] testEmptyRosterAndInvalidBatchReceiveNothing() (gas: 1419146)\n[PASS] testEveryWorkKindBoundedByHeartbeatAndAuthorizedProducer() (gas: 64315585)\n[PASS] testLazySettlementUnpaidAndCannotReplay() (gas: 6957525)\n[PASS] testOnlyFinalizePaidOnceAndEmptyWeekUnpaid() (gas: 2292196)\n[PASS] testPackEntropyCapturedOnceWithFullInventoryAndThroughPause() (gas: 3710376)\n[PASS] testPlanResolutionPaidOnceIncludingAdvanceForwarding() (gas: 2931539)\n[PASS] testRemovedWorkBountiesRejectedEvenFromOldProducer() (gas: 179981)\n[PASS] testStarterEntropySurvivesFullInventoryExpiryAndPauseWithoutReplayPayment() (gas: 5321268)\n[PASS] testWorkCreditRespectsZeroGasPricePriceCeilingAndUnitCap() (gas: 333726)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 100.73ms (90.58ms CPU time)\n\nRan 6 tests for test/CivicV35.t.sol:CivicV35Test\n[PASS] testBillboardsBidRefundTextRulesAndPoolOnly() (gas: 945542)\n[PASS] testBlackMarketDescendingLimitedAndPause() (gas: 3822256)\n[PASS] testCollapseSuccessAndSingleOutageFailure() (gas: 810718)\n[PASS] testDormantDisabledAndNoticeOnce() (gas: 303076)\n[PASS] testOnceSeasonBoostBoundsAndSnapshot() (gas: 1722426)\n[PASS] testWarFreezeScoresConservationAndPayoutOnlyOnce() (gas: 1365360)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 21.11ms (12.71ms CPU time)\n\nRan 2 tests for test/Factory.t.sol:FactoryTest\n[PASS] testFactoryInvalidSearchRange() (gas: 5016)\n[PASS] testHookFactoryFlagsImmutableConfigAndIdempotence() (gas: 17888831)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 144.99ms (136.31ms CPU time)\n\nRan 6 tests for test/V4Integration.t.sol:V4IntegrationTest\n[PASS] testRealV4BuyAndSingleSwapSellTaxConserveSettlement() (gas: 2268519)\n[PASS] testRealV4ManipulatedSpotCannotInstantlySetBuybackQuote() (gas: 1909248)\n[PASS] testRealV4SmallBuyPaysPositiveKeeperMargin() (gas: 2072079)\nLogs:\n  real V4 0.2ETH buy gas: 1933207\n  real V4 buy bounty wei: 48643350000000\n\n[PASS] testRealV4SystemBuyUsesTwapAndOnlySystemFunds() (gas: 2077956)\n[PASS] testRealV4SystemSalesUseDepthTwapNormalFeesAndConserveTokens() (gas: 2246438)\n[PASS] testSystemBuybackOffsetsRecordedSellImbalance() (gas: 2508945)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 148.03ms (8.46ms CPU time)\n\nRan 6 tests for test/Market.t.sol:MarketTest\n[PASS] testBuyChargesExactlyOnePercentAllToRewards() (gas: 1729871)\n[PASS] testFuzzTotalFeeHardCap(uint96) (runs: 256, μ: 1805641, ~: 1809158)\nLogs:\n  Bound result 22771638990251170674\n\n[PASS] testOnlyManagerCorrectPoolExactInputAndHookAddress() (gas: 113403)\n[PASS] testSingleDumpIncludesItselfAndFeeDecaysWithoutGriefReset() (gas: 17162149)\n[PASS] testTwapAveragesEthPriceAcrossUnequalPrices() (gas: 2330567)\n[PASS] testTwapWarmupAndFlashManipulationResistance() (gas: 1882285)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 246.35ms (259.22ms CPU time)\n\nRan 1 test for test/EndowmentGame.t.sol:EndowmentGameTest\n[PASS] testRealMiningCannotSpendFutureEndowment() (gas: 130414629)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 274.17ms (262.12ms CPU time)\n\nRan 11 tests for test/Items.t.sol:ItemsTest\n[PASS] testComputeHashSupportHashAndBonusesReplaceDuo() (gas: 4700115)\n[PASS] testDurabilityWearRepairAndEnhancementMetadataPreserved() (gas: 8369228)\n[PASS] testEquipRarityGatesAndMythicGate() (gas: 4144858)\n[PASS] testFullStackRarityCapAndRoomFlags() (gas: 7638418)\n[PASS] testInventoryMintCannotExceedCapacityAndExpansionRises() (gas: 3351443)\n[PASS] testLockedItemCannotBeScrappedUntilEpochRolls() (gas: 5971291)\n[PASS] testOffgridSavings() (gas: 2701968)\n[PASS] testPaidXpCannotBypassRoomTwoAgeGate() (gas: 3734443)\n[PASS] testRoomGatesAndLevelProgression() (gas: 78345249)\n[PASS] testScrapPaysPoolYieldAndCannotRepeat() (gas: 7543503)\n[PASS] testSoulboundOnlyOwnFarmAndNoDuplicateTypes() (gas: 2254731)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 308.03ms (323.53ms CPU time)\n\nRan 7 tests for test/HeartbeatBpsV313.t.sol:HeartbeatBpsV313Test\n[PASS] testFuzzAnyShareConservesEveryWeiAndNeverMovesTeamOrPot(uint16,uint96) (runs: 256, μ: 1398509, ~: 1627071)\nLogs:\n  Bound result 993\n  Bound result 274133272709038\n\n[PASS] testLaunchDefaultIsTwoPercentAndSplitUnchanged() (gas: 230935)\n[PASS] testLoweredShareBackToFloorAndFloorIsHard() (gas: 401104)\n[PASS] testMaximumShareWithPotEnabledIsClippedToWhatIsLeft() (gas: 1867739)\n[PASS] testOnlyTheSwarmWithinBoundsStepAndCooldownCanMoveTheShare() (gas: 341795)\n[PASS] testRaisedShareStillStopsAtTheOneEthCap() (gas: 480520)\n[PASS] testSwarmSet220CreditsTwoPointTwoPercentOfSurchargeAndTokens() (gas: 543701)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 317.37ms (316.48ms CPU time)\n\nRan 20 tests for test/SwarmDeskV37.t.sol:SwarmDeskV37Test\n[PASS] testBackupFailureUnknownFailureDeadlineAndPriceCap() (gas: 751172)\n[PASS] testBackupPullsExactPriceRecordsRequestAndRestrictsBodyAndCadence() (gas: 1199464)\n[PASS] testDeskSetHeartbeatBpsMovesFeeRouterShare() (gas: 937778)\n[PASS] testEmptyChainConstructorAndAuthenticatedBindingRejectSpoofs() (gas: 12471225)\n[PASS] testEventClampingAndFallbackWithoutAnswer() (gas: 1047688)\n[PASS] testExpiredOldSlotOldEpochAndUnexecutedAnswersNeverAct() (gas: 828312)\n[PASS] testFlatConstructorRejectsUnusedPackedBits() (gas: 6688433)\n[PASS] testForgedTamperedWrongSignerWrongDomainAndCallerRejected() (gas: 345940)\n[PASS] testFutureIssueWrongTypeMalformedLengthAndPriceNeverConsume() (gas: 311556)\n[PASS] testFuzzEveryParamHardBoundsAndTenPercentStep(uint8,uint248) (runs: 256, μ: 468593, ~: 469838)\nLogs:\n  Bound result 33\n\n[PASS] testNextSlotAcceptsSameQuestionAndChangedExecutionBytesReject() (gas: 1129615)\n[PASS] testNoAdminPathsAndEntireGraphUsesDesk() (gas: 388087)\n[PASS] testNoopRegulatorAcceptedAndParamsCooldownPreserved() (gas: 444622)\n[PASS] testRegulatorClampsParamsAnnouncesPhasesAndThirtyDayCaps() (gas: 1130422)\n[PASS] testReplayDifferentSourceAndSecondAnswerSameSlotIgnored() (gas: 1051768)\n[PASS] testRobinhoodNativeClockCallbackWithin200k() (gas: 344786)\n[PASS] testScheduleDeliveryStoresUnder200kThenExecutesTwoPlans() (gas: 976035)\n[PASS] testSubmitRelayAcceptsAttestedAnswerFromAnyoneOnce() (gas: 1075619)\n[PASS] testSubmitRelayRejectsForgedWrongQuestionStaleAndMalformed() (gas: 1808092)\n[PASS] testWrongQuestionUnknownRequestWeakPanelAndWindowRejected() (gas: 364606)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 321.41ms (325.75ms CPU time)\n\nRan 20 tests for test/V33.t.sol:V33Test\n[PASS] testActionBeforeExpiryMovesBucketWithoutDoubleCount() (gas: 25963547)\n[PASS] testAdvanceIsConstantInExpiringFarms() (gas: 38374918)\n[PASS] testAgeCapsAtBoundaries() (gas: 204618)\n[PASS] testClaimDoesNotRecommitWhileBehind() (gas: 37212442)\n[PASS] testClaimRecommitsAndPackRecommits() (gas: 60738557)\n[PASS] testDistrictScoreAveragePerFarmAndTenPercentWalletCap() (gas: 4607489)\n[PASS] testHeartbeatCapExcessGoesToPoolAndBaseFeeIsAllRewards() (gas: 270973)\n[PASS] testIdleFarmLeavesDenominatorAfterTwelveEpochs() (gas: 23496196)\n[PASS] testLaunchTaxDepositIsAllPoolAndMarketOnly() (gas: 137567)\n[PASS] testMergeRemoved() (gas: 512630)\n[PASS] testPackLobbySellSplit88Team10Heartbeat2() (gas: 407960)\n[PASS] testPackSaleOpensSixtyMinutesAfterLaunch() (gas: 1261148)\n[PASS] testPaidXpCannotBypassAgeGates() (gas: 58982706)\n[PASS] testPaidXpCappedPerDayActivityUncapped() (gas: 13235492)\n[PASS] testPartialRoomIsClippedNotReverted() (gas: 2148809)\n[PASS] testRewardsEarnedBeforeExpiryAreNeverLost() (gas: 47642242)\n[PASS] testSingleWhaleDistrictCannotWinAlone() (gas: 4534340)\n[PASS] testSyncRecommitsFromNextEpoch() (gas: 33350114)\n[PASS] testTokenPacksAlsoWaitForOpening() (gas: 59864)\n[PASS] testTopSpenderTrackingIsExact() (gas: 5411751)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 332.44ms (887.77ms CPU time)\n\nRan 13 tests for test/Events.t.sol:EventsTest\n[PASS] testCheapTariffAppliesCitywide() (gas: 6419970)\n[PASS] testColdPowerFireImmuneAndCleanPowerSurgeImmune() (gas: 7898411)\n[PASS] testFallbackAndExpiredSeedIndependentOfSwarmNumber() (gas: 1683539)\n[PASS] testFireNoCoolingZeroYieldColdPowerImmune() (gas: 6144568)\n[PASS] testGreenWaveRaisesDistrictMiningTenPercent() (gas: 6422047)\n[PASS] testLobbyOwnDistrictSplitDecayAndMinimumWeight() (gas: 1080859)\n[PASS] testOutageAndOffgridRoomMitigation() (gas: 7053841)\n[PASS] testPlansOnlyNextTwoOnceAndBoundedSeverity() (gas: 344816)\n[PASS] testRollingCapsAndInitialPositiveQuotaWithHostilePlans() (gas: 102235868)\n[PASS] testSurgeCanDestroyCommonButNeverLegendary() (gas: 6288094)\n[PASS] testSurgeDamagesExactlyOneItemAndCleanPowerImmune() (gas: 6294034)\n[PASS] testSurgeNeverDestroysLegendaryOrMythic() (gas: 9502005)\n[PASS] testTheftRouterDisabledAndRepairRestores() (gas: 6848091)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 411.85ms (361.16ms CPU time)\n\nRan 9 tests for test/Packs.t.sol:PacksTest\n[PASS] testExactPaymentAndFutureBlockRequired() (gas: 1667747)\n[PASS] testExactRarityThresholdsAndMythicGate() (gas: 282935)\n[PASS] testExpiryRearmsWithoutMintingAndInventoryOpeningLimit() (gas: 3790798)\n[PASS] testFuzzVrgdaAlwaysBounded(uint32,uint32) (runs: 256, μ: 61343, ~: 63041)\nLogs:\n  Bound result 18350\n\n[PASS] testItemTypeDistributionExact() (gas: 626492)\n[PASS] testNoWalletGlobalOrTokenPackDailyLimit() (gas: 4377219)\n[PASS] testStarterWindowProofTokenIdOnceAndInventoryFailureRetry() (gas: 881480)\n[PASS] testTokenPackSameQuoteAndSplitWhenUsingWalletOrCredits() (gas: 76424599)\n[PASS] testVrgdaInitialStepDecayFloorCeilingAndBulkPricing() (gas: 1296506)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 412.79ms (277.92ms CPU time)\n\nRan 6 tests for test/Regression.t.sol:RegressionTest\n[PASS] testCableRepairRestoresOnlyRemainingHalfEpoch() (gas: 11794355)\n[PASS] testEmptyEpochPreservesLastSettledRateButResetsScrapAllowance() (gas: 10984120)\n[PASS] testFuzzCableRepairBlendHandlesNonMonotonicRarityBonuses(uint16) (runs: 256, μ: 1374189, ~: 1374014)\nLogs:\n  Bound result 7026\n\n[PASS] testRegisterOnlyAccountsDoNotAddSettlementWorkAndEmptyFarmCanRetire() (gas: 2025433)\n[PASS] testRepairAndPaidPackCannotRetroactivelyBoostEpoch() (gas: 9542820)\n[PASS] testUnlimitedFreshPacksCannotDrainPoolByScrapping() (gas: 9641657)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 405.10ms (450.10ms CPU time)\n\nRan 14 tests for test/V34.t.sol:V34Test\n[PASS] testBestFarmCapsAbsoluteSpendAndBreaksTiesByAddress() (gas: 4665680)\n[PASS] testBestFarmNeedsTwentyEpochsAndUsesCappedAbsoluteSpend() (gas: 4144210)\n[PASS] testBuybackSlippage150BpsMaxAndIntervalCannotBeBypassed() (gas: 756168)\n[PASS] testDonationsAndOrdinaryInflowsCannotPretendToBeEndowment() (gas: 1520675)\n[PASS] testEntropyAt256BoundaryAndAt257RearmsWithoutPayOrMint() (gas: 3276985)\n[PASS] testFirstRewardStartsCurrentEpochAtHalfTimeAndSnapshotCannotBeReplaced() (gas: 4834300)\n[PASS] testFreeFarmDoesNotDiluteDistrictOrClaimPaidPrize() (gas: 4739665)\n[PASS] testGameReadinessBothChecksRollbackEthAndTokenPurchase() (gas: 3605912)\n[PASS] testHookUninitializedCannotOpenOrStartEpochAndCallerCannotStartClock() (gas: 5887799)\n[PASS] testLaunchTaxExactBoundaries() (gas: 5771057)\n[PASS] testMythicGateEvaluatedAtRevealNotAtPayment() (gas: 1620572)\n[PASS] testPackOpeningFollowsHookAndNotLegacyDeployTimestamp() (gas: 101151)\n[PASS] testRemainderTransferredToPredictedPoolBeforeDeploymentAndNoApprovalNeeded() (gas: 2800290)\n[PASS] testStarterEntropyRearmsAfterClaimWindowAndNoDoubleMint() (gas: 772300)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 432.71ms (65.83ms CPU time)\n\nRan 8 tests for test/FeesParams.t.sol:FeesParamsTest\n[PASS] testAllDefaultParamsWithinHardBounds() (gas: 1255771)\n[PASS] testBuyBackPoolOnlySlippageFailureRollbackAndDustGriefBlocked() (gas: 774066)\n[PASS] testExactEthSplitsHeartbeatCapAndPullPayments() (gas: 512724)\n[PASS] testFuzzNoStepAboveTenPercent(uint96) (runs: 256, μ: 44938, ~: 45115)\nLogs:\n  Bound result 4413\n\n[PASS] testFuzzSplitsConserveEveryWei(uint96) (runs: 256, μ: 207838, ~: 210856)\nLogs:\n  Bound result 33879714190044317703\n\n[PASS] testHeartbeatCapFixedAtOneEth() (gas: 207904)\n[PASS] testParamsStepCooldownBoundsAuthorityAndLetter() (gas: 195823)\n[PASS] testPoolNoPublicReserveRecycleOrPayment() (gas: 135304)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 483.21ms (89.51ms CPU time)\n\nRan 3 tests for test/Gas.t.sol:GasTest\n[PASS] testGasCommonActions() (gas: 10843346)\nLogs:\n  buy token pack: 922761\n  open one pack: 514543\n  equip: 963773\n  repair wallet: 611998\n  enhancement commit: 565794\n  expand: 387774\n  token pack wallet: 652058\n  withdraw: 253137\n  unequip: 404020\n\n[PASS] testGasFullFarmLongIdleBoundedChunks() (gas: 119172460)\nLogs:\n  settle full 24-item farm eight epochs after 40 idle: 12486576\n\n[PASS] testGasTypicalFarmSettlementHasNoBounty() (gas: 8924872)\nLogs:\n  settle typical three-item farm one epoch: 919736\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 488.90ms (523.33ms CPU time)\n\nRan 18 tests for test/EconomyV35.t.sol:EconomyV35Test\n[PASS] testAllEnhancementTableEndpointsAndGlobalBonusCap() (gas: 1477953)\n[PASS] testDurabilityBoundariesAndIdleNoWear() (gas: 38102739)\n[PASS] testEnhanceBurnFailureAndLevelGate() (gas: 1218555)\n[PASS] testEnhanceCapsNoticeUpwardOnlyAndThirtyDays() (gas: 355782)\n[PASS] testEnhanceCommitCannotPlaceScrapOrRetryAndCanRearm() (gas: 1798751)\n[PASS] testFeeSalesDepthSlippageCadenceAndNormalFeePot() (gas: 1734752)\n[PASS] testFreeAllowlistOnceWindowStarterScrapAndMetadata() (gas: 2989149)\n[PASS] testFreeRootRemainsFrozenAfterSevenDays() (gas: 43976)\n[PASS] testFreeRootWindowAndIndexLimit() (gas: 55991)\n[PASS] testFuzzPriceCurveDaysBounds(uint32,uint32) (runs: 256, μ: 88615, ~: 90122)\nLogs:\n  Bound result 18350\n\n[PASS] testLockBonusRedistributesWithinReservedEmission() (gas: 11653052)\n[PASS] testLockEscrowNoEarlyExitAndWalletCap() (gas: 5377416)\n[PASS] testQuoteScalesLastSettlementAndHasFloor() (gas: 4278490)\n[PASS] testRepairYieldQuoteAndAutoRepairCreditsOnly() (gas: 10789523)\n[PASS] testRoomsChargeYieldDaysAndRetainAgeGates() (gas: 2600055)\n[PASS] testSystemSellDustCannotOccupyCadenceAndCappedHeartbeatReturnsTokens() (gas: 1556688)\n[PASS] testTokenOnlyGiftSplitsNoEthPeg() (gas: 1734609)\n[PASS] testZapAtomicMinOutPauseAndRefund() (gas: 1438033)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 505.65ms (339.88ms CPU time)\n\nRan 6 tests for test/Endowment.t.sol:EndowmentTest\n[PASS] testDirectTransferCannotBypassOrBackdateDrip() (gas: 368166)\n[PASS] testExactFundingFullLinearDripAndConservation() (gas: 832168)\n[PASS] testFuzzCumulativePaymentsCannotExceedVestedPrincipal(uint32,uint128) (runs: 256, μ: 522785, ~: 524745)\nLogs:\n  Bound result 7476\n  Bound result 362822978\n\n[PASS] testNoTeamDonorOrSwarmWithdrawalOrReserveAuthority() (gas: 614309)\n[PASS] testParamsSnapshotCannotAccelerateOrRelockExistingEndowment() (gas: 303686)\n[PASS] testUnderfundingCannotActivateAndDonationsStayConserved() (gas: 453428)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 505.74ms (492.88ms CPU time)\n\nRan 2 tests for test/ReservedEventsV35.t.sol:ReservedEventsV35Test\n[PASS] testFuzzReservedFestivalCannotExceedFifteenPercent(uint16) (runs: 256, μ: 4918902, ~: 4918899)\n[PASS] testReservedHeatwaveExtraCoolingWearAndBothProtections() (gas: 10146981)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 855.54ms (890.13ms CPU time)\n\nRan 9 tests for test/Epochs.t.sol:EpochsTest\n[PASS] testCannotAdvanceEarlyAndBountyOnce() (gas: 2510478)\n[PASS] testClaimsEveryEpochAndRedistributionIsNextEpoch() (gas: 11985703)\n[PASS] testGasAdvanceIndependentOfRoster() (gas: 893047640)\nLogs:\n  advance empty roster: 1284132\n  advance 1000 farms: 1473629\n\n[PASS] testNoCatchupEmissionDuringGap() (gas: 6257752)\n[PASS] testNoRetroactiveEquipmentAndBoundedBatches() (gas: 5780602)\n[PASS] testNoWhaleCapHashShares() (gas: 10155257)\n[PASS] testReferralOneLevelSetOnceNoSelf() (gas: 7511550)\n[PASS] testTaxCurveExactAndFloor() (gas: 34112)\n[PASS] testWithdrawFailureRollsBackAndReentrancyCannotClaimTwice() (gas: 7428870)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 5.23s (5.30s CPU time)\n\nRan 6 tests for test/SeasonAudit.t.sol:SeasonAuditTest\n[PASS] testAuditThresholdStrictAndNoWhaleSoftCap() (gas: 40376130)\n[PASS] testLotteryEntitlementSurvivesFullInventory() (gas: 130888063)\n[PASS] testPackSupplyDropOnlyActiveFarmsAtDoublePace() (gas: 11727425)\n[PASS] testParameterChangesCannotChangeClosedEpochBetweenBatches() (gas: 12490901)\n[PASS] testSeasonCannotFinalizeEarlyAndExpiredLotteryMustRearm() (gas: 123852005)\n[PASS] testWeeklyThreeDistinctTicketWinnersRarePackAndBestPrize() (gas: 124081336)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 11.23s (1.31s CPU time)\n\nRan 2 tests for test/StandardMarket.t.sol:StandardMarketTest\n[PASS] testFuzzStandardSellNeverAddsProgressiveSurcharge(uint96) (runs: 256, μ: 1806051, ~: 1813947)\nLogs:\n  Bound result 33879714190044317703\n\n[PASS] testStandardBuyOnePercentAllToRewards() (gas: 1673242)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 11.23s (11.20s CPU time)\n\nRan 9 tests for test/LazyAccounting.t.sol:LazyAccountingTest\n[PASS] testAuditChargesTenPercentEvenAtHalfSeverityAndThresholdIsFrozen() (gas: 6152701)\n[PASS] testClaimCatchesUpWhilePacksPausedAndDoesNotEraseRemainingHistory() (gas: 25659680)\n[PASS] testExhaustedFarmCannotCollectRedistributionByRemainingIdle() (gas: 15152008)\n[PASS] testFuzzLazyEqualsIndependentEagerForRandomFarmsAndAllEvents(uint256) (runs: 256, μ: 45540997, ~: 45549637)\n[PASS] testGlobalAccumulatorAndWeightsAreSnapshottedBeforeMutations() (gas: 9289772)\n[PASS] testLateSeasonSettlementPaysMiningWithoutChangingFrozenWinners() (gas: 59428195)\n[PASS] testOneWeiMiningGreenCannotLockSettlementThroughEnvelopeRounding() (gas: 11045065)\n[PASS] testSparseMatureVintageConsumedBeforeRecentSlotAfterWrap() (gas: 43285171)\n[PASS] testStaleActionsRequireChunksAndNeverBlockGlobalAdvance() (gas: 40513874)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 11.20s (11.62s CPU time)\n\nRan 1 test for test/Invariants.t.sol:InvariantsTest\n[PASS]\nInvariantsTest invariants:\n[PASS] invariantAllowlistRootAndWalletLimit\n[PASS] invariantInventoryAndEthLiabilities\n[PASS] invariantLocksAndPotAlwaysBacked\n[PASS] invariantPriceAndParamsBounds\n[PASS] invariantReceiptsNeverForfeitOrFixMissingEntropy\n[PASS] invariantReservesBackedAndPendingCovered\n[PASS] invariantTokenConservationNoBurns\n InvariantsTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭-------------+-----------+-------+---------+----------╮\n| Contract    | Selector  | Calls | Reverts | Discards |\n+======================================================+\n| GameHandler | advance   | 604   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | buy       | 578   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | claim     | 587   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | equip     | 579   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | expand    | 549   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | freeClaim | 573   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | fundPot   | 572   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | lock      | 620   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | resolve   | 575   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | rollover  | 610   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | settle    | 578   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | tokenPack | 590   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | unlock    | 603   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | unplace   | 574   | 0       | 0        |\n╰-------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 100000000000000\n  Bound result 380000000000000000\n  Bound result 200000000000000000\n  Bound result 26\n  Bound result 928710291718670337550\n  Bound result 1000000000000000000000\n  Bound result 444378688767337168896\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 37.60s (37.56s CPU time)\n\nRan 49 test suites in 37.60s (83.79s CPU time): 277 tests passed, 0 failed, 6 skipped (283 total tests)\n","passed":true},{"durationMs":212,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Billboards.bidBillboard(uint256,uint256,string,string)\",\"Billboards.settleBillboard(uint256,uint256)\",\"Billboards.withdrawRefund()\",\"Civic.announce(uint256,string)\",\"Civic.buyLot(uint256)\",\"Civic.claimWar(uint256)\",\"Civic.consumeCityEvent()\",\"Civic.enable(uint256)\",\"Civic.finishCollapse()\",\"Civic.finishWar()\",\"Civic.fundCollapse(uint256)\",\"Civic.fundWar(uint256)\",\"Civic.grantDistrictBoost(uint256,uint16,string)\",\"Civic.listLot(uint8,uint8,uint8)\",\"Civic.startCollapse(uint256)\",\"Civic.startWar(uint8,uint8)\",\"Economy.autoRepair(address,uint256,uint256[24])\",\"Economy.lock(uint256,uint256)\",\"Economy.unlock()\",\"EndowmentEscrow.forward(address,uint64,uint256,bytes,uint64,uint256,bytes)\",\"Enhancement.activateCap()\",\"Enhancement.announceCap(uint8,string)\",\"Enhancement.capture(uint256)\",\"Enhancement.commit(uint256,uint256,bool)\",\"Enhancement.resolve(uint256)\",\"FarmCore.activity(address,uint256,uint256,uint256)\",\"FarmCore.autoRepair(address,uint256)\",\"FarmCore.buyRoom(uint256,bool)\",\"FarmCore.buyTokenPack(bool)\",\"FarmCore.civicPurchase(address,uint256)\",\"FarmCore.claimDrop()\",\"FarmCore.expand(bool)\",\"FarmCore.grantDrop(address,bytes32)\",\"FarmCore.lobby(uint256,bool)\",\"FarmCore.paidPackBought(address,uint256,uint256)\",\"FarmCore.place(uint256,uint256,uint256)\",\"FarmCore.prepareEnhancement(address,uint256,uint256,bool)\",\"FarmCore.process(address,uint256)\",\"FarmCore.register(address)\",\"FarmCore.repair(uint256,bool)\",\"FarmCore.repairCable(bool)\",\"FarmCore.retire(address)\",\"FarmCore.scrap(uint256,uint256)\",\"FarmCore.setAutoRepair(bool,uint16)\",\"FarmCore.setReferrer(address)\",\"FarmCore.sync()\",\"FarmCore.syncFor(address)\",\"FarmCore.unplace(uint256,uint256)\",\"FarmEngine.process(address,uint256,(uint256[24],uint8[24],uint16[24],bool,uint64,uint16))\",\"FarmItems.destroy(uint256)\",\"FarmItems.equip(address,uint256)\",\"FarmItems.expand(address)\",\"FarmItems.maintain(uint256,uint16,uint8)\",\"FarmItems.mint(address,uint8,uint8,bool)\",\"FarmItems.mintDrop(address,bytes32)\",\"FarmItems.safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\",\"FarmItems.safeTransferFrom(address,address,uint256,uint256,bytes)\",\"FarmItems.unequip(address,uint256)\",\"FarmRewards.advanceEpoch()\",\"FarmRewards.award(address,uint256)\",\"FarmRewards.beginMining(address,uint256)\",\"FarmRewards.claim(uint256)\",\"FarmRewards.initialize(address)\",\"FarmRewards.recordSales(uint256)\",\"FarmRewards.releasePrize(uint256)\",\"FarmRewards.scrap(address,uint256,uint256)\",\"FarmRewards.setReferrer(address,address)\",\"FarmRewards.setWeight(address,uint256)\",\"FarmRewards.settle(address,uint256)\",\"FarmRewards.spend(address,uint256)\",\"FarmRewards.spendTo(address,uint256,address)\",\"FeeRouter.depositBaseFee()\",\"FeeRouter.depositLaunchTax()\",\"FeeRouter.depositLobby()\",\"FeeRouter.depositPack()\",\"FeeRouter.depositSellTax()\",\"FeeRouter.executeBuys(uint256,uint256)\",\"FeeRouter.executePotBuys(uint256,uint256)\",\"FeeRouter.executeSells(uint256,uint256)\",\"FeeRouter.payBounty(address)\",\"FeeRouter.payWork(address,uint8,uint256,uint256)\",\"FeeRouter.receive()\",\"FeeRouter.routeTokens(uint256)\",\"FeeRouter.withdraw()\",\"FeeRouter.zapBuy(uint256,address)\",\"GameRegistry.register(uint256,uint64,uint256,bytes)\",\"GridOperator.lobbyETH()\",\"GridOperator.resolve(uint256)\",\"GridOperator.resolveFor(uint256,address)\",\"GridOperator.shift(uint256)\",\"GridOperator.submitPlan(uint256,uint8,uint16,bytes32,string)\",\"GridOperator.tokenLobby(address,uint256)\",\"MarketFactory.deploy((address,address,int24,address,address,address,bytes32),bytes32)\",\"PackSale.buyPackFor(address)\",\"PackSale.buyPacksFor(address,uint256,uint256)\",\"PackSale.buyWithETH(address,uint256,uint256,uint256)\",\"PackSale.captureEntropy(uint256)\",\"PackSale.openPack(uint256)\",\"PackSale.pause(uint256)\",\"PackSale.rearm(uint256)\",\"PackSale.resolve(uint256,uint256)\",\"PackSale.rewardPack(address)\",\"PackSale.tokenPack(address)\",\"PackSale.unpause()\",\"Params.set(uint8,uint256,string)\",\"RewardPool.donate(uint256)\",\"RewardPool.fundEndowment()\",\"RewardPool.pay(address,uint256)\",\"RewardPool.recordInflow(uint256)\",\"RewardPool.recycle(uint256)\",\"RewardPool.reserve(uint256)\",\"Season.addPrize(uint256,uint256)\",\"Season.claimBest(uint256)\",\"Season.claimDistrict(uint256)\",\"Season.claimLottery(uint256)\",\"Season.complete(address,uint256)\",\"Season.depositPot(uint256)\",\"Season.finalize(uint256)\",\"Season.prepare(uint256,uint256)\",\"Season.rearm(uint256)\",\"Season.recordActivity(address,uint256,uint256,uint256)\",\"Season.recordRepair(address,uint256,uint256)\",\"Season.recordSpend(address,uint256,bool)\",\"Season.rollover(uint256)\",\"StandardAdapter.buy(uint256,address)\",\"StandardAdapter.unlockCallback(bytes)\",\"StandardMarket.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"StandardMarket.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"StandardMarket.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"StandardMarket.bindFeeRouter(address,uint64,uint256)\",\"StandardMarket.buy(uint256,address)\",\"StandardMarket.flushFees()\",\"StandardMarket.receive()\",\"StandardMarket.sell(uint256,uint256,address)\",\"StandardMarket.unlockCallback(bytes)\",\"StarterClaim.captureEntropy(uint256)\",\"StarterClaim.claim(uint256,bytes32[])\",\"StarterClaim.claimFree(uint256,bytes32[])\",\"StarterClaim.rearm(uint256)\",\"StarterClaim.resolve(uint256)\",\"SwarmDesk.askBackup(uint8,bytes)\",\"SwarmDesk.bind(address,bytes,bytes,uint64,uint8,uint64,uint8)\",\"SwarmDesk.clearExpired(bytes32)\",\"SwarmDesk.execute(uint8,bytes)\",\"SwarmDesk.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"SwarmDesk.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"SwarmDesk.submit((bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"V4Market.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"V4Market.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"V4Market.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"V4Market.bindFeeRouter(address,uint64,uint256)\",\"V4Market.buy(uint256,address)\",\"V4Market.flushFees()\",\"V4Market.receive()\",\"V4Market.sell(uint256,uint256,address)\",\"V4Market.unlockCallback(bytes)\"],\"files\":{\".gitignore\":8,\"ADAPTATION.md\":172,\"README.md\":58,\"artifacts/build-lint-v3.txt\":2369,\"artifacts/build-v3.txt\":3,\"artifacts/economic-targets-v3.json\":9,\"artifacts/fmt-v3.txt\":0,\"artifacts/foundry-v3.txt\":845,\"artifacts/funded-sensitivity/simulation-v3.json\":13928,\"artifacts/funded-sensitivity/simulation-v3.md\":51,\"artifacts/funding-sensitivity-v3.json\":342,\"artifacts/gas-actions-v3.txt\":15,\"artifacts/policy-sensitivity-v3.json\":554,\"artifacts/python-tests-v3.txt\":18,\"artifacts/regulator-example.json\":59,\"artifacts/robinhood-fork-v3.txt\":7,\"artifacts/runtime-sizes-v3.json\":23,\"artifacts/simulation-v3.json\":13928,\"artifacts/simulation-v3.md\":51,\"artifacts/tuned-funded/simulation-v3.json\":13928,\"artifacts/tuned-funded/simulation-v3.md\":51,\"artifacts/v2/README.md\":3,\"artifacts/v2/foundry-tests.txt\":178,\"artifacts/v2/offline-tests.txt\":187,\"artifacts/v2/offline-verification.json\":21,\"artifacts/v2/previous-README.md\":108,\"artifacts/v2/previous-design.md\":120,\"artifacts/v2/previous-report.md\":75,\"artifacts/v2/previous-security-review.md\":29,\"artifacts/v2/previous-simulation-assumptions.md\":52,\"artifacts/v2/robinhood-fork.txt\":7,\"artifacts/v2/rpc-probe.json\":16,\"artifacts/v2/runtime-sizes.json\":21,\"artifacts/v2/simulation.md\":95,\"artifacts/v2/verification.json\":110,\"artifacts/v31/allocation-summary.md\":6,\"artifacts/v31/baseline-budget.md\":14,\"artifacts/v31/boundary-checks.json\":10880,\"artifacts/v31/candidate-stress/simulation.json\":32636,\"artifacts/v31/evidence/factory-prediction.json\":14,\"artifacts/v31/evidence/launch-and-cost-facts.json\":130,\"artifacts/v31/evidence/standalone-hook-build.json\":38,\"artifacts/v31/final/comparison.md\":50,\"artifacts/v31/funded/comparison.md\":52,\"artifacts/v31/funded/replay.json\":290,\"artifacts/v31/funding-comparison.md\":8,\"artifacts/v31/regulator-example.json\":73,\"artifacts/v31/stress-comparison.md\":20,\"artifacts/v31/summary.json\":13,\"artifacts/v31/validation.json\":250,\"artifacts/v310/forge-test-launch.txt\":496,\"artifacts/v310/forge-test-repo-changed-suites.txt\":115,\"artifacts/v310/forge-test-repo-full-before-new-tests.txt\":437,\"artifacts/v310/pins-check.txt\":2,\"artifacts/v311/rehearsal.log\":377,\"artifacts/v312/forge-fmt.txt\":1,\"artifacts/v312/forge-test-launch.txt\":381,\"artifacts/v312/forge-test-repo.txt\":384,\"artifacts/v312/launch-creation-hashes.txt\":5,\"artifacts/v312/node-tests.txt\":10,\"artifacts/v312/pins-check.txt\":2,\"artifacts/v312/python-tests.txt\":3,\"artifacts/v312/rehearsal.log\":368,\"artifacts/v313/forge-fmt.txt\":0,\"artifacts/v313/forge-test.txt\":468,\"artifacts/v313/launch-creation-hashes.txt\":6,\"artifacts/v313/module-pins.txt\":15,\"artifacts/v313/pins-check.txt\":2,\"artifacts/v32/contract-sizes.json\":54,\"artifacts/v32/forge-build.log\":2734,\"artifacts/v32/forge-fmt.log\":0,\"artifacts/v32/forge-test.log\":310,\"artifacts/v32/model-checks.log\":5,\"artifacts/v32/module-pins.log\":1,\"artifacts/v32/python-tests.log\":25,\"artifacts/v32/regulator-example.json\":73,\"artifacts/v32/simulation-checks.json\":11,\"artifacts/v32/simulation-checks.log\":11,\"artifacts/v32/validation.json\":61,\"artifacts/v32/verified-baseline/comparison.md\":8,\"artifacts/v32/verified-baseline/simulation.json\":22622,\"artifacts/v32/verified-sensitivities/comparison.md\":68,\"artifacts/v33/simulation.json\":116,\"artifacts/v34/build.txt\":2931,\"artifacts/v34/format.txt\":0,\"artifacts/v34/pins.txt\":1,\"artifacts/v34/python-tests.txt\":5,\"artifacts/v34/reveal-test.txt\":1,\"artifacts/v34/simulation.json\":91766,\"artifacts/v34/simulation.md\":43,\"artifacts/v34/tests.txt\":306,\"artifacts/v35/simulation.json\":22605,\"artifacts/v35/simulation.md\":104,\"artifacts/v35/verification.json\":132,\"artifacts/v36/simulation-phases.json\":179,\"artifacts/v36/simulation-phases.md\":13,\"artifacts/v37/byte-sizes.json\":131,\"artifacts/v37/verification.json\":28,\"artifacts/v39/forge-build-repo.txt\":3,\"artifacts/v39/forge-fmt.txt\":1,\"artifacts/v39/forge-test-launch.txt\":8,\"artifacts/v39/forge-test-repo.txt\":390,\"artifacts/v39/pins-check.txt\":2,\"artifacts/v39/pins.json\":68,\"artifacts/v39/runtime-sizes.json\":197,\"artifacts/v39/simulation.json\":381,\"artifacts/v39/simulation.md\":29,\"artifacts/verification-v3.json\":67,\"docs/api-v35.md\":41,\"docs/dependency-provenance.md\":9,\"docs/design.md\":69,\"docs/entropy-v34.md\":31,\"docs/launch-v31.md\":121,\"docs/launch-v34.md\":44,\"docs/launch-v35.md\":40,\"docs/lazy-accounting-v32.md\":48,\"docs/m2-trust-assumption.md\":101,\"docs/oracle-v37/event.json\":1,\"docs/oracle-v37/oracle-config.json\":21,\"docs/oracle-v37/regulator.json\":1,\"docs/params-keys-v313.md\":113,\"docs/report-v3.md\":143,\"docs/report-v31.md\":128,\"docs/report-v32.md\":138,\"docs/report-v33.md\":107,\"docs/report-v34.md\":58,\"docs/report-v36.md\":89,\"docs/report-v38.md\":83,\"docs/research/b94e6839-platform-report.md\":238,\"docs/review-v31.md\":77,\"docs/review-v32.md\":32,\"docs/review-v33.md\":19,\"docs/review-v34.md\":30,\"docs/review-v35-independent.md\":69,\"docs/review-v37-independent.md\":44,\"docs/review-v39-independent.md\":105,\"docs/security-review.md\":29,\"docs/simulation-assumptions.md\":43,\"docs/simulation-v3-historical.md\":44,\"docs/simulation-v34.md\":34,\"docs/swarm-bootstrap-v313/binding.json\":10,\"docs/swarm-bootstrap-v313/constructor-args.json\":16,\"foundry.toml\":21,\"keeper/README.md\":117,\"keeper/blackout-keeper.service\":23,\"keeper/keeper.env.example\":18,\"keeper/keeper.mjs\":537,\"keeper/lib/abi.mjs\":95,\"keeper/lib/eth.mjs\":186,\"keeper/lib/oracle.mjs\":57,\"keeper/wiring.example.json\":17,\"launch-v31.md\":3,\"launch-v36.md\":34,\"launch-v37.md\":144,\"launch-v38.md\":57,\"launch-v39.md\":292,\"launch.json\":23,\"launch/V4Market.sol\":1870,\"operations/dormant-v35.md\":17,\"regulator.md\":60,\"report.md\":290,\"script/Deploy.s.sol\":184,\"script/DeployMarket.s.sol\":15,\"script/PredictGame.s.sol\":49,\"script/SwarmArgs.sol\":30,\"sim/blackout_sim_v2.py\":509,\"sim/blackout_sim_v3.py\":338,\"sim/blackout_sim_v31.py\":24,\"sim/blackout_sim_v32.py\":380,\"sim/blackout_sim_v33.py\":395,\"sim/blackout_sim_v34.py\":444,\"sim/candidate_stress_v31.py\":21,\"sim/heartbeat_boundaries_v31.py\":25,\"sim/heartbeat_sweep_v31.py\":46,\"sim/policy_sensitivity_v3.py\":19,\"sim/run_v32.py\":34,\"sim/run_v33.py\":58,\"sim/run_v34.py\":54,\"sim/run_v35.py\":273,\"sim/run_v36.py\":83,\"sim/run_v39.py\":153,\"sim/tune_v3.py\":16,\"src/Billboards.sol\":135,\"src/Civic.sol\":302,\"src/Economy.sol\":207,\"src/EndowmentEscrow.sol\":112,\"src/Enhancement.sol\":126,\"src/FarmCore.sol\":597,\"src/FarmEngine.sol\":299,\"src/FarmItems.sol\":165,\"src/FarmRewards.sol\":577,\"src/FeeRouter.sol\":312,\"src/GameRegistry.sol\":102,\"src/GridOperator.sol\":261,\"src/MarketFactory.sol\":72,\"src/PackSale.sol\":293,\"src/Params.sol\":181,\"src/RewardPool.sol\":113,\"src/Season.sol\":371,\"src/StandardAdapter.sol\":77,\"src/StandardMarket.sol\":23,\"src/StarterClaim.sol\":149,\"src/SwarmDesk.sol\":479,\"src/V4Market.sol\":551,\"src/interfaces/IGame.sol\":51,\"src/interfaces/IGameRegistry.sol\":15,\"src/interfaces/ILaunchHook.sol\":7,\"src/interfaces/IV4.sol\":26,\"src/interfaces/Interfaces.sol\":20,\"src/lib/ChainClock.sol\":22,\"src/lib/EconomyMath.sol\":48,\"src/lib/Errors.sol\":13,\"src/lib/GameModule.sol\":17,\"src/lib/ItemMath.sol\":31,\"src/lib/ItemMetadata.sol\":79,\"src/lib/ModuleCode.sol\":51,\"src/lib/SwarmCode.sol\":18,\"src/oracle/OracleAttestation.sol\":221,\"src/oracle/SignatureCheckerCompat.sol\":14,\"test/AutoRepairReviewV35.t.sol\":39,\"test/Base.t.sol\":306,\"test/Bounties.t.sol\":290,\"test/CivicV35.t.sol\":224,\"test/Clock.t.sol\":54,\"test/Deployment.t.sol\":94,\"test/EconomyV35.t.sol\":389,\"test/Endowment.t.sol\":123,\"test/EndowmentEscrowV38.t.sol\":198,\"test/EndowmentGame.t.sol\":51,\"test/Epochs.t.sol\":177,\"test/Events.t.sol\":238,\"test/Factory.t.sol\":37,\"test/FeesParams.t.sol\":135,\"test/Gas.t.sol\":110,\"test/GridV35.t.sol\":66,\"test/HeartbeatBpsV313.t.sol\":149,\"test/HookBinding.t.sol\":113,\"test/Invariants.t.sol\":211,\"test/Items.t.sol\":246,\"test/KeeperProfit.t.sol\":95,\"test/LazyAccounting.t.sol\":447,\"test/Market.t.sol\":130,\"test/OracleConformanceV37.t.sol\":107,\"test/Packs.t.sol\":167,\"test/Pause.t.sol\":76,\"test/PhasedReleaseV36.t.sol\":165,\"test/PotV35.t.sol\":108,\"test/PredictionV34.t.sol\":48,\"test/Registry.t.sol\":141,\"test/Regression.t.sol\":154,\"test/ReservedEventsV35.t.sol\":41,\"test/ReviewV34.t.sol\":146,\"test/SeasonAudit.t.sol\":187,\"test/StandardAdapter.t.sol\":81,\"test/StandardMarket.t.sol\":63,\"test/StandardV4Integration.t.sol\":128,\"test/SwarmDeskBootstrap.t.sol\":149,\"test/SwarmDeskV37.t.sol\":646,\"test/TwinCaptureV312.t.sol\":175,\"test/V310.t.sol\":79,\"test/V33.t.sol\":561,\"test/V34.t.sol\":315,\"test/V39.t.sol\":226,\"test/V4Integration.t.sol\":190,\"test/WarReviewV35.t.sol\":69,\"test/YieldFloorReviewV35.t.sol\":31,\"test/fixtures/keeper-v39-vectors.json\":55,\"test/fixtures/oracle-hash-vectors.json\":102,\"test/fork/RehearsalV311.t.sol\":739,\"test/fork/RobinhoodFork.t.sol\":39,\"test/keeper-v39.test.mjs\":34,\"test/mocks/MockGameRegistry.sol\":52,\"test/mocks/MockMarket.sol\":67,\"test/mocks/MockSwarmIntake.sol\":67,\"test/mocks/MockToken.sol\":38,\"test/mocks/MockV4Manager.sol\":118,\"test/oracle-v310.test.mjs\":22,\"test/oracle-v37.test.mjs\":41,\"test/python/test_entropy_bot.py\":31,\"test/python/test_merkle.py\":19,\"test/python/test_regulator.py\":30,\"test/python/test_v31.py\":38,\"test/python/test_v32.py\":58,\"test/python/test_v34.py\":33,\"test/python/test_v35.py\":71,\"test/reveal.test.mjs\":24,\"test/swarm-bootstrap.test.mjs\":48,\"test/ui-v35.test.mjs\":27,\"tools/check_v32_results.py\":52,\"tools/check_v37_authority.py\":19,\"tools/entropy_bot.py\":106,\"tools/freepack_merkle.py\":20,\"tools/make_oracle_bodies.mjs\":45,\"tools/oracle_question_hash.mjs\":80,\"tools/pin_module_code.py\":103,\"tools/pin_swarm_code.py\":47,\"tools/regulator.py\":81,\"tools/rehearse_v311.sh\":25,\"tools/report_v31.py\":55,\"tools/schedule_bodies.mjs\":16,\"tools/starter_merkle.py\":72,\"tools/swarm_constructor_args.mjs\":44,\"ui/app.js\":178,\"ui/index.html\":22,\"ui/reveal.js\":34,\"ui/style.css\":3},\"excluded\":[\"vendor/\",\"node_modules/\"],\"truncated\":true}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"3b37aedbd90be21553fbb4a19646e1a9aa17c143a7c55340404da01359cb092d","verifiedTreeHash":"fef12794e92560dc25dec2910ce32e1c3478e81a","verifierVersion":"0.1.0+327e1e9f"},{"checks":[{"durationMs":43335,"exitCode":0,"name":"build","output":"Compiling 189 files with Solc 0.8.26\nSolc 0.8.26 finished in 42.78s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n  --> src/lib/EconomyMath.sol:17:48:\n   |\n17 |         returns (uint256 chance, uint256 burn, uint256 bonus, uint256 daysWad)\n   |                                                ^^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/lib/EconomyMath.sol:44:5:\n   |\n44 |     function bonus(uint256 level) internal pure returns (uint256 b) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (8760): This declaration has the same name as another declaration.\n   --> src/V4Market.sol:300:22:\n    |\n300 |     function _record(bool sell, uint256 amount) private {\n    |                      ^^^^^^^^^\nNote: The other declaration is here:\n   --> src/V4Market.sol:490:5:\n    |\n490 |     function sell(uint256 amount, uint256 minOut, address recipient) external nonReentrant returns (uint256 received) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (8760): This declaration has the same name as another declaration.\n  --> test/mocks/MockSwarmIntake.sol:26:9:\n   |\n26 |         bytes4 failure,\n   |         ^^^^^^^^^^^^^^\nNote: The other declaration is here:\n  --> test/mocks/MockSwarmIntake.sol:44:5:\n   |\n44 |     function failure(bytes32 id, uint8 status, bytes32 reason) external returns (bool) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2072): Unused local variable.\n   --> test/Events.t.sol:199:9:\n    |\n199 |         uint256 price = d.packs.quote(112);\n    |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n --> test/Gas.t.sol:9:9:\n  |\n9 |         uint256 price = d.packs.price();\n  |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Gas.t.sol:75:9:\n   |\n75 |         uint256 q = d.packs.quote(112);\n   |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Invariants.t.sol:56:9:\n   |\n56 |         uint256 price = d.packs.price();\n   |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Items.t.sol:76:9:\n   |\n76 |         uint256 cost = d.packs.quote(112);\n   |         ^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/Items.t.sol:106:9:\n    |\n106 |         uint256 q = d.packs.quote(16);\n    |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/LazyAccounting.t.sol:186:13:\n    |\n186 |             uint256 quote = d.packs.quote(112);\n    |             ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/LazyAccounting.t.sol:421:9:\n    |\n421 |         uint256 quote = d.packs.quote(112);\n    |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Packs.t.sol:37:9:\n   |\n37 |         uint256 quote = d.packs.quote(200);\n   |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Packs.t.sol:64:9:\n   |\n64 |         uint256 q = d.packs.quote(6);\n   |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Pause.t.sol:35:9:\n   |\n35 |         uint256 q = d.packs.quote(1);\n   |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Regression.t.sol:73:9:\n   |\n73 |         uint256 previous = d.items.data(id).durability;\n   |         ^^^^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/V33.t.sol:254:13:\n    |\n254 |             uint256 q = d.packs.quote(16);\n    |             ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/V33.t.sol:431:9:\n    |\n431 |         uint256 price = d.packs.price();\n    |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/V34.t.sol:78:9:\n   |\n78 |         uint256 q = d.packs.price();\n   |         ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> src/FarmRewards.sol:146:5:\n    |\n146 |     function ready() public view returns (bool) {\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/RehearsalV311.t.sol:216:5:\n    |\n216 |     function _oracle() internal view returns (SwarmDesk.OracleConfig memory o) {\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/RehearsalV311.t.sol:290:5:\n    |\n290 |     function _mineHookSalt(bytes memory initCode) internal view returns (bytes32 salt, address hook) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[missing-events-access-control]: `bestClaimed` is changed without an event but is used for access control\n   ╭▸ src/Season.sol:76:9\n   │\n76 │         bestClaimed[w] = true;\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/GridOperator.sol:116:16\n    │\n116 │         return block.timestamp < uint256(l.at) + 3 days ? l.amount : 0;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[missing-events-arithmetic]: `heldBase` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:461:9\n    │\n461 │         heldBase += base;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `heldSellTax` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:462:9\n    │\n462 │         heldSellTax += excess;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/GridOperator.sol:127:13\n    │\n127 │             total += stake[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/GridOperator.sol:128:28\n    │\n128 │             if (stake[i] > largest) largest = stake[i];\n    │                            ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:174:21\n    │\n174 │                     seasons[w].districtSpend[d] += districtSpendOf[w][p];\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-arithmetic]: `heldBase` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:520:9\n    │\n520 │         heldBase += base;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:126:24\n    │\n126 │             stake[i] = eco.districtStake(i);\n    │                        ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:241:17\n    │\n241 │                 seasons[w].districtSpend[d] += districtSpendOf[w][p];\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:263:9\n    │\n263 │         s.totalTickets += weight;\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:63:39\n   │\n63 │             FarmItems.Item memory x = inventory.data(id);\n   │                                       ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:95:45\n   │\n95 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                             ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:95:35\n   │\n95 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:87:45\n   │\n87 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                             ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:87:35\n   │\n87 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:275:9\n    │\n275 │         seasons[w].prize += amount;\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:52:30\n   │\n52 │         return IYieldRewards(registry.module(1));\n   │                              ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:91:64\n   │\n91 │         return Math.mulDiv(hash * 4, Math.max(HASH_RATE_FLOOR, rewards().lastYieldPerHash()), 1 ether);\n   │                                                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:99:30\n   │\n99 │             missing * Params(registry.params()).get(Params.Key.RepairHours),\n   │                              ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:99:23\n   │\n99 │             missing * Params(registry.params()).get(Params.Key.RepairHours),\n   │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:66:17\n   │\n66 │             if (reward.pending(p) < cost) continue;\n   │                 ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:67:21\n   │\n67 │             paid += reward.spend(p, cost);\n   │                     ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:68:13\n   │\n68 │             inventory.maintain(id, 10000, x.overclock);\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[missing-events-access-control]: `lotteryClaimed` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:364:9\n    │\n364 │         lotteryClaimed[w][msg.sender] = true;\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/Economy.sol:88:37\n   │\n88 │         if (x.holder == address(0)) revert InvalidValue();\n   │                                     ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n  ╭▸ src/lib/ItemMath.sol:8:25\n  │\n8 │         if (rarity > 4) revert InvalidValue();\n  │                         ━━━━━━━━━━━━━━━━━━━━━━\n  │\n  ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/lib/EconomyMath.sol:19:39\n   │\n19 │         if (level == 0 || level > 16) revert InvalidValue();\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/Economy.sol:77:27\n   │\n77 │         if (start == 0 || start > block.timestamp) revert NotConfigured();\n   │                           ━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n   ╭▸ src/Economy.sol:90:16\n   │\n90 │         hash = hash * (10000 + EconomyMath.bonus(x.overclock)) / 10000;\n   │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n   ╭▸ src/Economy.sol:91:28\n   │\n91 │         return Math.mulDiv(hash * 4, Math.max(HASH_RATE_FLOOR, rewards().lastYieldPerHash()), 1 ether);\n   │                            ━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[unused-return]: return value of an external call is not used\n   ╭▸ src/FarmEngine.sol:61:30\n   │\n61 │             (, uint256 hi) = params().bounds(k);\n   │                              ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:40:26\n   │\n40 │         return FarmItems(registry.module(3));\n   │                          ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:74:27\n   │\n74 │             f.clocks[i] = items().data(ids[i]).overclock;\n   │                           ━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:126:39\n    │\n126 │             FarmItems.Item memory x = items().data(id);\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/Economy.sol:136:9\n    │\n136 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\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/Economy.sol:149:9\n    │\n149 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:160:35\n    │\n160 │         FarmItems.Item memory x = items().data(id);\n    │                                   ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:44:23\n   │\n44 │         return Params(registry.params());\n   │                       ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:61:30\n   │\n61 │             (, uint256 hi) = params().bounds(k);\n   │                              ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:48:25\n   │\n48 │         return IRewards(registry.module(1));\n   │                         ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:64:25\n   │\n64 │         return active ? rewards().epochParam(e, uint256(k)) : params().get(k);\n   │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:64:63\n   │\n64 │         return active ? rewards().epochParam(e, uint256(k)) : params().get(k);\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/Economy.sol:150:9\n    │\n150 │         emit Locked(msg.sender, amount, block.timestamp + days_ * 1 days, bps);\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/FarmEngine.sol:121:24\n    │\n121 │         if (room >= 4) revert InvalidValue();\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Economy.sol:140:42\n    │\n140 │         locks[msg.sender] = Lock(amount, uint64(block.timestamp), uint64(block.timestamp + days_ * 1 days), uint16(bps));\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/Economy.sol:140:67\n    │\n140 │         locks[msg.sender] = Lock(amount, uint64(block.timestamp), uint64(block.timestamp + days_ * 1 days), uint16(bps));\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/Economy.sol:140:109\n    │\n140 │         locks[msg.sender] = Lock(amount, uint64(block.timestamp), uint64(block.timestamp + days_ * 1 days), uint16(bps));\n    │                                                                                                             ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/Economy.sol:148:13\n    │\n148 │         if (t.balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-no-eth]: external call can be reentered before `locks` is updated\n    ╭▸ src/Economy.sol:156:9\n    │\n156 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:88:39\n   │\n88 │             FarmItems.Item memory x = items().data(ids[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/Economy.sol:167:9\n    │\n167 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\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/Economy.sol:155:30\n    │\n155 │         if (l.amount == 0 || block.timestamp < l.end) 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/Economy.sol:169:9\n    │\n169 │         emit Unlocked(msg.sender, l.amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:168:29\n    │\n168 │         a.baseProductive += raw * tier / 10000;\n    │                             ━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:169:15\n    │\n169 │         raw = raw * (10000 + EconomyMath.bonus(f.clocks[idx])) / 10000;\n    │               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:171:25\n    │\n171 │         s.productive += raw * tier / 10000;\n    │                         ━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmEngine.sol:202:32\n    │\n202 │             if (f.ids[i] != 0) occupied++;\n    │                                ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:159:52\n    │\n159 │         lobbies[d] = Lobby(lobbyAmount(d) + value, uint64(block.timestamp));\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:121:31\n    │\n121 │         Economy eco = Economy(registry.module(10));\n    │                               ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:140:35\n    │\n140 │         stable += 5000 * lobby / (eco.averageDaily() * 5 + lobby);\n    │                                   ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:173:33\n    │\n173 │             outputBonus[e][d] = civic.outputBonus(d);\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/GridOperator.sol:120:21\n    │\n120 │         if (d >= 8) revert InvalidValue();\n    │                     ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:167:20\n    │\n167 │         x.target = uint64(ChainClock.number() + 1);\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/GridOperator.sol:168:21\n    │\n168 │         x.started = 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/Season.sol:67:26\n   │\n67 │         if (rolled[w] || block.timestamp >= claimDeadline(w)) 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/GridOperator.sol:250:9\n    │\n250 │         fees().payWork(keeper, Params.Key.EntropyBounty, 1, startGas - gasleft());\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/GridOperator.sol:210:27\n    │\n210 │             if (old == k) repeated++;\n    │                           ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/GridOperator.sol:209:57\n    │\n209 │             if (old == Kind.Green || old == Kind.Cheap) positives++;\n    │                                                         ━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/GridOperator.sol:225:13\n    │\n225 │             sum += w;\n    │             ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:233:34\n    │\n233 │                     x.district = uint8(d);\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Economy.sol:180:23\n    │\n180 │         previous[p] = prev;\n    │                       ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Economy.sol:191:25\n    │\n191 │         for (uint256 i; i < 10 && p != address(0); ++i) {\n    │                         ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[missing-events-arithmetic]: `otherInflow` is changed without an event but is used in arithmetic\n   ╭▸ src/RewardPool.sol:75:23\n   │\n75 │         if (!endowed) otherInflow += amount;\n   │                       ━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/RewardPool.sol:51:33\n   │\n51 │         if (endowment() == 0 || block.timestamp >= dripStart + dripPeriod) return 0;\n   │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/RewardPool.sol:91:13\n   │\n91 │         if (token().balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/RewardPool.sol:99:9\n   │\n99 │         emit Reserved(amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/RewardPool.sol:107:67\n    │\n107 │     function pay(address to, uint256 amount) external onlyRewards nonReentrant {\n    │                                                                   ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/Season.sol:81:26\n   │\n81 │         if (rolled[w] || block.timestamp < claimDeadline(w)) 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/Season.sol:154:13\n    │\n154 │         if (block.timestamp < launchTime()) 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/Season.sol:161:13\n    │\n161 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Season.sol:202:60\n    │\n202 │         if (districtSpendOf[w][p] > low) topSpenders[w][d][slot] = p;\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/Season.sol:234:13\n    │\n234 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:145:27\n    │\n145 │         o.questionChain = uint32(policyWord);\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/SwarmDesk.sol:146:23\n    │\n146 │         o.fromBlock = uint48(policyWord >> 32);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint48' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:147:21\n    │\n147 │         o.toBlock = uint48(policyWord >> 80);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint48' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:148:22\n    │\n148 │         o.maxPrice = uint96(policyWord >> 128);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint96' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:153:26\n    │\n153 │         b.heartbeatBps = uint16(policyWord >> 224);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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/Season.sol:253:13\n    │\n253 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\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/Season.sol:280:42\n    │\n280 │         if (!rewards().seasonReady(w) || block.timestamp < deadline(w) || limit == 0 || limit > 64) revert TooEarly();\n    │                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:283:20\n    │\n283 │         s.target = uint64(ChainClock.number() + 2);\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/SwarmDesk.sol:252:14\n    │\n252 │           id = ISwarmIntake(config.intake)\n    │ ┏━━━━━━━━━━━━━━┛\n253 │ ┃             .requestWithFailure(\n254 │ ┃                 config.action,\n255 │ ┃                 body,\n    ‡ ┃\n259 │ ┃                 price\n260 │ ┃             );\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/SwarmDesk.sol:246:20\n    │\n246 │                 || block.timestamp < s * _period(stream) + 1 hours\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/SwarmDesk.sol:265:13\n    │\n265 │         if (deadline > end) deadline = end;\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/SwarmDesk.sol:267:9\n    │\n267 │         emit BackupAsked(stream, s, id, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:266:31\n    │\n266 │         pending[id] = Pending(uint64(s), uint64(deadline), stream + 1);\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/SwarmDesk.sol:266:42\n    │\n266 │         pending[id] = Pending(uint64(s), uint64(deadline), stream + 1);\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/Season.sol:328:39\n    │\n328 │             if (s.best != address(0)) rewards().award(s.best, s.prize);\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/Season.sol:329:18\n    │\n329 │             else rewards().releasePrize(s.prize);\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/Season.sol:331:34\n    │\n331 │         if (s.participants != 0) fees().payWork(msg.sender, Params.Key.SeasonBounty, 1, startGas - gasleft());\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/Season.sol:319:25\n    │\n319 │         for (uint256 i; i < 3 && left != 0; ++i) {\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/Season.sol:332:9\n    │\n332 │         emit SeasonFinalized(w, s.winnerDistrict, s.best, s.seed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:315:36\n    │\n315 │                 s.winnerDistrict = uint8(d);\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/Season.sol:338:20\n    │\n338 │         s.target = uint64(ChainClock.number() + 2);\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/SwarmDesk.sol:313:13\n    │\n313 │             a.expiresAt < block.timestamp || uint256(a.issuedAt) + (stream == 0 ? 6 hours : 1 days) < block.timestamp\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/SwarmDesk.sol:313:46\n    │\n313 │             a.expiresAt < block.timestamp || uint256(a.issuedAt) + (stream == 0 ? 6 hours : 1 days) < block.timestamp\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/SwarmDesk.sol:314:31\n    │\n314 │                 || (direct && block.timestamp >= p.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/Season.sol:359:14\n    │\n359 │         id = packs().rewardPack(msg.sender);\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/SwarmDesk.sol:330:13\n    │\n330 │             emit AnswerIgnored(a.requestId, 2);\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/SwarmDesk.sol:334:13\n    │\n334 │             emit AnswerIgnored(a.requestId, 2);\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/SwarmDesk.sol:348:9\n    │\n348 │         emit AnswerStored(stream, a.requestId, s, a.answer);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:346:59\n    │\n346 │             keccak256(a.answer), a.requestId, a.issuedAt, uint64(until), uint64(s), true, uint48(ChainClock.number())\n    │                                                           ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:346:74\n    │\n346 │             keccak256(a.answer), a.requestId, a.issuedAt, uint64(until), uint64(s), true, uint48(ChainClock.number())\n    │                                                                          ━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:346:91\n    │\n346 │             keccak256(a.answer), a.requestId, a.issuedAt, uint64(until), uint64(s), true, uint48(ChainClock.number())\n    │                                                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint48' is safe 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/Season.sol:369:14\n    │\n369 │         id = items().mint(msg.sender, k, r, true);\n    │              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[missing-events-access-control]: `claims` is changed without an event but is used for access control\n   ╭▸ src/StarterClaim.sol:91:9\n   │\n91 │         claims[tokenId] = Claim(msg.sender, target, false);\n   │         ━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `entropyHash` is changed without an event but is used for access control\n    ╭▸ src/StarterClaim.sol:112:9\n    │\n112 │         entropyHash[tokenId] = h;\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `entropyCaptured` is changed without an event but is used for access control\n    ╭▸ src/StarterClaim.sol:113:9\n    │\n113 │         entropyCaptured[tokenId] = true;\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/StarterClaim.sol:47:9\n   │\n47 │         farm().register(msg.sender);\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/StarterClaim.sol:35:13\n   │\n35 │         if (block.timestamp >= freeClaimEnds()) 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/StarterClaim.sol:48:9\n   │\n48 │         emit StarterCommitted(id, msg.sender, ChainClock.number() + 2);\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/StarterClaim.sol:49:9\n   │\n49 │         emit FreePackClaimed(msg.sender, index, id);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StarterClaim.sol:46:40\n   │\n46 │         claims[id] = Claim(msg.sender, uint64(ChainClock.number() + 2), false);\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/StarterClaim.sol:92:9\n   │\n92 │         farm().register(msg.sender);\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/StarterClaim.sol:84:13\n   │\n84 │         if (block.timestamp < launchTime() + 48 hours || block.timestamp >= launchTime() + 16 days) 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/StarterClaim.sol:84:58\n   │\n84 │         if (block.timestamp < launchTime() + 48 hours || block.timestamp >= launchTime() + 16 days) 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/StarterClaim.sol:93:9\n   │\n93 │         emit StarterCommitted(tokenId, msg.sender, target);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StarterClaim.sol:90:25\n   │\n90 │         uint64 target = uint64(ChainClock.number() + 2);\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/StarterClaim.sol:114:9\n    │\n114 │         fees().payWork(keeper, Params.Key.EntropyBounty, 1, startGas - gasleft());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/StarterClaim.sol:130:20\n    │\n130 │         c.target = uint64(ChainClock.number() + 2);\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/StarterClaim.sol:145:13\n    │\n145 │             items().mint(c.player, k, r, true);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/StarterClaim.sol:72:26\n   │\n72 │         return FarmItems(registry.module(3));\n   │                          ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/StarterClaim.sol:145:13\n    │\n145 │             items().mint(c.player, k, r, true);\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/StarterClaim.sol:147:9\n    │\n147 │         emit StarterResolved(tokenId, h == bytes32(0));\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/StarterClaim.sol:145:13\n    │\n145 │             items().mint(c.player, k, r, true);\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/SwarmDesk.sol:365:37\n    │\n365 │         if (p.streamPlusOne == 0 || block.timestamp < p.deadline) revert TooEarly();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:367:35\n    │\n367 │         emit OracleFailure(id, 0, bytes32(\"timeout\"));\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[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:239:39\n    │\n239 │             FarmItems.Item memory x = items().data(id);\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/FarmRewards.sol:151:30\n    │\n151 │         return epoch != 0 && block.timestamp < epochs[epoch].end;\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:244:21\n    │\n244 │                     items().destroy(id);\n    │                     ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:259:13\n    │\n259 │             items().maintain(id, uint16(x.durability > damage ? x.durability - damage : 0), x.overclock);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:295:39\n    │\n295 │             FarmItems.Item memory x = items().data(id);\n    │                                       ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:296:13\n    │\n296 │             items().maintain(id, x.durability > 100 ? x.durability - 100 : 0, x.overclock);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `scrapAllowance` is updated\n    ╭▸ src/FarmRewards.sol:165:13\n    │\n165 │             pool().recycle(scrapAllowance);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:221:32\n    │\n221 │                 f.theftUntil = uint64(e + 2);\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 `epoch` is updated\n    ╭▸ src/FarmRewards.sol:169:13\n    │\n169 │             grid().resolveFor(epoch, msg.sender);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `epoch` is updated\n    ╭▸ src/FarmRewards.sol:179:17\n    │\n179 │                 pool().reserve(old.budget);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `epoch` is updated\n    ╭▸ src/FarmRewards.sol:186:33\n    │\n186 │                 if (prize != 0) season().addPrize(week, prize);\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/FarmRewards.sol:230:9\n    │\n230 │         grid().shift(epoch);\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/FarmRewards.sol:231:9\n    │\n231 │         fees().payBounty(msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmRewards.sol:189:40\n    │\n189 │                     lastAverageDaily = old.mining * (10000 - old.tariff) / 10000 * 4 / activeFarmCount[epoch];\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/FarmRewards.sol:163:13\n    │\n163 │         if (block.timestamp < launchTime() || (epoch != 0 && block.timestamp < epochs[epoch].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/FarmRewards.sol:163:62\n    │\n163 │         if (block.timestamp < launchTime() || (epoch != 0 && block.timestamp < epochs[epoch].end)) revert TooEarly();\n    │                                                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:115:23\n    │\n115 │         return Params(registry.params());\n    │                       ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:226:36\n    │\n226 │             epochParam[epoch][k] = params().get(Params.Key(k));\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/FarmRewards.sol:198:13\n    │\n198 │             emit EpochClosed(epoch, old.budget, old.raw);\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/FarmRewards.sol:209:13\n    │\n209 │             emit Expired(epoch, gone);\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/FarmRewards.sol:232:9\n    │\n232 │         emit EpochStarted(epoch, e.start, e.end, msg.sender);\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/FarmRewards.sol:171:13\n    │\n171 │             (old.kind, old.severity, old.district, old.seed,) = grid().eventAt(epoch);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:202:19\n    │\n202 │         e.start = 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/FarmRewards.sol:203:17\n    │\n203 │         e.end = uint64(block.timestamp + EPOCH);\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/SwarmDesk.sol:405:13\n    │\n405 │             grid.submitPlan(e, GridOperator.Kind(kind), severity, v[5], notice);\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/SwarmDesk.sol:421:13\n    │\n421 │             params.set(k, target, notice);\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/SwarmDesk.sol:426:47\n    │\n426 │             if (civic.noticeAt(feature) == 0) civic.announce(feature, notice);\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/SwarmDesk.sol:430:13\n    │\n430 │             enhancement.announceCap(enhancement.cap() == 8 ? 12 : 16, notice);\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/SwarmDesk.sol:434:17\n    │\n434 │               try civic.grantDistrictBoost(\n    │ ┏━━━━━━━━━━━━━━━━━┛\n435 │ ┃                 _clamp(uint256(v[11]) >> 128, 1, 8) - 1,\n436 │ ┃                 uint16(_clamp(uint256(v[11]) & type(uint128).max, 0, 1500)),\n437 │ ┃                 notice\n438 │ ┃             ) {}\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/SwarmDesk.sol:445:13\n    │\n445 │             packs.unpause();\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/SwarmDesk.sol:447:17\n    │\n447 │             try packs.pause(_clamp(uint256(v[12]) - 1, 1, 72 hours)) {}\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/SwarmDesk.sol:453:17\n    │\n453 │               try civic.startWar(\n    │ ┏━━━━━━━━━━━━━━━━━┛\n454 │ ┃                 uint8(_clamp(uint256(v[13]) >> 128, 1, 8) - 1),\n455 │ ┃                 uint8(_clamp(uint256(v[13]) & type(uint128).max, 1, 8) - 1)\n456 │ ┃             ) {}\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/SwarmDesk.sol:463:17\n    │\n463 │             try civic.startCollapse(_clamp(uint256(v[14]), daily, daily * 100)) {}\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/SwarmDesk.sol:469:17\n    │\n469 │               try civic.listLot(\n    │ ┏━━━━━━━━━━━━━━━━━┛\n470 │ ┃                 uint8(_clamp(uint256(v[15]) >> 16, 1, 12) - 1),\n471 │ ┃                 uint8(_clamp((uint256(v[15]) >> 8) & 255, 1, 3)),\n472 │ ┃                 uint8(_clamp(uint256(v[15]) & 255, 1, 3))\n473 │ ┃             ) {}\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/FarmRewards.sol:309:9\n    │\n309 │         emit MiningStarted(p, epoch, secondsLeft, weighted);\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/SwarmDesk.sol:375:13\n    │\n375 │         if (block.timestamp >= r.validUntil || r.slot != slot(stream)) {\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/SwarmDesk.sol:385:9\n    │\n385 │         emit Executed(stream, r.requestId, letter);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:404:33\n    │\n404 │             if (e <= current || grid.planAt(e).submitted) continue;\n    │                                 ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:405:13\n    │\n405 │             grid.submitPlan(e, GridOperator.Kind(kind), severity, v[5], notice);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:398:22\n    │\n398 │         uint8 kind = uint8(_clamp(uint256(v[2]), 0, maxKind));\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/SwarmDesk.sol:400:27\n    │\n400 │         uint16 severity = uint16(_clamp(uint256(v[3]), SEVERITY_MIN, SEVERITY_MAX));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:401:24\n    │\n401 │         districtHint = uint8(_clamp(uint256(v[4]), 0, 7)); // Advisory only; preserve weighted district/entropy rules.\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/SwarmDesk.sol:420:34\n    │\n420 │             if (target == old || block.timestamp < params.lastChanged(k) + 1 days) continue;\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:417:27\n    │\n417 │             uint256 old = params.get(k);\n    │                           ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:418:40\n    │\n418 │             (uint256 lo, uint256 hi) = params.bounds(k);\n    │                                        ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:420:52\n    │\n420 │             if (target == old || block.timestamp < params.lastChanged(k) + 1 days) continue;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:421:13\n    │\n421 │             params.set(k, target, notice);\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/SwarmDesk.sol:440:17\n    │\n440 │                 emit ActionSkipped(0, reason);\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/SwarmDesk.sol:449:17\n    │\n449 │                 emit ActionSkipped(1, reason);\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/SwarmDesk.sol:458:17\n    │\n458 │                 emit ActionSkipped(2, reason);\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/SwarmDesk.sol:465:17\n    │\n465 │                 emit ActionSkipped(3, reason);\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/SwarmDesk.sol:475:17\n    │\n475 │                 emit ActionSkipped(4, reason);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:436:17\n    │\n436 │                 uint16(_clamp(uint256(v[11]) & type(uint128).max, 0, 1500)),\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:454:17\n    │\n454 │                 uint8(_clamp(uint256(v[13]) >> 128, 1, 8) - 1),\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/SwarmDesk.sol:455:17\n    │\n455 │                 uint8(_clamp(uint256(v[13]) & type(uint128).max, 1, 8) - 1)\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/SwarmDesk.sol:470:17\n    │\n470 │                 uint8(_clamp(uint256(v[15]) >> 16, 1, 12) - 1),\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/SwarmDesk.sol:471:17\n    │\n471 │                 uint8(_clamp((uint256(v[15]) >> 8) & 255, 1, 3)),\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/SwarmDesk.sol:472:17\n    │\n472 │                 uint8(_clamp(uint256(v[15]) & 255, 1, 3))\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmEngine.sol:252:17\n    │\n252 │                 damage += 3000 * uint256(ev.severity) / 10000 / (before_.airflow ? 2 : 1);\n    │                 ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:258:29\n    │\n258 │             f.health[idx] = uint16(f.health[idx] > damage ? f.health[idx] - damage : 0);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:259:34\n    │\n259 │             items().maintain(id, uint16(x.durability > damage ? x.durability - damage : 0), x.overclock);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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/MarketFactory.sol:70:9\n   │\n70 │         emit MarketDeployed(address(market), salt);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:203:24\n    │\n203 │         if (base != 0) fees.depositBaseFee{value: base}();\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:204:26\n    │\n204 │         if (excess != 0) fees.depositSellTax{value: excess}();\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:205:29\n    │\n205 │         if (launchTax != 0) fees.depositLaunchTax{value: launchTax}();\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-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/V4Market.sol:206:9\n    │\n206 │         emit FeesFlushed(base, excess);\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/V4Market.sol:207:29\n    │\n207 │         if (launchTax != 0) emit LaunchTaxFlushed(launchTax);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-events-access-control]: `commits` is changed without an event but is used for access control\n    ╭▸ src/PackSale.sol:254:9\n    │\n254 │         c.seed = keccak256(abi.encode(h, address(this), id));\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/PackSale.sol:62:16\n   │\n62 │         return block.timestamp < pausedUntil;\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/PackSale.sol:68:13\n   │\n68 │         if (block.timestamp < nextPauseAt) 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/PackSale.sol:117:16\n    │\n117 │         return block.timestamp >= opensAt() && !paused();\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/PackSale.sol:144:13\n    │\n144 │         p = Economy(registry.module(10)).averageDaily() * daysPrice / 1 ether;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/PackSale.sol:130:27\n    │\n130 │         uint256 elapsed = block.timestamp > opensAt() ? block.timestamp - opensAt() : 0;\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:132:24\n    │\n132 │         int256 ahead = int256(sales * 1 ether) - int256(elapsed * target * 1 ether / 1 hours);\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/PackSale.sol:132:50\n    │\n132 │         int256 ahead = int256(sales * 1 ether) - int256(elapsed * target * 1 ether / 1 hours);\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/PackSale.sol:135:30\n    │\n135 │             exponent = wadLn(int256(1 ether + params().get(Params.Key.PriceStepBps) * 1e14)) * ahead / 1 ether;\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/PackSale.sol:137:30\n    │\n137 │             exponent = wadLn(int256(1 ether - decay * 1e14)) * (-ahead) / int256(target) / 1 ether;\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/PackSale.sol:137:75\n    │\n137 │             exponent = wadLn(int256(1 ether - decay * 1e14)) * (-ahead) / int256(target) / 1 ether;\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/PackSale.sol:141:37\n    │\n141 │         uint256 daysPrice = start * uint256(wadExp(exponent)) / 1 ether;\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/PackSale.sol:111:28\n    │\n111 │         return ILaunchHook(registry.market()).initializedAt() == 0\n    │                            ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:111:16\n    │\n111 │         return ILaunchHook(registry.market()).initializedAt() == 0\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:113:27\n    │\n113 │             : ILaunchHook(registry.market()).initializedAt() + OPEN_DELAY;\n    │                           ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:113:15\n    │\n113 │             : ILaunchHook(registry.market()).initializedAt() + OPEN_DELAY;\n    │               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:91:23\n   │\n91 │         return Params(registry.params());\n   │                       ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:135:47\n    │\n135 │             exponent = wadLn(int256(1 ether + params().get(Params.Key.PriceStepBps) * 1e14)) * ahead / 1 ether;\n    │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:144:21\n    │\n144 │         p = Economy(registry.module(10)).averageDaily() * daysPrice / 1 ether;\n    │                     ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:144:13\n    │\n144 │         p = Economy(registry.module(10)).averageDaily() * daysPrice / 1 ether;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:52:33\n   │\n52 │         uint256 daily = Economy(registry.module(10)).averageDaily();\n   │                                 ━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:52:25\n   │\n52 │         uint256 daily = Economy(registry.module(10)).averageDaily();\n   │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/PackSale.sol:47:9\n   │\n47 │         revert InvalidValue();\n   │         ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmRewards.sol:350:25\n    │\n350 │         for (uint256 n; n < limit && cursor < settledEpoch; ++n) {\n    │                         ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:123:22\n    │\n123 │         return ICore(registry.module(2));\n    │                      ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:359:60\n    │\n359 │         (uint256 raw, uint256 productive, uint256 power) = core().process(p, id);\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:139:16\n    │\n139 │         return registry.launchTime();\n    │                ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:425:9\n    │\n425 │         core().autoRepair(p, id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:119:27\n    │\n119 │         return RewardPool(registry.module(0));\n    │                           ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:446:26\n    │\n446 │         if (unused != 0) pool().recycle(unused);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:449:28\n    │\n449 │             if (dust != 0) pool().recycle(dust);\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:431:13\n    │\n431 │             core().activity(p, id, o.gross, o.net);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:433:17\n    │\n433 │                 core().grantDrop(p, keccak256(abi.encode(e.seed, p, \"item\")));\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:135:24\n    │\n135 │         return ISeason(registry.module(8));\n    │                        ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:435:13\n    │\n435 │             season().recordActivity(p, week, o.gross, weight);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:380:13\n    │\n380 │             season().complete(p, week);\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/FarmRewards.sol:477:13\n    │\n477 │             emit Credited(p, e, 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/FarmRewards.sol:488:9\n    │\n488 │         emit Credited(p, e, 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/FarmRewards.sol:450:13\n    │\n450 │             emit EpochSettled(id, e.spent, dust);\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/FarmRewards.sol:422:35\n    │\n422 │         if (spent > o.allocation) revert InvalidValue();\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/FarmRewards.sol:475:13\n    │\n475 │         if (block.timestamp >= at + 7 days) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:485:19\n    │\n485 │         v.epoch = uint64(e);\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/FarmRewards.sol:486:48\n    │\n486 │         if (at > v.at || v.amount == 0) v.at = uint64(at);\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/FarmRewards.sol:514:25\n    │\n514 │         for (uint256 n; n < 32 && amount != 0; ++n) {\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/FarmRewards.sol:503:36\n    │\n503 │             if (old.amount != 0 && block.timestamp >= uint256(old.at) + 7 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/FarmRewards.sol:520:45\n    │\n520 │             if (taxed) tax += used * taxBps(block.timestamp > v.at ? block.timestamp - v.at : 0) / 10000;\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/V4Market.sol:262:13\n    │\n262 │             emit PriceObserved(now_, price);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/V4Market.sol:275:9\n    │\n275 │         emit PriceObserved(now_, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/V4Market.sol:269:38\n    │\n269 │             uint256 c = cumulative + (1e60 / lastPrice) * (minute * 60 - updatedAt);\n    │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/V4Market.sol:272:23\n    │\n272 │         cumulative += (1e60 / lastPrice) * (now_ - updatedAt);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/V4Market.sol:267:13\n    │\n267 │         if (last >= 32 && first < last - 31) first = last - 31;\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/V4Market.sol:267:27\n    │\n267 │         if (last >= 32 && first < last - 31) first = last - 31;\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/V4Market.sol:268:38\n    │\n268 │         for (uint256 minute = first; minute <= last; ++minute) {\n    │                                      ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:270:53\n    │\n270 │             observations[minute % 32] = Observation(uint64(minute), c);\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[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/V4Market.sol:281:50\n    │\n281 │         if (ts >= updatedAt) return cumulative + (1e60 / lastPrice) * (ts - updatedAt);\n    │                                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/V4Market.sol:288:35\n    │\n288 │         if (initializedAt == 0 || block.timestamp < initializedAt + 31 minutes) revert NotConfigured();\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/V4Market.sol:304:13\n    │\n304 │         if (a.period != p) {\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/V4Market.sol:310:13\n    │\n310 │         if (b.period != p) {\n    │             ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:306:24\n    │\n306 │             a.period = uint64(p);\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/V4Market.sol:312:24\n    │\n312 │             b.period = uint64(p);\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/V4Market.sol:315:24\n    │\n315 │             a.sells += uint192(amount);\n    │                        ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:316:24\n    │\n316 │             b.sells += uint192(amount);\n    │                        ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:318:23\n    │\n318 │             a.buys += uint192(amount);\n    │                       ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:319:23\n    │\n319 │             b.buys += uint192(amount);\n    │                       ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe 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/V4Market.sol:330:17\n    │\n330 │                 b += shortVolumes[i].buys;\n    │                 ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/V4Market.sol:329:17\n    │\n329 │                 s += shortVolumes[i].sells;\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/V4Market.sol:328:17\n    │\n328 │             if (uint256(shortVolumes[i].period) + 12 > current) {\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/V4Market.sol:338:17\n    │\n338 │             if (uint256(longVolumes[i].period) + 24 > current) {\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/V4Market.sol:394:13\n    │\n394 │         if (average != 0 && price > average) dev = Math.min(1000, 10000 - Math.mulDiv(average, 10000, price));\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/V4Market.sol:393:13\n    │\n393 │         if (block.timestamp >= initializedAt + 31 minutes) average = twap();\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/V4Market.sol:399:27\n    │\n399 │         uint256 decayed = storedFeeWad > fall ? storedFeeWad - fall : PROJECT_BPS * 1 ether;\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/V4Market.sol:420:13\n    │\n420 │             emit LaunchTax(sender, ethIn, taxBps, fee);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:413:25\n    │\n413 │         uint256 ethIn = uint256(-p.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/V4Market.sol:416:19\n    │\n416 │         if (fee > uint256(uint128(type(int128).max))) revert InvalidValue();\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/V4Market.sol:416:27\n    │\n416 │         if (fee > uint256(uint128(type(int128).max))) revert InvalidValue();\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/V4Market.sol:425:43\n    │\n425 │         return (this.beforeSwap.selector, int256(fee << 128), 0);\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/V4Market.sol:454:9\n    │\n454 │         emit SellFee(sender, output, bps, hour, day, dev);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:436:27\n    │\n436 │         int128 ethDelta = int128(delta >> 128);\n    │                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:439:28\n    │\n439 │             _record(false, uint256(-int256(ethDelta)));\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/V4Market.sol:443:26\n    │\n443 │         uint256 output = uint256(uint128(ethDelta));\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/V4Market.sol:443:34\n    │\n443 │         uint256 output = uint256(uint128(ethDelta));\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/V4Market.sol:445:42\n    │\n445 │         return (this.afterSwap.selector, int128(int256(_chargeSell(sender, output, price))));\n    │                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:445:49\n    │\n445 │         return (this.afterSwap.selector, int128(int256(_chargeSell(sender, output, price))));\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/FarmRewards.sol:359:60\n    │\n359 │         (uint256 raw, uint256 productive, uint256 power) = core().process(p, id);\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/FarmRewards.sol:380:13\n    │\n380 │             season().complete(p, week);\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/FarmRewards.sol:425:9\n    │\n425 │         core().autoRepair(p, id);\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/FarmRewards.sol:431:13\n    │\n431 │             core().activity(p, id, o.gross, o.net);\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/FarmRewards.sol:433:17\n    │\n433 │                 core().grantDrop(p, keccak256(abi.encode(e.seed, p, \"item\")));\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/FarmRewards.sol:435:13\n    │\n435 │             season().recordActivity(p, week, o.gross, weight);\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/FarmRewards.sol:446:26\n    │\n446 │         if (unused != 0) pool().recycle(unused);\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/FarmRewards.sol:449:28\n    │\n449 │             if (dust != 0) pool().recycle(dust);\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/FarmRewards.sol:533:9\n    │\n533 │         pool().pay(msg.sender, net);\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/FarmRewards.sol:293:9\n    │\n293 │         emit Committed(p, weight, epoch + 1, expiry);\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/FarmRewards.sol:534:9\n    │\n534 │         emit Claimed(msg.sender, amount, tax);\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/FarmRewards.sol:542:9\n    │\n542 │         emit Spent(p, consumed);\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/FeeRouter.sol:172:9\n    │\n172 │         RewardPool(rewardPool()).recordInflow(reward);\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/FeeRouter.sol:173:9\n    │\n173 │         emit TokensRouted(reward, t, h);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/FeeRouter.sol:181:9\n    │\n181 │         market().buy{value: msg.value}(minOut, recipient);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-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/FarmRewards.sol:553:9\n    │\n553 │         emit Spent(p, amount);\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/FeeRouter.sol:181:9\n    │\n181 │         market().buy{value: msg.value}(minOut, recipient);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/FarmRewards.sol:556:80\n    │\n556 │     function scrap(address p, uint256 hash, uint256 minimum) external onlyCore nonReentrant returns (uint256 amount) {\n    │                                                                                ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[reentrancy-no-eth]: external call can be reentered before `heartbeatTokens` is updated\n    ╭▸ src/FeeRouter.sol:199:13\n    │\n199 │             RewardPool(rewardPool()).recordInflow(excess);\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/FarmRewards.sol:570:9\n    │\n570 │         pool().recycle(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-balance]: external call can be reentered before a stale contract balance is checked\n    ╭▸ src/FeeRouter.sol:214:9\n    │\n214 │         m.sell(amount, minOut, address(this));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-balance\n\nwarning[boolean-cst]: misuse of a boolean constant\n   ╭▸ src/Enhancement.sol:55:63\n   │\n55 │             (cap == 8 ? next != 12 : cap == 12 ? next != 16 : true) || announcedCap != 0 || bytes(letter).length == 0\n   │                                                               ━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[reentrancy-no-eth]: external call can be reentered before `heartbeatBalance` is updated\n    ╭▸ src/FeeRouter.sol:214:9\n    │\n214 │         m.sell(amount, minOut, address(this));\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/V4Market.sol:472:31\n    │\n472 │         received = abi.decode(manager.unlock(abi.encode(msg.value, minOut, recipient)), (uint256));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FeeRouter.sol:219:22\n    │\n219 │         uint256 hb = received * h / amount;\n    │                      ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/FeeRouter.sol:194:30\n    │\n194 │         if (lastSell != 0 && block.timestamp < lastSell + 5 minutes) 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/FeeRouter.sol:224:9\n    │\n224 │         emit TokensSold(amount, 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/FeeRouter.sol:214:9\n    │\n214 │         m.sell(amount, minOut, address(this));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/FeeRouter.sol:236:9\n    │\n236 │         market().buy{value: amount}(minOut, season());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/Enhancement.sol:66:34\n   │\n66 │         if (announcedCap == 0 || block.timestamp < activationAt) 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/FeeRouter.sol:239:9\n    │\n239 │         IPotSeason(season()).depositPot(received);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `pending` is updated\n   ╭▸ src/Enhancement.sol:85:9\n   │\n85 │         core.prepareEnhancement(msg.sender, item, cost, wallet);\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/FeeRouter.sol:229:29\n    │\n229 │         if (lastBuy != 0 && block.timestamp < lastBuy + 5 minutes) 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/FeeRouter.sol:240:9\n    │\n240 │         emit PotBought(amount, received);\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/Enhancement.sol:89:9\n   │\n89 │         emit EnhancementCommitted(id, msg.sender, item, target, ChainClock.number() + 2, cost);\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/FeeRouter.sol:236:9\n    │\n236 │         market().buy{value: amount}(minOut, season());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/Enhancement.sol:88:50\n   │\n88 │         attempts[id] = Attempt(msg.sender, item, uint64(ChainClock.number() + 2), target, bytes32(0), false, false);\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/Enhancement.sol:100:24\n    │\n100 │             a.target = uint64(ChainClock.number() + 2);\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/Enhancement.sol:122:21\n    │\n122 │         if (burned) inventory.destroy(a.item);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-eth]: uncapped ETH transfer can be reentered before `_status` is updated\n    ╭▸ src/FeeRouter.sol:281:22\n    │\n281 │         (bool ok,) = msg.sender.call{value: a}(\"\");\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/Enhancement.sol:123:14\n    │\n123 │         else inventory.maintain(a.item, x.durability, level);\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/FeeRouter.sol:283:9\n    │\n283 │         emit Withdrawn(msg.sender, a);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/FeeRouter.sol:302:9\n    │\n302 │         market().buy{value: ethAmount}(minOut, rewardPool());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-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/Enhancement.sol:124:9\n    │\n124 │         emit EnhancementResolved(id, success, burned, level);\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/FeeRouter.sol:305:50\n    │\n305 │         if (!RewardPool(rewardPool()).endowed()) RewardPool(rewardPool()).recordInflow(received);\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/StandardAdapter.sol:46:64\n   │\n46 │         if (rate == 0 || rate > 1e40 || window < 30 minutes || at > block.timestamp || block.timestamp - at > 5 minutes)\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/FeeRouter.sol:293:29\n    │\n293 │         if (lastBuy != 0 && block.timestamp < lastBuy + MIN_BUY_INTERVAL) 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/StandardAdapter.sol:46:88\n   │\n46 │         if (rate == 0 || rate > 1e40 || window < 30 minutes || at > block.timestamp || block.timestamp - at > 5 minutes)\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/FeeRouter.sol:309:9\n    │\n309 │         emit WorkBounty(msg.sender, Params.Key.BuyBounty, ethAmount, paid);\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/FeeRouter.sol:310:9\n    │\n310 │         emit Bought(ethAmount, 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/FeeRouter.sol:302:9\n    │\n302 │         market().buy{value: ethAmount}(minOut, rewardPool());\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/StandardAdapter.sol:58:9\n   │\n58 │         manager.unlock(abi.encode(msg.value, minOut, recipient));\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unused-return]: return value of an external call is not used\n   ╭▸ src/StandardAdapter.sol:58:9\n   │\n58 │         manager.unlock(abi.encode(msg.value, minOut, recipient));\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:67:62\n   │\n67 │         int256 delta = manager.swap(key(), SwapParams(true, -int256(input), 4295128740), \"\");\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/StandardAdapter.sol:68:27\n   │\n68 │         int128 ethDelta = int128(delta >> 128);\n   │                           ━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'int128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:69:22\n   │\n69 │         int128 out = int128(delta);\n   │                      ━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'int128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:70:30\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\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/StandardAdapter.sol:70:81\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\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/StandardAdapter.sol:70:89\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\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/StandardAdapter.sol:73:9\n   │\n73 │         manager.settle{value: input}();\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:74:49\n   │\n74 │         manager.take(address(token), recipient, uint256(uint128(out)));\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/StandardAdapter.sol:74:57\n   │\n74 │         manager.take(address(token), recipient, uint256(uint128(out)));\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/StandardAdapter.sol:75:27\n   │\n75 │         return abi.encode(uint256(uint128(out)));\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/StandardAdapter.sol:75:35\n   │\n75 │         return abi.encode(uint256(uint128(out)));\n   │                                   ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/V4Market.sol:498:31\n    │\n498 │         received = abi.decode(manager.unlock(abi.encode(amount, minOut, recipient)), (uint256));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:522:22\n    │\n522 │         (bool ok,) = recipient.call{value: net}(\"\");\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/PackSale.sol:182:28\n    │\n182 │         uint256 received = fees().zapBuy{value: msg.value}(minTokens, address(this));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:506:39\n    │\n506 │             key(), SwapParams(false, -int256(amount), 1461446703485210103287273052203988822378723970341), \"\"\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/V4Market.sol:509:25\n    │\n509 │         int128 ethOut = int128(delta >> 128);\n    │                         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:510:26\n    │\n510 │         int128 tokenIn = int128(delta);\n    │                          ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:511:44\n    │\n511 │         if (ethOut <= 0 || tokenIn >= 0 || uint256(-int256(tokenIn)) != amount) revert InsufficientBalance();\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/V4Market.sol:512:25\n    │\n512 │         uint256 gross = uint256(uint128(ethOut));\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/V4Market.sol:512:33\n    │\n512 │         uint256 gross = uint256(uint128(ethOut));\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/V4Market.sol:518:9\n    │\n518 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/Billboards.sol:60:13\n   │\n60 │         if (t.balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/Billboards.sol:82:17\n   │\n82 │                 revert InvalidValue();\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/Billboards.sol:88:17\n   │\n88 │                 revert InvalidValue();\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/Billboards.sol:70:9\n   │\n70 │         RewardPool(pool).donate(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/Billboards.sol:120:9\n    │\n120 │         emit BillboardSettled(w, d, b.bid);\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/Params.sol:176:13\n    │\n176 │         if (block.timestamp < lastChanged[k] + 1 days) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `updatedAt` is updated\n    ╭▸ src/V4Market.sol:505:24\n    │\n505 │           int256 delta = manager.swap(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━━━━┛\n506 │ ┃             key(), SwapParams(false, -int256(amount), 1461446703485210103287273052203988822378723970341), \"\"\n507 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:287:9\n    │\n287 │         f.serial = nextSerial++;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `purchasedRoom` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:107:9\n    │\n107 │         purchasedRoom[msg.sender][room] = true;\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:241:9\n    │\n241 │         f.paidXpToday += amount;\n    │         ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[reentrancy-no-eth]: external call can be reentered before `updatedAt` is updated\n    ╭▸ src/V4Market.sol:535:24\n    │\n535 │         int256 delta = manager.swap(key(), SwapParams(true, -int256(input), 4295128740), \"\");\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:535:62\n    │\n535 │         int256 delta = manager.swap(key(), SwapParams(true, -int256(input), 4295128740), \"\");\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/V4Market.sol:537:27\n    │\n537 │         int128 ethDelta = int128(delta >> 128);\n    │                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:538:29\n    │\n538 │         int128 tokenDelta = int128(delta);\n    │                             ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe 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]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:312:9\n    │\n312 │         f.active = f.loadout;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:559:9\n    │\n559 │         farms[p].xp += 100;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:540:30\n    │\n540 │             ethDelta >= 0 || uint256(-int256(ethDelta)) != input || tokenDelta <= 0\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/V4Market.sol:541:20\n    │\n541 │                 || uint256(uint128(tokenDelta)) < minOut\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/V4Market.sol:541:28\n    │\n541 │                 || uint256(uint128(tokenDelta)) < minOut\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/V4Market.sol:546:9\n    │\n546 │         manager.settle{value: input}();\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:547:40\n    │\n547 │         manager.take(token, recipient, uint256(uint128(tokenDelta)));\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/V4Market.sol:547:48\n    │\n547 │         manager.take(token, recipient, uint256(uint128(tokenDelta)));\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/V4Market.sol:549:27\n    │\n549 │         return abi.encode(uint256(uint128(tokenDelta)));\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/V4Market.sol:549:35\n    │\n549 │         return abi.encode(uint256(uint128(tokenDelta)));\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 `farms` is updated\n    ╭▸ src/FarmCore.sol:288:9\n    │\n288 │         rewards().initialize(p);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:295:13\n    │\n295 │         if (rewards().settle(p, 8) < rewards().settledEpoch()) revert CatchUpRequired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:301:9\n    │\n301 │ ┏         rewards()\n302 │ ┃             .setWeight(\n303 │ ┃                 p,\n304 │ ┃                 engine().allocationHash(farms[p].loadout, farms[p].paid != 0) * (10000 + _boost(p, block.timestamp))\n305 │ ┃                     / 10000\n306 │ ┃             );\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/FarmCore.sol:92:9\n   │\n92 │         season().recordSpend(p, cost, true);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/Civic.sol:61:13\n   │\n61 │         if (t.balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/Civic.sol:84:82\n   │\n84 │         if (feature >= FEATURES || noticeAt[feature] == 0 || enabled[feature] || block.timestamp < noticeAt[feature]) {\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/Civic.sol:103:17\n    │\n103 │         return (block.timestamp < boostUntil[d] ? seasonBoost[d] : 0) + (block.timestamp < warBoostUntil[d] ? 1000 : 0);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Civic.sol:103:74\n    │\n103 │         return (block.timestamp < boostUntil[d] ? seasonBoost[d] : 0) + (block.timestamp < warBoostUntil[d] ? 1000 : 0);\n    │                                                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Civic.sol:137:13\n    │\n137 │             uint64(block.timestamp + 48 hours),\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/FarmCore.sol:288:9\n    │\n288 │         rewards().initialize(p);\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/FarmCore.sol:295:13\n    │\n295 │         if (rewards().settle(p, 8) < rewards().settledEpoch()) revert CatchUpRequired();\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/FarmCore.sol:301:9\n    │\n301 │ ┏         rewards()\n302 │ ┃             .setWeight(\n303 │ ┃                 p,\n304 │ ┃                 engine().allocationHash(farms[p].loadout, farms[p].paid != 0) * (10000 + _boost(p, block.timestamp))\n305 │ ┃                     / 10000\n306 │ ┃             );\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/Civic.sol:173:66\n    │\n173 │         if (!found && contribution[warId][msg.sender] > low) top[slot] = msg.sender;\n    │                                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Civic.sol:173:14\n    │\n173 │         if (!found && contribution[warId][msg.sender] > low) top[slot] = 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/Civic.sol:152:42\n    │\n152 │         if (!enabled[0] || warId == 0 || block.timestamp >= w.end || w.settled || (d != w.a && d != w.b)) {\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/Civic.sol:71:9\n   │\n71 │         RewardPool(pool).donate(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/Civic.sol:192:40\n    │\n192 │         if (warId == 0 || w.settled || block.timestamp < w.end) 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/Civic.sol:202:9\n    │\n202 │         emit WarFinished(warId, w.winner, w.payout, toPool);\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/Civic.sol:228:67\n    │\n228 │             !enabled[1] || !collapseFinalized || outagePending || block.timestamp < greenUntil\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/Civic.sol:239:34\n    │\n239 │         if (collapseFinalized || block.timestamp >= collapseEnd) 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/Civic.sol:243:9\n    │\n243 │         emit CollapseFunded(msg.sender, amount);\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/Civic.sol:247:34\n    │\n247 │         if (collapseFinalized || block.timestamp < collapseEnd) 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/Civic.sol:261:13\n    │\n261 │         if (block.timestamp < greenUntil) return 1;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `purchasedRoom` is updated\n    ╭▸ src/FarmCore.sol:432:13\n    │\n432 │             RewardPool(pool()).recordInflow(paid);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `purchasedRoom` is updated\n    ╭▸ src/FarmCore.sol:434:20\n    │\n434 │             paid = rewards().spend(p, nominal);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `purchasedRoom` is updated\n    ╭▸ src/FarmCore.sol:437:9\n    │\n437 │         season().recordSpend(p, paid, kind == 0 || kind == 3 || kind == 4);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Civic.sol:280:48\n    │\n280 │         lots[w] = Lot(kind, rarity, supply, 0, uint64(block.timestamp));\n    │                                                ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/PackSale.sol:199:9\n    │\n199 │         farm().register(recipient);\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/PackSale.sol:200:9\n    │\n200 │         farm().paidPackBought(recipient, n, cost);\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/PackSale.sol:207:9\n    │\n207 │         fees().routeTokens(cost);\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/Civic.sol:298:9\n    │\n298 │         ICore(registry.module(2)).civicPurchase(msg.sender, cost);\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/Civic.sol:299:14\n    │\n299 │         id = FarmItems(registry.module(3)).mint(msg.sender, l.kind, l.rarity, false);\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/FarmCore.sol:438:9\n    │\n438 │         emit Spent(p, kind, paid, nominal);\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/FarmCore.sol:108:9\n    │\n108 │         emit RoomPurchased(msg.sender, room, price);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/Civic.sol:300:9\n    │\n300 │         emit LotBought(w, msg.sender, id, cost);\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/FarmCore.sol:116:9\n    │\n116 │         emit AutoRepairSet(msg.sender, autoRepairThreshold[msg.sender]);\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/PackSale.sol:234:9\n    │\n234 │         emit PackCommitted(id, p, n, target, guaranteed);\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/FarmCore.sol:127:13\n    │\n127 │             emit Spent(p, 0, paid, paid);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/PackSale.sol:206:13\n    │\n206 │         if (t.balanceOf(address(fees())) - before_ != cost) revert InvalidValue();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/PackSale.sol:212:25\n    │\n212 │         if (paused() || block.timestamp < opensAt()) revert TooEarly();\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:232:25\n    │\n232 │         uint64 target = uint64(ChainClock.number() + 2);\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/PackSale.sol:256:9\n    │\n256 │         fees().payWork(keeper, Params.Key.EntropyBounty, 1, startGas - gasleft());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:270:20\n    │\n270 │         c.target = uint64(ChainClock.number() + 2);\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/FarmCore.sol:432:13\n    │\n432 │             RewardPool(pool()).recordInflow(paid);\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/FarmCore.sol:434:20\n    │\n434 │             paid = rewards().spend(p, nominal);\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/FarmCore.sol:437:9\n    │\n437 │         season().recordSpend(p, paid, kind == 0 || kind == 3 || kind == 4);\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/PackSale.sol:289:13\n    │\n289 │             items().mint(c.player, k, r, c.guaranteed);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:87:26\n   │\n87 │         return FarmItems(registry.module(3));\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/FarmCore.sol:218:36\n    │\n218 │         uint256 age = born == 0 || block.timestamp < born ? 0 : block.timestamp - born;\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:289:13\n    │\n289 │             items().mint(c.player, k, r, c.guaranteed);\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/FarmCore.sol:219:13\n    │\n219 │         if (age >= 5 days) return 10;\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/FarmCore.sol:220:13\n    │\n220 │         if (age >= 3 days) return 9;\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/FarmCore.sol:221:13\n    │\n221 │         if (age >= 1 days) return 6;\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/PackSale.sol:291:9\n    │\n291 │         emit PackOpened(id, n, c.expired);\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/FarmCore.sol:228:13\n    │\n228 │         if (f.paidXpDay != block.timestamp / 1 days) return PAID_XP_PER_DAY;\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/PackSale.sol:289:13\n    │\n289 │             items().mint(c.player, k, r, c.guaranteed);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:234:24\n    │\n234 │         uint64 today = uint64(block.timestamp / 1 days);\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/FarmCore.sol:261:53\n    │\n261 │         if (room == 1) return farms[p].born != 0 && block.timestamp >= farms[p].born + 3 days;\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/FarmCore.sol:289:9\n    │\n289 │         emit Registered(p, district(p));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:286:18\n    │\n286 │         f.born = uint64(block.timestamp);\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:146:26\n    │\n146 │         return FarmItems(registry.module(3));\n    │                          ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:320:39\n    │\n320 │             FarmItems.Item memory x = items().data(f.active[i]);\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:313:25\n    │\n313 │         f.activeEpoch = uint64(e);\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/FarmCore.sol:315:25\n    │\n315 │         f.activeBoost = uint16(_boost(p, rewards().epochTime(e)));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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/FarmCore.sol:332:9\n    │\n332 │         rewards().recordSales(n);\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/FarmCore.sol:333:9\n    │\n333 │         season().recordSpend(p, ethValue, true);\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/FarmCore.sol:344:9\n    │\n344 │         rewards().setReferrer(msg.sender, inviter);\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/FarmCore.sol:373:9\n    │\n373 │         items().equip(msg.sender, id);\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/FarmCore.sol:375:13\n    │\n375 │           if (rewards()\n    │ ┏━━━━━━━━━━━━━┛\n376 │ ┃                 .beginMining(\n377 │ ┃                     msg.sender,\n378 │ ┃                     engine().allocationHash(f.loadout, f.paid != 0) * (10000 + _boost(msg.sender, block.timestamp))\n379 │ ┃                         / 10000\n380 │ ┃                 )) {\n    │ ┗━━━━━━━━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:366:29\n    │\n366 │             if (old != 0 && items().data(old).kind == x.kind) revert InvalidValue();\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/FarmCore.sol:385:9\n    │\n385 │         emit Placed(msg.sender, id, room, slot);\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/FarmCore.sol:366:63\n    │\n366 │             if (old != 0 && items().data(old).kind == x.kind) revert InvalidValue();\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:395:9\n    │\n395 │         items().unequip(msg.sender, id);\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/FarmCore.sol:397:9\n    │\n397 │         emit Unplaced(msg.sender, id, room, slot);\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/FarmCore.sol:414:9\n    │\n414 │         emit Retired(p);\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/FarmCore.sol:405:56\n    │\n405 │             if (f.loadout[i] != 0 || f.active[i] != 0) revert InvalidValue();\n    │                                                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[arbitrary-send-erc20]: `transferFrom` uses an arbitrary `from`; require it to equal `msg.sender` or `address(this)`\n    ╭▸ src/FarmCore.sol:430:13\n    │\n430 │             token().safeTransferFrom(p, pool(), paid);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-erc20\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/FarmCore.sol:431:17\n    │\n431 │             if (token().balanceOf(pool()) - before_ != paid) revert InvalidValue();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:447:9\n    │\n447 │         items().maintain(id, 10000, x.overclock);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:456:32\n    │\n456 │         f.cableRepairedEpoch = uint64(rewards().epoch());\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/FarmCore.sol:457:29\n    │\n457 │         f.routerRepairBps = uint16((rewards().epochEnd() - block.timestamp) * 10000 / 6 hours);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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/FarmCore.sol:470:9\n    │\n470 │         items().expand(msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:492:13\n    │\n492 │             rewards().spendTo(p, amount, router);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:494:9\n    │\n494 │         FeeRouter(payable(router)).routeTokens(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/FarmCore.sol:480:9\n    │\n480 │         rewards().recordSales(1);\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/FarmCore.sol:481:9\n    │\n481 │         season().recordSpend(msg.sender, price, true);\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/FarmCore.sol:482:14\n    │\n482 │         id = ITokenPacks(packs()).tokenPack(msg.sender);\n    │              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/FarmCore.sol:490:17\n    │\n490 │             if (token().balanceOf(router) - before_ != amount) revert InvalidValue();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:492:13\n    │\n492 │             rewards().spendTo(p, amount, router);\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/FarmCore.sol:494:9\n    │\n494 │         FeeRouter(payable(router)).routeTokens(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/FarmCore.sol:501:9\n    │\n501 │         season().recordSpend(msg.sender, amount, true);\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/FarmCore.sol:502:9\n    │\n502 │         grid().tokenLobby(msg.sender, 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/FarmCore.sol:513:9\n    │\n513 │         items().destroy(id);\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/FarmCore.sol:514:26\n    │\n514 │         uint256 earned = rewards().scrap(msg.sender, hash, minimum);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmCore.sol:512:24\n    │\n512 │         uint256 hash = ItemMath.baseHash(x.rarity) * (x.kind < 3 ? 10000 : 6000) / 10000 * x.durability / 10000;\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/FarmCore.sol:515:9\n    │\n515 │         emit Scrapped(msg.sender, id, earned);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmCore.sol:535:14\n    │\n535 │         if (!occupied) return (0, 0, 0);\n    │              ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:546:28\n    │\n546 │             if (id != 0 && items().data(id).holder == address(0)) _remove(f, id);\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/FarmCore.sol:578:14\n    │\n578 │         id = items().mintDrop(msg.sender, seed);\n    │              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/EconomyV35.t.sol:152:43\n    │\n152 │         assertEq(d.economy.boostAt(alice, block.timestamp), 500);\n    │                                           ━━━━━━━━━━━━━━━\n    ‡\n156 │         vm.warp(block.timestamp + 7 days);\n    │         ───────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/EconomyV35.t.sol:156:17\n    │\n156 │         vm.warp(block.timestamp + 7 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PhasedReleaseV36.t.sol:145:49\n    │\n145 │         assertEq(d.civic.noticeAt(ENHANCEMENT), block.timestamp + 48 hours);\n    │                                                 ━━━━━━━━━━━━━━━\n146 │         vm.warp(block.timestamp + 48 hours - 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/PhasedReleaseV36.t.sol:146:17\n    │\n146 │         vm.warp(block.timestamp + 48 hours - 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/SwarmDeskV37.t.sol:210:17\n    │\n210 │         vm.warp(block.timestamp + 1 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:67:29\n    │\n 67 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n227 │         vm.warp(d.civic.noticeAt(3));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:68:30\n    │\n 68 │         a.expiresAt = uint64(block.timestamp + 6 hours);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n227 │         vm.warp(d.civic.noticeAt(3));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:220:39\n    │\n220 │         assertEq(d.civic.noticeAt(3), block.timestamp + 48 hours);\n    │                                       ━━━━━━━━━━━━━━━\n    ‡\n227 │         vm.warp(d.civic.noticeAt(3));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:283:17\n    │\n283 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:67:29\n    │\n 67 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n336 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:68:30\n    │\n 68 │         a.expiresAt = uint64(block.timestamp + 6 hours);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n336 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:336:17\n    │\n336 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:606:17\n    │\n606 │         vm.warp(block.timestamp + 2 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:631:17\n    │\n631 │         vm.warp(block.timestamp + 2 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/V34.t.sol:149:25\n    │\n149 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n152 │         vm.warp(start + 60 minutes - 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/V34.t.sol:230:17\n    │\n230 │         vm.warp(block.timestamp + 5 minutes - 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/V34.t.sol:233:17\n    │\n233 │         vm.warp(block.timestamp + 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/fork/RehearsalV311.t.sol:630:18\n    │\n630 │         vm.warp((block.timestamp / 6 hours) * 6 hours + 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":52557,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/Clock.t.sol:ClockTest\n[PASS] testLocalEvmFutureBlockAnd256BlockBoundary() (gas: 225376)\n[PASS] testRobinhoodUsesArbSysNotL1EstimateAndHandlesExpiry() (gas: 238560)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 1.46ms (1.27ms CPU time)\n\nRan 1 test for test/fork/RobinhoodFork.t.sol:RobinhoodForkTest\n[SKIP] testForkArbSysAndHistoricalHash() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 1.13ms (979.30µs CPU time)\n\nRan 2 tests for test/V310.t.sol:ToolchainPinsV310Test\n[PASS] testEveryModuleOfThisBuildMatchesOneToolchainPin() (gas: 167162)\n[PASS] testPinsAreOneToolchainAndRejectUnknownCode() (gas: 162929)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 3.69ms (1.45ms CPU time)\n\nRan 5 tests for test/fork/RehearsalV311.t.sol:RehearsalV311Test\n[SKIP] testRehearsalAttestedAnswerChangesPlanWithinBand() (gas: 0)\n[SKIP] testRehearsalGasPerLaunchUnderPlatformCeiling() (gas: 0)\n[SKIP] testRehearsalKeeperPassAdvancesEpochsRevealsEntropyAndClaimFeesPaysTeam() (gas: 0)\n[SKIP] testRehearsalLaunchTaxThenOnePercentAndSurcharge() (gas: 0)\n[SKIP] testRehearsalPacksOpenOneHourAfterLaunch() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 5 skipped; finished in 16.76ms (16.02ms CPU time)\n\nRan 1 test for test/PredictionV34.t.sol:PredictionV34Test\n[PASS] testFullGraphPredictsPoolBeforeRegistryDeployment() (gas: 4190905)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 22.93ms (1.20ms CPU time)\n\nRan 6 tests for test/CivicV35.t.sol:CivicV35Test\n[PASS] testBillboardsBidRefundTextRulesAndPoolOnly() (gas: 945542)\n[PASS] testBlackMarketDescendingLimitedAndPause() (gas: 3822256)\n[PASS] testCollapseSuccessAndSingleOutageFailure() (gas: 810718)\n[PASS] testDormantDisabledAndNoticeOnce() (gas: 303076)\n[PASS] testOnceSeasonBoostBoundsAndSnapshot() (gas: 1722426)\n[PASS] testWarFreezeScoresConservationAndPayoutOnlyOnce() (gas: 1365360)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 35.34ms (26.45ms CPU time)\n\nRan 5 tests for test/Registry.t.sol:RegistryTest\n[PASS] testAllModulePinsMatchExactPinnedCompilerArtifacts() (gas: 1064523)\n[PASS] testAuthenticatedEnrollmentRejectsUncreatedWrongCodeAndWrongRegistry() (gas: 3270493)\n[PASS] testConstructorAcceptsEmptyGraphWithoutExternalCalls() (gas: 13657)\n[PASS] testCounterfeitRuntimeAtAnotherFactoryCannotEnroll() (gas: 1882067)\n[PASS] testCounterfeitRuntimeWithPoisonedCreditCannotEnroll() (gas: 6217486)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 35.94ms (19.07ms CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] testConstructorRejectsMissingInputsAndDoesNotCallExternalContracts() (gas: 3994)\n[PASS] testForeignCallerDoesNotGetAnyAuthority() (gas: 42642091)\n[PASS] testImmutableGraphAndEip170Sizes() (gas: 187323)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 37.81ms (21.14ms CPU time)\n\nRan 3 tests for test/TwinCaptureV312.t.sol:TwinCaptureV312Test\n[PASS] testHonestBindThenForwardReachesHonestPool() (gas: 6020873)\n[PASS] testTwinCaptureCannotPayAttacker() (gas: 11367879)\n[PASS] testTwinCaptureOrphansHonestGame() (gas: 11350429)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 39.41ms (17.07ms CPU time)\n\nRan 1 test for test/WarReviewV35.t.sol:IndependentWarReview\n[PASS] testWarWinnerCannotChangeAfterDeadline() (gas: 5734360)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.65ms (1.45ms CPU time)\n\nRan 1 test for test/YieldFloorReviewV35.t.sol:IndependentYieldFloorReview\n[PASS] testFirstEpochItemQuotesKeepNonzeroFloorAtCorrectScale() (gas: 673277)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 998.41µs (876.48µs CPU time)\n\nRan 2 tests for test/AutoRepairReviewV35.t.sol:IndependentAutoRepairReview\n[PASS] testAutomaticRepairRecordsHistoricalWeekBeforeCompletion() (gas: 5402724)\n[PASS] testLateAutomaticRepairCannotReopenSeasonEligibility() (gas: 4266739)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 63.28ms (51.23ms CPU time)\n\nRan 7 tests for test/V33.t.sol:LaunchProtectionTest\n[PASS] testBuyTaxHasImmutableSteps() (gas: 97524)\n[PASS] testLaunchTaxChargedAndRoutedEntirelyToPool() (gas: 227992)\n[PASS] testNoBuySizeLimitAtAnyLaunchStep() (gas: 1690997)\n[PASS] testNormalBuyAfterDecayHasNoLaunchTax() (gas: 1479403)\n[PASS] testSellsPayNormalFeeDuringLaunch() (gas: 339655)\n[PASS] testSnipersSplittingBuysStillPayTheCurve() (gas: 655730)\n[PASS] testViewsBeforeInitialization() (gas: 4725627)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 64.30ms (6.78ms CPU time)\n\nRan 6 tests for test/EndowmentEscrowV38.t.sol:EndowmentEscrowV38Test\n[PASS] testConstructorRejectsMissingInputs() (gas: 6182)\n[PASS] testForwardRejectsBadProofs() (gas: 2663621)\n[PASS] testForwardRequiresBalance() (gas: 752051)\n[PASS] testForwardSendsWholeBalanceOnceToAuthenticatedPoolAndFundsEndowment() (gas: 1713359)\n[PASS] testForwardWithRealEndowmentActivatesDrip() (gas: 12550408)\n[PASS] testTwinWithForeignTokenCannotDrainEscrow() (gas: 12456243)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 71.40ms (37.62ms CPU time)\n\nRan 3 tests for test/Pause.t.sol:PauseTest\n[PASS] testOnlySwarmBoundedDurationAndCannotExtendPause() (gas: 242972)\n[PASS] testSalePausedWhileEntropyClaimsWithdrawalsAndEpochsContinue() (gas: 15156588)\n[PASS] testUnpauseCannotResetNextPauseCooldown() (gas: 194647)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 71.95ms (55.58ms CPU time)\n\nRan 3 tests for test/PotV35.t.sol:PotV35Test\n[PASS] testPotDepositRequiresActualTokensAndAuthority() (gas: 256924)\n[PASS] testPotSplitDistinctLotteryDistrictAndRollbackOnFullInventory() (gas: 11488024)\n[PASS] testPotUnclaimedRolloverOnlyAfterFourWeeksNoDoubleClaim() (gas: 6429645)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 74.28ms (37.34ms CPU time)\n\nRan 3 tests for test/StandardAdapter.t.sol:StandardAdapterTest\n[PASS] testExistingHookKeyPreservedAndNoExtraFee() (gas: 330662)\n[PASS] testRequiresThirtyMinutesFreshOracleAndAuthorizedCallback() (gas: 198351)\n[PASS] testSettlementSlippageFailurePreservesCredits() (gas: 240594)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 34.26ms (1.70ms CPU time)\n\nRan 8 tests for test/V39.t.sol:V39Test\n[PASS] testBaseDepositsAreEntirelyRewardEth() (gas: 190166)\n[PASS] testGridAcceptsSeverityFromThreeThousandAndRejectsBelow() (gas: 2946787)\n[PASS] testHookAddsExactlyOnePercentOnBuysAndSellsAfterLaunchWindow() (gas: 2179711)\n[PASS] testHookHasNoNetworkShareRecipientOrWithdrawal() (gas: 109842)\n[PASS] testMarketFactoryConfigHasNoNetworkRecipient() (gas: 7421825)\n[PASS] testRegistryAcceptsEitherToolchainPinAndNothingElse() (gas: 930391)\n[PASS] testSellSurchargeStillProgressiveAndCappedAtFifteenPercent() (gas: 1832600)\n[PASS] testStepLaunchTaxUnchangedAndFullyToRewards() (gas: 1291729)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 81.73ms (56.11ms CPU time)\n\nRan 8 tests for test/PhasedReleaseV36.t.sol:PhasedReleaseV36Test\n[PASS] testBillboardsDisabledThenEnabled() (gas: 414502)\n[PASS] testEnableIsNoticedOnceNeverOffAndSwarmOnly() (gas: 355991)\n[PASS] testEnhancementDisabledThenEnabledOnce() (gas: 1096283)\n[PASS] testEverythingDeploysDisabledAndCoreStillWorks() (gas: 8162777)\n[PASS] testFuzzUnannouncedFeatureCannotBeEnabled(uint256) (runs: 256, μ: 30080, ~: 29956)\n[PASS] testLocksStakeAndLobbyDisabledThenEnabled() (gas: 2849495)\n[PASS] testPotDisabledFollowsV34RoutingThenEnabled() (gas: 455827)\n[PASS] testReservedEventsDisabledThenEnabled() (gas: 557613)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 96.91ms (113.73ms CPU time)\n\nRan 3 tests for test/HookBinding.t.sol:HookBindingTest\n[PASS] testHoldBeforeGameExistsThenBindOnceAndFlushExactStreams() (gas: 43111685)\n[PASS] testLookAlikeCannotBindEvenWhenTeamCalls() (gas: 1907686)\n[PASS] testWrongRouterAndMissingCodeRejectedBeforePermanentBind() (gas: 40825860)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 115.13ms (47.43ms CPU time)\n\nRan 5 tests for test/ReviewV34.t.sol:ReviewV34Test\n[PASS] testCanonicalCompetingRegistryCannotTakeOverBinding() (gas: 9451528)\n[PASS] testDustBuyCannotConsumeGlobalBuyInterval() (gas: 336156)\n[PASS] testLateGreenEntrySettlesWithinReservedEnvelope() (gas: 4432362)\n[PASS] testMeaningfulSmallBuyCanUseLessThanMaximumBatch() (gas: 263646)\n[PASS] testSameConfigurationAtUncommittedCoordinatesCannotBind() (gas: 9538431)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 123.50ms (62.48ms CPU time)\n\nRan 2 tests for test/GridV35.t.sol:GridV35Test\n[PASS] testGreenAndCheapBothFavorTheStableDistrict() (gas: 4116213)\n[PASS] testReservedEventsHaveZeroLaunchWeightAndPlanOnlyWhenEnabled() (gas: 721158)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 70.16ms (23.43ms CPU time)\n\nRan 1 test for test/StandardV4Integration.t.sol:StandardV4IntegrationTest\n[PASS] testStandardAdapterRealPoolPaysExistingHookExactlyOnce() (gas: 1948176)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 182.41ms (1.89ms CPU time)\n\nRan 4 tests for test/OracleConformanceV37.t.sol:OracleConformanceV37Test\n[PASS] testAcceptsOriginalProtocolSignature() (gas: 17956)\n[PASS] testDigestMatchesUnmodifiedProtocolVector() (gas: 13636)\n[PASS] testFreshVectorSignerSignature() (gas: 30407)\n[PASS] testSelectorsExactlyMatchLiveProtocol() (gas: 3520)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.47ms (480.61µs CPU time)\n\nRan 6 tests for test/Endowment.t.sol:EndowmentTest\n[PASS] testDirectTransferCannotBypassOrBackdateDrip() (gas: 368166)\n[PASS] testExactFundingFullLinearDripAndConservation() (gas: 832168)\n[PASS] testFuzzCumulativePaymentsCannotExceedVestedPrincipal(uint32,uint128) (runs: 256, μ: 522846, ~: 524745)\nLogs:\n  Bound result 3782363\n  Bound result 43760367050363505751462729\n\n[PASS] testNoTeamDonorOrSwarmWithdrawalOrReserveAuthority() (gas: 614309)\n[PASS] testParamsSnapshotCannotAccelerateOrRelockExistingEndowment() (gas: 303686)\n[PASS] testUnderfundingCannotActivateAndDonationsStayConserved() (gas: 453428)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 216.96ms (205.68ms CPU time)\n\nRan 8 tests for test/FeesParams.t.sol:FeesParamsTest\n[PASS] testAllDefaultParamsWithinHardBounds() (gas: 1255771)\n[PASS] testBuyBackPoolOnlySlippageFailureRollbackAndDustGriefBlocked() (gas: 774066)\n[PASS] testExactEthSplitsHeartbeatCapAndPullPayments() (gas: 512724)\n[PASS] testFuzzNoStepAboveTenPercent(uint96) (runs: 256, μ: 44950, ~: 45115)\nLogs:\n  Bound result 3598\n\n[PASS] testFuzzSplitsConserveEveryWei(uint96) (runs: 256, μ: 207834, ~: 210856)\nLogs:\n  Bound result 3598\n\n[PASS] testHeartbeatCapFixedAtOneEth() (gas: 207904)\n[PASS] testParamsStepCooldownBoundsAuthorityAndLetter() (gas: 195823)\n[PASS] testPoolNoPublicReserveRecycleOrPayment() (gas: 135304)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 231.71ms (164.31ms CPU time)\n\nRan 2 tests for test/StandardMarket.t.sol:StandardMarketTest\n[PASS] testFuzzStandardSellNeverAddsProgressiveSurcharge(uint96) (runs: 256, μ: 1805289, ~: 1813953)\nLogs:\n  Bound result 14368\n\n[PASS] testStandardBuyOnePercentAllToRewards() (gas: 1673242)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 312.18ms (287.92ms CPU time)\n\nRan 1 test for test/EndowmentGame.t.sol:EndowmentGameTest\n[PASS] testRealMiningCannotSpendFutureEndowment() (gas: 130414629)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 329.39ms (312.39ms CPU time)\n\nRan 5 tests for test/KeeperProfit.t.sol:KeeperProfitTest\n[PASS] testPaidPackEntropyKeeperProfit() (gas: 1179133)\nLogs:\n  paid pack entropy execution gas: 139616\n  paid pack entropy bounty wei: 3380475000000\n  paid pack entropy execution plus 21000 gas cost wei: 3212320000000\n\n[PASS] testPlanEntropyKeeperProfit() (gas: 1665825)\nLogs:\n  plan entropy execution gas: 163594\n  plan entropy bounty wei: 4488125000000\n  plan entropy execution plus 21000 gas cost wei: 3691880000000\n\n[PASS] testSeasonFinalizeThreeWinnersAndPrizeKeeperProfit() (gas: 3451176)\nLogs:\n  season finalize three winners and prize execution gas: 644051\n  season finalize three winners and prize bounty wei: 15825150000000\n  season finalize three winners and prize execution plus 21000 gas cost wei: 13301020000000\n\n[PASS] testSeasonPrepareIsConstantUnpaidWork() (gas: 1342777)\n[PASS] testStarterEntropyKeeperProfit() (gas: 324553)\nLogs:\n  starter entropy execution gas: 142744\n  starter entropy bounty wei: 3380150000000\n  starter entropy execution plus 21000 gas cost wei: 3274880000000\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 28.76ms (15.24ms CPU time)\n\nRan 10 tests for test/Bounties.t.sol:BountiesTest\n[PASS] testBuyBountyProportionalCapNoDustCreditAndFailureRollback() (gas: 680020)\n[PASS] testEmptyRosterAndInvalidBatchReceiveNothing() (gas: 1419146)\n[PASS] testEveryWorkKindBoundedByHeartbeatAndAuthorizedProducer() (gas: 64315585)\n[PASS] testLazySettlementUnpaidAndCannotReplay() (gas: 6957525)\n[PASS] testOnlyFinalizePaidOnceAndEmptyWeekUnpaid() (gas: 2292196)\n[PASS] testPackEntropyCapturedOnceWithFullInventoryAndThroughPause() (gas: 3710376)\n[PASS] testPlanResolutionPaidOnceIncludingAdvanceForwarding() (gas: 2931539)\n[PASS] testRemovedWorkBountiesRejectedEvenFromOldProducer() (gas: 179981)\n[PASS] testStarterEntropySurvivesFullInventoryExpiryAndPauseWithoutReplayPayment() (gas: 5321268)\n[PASS] testWorkCreditRespectsZeroGasPricePriceCeilingAndUnitCap() (gas: 333726)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 377.51ms (309.50ms CPU time)\n\nRan 20 tests for test/SwarmDeskV37.t.sol:SwarmDeskV37Test\n[PASS] testBackupFailureUnknownFailureDeadlineAndPriceCap() (gas: 751172)\n[PASS] testBackupPullsExactPriceRecordsRequestAndRestrictsBodyAndCadence() (gas: 1199464)\n[PASS] testDeskSetHeartbeatBpsMovesFeeRouterShare() (gas: 937778)\n[PASS] testEmptyChainConstructorAndAuthenticatedBindingRejectSpoofs() (gas: 12471225)\n[PASS] testEventClampingAndFallbackWithoutAnswer() (gas: 1047688)\n[PASS] testExpiredOldSlotOldEpochAndUnexecutedAnswersNeverAct() (gas: 828312)\n[PASS] testFlatConstructorRejectsUnusedPackedBits() (gas: 6688433)\n[PASS] testForgedTamperedWrongSignerWrongDomainAndCallerRejected() (gas: 345940)\n[PASS] testFutureIssueWrongTypeMalformedLengthAndPriceNeverConsume() (gas: 311556)\n[PASS] testFuzzEveryParamHardBoundsAndTenPercentStep(uint8,uint248) (runs: 256, μ: 468384, ~: 469802)\nLogs:\n  Bound result 15\n\n[PASS] testNextSlotAcceptsSameQuestionAndChangedExecutionBytesReject() (gas: 1129615)\n[PASS] testNoAdminPathsAndEntireGraphUsesDesk() (gas: 388087)\n[PASS] testNoopRegulatorAcceptedAndParamsCooldownPreserved() (gas: 444622)\n[PASS] testRegulatorClampsParamsAnnouncesPhasesAndThirtyDayCaps() (gas: 1130422)\n[PASS] testReplayDifferentSourceAndSecondAnswerSameSlotIgnored() (gas: 1051768)\n[PASS] testRobinhoodNativeClockCallbackWithin200k() (gas: 344786)\n[PASS] testScheduleDeliveryStoresUnder200kThenExecutesTwoPlans() (gas: 976035)\n[PASS] testSubmitRelayAcceptsAttestedAnswerFromAnyoneOnce() (gas: 1075619)\n[PASS] testSubmitRelayRejectsForgedWrongQuestionStaleAndMalformed() (gas: 1808092)\n[PASS] testWrongQuestionUnknownRequestWeakPanelAndWindowRejected() (gas: 364606)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 446.39ms (453.83ms CPU time)\n\nRan 2 tests for test/Factory.t.sol:FactoryTest\n[PASS] testFactoryInvalidSearchRange() (gas: 5016)\n[PASS] testHookFactoryFlagsImmutableConfigAndIdempotence() (gas: 17888831)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 337.62ms (324.32ms CPU time)\n\nRan 6 tests for test/V4Integration.t.sol:V4IntegrationTest\n[PASS] testRealV4BuyAndSingleSwapSellTaxConserveSettlement() (gas: 2268519)\n[PASS] testRealV4ManipulatedSpotCannotInstantlySetBuybackQuote() (gas: 1909248)\n[PASS] testRealV4SmallBuyPaysPositiveKeeperMargin() (gas: 2072079)\nLogs:\n  real V4 0.2ETH buy gas: 1933207\n  real V4 buy bounty wei: 48643350000000\n\n[PASS] testRealV4SystemBuyUsesTwapAndOnlySystemFunds() (gas: 2077956)\n[PASS] testRealV4SystemSalesUseDepthTwapNormalFeesAndConserveTokens() (gas: 2246438)\n[PASS] testSystemBuybackOffsetsRecordedSellImbalance() (gas: 2508945)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 551.16ms (16.64ms CPU time)\n\nRan 11 tests for test/Items.t.sol:ItemsTest\n[PASS] testComputeHashSupportHashAndBonusesReplaceDuo() (gas: 4700115)\n[PASS] testDurabilityWearRepairAndEnhancementMetadataPreserved() (gas: 8369228)\n[PASS] testEquipRarityGatesAndMythicGate() (gas: 4144858)\n[PASS] testFullStackRarityCapAndRoomFlags() (gas: 7638418)\n[PASS] testInventoryMintCannotExceedCapacityAndExpansionRises() (gas: 3351443)\n[PASS] testLockedItemCannotBeScrappedUntilEpochRolls() (gas: 5971291)\n[PASS] testOffgridSavings() (gas: 2701968)\n[PASS] testPaidXpCannotBypassRoomTwoAgeGate() (gas: 3734443)\n[PASS] testRoomGatesAndLevelProgression() (gas: 78345249)\n[PASS] testScrapPaysPoolYieldAndCannotRepeat() (gas: 7543503)\n[PASS] testSoulboundOnlyOwnFarmAndNoDuplicateTypes() (gas: 2254731)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 643.66ms (768.70ms CPU time)\n\nRan 9 tests for test/Packs.t.sol:PacksTest\n[PASS] testExactPaymentAndFutureBlockRequired() (gas: 1667747)\n[PASS] testExactRarityThresholdsAndMythicGate() (gas: 282935)\n[PASS] testExpiryRearmsWithoutMintingAndInventoryOpeningLimit() (gas: 3790798)\n[PASS] testFuzzVrgdaAlwaysBounded(uint32,uint32) (runs: 256, μ: 61396, ~: 63041)\nLogs:\n  Bound result 60645492\n\n[PASS] testItemTypeDistributionExact() (gas: 626492)\n[PASS] testNoWalletGlobalOrTokenPackDailyLimit() (gas: 4377219)\n[PASS] testStarterWindowProofTokenIdOnceAndInventoryFailureRetry() (gas: 881480)\n[PASS] testTokenPackSameQuoteAndSplitWhenUsingWalletOrCredits() (gas: 76424599)\n[PASS] testVrgdaInitialStepDecayFloorCeilingAndBulkPricing() (gas: 1296506)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 451.92ms (442.73ms CPU time)\n\nRan 18 tests for test/EconomyV35.t.sol:EconomyV35Test\n[PASS] testAllEnhancementTableEndpointsAndGlobalBonusCap() (gas: 1477953)\n[PASS] testDurabilityBoundariesAndIdleNoWear() (gas: 38102739)\n[PASS] testEnhanceBurnFailureAndLevelGate() (gas: 1218555)\n[PASS] testEnhanceCapsNoticeUpwardOnlyAndThirtyDays() (gas: 355782)\n[PASS] testEnhanceCommitCannotPlaceScrapOrRetryAndCanRearm() (gas: 1798751)\n[PASS] testFeeSalesDepthSlippageCadenceAndNormalFeePot() (gas: 1734752)\n[PASS] testFreeAllowlistOnceWindowStarterScrapAndMetadata() (gas: 2989149)\n[PASS] testFreeRootRemainsFrozenAfterSevenDays() (gas: 43976)\n[PASS] testFreeRootWindowAndIndexLimit() (gas: 55991)\n[PASS] testFuzzPriceCurveDaysBounds(uint32,uint32) (runs: 256, μ: 88543, ~: 90122)\nLogs:\n  Bound result 5264213\n\n[PASS] testLockBonusRedistributesWithinReservedEmission() (gas: 11653052)\n[PASS] testLockEscrowNoEarlyExitAndWalletCap() (gas: 5377416)\n[PASS] testQuoteScalesLastSettlementAndHasFloor() (gas: 4278490)\n[PASS] testRepairYieldQuoteAndAutoRepairCreditsOnly() (gas: 10789523)\n[PASS] testRoomsChargeYieldDaysAndRetainAgeGates() (gas: 2600055)\n[PASS] testSystemSellDustCannotOccupyCadenceAndCappedHeartbeatReturnsTokens() (gas: 1556688)\n[PASS] testTokenOnlyGiftSplitsNoEthPeg() (gas: 1734609)\n[PASS] testZapAtomicMinOutPauseAndRefund() (gas: 1438033)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 665.60ms (646.29ms CPU time)\n\nRan 7 tests for test/HeartbeatBpsV313.t.sol:HeartbeatBpsV313Test\n[PASS] testFuzzAnyShareConservesEveryWeiAndNeverMovesTeamOrPot(uint16,uint96) (runs: 256, μ: 1396752, ~: 1626529)\nLogs:\n  Bound result 743\n  Bound result 5823\n\n[PASS] testLaunchDefaultIsTwoPercentAndSplitUnchanged() (gas: 230935)\n[PASS] testLoweredShareBackToFloorAndFloorIsHard() (gas: 401104)\n[PASS] testMaximumShareWithPotEnabledIsClippedToWhatIsLeft() (gas: 1867739)\n[PASS] testOnlyTheSwarmWithinBoundsStepAndCooldownCanMoveTheShare() (gas: 341795)\n[PASS] testRaisedShareStillStopsAtTheOneEthCap() (gas: 480520)\n[PASS] testSwarmSet220CreditsTwoPointTwoPercentOfSurchargeAndTokens() (gas: 543701)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 689.99ms (692.66ms CPU time)\n\nRan 6 tests for test/Regression.t.sol:RegressionTest\n[PASS] testCableRepairRestoresOnlyRemainingHalfEpoch() (gas: 11794355)\n[PASS] testEmptyEpochPreservesLastSettledRateButResetsScrapAllowance() (gas: 10984120)\n[PASS] testFuzzCableRepairBlendHandlesNonMonotonicRarityBonuses(uint16) (runs: 256, μ: 1374201, ~: 1374014)\nLogs:\n  Bound result 7200\n\n[PASS] testRegisterOnlyAccountsDoNotAddSettlementWorkAndEmptyFarmCanRetire() (gas: 2025433)\n[PASS] testRepairAndPaidPackCannotRetroactivelyBoostEpoch() (gas: 9542820)\n[PASS] testUnlimitedFreshPacksCannotDrainPoolByScrapping() (gas: 9641657)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 996.25ms (1.07s CPU time)\n\nRan 14 tests for test/V34.t.sol:V34Test\n[PASS] testBestFarmCapsAbsoluteSpendAndBreaksTiesByAddress() (gas: 4665680)\n[PASS] testBestFarmNeedsTwentyEpochsAndUsesCappedAbsoluteSpend() (gas: 4144210)\n[PASS] testBuybackSlippage150BpsMaxAndIntervalCannotBeBypassed() (gas: 756168)\n[PASS] testDonationsAndOrdinaryInflowsCannotPretendToBeEndowment() (gas: 1520675)\n[PASS] testEntropyAt256BoundaryAndAt257RearmsWithoutPayOrMint() (gas: 3276985)\n[PASS] testFirstRewardStartsCurrentEpochAtHalfTimeAndSnapshotCannotBeReplaced() (gas: 4834300)\n[PASS] testFreeFarmDoesNotDiluteDistrictOrClaimPaidPrize() (gas: 4739665)\n[PASS] testGameReadinessBothChecksRollbackEthAndTokenPurchase() (gas: 3605912)\n[PASS] testHookUninitializedCannotOpenOrStartEpochAndCallerCannotStartClock() (gas: 5887799)\n[PASS] testLaunchTaxExactBoundaries() (gas: 5771057)\n[PASS] testMythicGateEvaluatedAtRevealNotAtPayment() (gas: 1620572)\n[PASS] testPackOpeningFollowsHookAndNotLegacyDeployTimestamp() (gas: 101151)\n[PASS] testRemainderTransferredToPredictedPoolBeforeDeploymentAndNoApprovalNeeded() (gas: 2800290)\n[PASS] testStarterEntropyRearmsAfterClaimWindowAndNoDoubleMint() (gas: 772300)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 1.02s (74.04ms CPU time)\n\nRan 3 tests for test/Gas.t.sol:GasTest\n[PASS] testGasCommonActions() (gas: 10843346)\nLogs:\n  buy token pack: 922761\n  open one pack: 514543\n  equip: 963773\n  repair wallet: 611998\n  enhancement commit: 565794\n  expand: 387774\n  token pack wallet: 652058\n  withdraw: 253137\n  unequip: 404020\n\n[PASS] testGasFullFarmLongIdleBoundedChunks() (gas: 119172460)\nLogs:\n  settle full 24-item farm eight epochs after 40 idle: 12486576\n\n[PASS] testGasTypicalFarmSettlementHasNoBounty() (gas: 8924872)\nLogs:\n  settle typical three-item farm one epoch: 919736\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 1.35s (998.15ms CPU time)\n\nRan 2 tests for test/ReservedEventsV35.t.sol:ReservedEventsV35Test\n[PASS] testFuzzReservedFestivalCannotExceedFifteenPercent(uint16) (runs: 256, μ: 4918902, ~: 4918899)\n[PASS] testReservedHeatwaveExtraCoolingWearAndBothProtections() (gas: 10146981)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 1.35s (1.44s CPU time)\n\nRan 9 tests for test/Epochs.t.sol:EpochsTest\n[PASS] testCannotAdvanceEarlyAndBountyOnce() (gas: 2510478)\n[PASS] testClaimsEveryEpochAndRedistributionIsNextEpoch() (gas: 11985703)\n[PASS] testGasAdvanceIndependentOfRoster() (gas: 893047640)\nLogs:\n  advance empty roster: 1284132\n  advance 1000 farms: 1473629\n\n[PASS] testNoCatchupEmissionDuringGap() (gas: 6257752)\n[PASS] testNoRetroactiveEquipmentAndBoundedBatches() (gas: 5780602)\n[PASS] testNoWhaleCapHashShares() (gas: 10155257)\n[PASS] testReferralOneLevelSetOnceNoSelf() (gas: 7511550)\n[PASS] testTaxCurveExactAndFloor() (gas: 34112)\n[PASS] testWithdrawFailureRollsBackAndReentrancyCannotClaimTwice() (gas: 7428870)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 7.86s (8.05s CPU time)\n\nRan 20 tests for test/V33.t.sol:V33Test\n[PASS] testActionBeforeExpiryMovesBucketWithoutDoubleCount() (gas: 25963547)\n[PASS] testAdvanceIsConstantInExpiringFarms() (gas: 38374918)\n[PASS] testAgeCapsAtBoundaries() (gas: 204618)\n[PASS] testClaimDoesNotRecommitWhileBehind() (gas: 37212442)\n[PASS] testClaimRecommitsAndPackRecommits() (gas: 60738557)\n[PASS] testDistrictScoreAveragePerFarmAndTenPercentWalletCap() (gas: 4607489)\n[PASS] testHeartbeatCapExcessGoesToPoolAndBaseFeeIsAllRewards() (gas: 270973)\n[PASS] testIdleFarmLeavesDenominatorAfterTwelveEpochs() (gas: 23496196)\n[PASS] testLaunchTaxDepositIsAllPoolAndMarketOnly() (gas: 137567)\n[PASS] testMergeRemoved() (gas: 512630)\n[PASS] testPackLobbySellSplit88Team10Heartbeat2() (gas: 407960)\n[PASS] testPackSaleOpensSixtyMinutesAfterLaunch() (gas: 1261148)\n[PASS] testPaidXpCannotBypassAgeGates() (gas: 58982706)\n[PASS] testPaidXpCappedPerDayActivityUncapped() (gas: 13235492)\n[PASS] testPartialRoomIsClippedNotReverted() (gas: 2148809)\n[PASS] testRewardsEarnedBeforeExpiryAreNeverLost() (gas: 47642242)\n[PASS] testSingleWhaleDistrictCannotWinAlone() (gas: 4534340)\n[PASS] testSyncRecommitsFromNextEpoch() (gas: 33350114)\n[PASS] testTokenPacksAlsoWaitForOpening() (gas: 59864)\n[PASS] testTopSpenderTrackingIsExact() (gas: 5411751)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 14.89s (2.46s CPU time)\n\nRan 13 tests for test/Events.t.sol:EventsTest\n[PASS] testCheapTariffAppliesCitywide() (gas: 6419970)\n[PASS] testColdPowerFireImmuneAndCleanPowerSurgeImmune() (gas: 7898411)\n[PASS] testFallbackAndExpiredSeedIndependentOfSwarmNumber() (gas: 1683539)\n[PASS] testFireNoCoolingZeroYieldColdPowerImmune() (gas: 6144568)\n[PASS] testGreenWaveRaisesDistrictMiningTenPercent() (gas: 6422047)\n[PASS] testLobbyOwnDistrictSplitDecayAndMinimumWeight() (gas: 1080859)\n[PASS] testOutageAndOffgridRoomMitigation() (gas: 7053841)\n[PASS] testPlansOnlyNextTwoOnceAndBoundedSeverity() (gas: 344816)\n[PASS] testRollingCapsAndInitialPositiveQuotaWithHostilePlans() (gas: 102235868)\n[PASS] testSurgeCanDestroyCommonButNeverLegendary() (gas: 6288094)\n[PASS] testSurgeDamagesExactlyOneItemAndCleanPowerImmune() (gas: 6294034)\n[PASS] testSurgeNeverDestroysLegendaryOrMythic() (gas: 9502005)\n[PASS] testTheftRouterDisabledAndRepairRestores() (gas: 6848091)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 14.89s (619.58ms CPU time)\n\nRan 9 tests for test/LazyAccounting.t.sol:LazyAccountingTest\n[PASS] testAuditChargesTenPercentEvenAtHalfSeverityAndThresholdIsFrozen() (gas: 6152701)\n[PASS] testClaimCatchesUpWhilePacksPausedAndDoesNotEraseRemainingHistory() (gas: 25659680)\n[PASS] testExhaustedFarmCannotCollectRedistributionByRemainingIdle() (gas: 15152008)\n[PASS] testFuzzLazyEqualsIndependentEagerForRandomFarmsAndAllEvents(uint256) (runs: 256, μ: 45539702, ~: 45548337)\n[PASS] testGlobalAccumulatorAndWeightsAreSnapshottedBeforeMutations() (gas: 9289772)\n[PASS] testLateSeasonSettlementPaysMiningWithoutChangingFrozenWinners() (gas: 59428195)\n[PASS] testOneWeiMiningGreenCannotLockSettlementThroughEnvelopeRounding() (gas: 11045065)\n[PASS] testSparseMatureVintageConsumedBeforeRecentSlotAfterWrap() (gas: 43285171)\n[PASS] testStaleActionsRequireChunksAndNeverBlockGlobalAdvance() (gas: 40513874)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 14.78s (15.52s CPU time)\n\nRan 6 tests for test/Market.t.sol:MarketTest\n[PASS] testBuyChargesExactlyOnePercentAllToRewards() (gas: 1729871)\n[PASS] testFuzzTotalFeeHardCap(uint96) (runs: 256, μ: 1805586, ~: 1809146)\nLogs:\n  Bound result 92288989450149280048\n\n[PASS] testOnlyManagerCorrectPoolExactInputAndHookAddress() (gas: 113403)\n[PASS] testSingleDumpIncludesItselfAndFeeDecaysWithoutGriefReset() (gas: 17162149)\n[PASS] testTwapAveragesEthPriceAcrossUnequalPrices() (gas: 2330567)\n[PASS] testTwapWarmupAndFlashManipulationResistance() (gas: 1882285)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 15.00s (14.98s CPU time)\n\nRan 1 test for test/Invariants.t.sol:InvariantsTest\n[PASS]\nInvariantsTest invariants:\n[PASS] invariantAllowlistRootAndWalletLimit\n[PASS] invariantInventoryAndEthLiabilities\n[PASS] invariantLocksAndPotAlwaysBacked\n[PASS] invariantPriceAndParamsBounds\n[PASS] invariantReceiptsNeverForfeitOrFixMissingEntropy\n[PASS] invariantReservesBackedAndPendingCovered\n[PASS] invariantTokenConservationNoBurns\n InvariantsTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭-------------+-----------+-------+---------+----------╮\n| Contract    | Selector  | Calls | Reverts | Discards |\n+======================================================+\n| GameHandler | advance   | 570   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | buy       | 575   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | claim     | 572   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | equip     | 590   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | expand    | 551   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | freeClaim | 606   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | fundPot   | 568   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | lock      | 567   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | resolve   | 578   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | rollover  | 618   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | settle    | 574   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | tokenPack | 590   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | unlock    | 600   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | unplace   | 633   | 0       | 0        |\n╰-------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 122\n  Bound result 924834621085951488921\n  Bound result 15333\n  Bound result 13037\n  Bound result 13692\n  Bound result 2162\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 52.21s (52.15s CPU time)\n\nRan 4 tests for test/SwarmDeskBootstrap.t.sol:SwarmDeskBootstrapTest\n[PASS] testEip712DomainUsesRobinhoodAndDeployedDesk() (gas: 5114543)\n[PASS] testFactoryDeploysExactlyOneUnboundDeskWithoutExternalCalls() (gas: 5326765)\n[PASS] testRuntimeSizeAndForbiddenOpcodes() (gas: 18684417)\n[PASS] testUnboundDeskRejectsOracleAndBackupActions() (gas: 5218365)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 52.30s (61.62ms CPU time)\n\nRan 6 tests for test/SeasonAudit.t.sol:SeasonAuditTest\n[PASS] testAuditThresholdStrictAndNoWhaleSoftCap() (gas: 40376130)\n[PASS] testLotteryEntitlementSurvivesFullInventory() (gas: 130888063)\n[PASS] testPackSupplyDropOnlyActiveFarmsAtDoublePace() (gas: 11727425)\n[PASS] testParameterChangesCannotChangeClosedEpochBetweenBatches() (gas: 12490901)\n[PASS] testSeasonCannotFinalizeEarlyAndExpiredLotteryMustRearm() (gas: 123852005)\n[PASS] testWeeklyThreeDistinctTicketWinnersRarePackAndBestPrize() (gas: 124081336)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 52.32s (2.43s CPU time)\n\nRan 49 test suites in 52.32s (235.51s CPU time): 277 tests passed, 0 failed, 6 skipped (283 total tests)\n","passed":true},{"durationMs":378,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Billboards.bidBillboard(uint256,uint256,string,string)\",\"Billboards.settleBillboard(uint256,uint256)\",\"Billboards.withdrawRefund()\",\"Civic.announce(uint256,string)\",\"Civic.buyLot(uint256)\",\"Civic.claimWar(uint256)\",\"Civic.consumeCityEvent()\",\"Civic.enable(uint256)\",\"Civic.finishCollapse()\",\"Civic.finishWar()\",\"Civic.fundCollapse(uint256)\",\"Civic.fundWar(uint256)\",\"Civic.grantDistrictBoost(uint256,uint16,string)\",\"Civic.listLot(uint8,uint8,uint8)\",\"Civic.startCollapse(uint256)\",\"Civic.startWar(uint8,uint8)\",\"Economy.autoRepair(address,uint256,uint256[24])\",\"Economy.lock(uint256,uint256)\",\"Economy.unlock()\",\"EndowmentEscrow.forward(address,uint64,uint256,bytes,uint64,uint256,bytes)\",\"Enhancement.activateCap()\",\"Enhancement.announceCap(uint8,string)\",\"Enhancement.capture(uint256)\",\"Enhancement.commit(uint256,uint256,bool)\",\"Enhancement.resolve(uint256)\",\"FarmCore.activity(address,uint256,uint256,uint256)\",\"FarmCore.autoRepair(address,uint256)\",\"FarmCore.buyRoom(uint256,bool)\",\"FarmCore.buyTokenPack(bool)\",\"FarmCore.civicPurchase(address,uint256)\",\"FarmCore.claimDrop()\",\"FarmCore.expand(bool)\",\"FarmCore.grantDrop(address,bytes32)\",\"FarmCore.lobby(uint256,bool)\",\"FarmCore.paidPackBought(address,uint256,uint256)\",\"FarmCore.place(uint256,uint256,uint256)\",\"FarmCore.prepareEnhancement(address,uint256,uint256,bool)\",\"FarmCore.process(address,uint256)\",\"FarmCore.register(address)\",\"FarmCore.repair(uint256,bool)\",\"FarmCore.repairCable(bool)\",\"FarmCore.retire(address)\",\"FarmCore.scrap(uint256,uint256)\",\"FarmCore.setAutoRepair(bool,uint16)\",\"FarmCore.setReferrer(address)\",\"FarmCore.sync()\",\"FarmCore.syncFor(address)\",\"FarmCore.unplace(uint256,uint256)\",\"FarmEngine.process(address,uint256,(uint256[24],uint8[24],uint16[24],bool,uint64,uint16))\",\"FarmItems.destroy(uint256)\",\"FarmItems.equip(address,uint256)\",\"FarmItems.expand(address)\",\"FarmItems.maintain(uint256,uint16,uint8)\",\"FarmItems.mint(address,uint8,uint8,bool)\",\"FarmItems.mintDrop(address,bytes32)\",\"FarmItems.safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\",\"FarmItems.safeTransferFrom(address,address,uint256,uint256,bytes)\",\"FarmItems.unequip(address,uint256)\",\"FarmRewards.advanceEpoch()\",\"FarmRewards.award(address,uint256)\",\"FarmRewards.beginMining(address,uint256)\",\"FarmRewards.claim(uint256)\",\"FarmRewards.initialize(address)\",\"FarmRewards.recordSales(uint256)\",\"FarmRewards.releasePrize(uint256)\",\"FarmRewards.scrap(address,uint256,uint256)\",\"FarmRewards.setReferrer(address,address)\",\"FarmRewards.setWeight(address,uint256)\",\"FarmRewards.settle(address,uint256)\",\"FarmRewards.spend(address,uint256)\",\"FarmRewards.spendTo(address,uint256,address)\",\"FeeRouter.depositBaseFee()\",\"FeeRouter.depositLaunchTax()\",\"FeeRouter.depositLobby()\",\"FeeRouter.depositPack()\",\"FeeRouter.depositSellTax()\",\"FeeRouter.executeBuys(uint256,uint256)\",\"FeeRouter.executePotBuys(uint256,uint256)\",\"FeeRouter.executeSells(uint256,uint256)\",\"FeeRouter.payBounty(address)\",\"FeeRouter.payWork(address,uint8,uint256,uint256)\",\"FeeRouter.receive()\",\"FeeRouter.routeTokens(uint256)\",\"FeeRouter.withdraw()\",\"FeeRouter.zapBuy(uint256,address)\",\"GameRegistry.register(uint256,uint64,uint256,bytes)\",\"GridOperator.lobbyETH()\",\"GridOperator.resolve(uint256)\",\"GridOperator.resolveFor(uint256,address)\",\"GridOperator.shift(uint256)\",\"GridOperator.submitPlan(uint256,uint8,uint16,bytes32,string)\",\"GridOperator.tokenLobby(address,uint256)\",\"MarketFactory.deploy((address,address,int24,address,address,address,bytes32),bytes32)\",\"PackSale.buyPackFor(address)\",\"PackSale.buyPacksFor(address,uint256,uint256)\",\"PackSale.buyWithETH(address,uint256,uint256,uint256)\",\"PackSale.captureEntropy(uint256)\",\"PackSale.openPack(uint256)\",\"PackSale.pause(uint256)\",\"PackSale.rearm(uint256)\",\"PackSale.resolve(uint256,uint256)\",\"PackSale.rewardPack(address)\",\"PackSale.tokenPack(address)\",\"PackSale.unpause()\",\"Params.set(uint8,uint256,string)\",\"RewardPool.donate(uint256)\",\"RewardPool.fundEndowment()\",\"RewardPool.pay(address,uint256)\",\"RewardPool.recordInflow(uint256)\",\"RewardPool.recycle(uint256)\",\"RewardPool.reserve(uint256)\",\"Season.addPrize(uint256,uint256)\",\"Season.claimBest(uint256)\",\"Season.claimDistrict(uint256)\",\"Season.claimLottery(uint256)\",\"Season.complete(address,uint256)\",\"Season.depositPot(uint256)\",\"Season.finalize(uint256)\",\"Season.prepare(uint256,uint256)\",\"Season.rearm(uint256)\",\"Season.recordActivity(address,uint256,uint256,uint256)\",\"Season.recordRepair(address,uint256,uint256)\",\"Season.recordSpend(address,uint256,bool)\",\"Season.rollover(uint256)\",\"StandardAdapter.buy(uint256,address)\",\"StandardAdapter.unlockCallback(bytes)\",\"StandardMarket.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"StandardMarket.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"StandardMarket.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"StandardMarket.bindFeeRouter(address,uint64,uint256)\",\"StandardMarket.buy(uint256,address)\",\"StandardMarket.flushFees()\",\"StandardMarket.receive()\",\"StandardMarket.sell(uint256,uint256,address)\",\"StandardMarket.unlockCallback(bytes)\",\"StarterClaim.captureEntropy(uint256)\",\"StarterClaim.claim(uint256,bytes32[])\",\"StarterClaim.claimFree(uint256,bytes32[])\",\"StarterClaim.rearm(uint256)\",\"StarterClaim.resolve(uint256)\",\"SwarmDesk.askBackup(uint8,bytes)\",\"SwarmDesk.bind(address,bytes,bytes,uint64,uint8,uint64,uint8)\",\"SwarmDesk.clearExpired(bytes32)\",\"SwarmDesk.execute(uint8,bytes)\",\"SwarmDesk.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"SwarmDesk.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"SwarmDesk.submit((bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"V4Market.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"V4Market.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"V4Market.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"V4Market.bindFeeRouter(address,uint64,uint256)\",\"V4Market.buy(uint256,address)\",\"V4Market.flushFees()\",\"V4Market.receive()\",\"V4Market.sell(uint256,uint256,address)\",\"V4Market.unlockCallback(bytes)\"],\"files\":{\".gitignore\":8,\"ADAPTATION.md\":172,\"README.md\":58,\"artifacts/build-lint-v3.txt\":2369,\"artifacts/build-v3.txt\":3,\"artifacts/economic-targets-v3.json\":9,\"artifacts/fmt-v3.txt\":0,\"artifacts/foundry-v3.txt\":845,\"artifacts/funded-sensitivity/simulation-v3.json\":13928,\"artifacts/funded-sensitivity/simulation-v3.md\":51,\"artifacts/funding-sensitivity-v3.json\":342,\"artifacts/gas-actions-v3.txt\":15,\"artifacts/policy-sensitivity-v3.json\":554,\"artifacts/python-tests-v3.txt\":18,\"artifacts/regulator-example.json\":59,\"artifacts/robinhood-fork-v3.txt\":7,\"artifacts/runtime-sizes-v3.json\":23,\"artifacts/simulation-v3.json\":13928,\"artifacts/simulation-v3.md\":51,\"artifacts/tuned-funded/simulation-v3.json\":13928,\"artifacts/tuned-funded/simulation-v3.md\":51,\"artifacts/v2/README.md\":3,\"artifacts/v2/foundry-tests.txt\":178,\"artifacts/v2/offline-tests.txt\":187,\"artifacts/v2/offline-verification.json\":21,\"artifacts/v2/previous-README.md\":108,\"artifacts/v2/previous-design.md\":120,\"artifacts/v2/previous-report.md\":75,\"artifacts/v2/previous-security-review.md\":29,\"artifacts/v2/previous-simulation-assumptions.md\":52,\"artifacts/v2/robinhood-fork.txt\":7,\"artifacts/v2/rpc-probe.json\":16,\"artifacts/v2/runtime-sizes.json\":21,\"artifacts/v2/simulation.md\":95,\"artifacts/v2/verification.json\":110,\"artifacts/v31/allocation-summary.md\":6,\"artifacts/v31/baseline-budget.md\":14,\"artifacts/v31/boundary-checks.json\":10880,\"artifacts/v31/candidate-stress/simulation.json\":32636,\"artifacts/v31/evidence/factory-prediction.json\":14,\"artifacts/v31/evidence/launch-and-cost-facts.json\":130,\"artifacts/v31/evidence/standalone-hook-build.json\":38,\"artifacts/v31/final/comparison.md\":50,\"artifacts/v31/funded/comparison.md\":52,\"artifacts/v31/funded/replay.json\":290,\"artifacts/v31/funding-comparison.md\":8,\"artifacts/v31/regulator-example.json\":73,\"artifacts/v31/stress-comparison.md\":20,\"artifacts/v31/summary.json\":13,\"artifacts/v31/validation.json\":250,\"artifacts/v310/forge-test-launch.txt\":496,\"artifacts/v310/forge-test-repo-changed-suites.txt\":115,\"artifacts/v310/forge-test-repo-full-before-new-tests.txt\":437,\"artifacts/v310/pins-check.txt\":2,\"artifacts/v311/rehearsal.log\":377,\"artifacts/v312/forge-fmt.txt\":1,\"artifacts/v312/forge-test-launch.txt\":381,\"artifacts/v312/forge-test-repo.txt\":384,\"artifacts/v312/launch-creation-hashes.txt\":5,\"artifacts/v312/node-tests.txt\":10,\"artifacts/v312/pins-check.txt\":2,\"artifacts/v312/python-tests.txt\":3,\"artifacts/v312/rehearsal.log\":368,\"artifacts/v313/forge-fmt.txt\":0,\"artifacts/v313/forge-test.txt\":468,\"artifacts/v313/launch-creation-hashes.txt\":6,\"artifacts/v313/module-pins.txt\":15,\"artifacts/v313/pins-check.txt\":2,\"artifacts/v32/contract-sizes.json\":54,\"artifacts/v32/forge-build.log\":2734,\"artifacts/v32/forge-fmt.log\":0,\"artifacts/v32/forge-test.log\":310,\"artifacts/v32/model-checks.log\":5,\"artifacts/v32/module-pins.log\":1,\"artifacts/v32/python-tests.log\":25,\"artifacts/v32/regulator-example.json\":73,\"artifacts/v32/simulation-checks.json\":11,\"artifacts/v32/simulation-checks.log\":11,\"artifacts/v32/validation.json\":61,\"artifacts/v32/verified-baseline/comparison.md\":8,\"artifacts/v32/verified-baseline/simulation.json\":22622,\"artifacts/v32/verified-sensitivities/comparison.md\":68,\"artifacts/v33/simulation.json\":116,\"artifacts/v34/build.txt\":2931,\"artifacts/v34/format.txt\":0,\"artifacts/v34/pins.txt\":1,\"artifacts/v34/python-tests.txt\":5,\"artifacts/v34/reveal-test.txt\":1,\"artifacts/v34/simulation.json\":91766,\"artifacts/v34/simulation.md\":43,\"artifacts/v34/tests.txt\":306,\"artifacts/v35/simulation.json\":22605,\"artifacts/v35/simulation.md\":104,\"artifacts/v35/verification.json\":132,\"artifacts/v36/simulation-phases.json\":179,\"artifacts/v36/simulation-phases.md\":13,\"artifacts/v37/byte-sizes.json\":131,\"artifacts/v37/verification.json\":28,\"artifacts/v39/forge-build-repo.txt\":3,\"artifacts/v39/forge-fmt.txt\":1,\"artifacts/v39/forge-test-launch.txt\":8,\"artifacts/v39/forge-test-repo.txt\":390,\"artifacts/v39/pins-check.txt\":2,\"artifacts/v39/pins.json\":68,\"artifacts/v39/runtime-sizes.json\":197,\"artifacts/v39/simulation.json\":381,\"artifacts/v39/simulation.md\":29,\"artifacts/verification-v3.json\":67,\"docs/api-v35.md\":41,\"docs/dependency-provenance.md\":9,\"docs/design.md\":69,\"docs/entropy-v34.md\":31,\"docs/launch-v31.md\":121,\"docs/launch-v34.md\":44,\"docs/launch-v35.md\":40,\"docs/lazy-accounting-v32.md\":48,\"docs/m2-trust-assumption.md\":101,\"docs/oracle-v37/event.json\":1,\"docs/oracle-v37/oracle-config.json\":21,\"docs/oracle-v37/regulator.json\":1,\"docs/params-keys-v313.md\":113,\"docs/report-v3.md\":143,\"docs/report-v31.md\":128,\"docs/report-v32.md\":138,\"docs/report-v33.md\":107,\"docs/report-v34.md\":58,\"docs/report-v36.md\":89,\"docs/report-v38.md\":83,\"docs/research/b94e6839-platform-report.md\":238,\"docs/review-v31.md\":77,\"docs/review-v32.md\":32,\"docs/review-v33.md\":19,\"docs/review-v34.md\":30,\"docs/review-v35-independent.md\":69,\"docs/review-v37-independent.md\":44,\"docs/review-v39-independent.md\":105,\"docs/security-review.md\":29,\"docs/simulation-assumptions.md\":43,\"docs/simulation-v3-historical.md\":44,\"docs/simulation-v34.md\":34,\"docs/swarm-bootstrap-v313/binding.json\":10,\"docs/swarm-bootstrap-v313/constructor-args.json\":16,\"foundry.toml\":21,\"keeper/README.md\":117,\"keeper/blackout-keeper.service\":23,\"keeper/keeper.env.example\":18,\"keeper/keeper.mjs\":537,\"keeper/lib/abi.mjs\":95,\"keeper/lib/eth.mjs\":186,\"keeper/lib/oracle.mjs\":57,\"keeper/wiring.example.json\":17,\"launch-v31.md\":3,\"launch-v36.md\":34,\"launch-v37.md\":144,\"launch-v38.md\":57,\"launch-v39.md\":292,\"launch/V4Market.sol\":1870,\"operations/dormant-v35.md\":17,\"regulator.md\":60,\"report.md\":290,\"script/Deploy.s.sol\":184,\"script/DeployMarket.s.sol\":15,\"script/PredictGame.s.sol\":49,\"script/SwarmArgs.sol\":30,\"sim/blackout_sim_v2.py\":509,\"sim/blackout_sim_v3.py\":338,\"sim/blackout_sim_v31.py\":24,\"sim/blackout_sim_v32.py\":380,\"sim/blackout_sim_v33.py\":395,\"sim/blackout_sim_v34.py\":444,\"sim/candidate_stress_v31.py\":21,\"sim/heartbeat_boundaries_v31.py\":25,\"sim/heartbeat_sweep_v31.py\":46,\"sim/policy_sensitivity_v3.py\":19,\"sim/run_v32.py\":34,\"sim/run_v33.py\":58,\"sim/run_v34.py\":54,\"sim/run_v35.py\":273,\"sim/run_v36.py\":83,\"sim/run_v39.py\":153,\"sim/tune_v3.py\":16,\"src/Billboards.sol\":135,\"src/Civic.sol\":302,\"src/Economy.sol\":207,\"src/EndowmentEscrow.sol\":112,\"src/Enhancement.sol\":126,\"src/FarmCore.sol\":597,\"src/FarmEngine.sol\":299,\"src/FarmItems.sol\":165,\"src/FarmRewards.sol\":577,\"src/FeeRouter.sol\":312,\"src/GameRegistry.sol\":102,\"src/GridOperator.sol\":261,\"src/MarketFactory.sol\":72,\"src/PackSale.sol\":293,\"src/Params.sol\":181,\"src/RewardPool.sol\":113,\"src/Season.sol\":371,\"src/StandardAdapter.sol\":77,\"src/StandardMarket.sol\":23,\"src/StarterClaim.sol\":149,\"src/SwarmDesk.sol\":479,\"src/V4Market.sol\":551,\"src/interfaces/IGame.sol\":51,\"src/interfaces/IGameRegistry.sol\":15,\"src/interfaces/ILaunchHook.sol\":7,\"src/interfaces/IV4.sol\":26,\"src/interfaces/Interfaces.sol\":20,\"src/lib/ChainClock.sol\":22,\"src/lib/EconomyMath.sol\":48,\"src/lib/Errors.sol\":13,\"src/lib/GameModule.sol\":17,\"src/lib/ItemMath.sol\":31,\"src/lib/ItemMetadata.sol\":79,\"src/lib/ModuleCode.sol\":51,\"src/lib/SwarmCode.sol\":18,\"src/oracle/OracleAttestation.sol\":221,\"src/oracle/SignatureCheckerCompat.sol\":14,\"test/AutoRepairReviewV35.t.sol\":39,\"test/Base.t.sol\":306,\"test/Bounties.t.sol\":290,\"test/CivicV35.t.sol\":224,\"test/Clock.t.sol\":54,\"test/Deployment.t.sol\":94,\"test/EconomyV35.t.sol\":389,\"test/Endowment.t.sol\":123,\"test/EndowmentEscrowV38.t.sol\":198,\"test/EndowmentGame.t.sol\":51,\"test/Epochs.t.sol\":177,\"test/Events.t.sol\":238,\"test/Factory.t.sol\":37,\"test/FeesParams.t.sol\":135,\"test/Gas.t.sol\":110,\"test/GridV35.t.sol\":66,\"test/HeartbeatBpsV313.t.sol\":149,\"test/HookBinding.t.sol\":113,\"test/Invariants.t.sol\":211,\"test/Items.t.sol\":246,\"test/KeeperProfit.t.sol\":95,\"test/LazyAccounting.t.sol\":447,\"test/Market.t.sol\":130,\"test/OracleConformanceV37.t.sol\":107,\"test/Packs.t.sol\":167,\"test/Pause.t.sol\":76,\"test/PhasedReleaseV36.t.sol\":165,\"test/PotV35.t.sol\":108,\"test/PredictionV34.t.sol\":48,\"test/Registry.t.sol\":141,\"test/Regression.t.sol\":154,\"test/ReservedEventsV35.t.sol\":41,\"test/ReviewV34.t.sol\":146,\"test/SeasonAudit.t.sol\":187,\"test/StandardAdapter.t.sol\":81,\"test/StandardMarket.t.sol\":63,\"test/StandardV4Integration.t.sol\":128,\"test/SwarmDeskBootstrap.t.sol\":149,\"test/SwarmDeskV37.t.sol\":646,\"test/TwinCaptureV312.t.sol\":175,\"test/V310.t.sol\":79,\"test/V33.t.sol\":561,\"test/V34.t.sol\":315,\"test/V39.t.sol\":226,\"test/V4Integration.t.sol\":190,\"test/WarReviewV35.t.sol\":69,\"test/YieldFloorReviewV35.t.sol\":31,\"test/fixtures/keeper-v39-vectors.json\":55,\"test/fixtures/oracle-hash-vectors.json\":102,\"test/fork/RehearsalV311.t.sol\":739,\"test/fork/RobinhoodFork.t.sol\":39,\"test/keeper-v39.test.mjs\":34,\"test/mocks/MockGameRegistry.sol\":52,\"test/mocks/MockMarket.sol\":67,\"test/mocks/MockSwarmIntake.sol\":67,\"test/mocks/MockToken.sol\":38,\"test/mocks/MockV4Manager.sol\":118,\"test/oracle-v310.test.mjs\":22,\"test/oracle-v37.test.mjs\":41,\"test/python/test_entropy_bot.py\":31,\"test/python/test_merkle.py\":19,\"test/python/test_regulator.py\":30,\"test/python/test_v31.py\":38,\"test/python/test_v32.py\":58,\"test/python/test_v34.py\":33,\"test/python/test_v35.py\":71,\"test/reveal.test.mjs\":24,\"test/swarm-bootstrap.test.mjs\":48,\"test/ui-v35.test.mjs\":27,\"tools/check_v32_results.py\":52,\"tools/check_v37_authority.py\":19,\"tools/entropy_bot.py\":106,\"tools/freepack_merkle.py\":20,\"tools/make_oracle_bodies.mjs\":45,\"tools/oracle_question_hash.mjs\":80,\"tools/pin_module_code.py\":103,\"tools/pin_swarm_code.py\":47,\"tools/regulator.py\":81,\"tools/rehearse_v311.sh\":25,\"tools/report_v31.py\":55,\"tools/schedule_bodies.mjs\":16,\"tools/starter_merkle.py\":72,\"tools/swarm_constructor_args.mjs\":44,\"ui/app.js\":178,\"ui/index.html\":22,\"ui/reveal.js\":34,\"ui/style.css\":3},\"excluded\":[\"vendor/\",\"node_modules/\"],\"truncated\":true}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"8c3493c494bff7b302f13119ed2a7361fc8832de0074a9cb057dd2402ac3efdc","verifiedTreeHash":"60e22d9fb1aec92d8292e80bb0509e43a530950b","verifierVersion":"0.1.0+327e1e9f"},{"checks":[{"durationMs":27329,"exitCode":0,"name":"build","output":"Compiling 193 files with Solc 0.8.26\nSolc 0.8.26 finished in 26.93s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n  --> src/lib/EconomyMath.sol:17:48:\n   |\n17 |         returns (uint256 chance, uint256 burn, uint256 bonus, uint256 daysWad)\n   |                                                ^^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n  --> src/lib/EconomyMath.sol:44:5:\n   |\n44 |     function bonus(uint256 level) internal pure returns (uint256 b) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (8760): This declaration has the same name as another declaration.\n   --> src/V4Market.sol:300:22:\n    |\n300 |     function _record(bool sell, uint256 amount) private {\n    |                      ^^^^^^^^^\nNote: The other declaration is here:\n   --> src/V4Market.sol:490:5:\n    |\n490 |     function sell(uint256 amount, uint256 minOut, address recipient) external nonReentrant returns (uint256 received) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (8760): This declaration has the same name as another declaration.\n  --> test/mocks/MockSwarmIntake.sol:26:9:\n   |\n26 |         bytes4 failure,\n   |         ^^^^^^^^^^^^^^\nNote: The other declaration is here:\n  --> test/mocks/MockSwarmIntake.sol:44:5:\n   |\n44 |     function failure(bytes32 id, uint8 status, bytes32 reason) external returns (bool) {\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nWarning (2072): Unused local variable.\n   --> test/Events.t.sol:199:9:\n    |\n199 |         uint256 price = d.packs.quote(112);\n    |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n --> test/Gas.t.sol:9:9:\n  |\n9 |         uint256 price = d.packs.price();\n  |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Gas.t.sol:75:9:\n   |\n75 |         uint256 q = d.packs.quote(112);\n   |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Invariants.t.sol:56:9:\n   |\n56 |         uint256 price = d.packs.price();\n   |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Items.t.sol:76:9:\n   |\n76 |         uint256 cost = d.packs.quote(112);\n   |         ^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/Items.t.sol:106:9:\n    |\n106 |         uint256 q = d.packs.quote(16);\n    |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/LazyAccounting.t.sol:186:13:\n    |\n186 |             uint256 quote = d.packs.quote(112);\n    |             ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/LazyAccounting.t.sol:421:9:\n    |\n421 |         uint256 quote = d.packs.quote(112);\n    |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Packs.t.sol:37:9:\n   |\n37 |         uint256 quote = d.packs.quote(200);\n   |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Packs.t.sol:64:9:\n   |\n64 |         uint256 q = d.packs.quote(6);\n   |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Pause.t.sol:35:9:\n   |\n35 |         uint256 q = d.packs.quote(1);\n   |         ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/Regression.t.sol:73:9:\n   |\n73 |         uint256 previous = d.items.data(id).durability;\n   |         ^^^^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/V33.t.sol:254:13:\n    |\n254 |             uint256 q = d.packs.quote(16);\n    |             ^^^^^^^^^\n\nWarning (2072): Unused local variable.\n   --> test/V33.t.sol:431:9:\n    |\n431 |         uint256 price = d.packs.price();\n    |         ^^^^^^^^^^^^^\n\nWarning (2072): Unused local variable.\n  --> test/V34.t.sol:78:9:\n   |\n78 |         uint256 q = d.packs.price();\n   |         ^^^^^^^^^\n\nWarning (2018): Function state mutability can be restricted to pure\n   --> src/FarmRewards.sol:146:5:\n    |\n146 |     function ready() public view returns (bool) {\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/RehearsalV311.t.sol:216:5:\n    |\n216 |     function _oracle() internal view returns (SwarmDesk.OracleConfig memory o) {\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/RehearsalV311.t.sol:290:5:\n    |\n290 |     function _mineHookSalt(bytes memory initCode) internal view returns (bytes32 salt, address hook) {\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[boolean-cst]: misuse of a boolean constant\n   ╭▸ src/Enhancement.sol:55:63\n   │\n55 │             (cap == 8 ? next != 12 : cap == 12 ? next != 16 : true) || announcedCap != 0 || bytes(letter).length == 0\n   │                                                               ━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/boolean-cst\n\nwarning[missing-events-arithmetic]: `heldBase` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:461:9\n    │\n461 │         heldBase += base;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/Enhancement.sol:66:34\n   │\n66 │         if (announcedCap == 0 || block.timestamp < activationAt) revert TooEarly();\n   │                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[missing-events-arithmetic]: `heldSellTax` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:462:9\n    │\n462 │         heldSellTax += excess;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[reentrancy-no-eth]: external call can be reentered before `pending` is updated\n   ╭▸ src/Enhancement.sol:85:9\n   │\n85 │         core.prepareEnhancement(msg.sender, item, cost, wallet);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[missing-events-arithmetic]: `heldBase` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:520:9\n    │\n520 │         heldBase += base;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/Enhancement.sol:89:9\n   │\n89 │         emit EnhancementCommitted(id, msg.sender, item, target, ChainClock.number() + 2, cost);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/Enhancement.sol:88:50\n   │\n88 │         attempts[id] = Attempt(msg.sender, item, uint64(ChainClock.number() + 2), target, bytes32(0), false, false);\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/Enhancement.sol:100:24\n    │\n100 │             a.target = uint64(ChainClock.number() + 2);\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/Enhancement.sol:122:21\n    │\n122 │         if (burned) inventory.destroy(a.item);\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/Enhancement.sol:123:14\n    │\n123 │         else inventory.maintain(a.item, x.durability, level);\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/Enhancement.sol:124:9\n    │\n124 │         emit EnhancementResolved(id, success, burned, level);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:287:9\n    │\n287 │         f.serial = nextSerial++;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:145:27\n    │\n145 │         o.questionChain = uint32(policyWord);\n    │                           ━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint32' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[missing-events-access-control]: `purchasedRoom` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:107:9\n    │\n107 │         purchasedRoom[msg.sender][room] = true;\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:146:23\n    │\n146 │         o.fromBlock = uint48(policyWord >> 32);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint48' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:147:21\n    │\n147 │         o.toBlock = uint48(policyWord >> 80);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint48' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:148:22\n    │\n148 │         o.maxPrice = uint96(policyWord >> 128);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint96' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:241:9\n    │\n241 │         f.paidXpToday += amount;\n    │         ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:153:26\n    │\n153 │         b.heartbeatBps = uint16(policyWord >> 224);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:312:9\n    │\n312 │         f.active = f.loadout;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:559:9\n    │\n559 │         farms[p].xp += 100;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:203:24\n    │\n203 │         if (base != 0) fees.depositBaseFee{value: base}();\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:204:26\n    │\n204 │         if (excess != 0) fees.depositSellTax{value: excess}();\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:205:29\n    │\n205 │         if (launchTax != 0) fees.depositLaunchTax{value: launchTax}();\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-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/V4Market.sol:206:9\n    │\n206 │         emit FeesFlushed(base, excess);\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/V4Market.sol:207:29\n    │\n207 │         if (launchTax != 0) emit LaunchTaxFlushed(launchTax);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-events-access-control]: `commits` is changed without an event but is used for access control\n    ╭▸ src/PackSale.sol:254:9\n    │\n254 │         c.seed = keccak256(abi.encode(h, address(this), id));\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/PackSale.sol:62:16\n   │\n62 │         return block.timestamp < pausedUntil;\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/PackSale.sol:68:13\n   │\n68 │         if (block.timestamp < nextPauseAt) 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/PackSale.sol:117:16\n    │\n117 │         return block.timestamp >= opensAt() && !paused();\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:288:9\n    │\n288 │         rewards().initialize(p);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:295:13\n    │\n295 │         if (rewards().settle(p, 8) < rewards().settledEpoch()) revert CatchUpRequired();\n    │             ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/PackSale.sol:144:13\n    │\n144 │         p = Economy(registry.module(10)).averageDaily() * daysPrice / 1 ether;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:301:9\n    │\n301 │ ┏         rewards()\n302 │ ┃             .setWeight(\n303 │ ┃                 p,\n304 │ ┃                 engine().allocationHash(farms[p].loadout, farms[p].paid != 0) * (10000 + _boost(p, block.timestamp))\n305 │ ┃                     / 10000\n306 │ ┃             );\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/PackSale.sol:130:27\n    │\n130 │         uint256 elapsed = block.timestamp > opensAt() ? block.timestamp - opensAt() : 0;\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:132:24\n    │\n132 │         int256 ahead = int256(sales * 1 ether) - int256(elapsed * target * 1 ether / 1 hours);\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/PackSale.sol:132:50\n    │\n132 │         int256 ahead = int256(sales * 1 ether) - int256(elapsed * target * 1 ether / 1 hours);\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/PackSale.sol:135:30\n    │\n135 │             exponent = wadLn(int256(1 ether + params().get(Params.Key.PriceStepBps) * 1e14)) * ahead / 1 ether;\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/FarmCore.sol:92:9\n   │\n92 │         season().recordSpend(p, cost, true);\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/MarketFactory.sol:70:9\n   │\n70 │         emit MarketDeployed(address(market), salt);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:137:30\n    │\n137 │             exponent = wadLn(int256(1 ether - decay * 1e14)) * (-ahead) / int256(target) / 1 ether;\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/PackSale.sol:137:75\n    │\n137 │             exponent = wadLn(int256(1 ether - decay * 1e14)) * (-ahead) / int256(target) / 1 ether;\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/PackSale.sol:141:37\n    │\n141 │         uint256 daysPrice = start * uint256(wadExp(exponent)) / 1 ether;\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/PackSale.sol:111:28\n    │\n111 │         return ILaunchHook(registry.market()).initializedAt() == 0\n    │                            ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:111:16\n    │\n111 │         return ILaunchHook(registry.market()).initializedAt() == 0\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:113:27\n    │\n113 │             : ILaunchHook(registry.market()).initializedAt() + OPEN_DELAY;\n    │                           ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:113:15\n    │\n113 │             : ILaunchHook(registry.market()).initializedAt() + OPEN_DELAY;\n    │               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:91:23\n   │\n91 │         return Params(registry.params());\n   │                       ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:135:47\n    │\n135 │             exponent = wadLn(int256(1 ether + params().get(Params.Key.PriceStepBps) * 1e14)) * ahead / 1 ether;\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/SwarmDesk.sol:252:14\n    │\n252 │           id = ISwarmIntake(config.intake)\n    │ ┏━━━━━━━━━━━━━━┛\n253 │ ┃             .requestWithFailure(\n254 │ ┃                 config.action,\n255 │ ┃                 body,\n    ‡ ┃\n259 │ ┃                 price\n260 │ ┃             );\n    │ ┗━━━━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:144:21\n    │\n144 │         p = Economy(registry.module(10)).averageDaily() * daysPrice / 1 ether;\n    │                     ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:144:13\n    │\n144 │         p = Economy(registry.module(10)).averageDaily() * daysPrice / 1 ether;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:52:33\n   │\n52 │         uint256 daily = Economy(registry.module(10)).averageDaily();\n   │                                 ━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:52:25\n   │\n52 │         uint256 daily = Economy(registry.module(10)).averageDaily();\n   │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/PackSale.sol:47:9\n   │\n47 │         revert InvalidValue();\n   │         ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:288:9\n    │\n288 │         rewards().initialize(p);\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/SwarmDesk.sol:246:20\n    │\n246 │                 || block.timestamp < s * _period(stream) + 1 hours\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/SwarmDesk.sol:265:13\n    │\n265 │         if (deadline > end) deadline = end;\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/FarmCore.sol:295:13\n    │\n295 │         if (rewards().settle(p, 8) < rewards().settledEpoch()) revert CatchUpRequired();\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/FarmCore.sol:301:9\n    │\n301 │ ┏         rewards()\n302 │ ┃             .setWeight(\n303 │ ┃                 p,\n304 │ ┃                 engine().allocationHash(farms[p].loadout, farms[p].paid != 0) * (10000 + _boost(p, block.timestamp))\n305 │ ┃                     / 10000\n306 │ ┃             );\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/SwarmDesk.sol:267:9\n    │\n267 │         emit BackupAsked(stream, s, id, price);\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/GridOperator.sol:116:16\n    │\n116 │         return block.timestamp < uint256(l.at) + 3 days ? l.amount : 0;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:266:31\n    │\n266 │         pending[id] = Pending(uint64(s), uint64(deadline), stream + 1);\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/SwarmDesk.sol:266:42\n    │\n266 │         pending[id] = Pending(uint64(s), uint64(deadline), stream + 1);\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/GridOperator.sol:127:13\n    │\n127 │             total += stake[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/GridOperator.sol:128:28\n    │\n128 │             if (stake[i] > largest) largest = stake[i];\n    │                            ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:126:24\n    │\n126 │             stake[i] = eco.districtStake(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/FeeRouter.sol:172:9\n    │\n172 │         RewardPool(rewardPool()).recordInflow(reward);\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/FeeRouter.sol:173:9\n    │\n173 │         emit TokensRouted(reward, t, h);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/FeeRouter.sol:181:9\n    │\n181 │         market().buy{value: msg.value}(minOut, recipient);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/FeeRouter.sol:181:9\n    │\n181 │         market().buy{value: msg.value}(minOut, recipient);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-no-eth]: external call can be reentered before `heartbeatTokens` is updated\n    ╭▸ src/FeeRouter.sol:199:13\n    │\n199 │             RewardPool(rewardPool()).recordInflow(excess);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-balance]: external call can be reentered before a stale contract balance is checked\n    ╭▸ src/FeeRouter.sol:214:9\n    │\n214 │         m.sell(amount, minOut, address(this));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-balance\n\nwarning[reentrancy-no-eth]: external call can be reentered before `heartbeatBalance` is updated\n    ╭▸ src/FeeRouter.sol:214:9\n    │\n214 │         m.sell(amount, minOut, address(this));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FeeRouter.sol:219:22\n    │\n219 │         uint256 hb = received * h / amount;\n    │                      ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[reentrancy-no-eth]: external call can be reentered before `purchasedRoom` is updated\n    ╭▸ src/FarmCore.sol:432:13\n    │\n432 │             RewardPool(pool()).recordInflow(paid);\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/FeeRouter.sol:194:30\n    │\n194 │         if (lastSell != 0 && block.timestamp < lastSell + 5 minutes) revert TooEarly();\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `purchasedRoom` is updated\n    ╭▸ src/FarmCore.sol:434:20\n    │\n434 │             paid = rewards().spend(p, nominal);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `purchasedRoom` is updated\n    ╭▸ src/FarmCore.sol:437:9\n    │\n437 │         season().recordSpend(p, paid, kind == 0 || kind == 3 || kind == 4);\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/FeeRouter.sol:224:9\n    │\n224 │         emit TokensSold(amount, 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/FeeRouter.sol:214:9\n    │\n214 │         m.sell(amount, minOut, address(this));\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/FeeRouter.sol:236:9\n    │\n236 │         market().buy{value: amount}(minOut, season());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-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/FarmCore.sol:438:9\n    │\n438 │         emit Spent(p, kind, paid, nominal);\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/FarmCore.sol:108:9\n    │\n108 │         emit RoomPurchased(msg.sender, room, price);\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/FeeRouter.sol:239:9\n    │\n239 │         IPotSeason(season()).depositPot(received);\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/FeeRouter.sol:229:29\n    │\n229 │         if (lastBuy != 0 && block.timestamp < lastBuy + 5 minutes) 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/FeeRouter.sol:240:9\n    │\n240 │         emit PotBought(amount, 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/FeeRouter.sol:236:9\n    │\n236 │         market().buy{value: amount}(minOut, season());\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/FarmCore.sol:116:9\n    │\n116 │         emit AutoRepairSet(msg.sender, autoRepairThreshold[msg.sender]);\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/FarmCore.sol:127:13\n    │\n127 │             emit Spent(p, 0, paid, paid);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-eth]: uncapped ETH transfer can be reentered before `_status` is updated\n    ╭▸ src/FeeRouter.sol:281:22\n    │\n281 │         (bool ok,) = msg.sender.call{value: a}(\"\");\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-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/FeeRouter.sol:283:9\n    │\n283 │         emit Withdrawn(msg.sender, a);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/FeeRouter.sol:302:9\n    │\n302 │         market().buy{value: ethAmount}(minOut, rewardPool());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FeeRouter.sol:305:50\n    │\n305 │         if (!RewardPool(rewardPool()).endowed()) RewardPool(rewardPool()).recordInflow(received);\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/FeeRouter.sol:293:29\n    │\n293 │         if (lastBuy != 0 && block.timestamp < lastBuy + MIN_BUY_INTERVAL) 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/FeeRouter.sol:309:9\n    │\n309 │         emit WorkBounty(msg.sender, Params.Key.BuyBounty, ethAmount, paid);\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/FeeRouter.sol:310:9\n    │\n310 │         emit Bought(ethAmount, 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/FeeRouter.sol:302:9\n    │\n302 │         market().buy{value: ethAmount}(minOut, rewardPool());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:159:52\n    │\n159 │         lobbies[d] = Lobby(lobbyAmount(d) + value, uint64(block.timestamp));\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:432:13\n    │\n432 │             RewardPool(pool()).recordInflow(paid);\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/FarmCore.sol:434:20\n    │\n434 │             paid = rewards().spend(p, nominal);\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/FarmCore.sol:437:9\n    │\n437 │         season().recordSpend(p, paid, kind == 0 || kind == 3 || kind == 4);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[missing-events-access-control]: `bestClaimed` is changed without an event but is used for access control\n   ╭▸ src/Season.sol:76:9\n   │\n76 │         bestClaimed[w] = true;\n   │         ━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:174:21\n    │\n174 │                     seasons[w].districtSpend[d] += districtSpendOf[w][p];\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:241:17\n    │\n241 │                 seasons[w].districtSpend[d] += districtSpendOf[w][p];\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:263:9\n    │\n263 │         s.totalTickets += weight;\n    │         ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `seasons` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:275:9\n    │\n275 │         seasons[w].prize += amount;\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `lotteryClaimed` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:364:9\n    │\n364 │         lotteryClaimed[w][msg.sender] = true;\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/FarmCore.sol:218:36\n    │\n218 │         uint256 age = born == 0 || block.timestamp < born ? 0 : block.timestamp - born;\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/FarmCore.sol:219:13\n    │\n219 │         if (age >= 5 days) return 10;\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/FarmCore.sol:220:13\n    │\n220 │         if (age >= 3 days) return 9;\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/FarmCore.sol:221:13\n    │\n221 │         if (age >= 1 days) return 6;\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/Season.sol:67:26\n   │\n67 │         if (rolled[w] || block.timestamp >= claimDeadline(w)) 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/FarmCore.sol:228:13\n    │\n228 │         if (f.paidXpDay != block.timestamp / 1 days) return PAID_XP_PER_DAY;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:121:31\n    │\n121 │         Economy eco = Economy(registry.module(10));\n    │                               ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:140:35\n    │\n140 │         stable += 5000 * lobby / (eco.averageDaily() * 5 + lobby);\n    │                                   ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:173:33\n    │\n173 │             outputBonus[e][d] = civic.outputBonus(d);\n    │                                 ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/GridOperator.sol:120:21\n    │\n120 │         if (d >= 8) revert InvalidValue();\n    │                     ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:167:20\n    │\n167 │         x.target = uint64(ChainClock.number() + 1);\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/GridOperator.sol:168:21\n    │\n168 │         x.started = uint64(block.timestamp);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/GridOperator.sol:250:9\n    │\n250 │         fees().payWork(keeper, Params.Key.EntropyBounty, 1, startGas - gasleft());\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/V4Market.sol:262:13\n    │\n262 │             emit PriceObserved(now_, price);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/V4Market.sol:275:9\n    │\n275 │         emit PriceObserved(now_, price);\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/Season.sol:81:26\n   │\n81 │         if (rolled[w] || block.timestamp < claimDeadline(w)) 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/GridOperator.sol:225:13\n    │\n225 │             sum += w;\n    │             ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/GridOperator.sol:210:27\n    │\n210 │             if (old == k) repeated++;\n    │                           ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/GridOperator.sol:209:57\n    │\n209 │             if (old == Kind.Green || old == Kind.Cheap) positives++;\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/Season.sol:154:13\n    │\n154 │         if (block.timestamp < launchTime()) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:233:34\n    │\n233 │                     x.district = uint8(d);\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/Season.sol:161:13\n    │\n161 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Season.sol:202:60\n    │\n202 │         if (districtSpendOf[w][p] > low) topSpenders[w][d][slot] = p;\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/SwarmDesk.sol:313:13\n    │\n313 │             a.expiresAt < block.timestamp || uint256(a.issuedAt) + (stream == 0 ? 6 hours : 1 days) < block.timestamp\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/SwarmDesk.sol:313:46\n    │\n313 │             a.expiresAt < block.timestamp || uint256(a.issuedAt) + (stream == 0 ? 6 hours : 1 days) < block.timestamp\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/SwarmDesk.sol:314:31\n    │\n314 │                 || (direct && block.timestamp >= p.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/SwarmDesk.sol:330:13\n    │\n330 │             emit AnswerIgnored(a.requestId, 2);\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/SwarmDesk.sol:334:13\n    │\n334 │             emit AnswerIgnored(a.requestId, 2);\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/SwarmDesk.sol:348:9\n    │\n348 │         emit AnswerStored(stream, a.requestId, s, a.answer);\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/Season.sol:234:13\n    │\n234 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:346:59\n    │\n346 │             keccak256(a.answer), a.requestId, a.issuedAt, uint64(until), uint64(s), true, uint48(ChainClock.number())\n    │                                                           ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:346:74\n    │\n346 │             keccak256(a.answer), a.requestId, a.issuedAt, uint64(until), uint64(s), true, uint48(ChainClock.number())\n    │                                                                          ━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:346:91\n    │\n346 │             keccak256(a.answer), a.requestId, a.issuedAt, uint64(until), uint64(s), true, uint48(ChainClock.number())\n    │                                                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint48' is safe 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/Season.sol:253:13\n    │\n253 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\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/Season.sol:280:42\n    │\n280 │         if (!rewards().seasonReady(w) || block.timestamp < deadline(w) || limit == 0 || limit > 64) revert TooEarly();\n    │                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:283:20\n    │\n283 │         s.target = uint64(ChainClock.number() + 2);\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/Season.sol:328:39\n    │\n328 │             if (s.best != address(0)) rewards().award(s.best, s.prize);\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/Season.sol:329:18\n    │\n329 │             else rewards().releasePrize(s.prize);\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/Season.sol:331:34\n    │\n331 │         if (s.participants != 0) fees().payWork(msg.sender, Params.Key.SeasonBounty, 1, startGas - gasleft());\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/Season.sol:319:25\n    │\n319 │         for (uint256 i; i < 3 && left != 0; ++i) {\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/Season.sol:332:9\n    │\n332 │         emit SeasonFinalized(w, s.winnerDistrict, s.best, s.seed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:315:36\n    │\n315 │                 s.winnerDistrict = uint8(d);\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/Season.sol:338:20\n    │\n338 │         s.target = uint64(ChainClock.number() + 2);\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/Season.sol:359:14\n    │\n359 │         id = packs().rewardPack(msg.sender);\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/Season.sol:369:14\n    │\n369 │         id = items().mint(msg.sender, k, r, true);\n    │              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[missing-events-arithmetic]: `otherInflow` is changed without an event but is used in arithmetic\n   ╭▸ src/RewardPool.sol:75:23\n   │\n75 │         if (!endowed) otherInflow += amount;\n   │                       ━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:234:24\n    │\n234 │         uint64 today = uint64(block.timestamp / 1 days);\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/RewardPool.sol:51:33\n   │\n51 │         if (endowment() == 0 || block.timestamp >= dripStart + dripPeriod) return 0;\n   │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/FarmCore.sol:261:53\n    │\n261 │         if (room == 1) return farms[p].born != 0 && block.timestamp >= farms[p].born + 3 days;\n    │                                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/V4Market.sol:269:38\n    │\n269 │             uint256 c = cumulative + (1e60 / lastPrice) * (minute * 60 - updatedAt);\n    │                                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/V4Market.sol:272:23\n    │\n272 │         cumulative += (1e60 / lastPrice) * (now_ - updatedAt);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/RewardPool.sol:91:13\n   │\n91 │         if (token().balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/V4Market.sol:267:13\n    │\n267 │         if (last >= 32 && first < last - 31) first = last - 31;\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/V4Market.sol:267:27\n    │\n267 │         if (last >= 32 && first < last - 31) first = last - 31;\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/V4Market.sol:268:38\n    │\n268 │         for (uint256 minute = first; minute <= last; ++minute) {\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/FarmCore.sol:289:9\n    │\n289 │         emit Registered(p, district(p));\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/RewardPool.sol:99:9\n   │\n99 │         emit Reserved(amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:270:53\n    │\n270 │             observations[minute % 32] = Observation(uint64(minute), c);\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/FarmCore.sol:286:18\n    │\n286 │         f.born = 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[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/RewardPool.sol:107:67\n    │\n107 │     function pay(address to, uint256 amount) external onlyRewards nonReentrant {\n    │                                                                   ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/V4Market.sol:281:50\n    │\n281 │         if (ts >= updatedAt) return cumulative + (1e60 / lastPrice) * (ts - updatedAt);\n    │                                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/V4Market.sol:288:35\n    │\n288 │         if (initializedAt == 0 || block.timestamp < initializedAt + 31 minutes) revert NotConfigured();\n    │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:146:26\n    │\n146 │         return FarmItems(registry.module(3));\n    │                          ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:320:39\n    │\n320 │             FarmItems.Item memory x = items().data(f.active[i]);\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:313:25\n    │\n313 │         f.activeEpoch = uint64(e);\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/FarmCore.sol:315:25\n    │\n315 │         f.activeBoost = uint16(_boost(p, rewards().epochTime(e)));\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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/V4Market.sol:304:13\n    │\n304 │         if (a.period != p) {\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/V4Market.sol:310:13\n    │\n310 │         if (b.period != p) {\n    │             ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:306:24\n    │\n306 │             a.period = uint64(p);\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/V4Market.sol:312:24\n    │\n312 │             b.period = uint64(p);\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/V4Market.sol:315:24\n    │\n315 │             a.sells += uint192(amount);\n    │                        ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:316:24\n    │\n316 │             b.sells += uint192(amount);\n    │                        ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:318:23\n    │\n318 │             a.buys += uint192(amount);\n    │                       ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:319:23\n    │\n319 │             b.buys += uint192(amount);\n    │                       ━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint192' is safe 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/SwarmDesk.sol:365:37\n    │\n365 │         if (p.streamPlusOne == 0 || block.timestamp < p.deadline) revert TooEarly();\n    │                                     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:367:35\n    │\n367 │         emit OracleFailure(id, 0, bytes32(\"timeout\"));\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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/V4Market.sol:330:17\n    │\n330 │                 b += shortVolumes[i].buys;\n    │                 ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/V4Market.sol:329:17\n    │\n329 │                 s += shortVolumes[i].sells;\n    │                 ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/Civic.sol:61:13\n   │\n61 │         if (t.balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/V4Market.sol:328:17\n    │\n328 │             if (uint256(shortVolumes[i].period) + 12 > current) {\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/V4Market.sol:338:17\n    │\n338 │             if (uint256(longVolumes[i].period) + 24 > current) {\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/Civic.sol:84:82\n   │\n84 │         if (feature >= FEATURES || noticeAt[feature] == 0 || enabled[feature] || block.timestamp < noticeAt[feature]) {\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/Civic.sol:103:17\n    │\n103 │         return (block.timestamp < boostUntil[d] ? seasonBoost[d] : 0) + (block.timestamp < warBoostUntil[d] ? 1000 : 0);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Civic.sol:103:74\n    │\n103 │         return (block.timestamp < boostUntil[d] ? seasonBoost[d] : 0) + (block.timestamp < warBoostUntil[d] ? 1000 : 0);\n    │                                                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/V4Market.sol:394:13\n    │\n394 │         if (average != 0 && price > average) dev = Math.min(1000, 10000 - Math.mulDiv(average, 10000, price));\n    │             ━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:332:9\n    │\n332 │         rewards().recordSales(n);\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/FarmCore.sol:333:9\n    │\n333 │         season().recordSpend(p, ethValue, true);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Civic.sol:137:13\n    │\n137 │             uint64(block.timestamp + 48 hours),\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/V4Market.sol:393:13\n    │\n393 │         if (block.timestamp >= initializedAt + 31 minutes) average = twap();\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/V4Market.sol:399:27\n    │\n399 │         uint256 decayed = storedFeeWad > fall ? storedFeeWad - fall : PROJECT_BPS * 1 ether;\n    │                           ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Civic.sol:173:66\n    │\n173 │         if (!found && contribution[warId][msg.sender] > low) top[slot] = msg.sender;\n    │                                                                  ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Civic.sol:173:14\n    │\n173 │         if (!found && contribution[warId][msg.sender] > low) top[slot] = 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/Civic.sol:152:42\n    │\n152 │         if (!enabled[0] || warId == 0 || block.timestamp >= w.end || w.settled || (d != w.a && d != w.b)) {\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/V4Market.sol:420:13\n    │\n420 │             emit LaunchTax(sender, ethIn, taxBps, fee);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:413:25\n    │\n413 │         uint256 ethIn = uint256(-p.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-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/Civic.sol:71:9\n   │\n71 │         RewardPool(pool).donate(amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:416:19\n    │\n416 │         if (fee > uint256(uint128(type(int128).max))) revert InvalidValue();\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/V4Market.sol:416:27\n    │\n416 │         if (fee > uint256(uint128(type(int128).max))) revert InvalidValue();\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/V4Market.sol:425:43\n    │\n425 │         return (this.beforeSwap.selector, int256(fee << 128), 0);\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/Civic.sol:192:40\n    │\n192 │         if (warId == 0 || w.settled || block.timestamp < w.end) 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/Civic.sol:202:9\n    │\n202 │         emit WarFinished(warId, w.winner, w.payout, toPool);\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/Civic.sol:228:67\n    │\n228 │             !enabled[1] || !collapseFinalized || outagePending || block.timestamp < greenUntil\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/Civic.sol:239:34\n    │\n239 │         if (collapseFinalized || block.timestamp >= collapseEnd) 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/Civic.sol:243:9\n    │\n243 │         emit CollapseFunded(msg.sender, 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/FarmCore.sol:344:9\n    │\n344 │         rewards().setReferrer(msg.sender, inviter);\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/Civic.sol:247:34\n    │\n247 │         if (collapseFinalized || block.timestamp < collapseEnd) 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/Civic.sol:261:13\n    │\n261 │         if (block.timestamp < greenUntil) return 1;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Civic.sol:280:48\n    │\n280 │         lots[w] = Lot(kind, rarity, supply, 0, uint64(block.timestamp));\n    │                                                ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/Civic.sol:298:9\n    │\n298 │         ICore(registry.module(2)).civicPurchase(msg.sender, cost);\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/Civic.sol:299:14\n    │\n299 │         id = FarmItems(registry.module(3)).mint(msg.sender, l.kind, l.rarity, false);\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/Civic.sol:300:9\n    │\n300 │         emit LotBought(w, msg.sender, id, cost);\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/V4Market.sol:454:9\n    │\n454 │         emit SellFee(sender, output, bps, hour, day, dev);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:436:27\n    │\n436 │         int128 ethDelta = int128(delta >> 128);\n    │                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:439:28\n    │\n439 │             _record(false, uint256(-int256(ethDelta)));\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/V4Market.sol:443:26\n    │\n443 │         uint256 output = uint256(uint128(ethDelta));\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/V4Market.sol:443:34\n    │\n443 │         uint256 output = uint256(uint128(ethDelta));\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/V4Market.sol:445:42\n    │\n445 │         return (this.afterSwap.selector, int128(int256(_chargeSell(sender, output, price))));\n    │                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:445:49\n    │\n445 │         return (this.afterSwap.selector, int128(int256(_chargeSell(sender, output, price))));\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]: `claims` is changed without an event but is used for access control\n   ╭▸ src/StarterClaim.sol:91:9\n   │\n91 │         claims[tokenId] = Claim(msg.sender, target, false);\n   │         ━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/PackSale.sol:182:28\n    │\n182 │         uint256 received = fees().zapBuy{value: msg.value}(minTokens, address(this));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/SwarmDesk.sol:405:13\n    │\n405 │             grid.submitPlan(e, GridOperator.Kind(kind), severity, v[5], notice);\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/SwarmDesk.sol:421:13\n    │\n421 │             params.set(k, target, notice);\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/SwarmDesk.sol:426:47\n    │\n426 │             if (civic.noticeAt(feature) == 0) civic.announce(feature, notice);\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/SwarmDesk.sol:430:13\n    │\n430 │             enhancement.announceCap(enhancement.cap() == 8 ? 12 : 16, notice);\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/SwarmDesk.sol:434:17\n    │\n434 │               try civic.grantDistrictBoost(\n    │ ┏━━━━━━━━━━━━━━━━━┛\n435 │ ┃                 _clamp(uint256(v[11]) >> 128, 1, 8) - 1,\n436 │ ┃                 uint16(_clamp(uint256(v[11]) & type(uint128).max, 0, 1500)),\n437 │ ┃                 notice\n438 │ ┃             ) {}\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/SwarmDesk.sol:445:13\n    │\n445 │             packs.unpause();\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/SwarmDesk.sol:447:17\n    │\n447 │             try packs.pause(_clamp(uint256(v[12]) - 1, 1, 72 hours)) {}\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/SwarmDesk.sol:453:17\n    │\n453 │               try civic.startWar(\n    │ ┏━━━━━━━━━━━━━━━━━┛\n454 │ ┃                 uint8(_clamp(uint256(v[13]) >> 128, 1, 8) - 1),\n455 │ ┃                 uint8(_clamp(uint256(v[13]) & type(uint128).max, 1, 8) - 1)\n456 │ ┃             ) {}\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/SwarmDesk.sol:463:17\n    │\n463 │             try civic.startCollapse(_clamp(uint256(v[14]), daily, daily * 100)) {}\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/SwarmDesk.sol:469:17\n    │\n469 │               try civic.listLot(\n    │ ┏━━━━━━━━━━━━━━━━━┛\n470 │ ┃                 uint8(_clamp(uint256(v[15]) >> 16, 1, 12) - 1),\n471 │ ┃                 uint8(_clamp((uint256(v[15]) >> 8) & 255, 1, 3)),\n472 │ ┃                 uint8(_clamp(uint256(v[15]) & 255, 1, 3))\n473 │ ┃             ) {}\n    │ ┗━━━━━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[missing-events-access-control]: `entropyHash` is changed without an event but is used for access control\n    ╭▸ src/StarterClaim.sol:112:9\n    │\n112 │         entropyHash[tokenId] = h;\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[missing-events-access-control]: `entropyCaptured` is changed without an event but is used for access control\n    ╭▸ src/StarterClaim.sol:113:9\n    │\n113 │         entropyCaptured[tokenId] = true;\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:373:9\n    │\n373 │         items().equip(msg.sender, id);\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/FarmCore.sol:375:13\n    │\n375 │           if (rewards()\n    │ ┏━━━━━━━━━━━━━┛\n376 │ ┃                 .beginMining(\n377 │ ┃                     msg.sender,\n378 │ ┃                     engine().allocationHash(f.loadout, f.paid != 0) * (10000 + _boost(msg.sender, block.timestamp))\n379 │ ┃                         / 10000\n380 │ ┃                 )) {\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/StarterClaim.sol:47:9\n   │\n47 │         farm().register(msg.sender);\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/StarterClaim.sol:35:13\n   │\n35 │         if (block.timestamp >= freeClaimEnds()) 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/StarterClaim.sol:48:9\n   │\n48 │         emit StarterCommitted(id, msg.sender, ChainClock.number() + 2);\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/SwarmDesk.sol:375:13\n    │\n375 │         if (block.timestamp >= r.validUntil || r.slot != slot(stream)) {\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/StarterClaim.sol:49:9\n   │\n49 │         emit FreePackClaimed(msg.sender, index, id);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:366:29\n    │\n366 │             if (old != 0 && items().data(old).kind == x.kind) revert InvalidValue();\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/SwarmDesk.sol:385:9\n    │\n385 │         emit Executed(stream, r.requestId, letter);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StarterClaim.sol:46:40\n   │\n46 │         claims[id] = Claim(msg.sender, uint64(ChainClock.number() + 2), false);\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/FarmCore.sol:385:9\n    │\n385 │         emit Placed(msg.sender, id, room, slot);\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/FarmCore.sol:366:63\n    │\n366 │             if (old != 0 && items().data(old).kind == x.kind) revert InvalidValue();\n    │                                                               ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/StarterClaim.sol:92:9\n   │\n92 │         farm().register(msg.sender);\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/StarterClaim.sol:84:13\n   │\n84 │         if (block.timestamp < launchTime() + 48 hours || block.timestamp >= launchTime() + 16 days) 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/StarterClaim.sol:84:58\n   │\n84 │         if (block.timestamp < launchTime() + 48 hours || block.timestamp >= launchTime() + 16 days) revert TooEarly();\n   │                                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:404:33\n    │\n404 │             if (e <= current || grid.planAt(e).submitted) continue;\n    │                                 ━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:405:13\n    │\n405 │             grid.submitPlan(e, GridOperator.Kind(kind), severity, v[5], notice);\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/StarterClaim.sol:93:9\n   │\n93 │         emit StarterCommitted(tokenId, msg.sender, target);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:398:22\n    │\n398 │         uint8 kind = uint8(_clamp(uint256(v[2]), 0, maxKind));\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/StarterClaim.sol:90:25\n   │\n90 │         uint64 target = uint64(ChainClock.number() + 2);\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/SwarmDesk.sol:400:27\n    │\n400 │         uint16 severity = uint16(_clamp(uint256(v[3]), SEVERITY_MIN, SEVERITY_MAX));\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:401:24\n    │\n401 │         districtHint = uint8(_clamp(uint256(v[4]), 0, 7)); // Advisory only; preserve weighted district/entropy rules.\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/StarterClaim.sol:114:9\n    │\n114 │         fees().payWork(keeper, Params.Key.EntropyBounty, 1, startGas - gasleft());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/StarterClaim.sol:130:20\n    │\n130 │         c.target = uint64(ChainClock.number() + 2);\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/StarterClaim.sol:145:13\n    │\n145 │             items().mint(c.player, k, r, true);\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/SwarmDesk.sol:420:34\n    │\n420 │             if (target == old || block.timestamp < params.lastChanged(k) + 1 days) continue;\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/StarterClaim.sol:72:26\n   │\n72 │         return FarmItems(registry.module(3));\n   │                          ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:417:27\n    │\n417 │             uint256 old = params.get(k);\n    │                           ━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:418:40\n    │\n418 │             (uint256 lo, uint256 hi) = params.bounds(k);\n    │                                        ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/StarterClaim.sol:145:13\n    │\n145 │             items().mint(c.player, k, r, true);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:420:52\n    │\n420 │             if (target == old || block.timestamp < params.lastChanged(k) + 1 days) continue;\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/SwarmDesk.sol:421:13\n    │\n421 │             params.set(k, target, notice);\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/StarterClaim.sol:147:9\n    │\n147 │         emit StarterResolved(tokenId, h == bytes32(0));\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/FarmCore.sol:395:9\n    │\n395 │         items().unequip(msg.sender, id);\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/SwarmDesk.sol:440:17\n    │\n440 │                 emit ActionSkipped(0, reason);\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/SwarmDesk.sol:449:17\n    │\n449 │                 emit ActionSkipped(1, reason);\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/SwarmDesk.sol:458:17\n    │\n458 │                 emit ActionSkipped(2, reason);\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/SwarmDesk.sol:465:17\n    │\n465 │                 emit ActionSkipped(3, reason);\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/StarterClaim.sol:145:13\n    │\n145 │             items().mint(c.player, k, r, true);\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/SwarmDesk.sol:475:17\n    │\n475 │                 emit ActionSkipped(4, reason);\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/FarmCore.sol:397:9\n    │\n397 │         emit Unplaced(msg.sender, id, room, slot);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:436:17\n    │\n436 │                 uint16(_clamp(uint256(v[11]) & type(uint128).max, 0, 1500)),\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/SwarmDesk.sol:454:17\n    │\n454 │                 uint8(_clamp(uint256(v[13]) >> 128, 1, 8) - 1),\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/SwarmDesk.sol:455:17\n    │\n455 │                 uint8(_clamp(uint256(v[13]) & type(uint128).max, 1, 8) - 1)\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/SwarmDesk.sol:470:17\n    │\n470 │                 uint8(_clamp(uint256(v[15]) >> 16, 1, 12) - 1),\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/SwarmDesk.sol:471:17\n    │\n471 │                 uint8(_clamp((uint256(v[15]) >> 8) & 255, 1, 3)),\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/SwarmDesk.sol:472:17\n    │\n472 │                 uint8(_clamp(uint256(v[15]) & 255, 1, 3))\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[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/Billboards.sol:60:13\n   │\n60 │         if (t.balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/FarmCore.sol:414:9\n    │\n414 │         emit Retired(p);\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/FarmCore.sol:405:56\n    │\n405 │             if (f.loadout[i] != 0 || f.active[i] != 0) revert InvalidValue();\n    │                                                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[arbitrary-send-erc20]: `transferFrom` uses an arbitrary `from`; require it to equal `msg.sender` or `address(this)`\n    ╭▸ src/FarmCore.sol:430:13\n    │\n430 │             token().safeTransferFrom(p, pool(), paid);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-erc20\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/FarmCore.sol:431:17\n    │\n431 │             if (token().balanceOf(pool()) - before_ != paid) revert InvalidValue();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/Billboards.sol:82:17\n   │\n82 │                 revert InvalidValue();\n   │                 ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/Billboards.sol:88:17\n   │\n88 │                 revert InvalidValue();\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/FarmRewards.sol:151:30\n    │\n151 │         return epoch != 0 && block.timestamp < epochs[epoch].end;\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `scrapAllowance` is updated\n    ╭▸ src/FarmRewards.sol:165:13\n    │\n165 │             pool().recycle(scrapAllowance);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `epoch` is updated\n    ╭▸ src/FarmRewards.sol:169:13\n    │\n169 │             grid().resolveFor(epoch, msg.sender);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `epoch` is updated\n    ╭▸ src/FarmRewards.sol:179:17\n    │\n179 │                 pool().reserve(old.budget);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `epoch` is updated\n    ╭▸ src/FarmRewards.sol:186:33\n    │\n186 │                 if (prize != 0) season().addPrize(week, prize);\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/Billboards.sol:70:9\n   │\n70 │         RewardPool(pool).donate(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/FarmRewards.sol:230:9\n    │\n230 │         grid().shift(epoch);\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/FarmRewards.sol:231:9\n    │\n231 │         fees().payBounty(msg.sender);\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/Billboards.sol:120:9\n    │\n120 │         emit BillboardSettled(w, d, b.bid);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmRewards.sol:189:40\n    │\n189 │                     lastAverageDaily = old.mining * (10000 - old.tariff) / 10000 * 4 / activeFarmCount[epoch];\n    │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/FarmRewards.sol:163:13\n    │\n163 │         if (block.timestamp < launchTime() || (epoch != 0 && block.timestamp < epochs[epoch].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/FarmRewards.sol:163:62\n    │\n163 │         if (block.timestamp < launchTime() || (epoch != 0 && block.timestamp < epochs[epoch].end)) revert TooEarly();\n    │                                                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:115:23\n    │\n115 │         return Params(registry.params());\n    │                       ━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:226:36\n    │\n226 │             epochParam[epoch][k] = params().get(Params.Key(k));\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/FarmRewards.sol:198:13\n    │\n198 │             emit EpochClosed(epoch, old.budget, old.raw);\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/FarmRewards.sol:209:13\n    │\n209 │             emit Expired(epoch, gone);\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/FarmRewards.sol:232:9\n    │\n232 │         emit EpochStarted(epoch, e.start, e.end, msg.sender);\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/FarmRewards.sol:171:13\n    │\n171 │             (old.kind, old.severity, old.district, old.seed,) = grid().eventAt(epoch);\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/FarmCore.sol:447:9\n    │\n447 │         items().maintain(id, 10000, x.overclock);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:202:19\n    │\n202 │         e.start = 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/FarmRewards.sol:203:17\n    │\n203 │         e.end = uint64(block.timestamp + EPOCH);\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/FarmRewards.sol:309:9\n    │\n309 │         emit MiningStarted(p, epoch, secondsLeft, weighted);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:456:32\n    │\n456 │         f.cableRepairedEpoch = uint64(rewards().epoch());\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/FarmCore.sol:457:29\n    │\n457 │         f.routerRepairBps = uint16((rewards().epochEnd() - block.timestamp) * 10000 / 6 hours);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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/FarmCore.sol:470:9\n    │\n470 │         items().expand(msg.sender);\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/PackSale.sol:199:9\n    │\n199 │         farm().register(recipient);\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/PackSale.sol:200:9\n    │\n200 │         farm().paidPackBought(recipient, n, cost);\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/PackSale.sol:207:9\n    │\n207 │         fees().routeTokens(cost);\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/PackSale.sol:234:9\n    │\n234 │         emit PackCommitted(id, p, n, target, guaranteed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:492:13\n    │\n492 │             rewards().spendTo(p, amount, router);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:494:9\n    │\n494 │         FeeRouter(payable(router)).routeTokens(amount);\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/FarmRewards.sol:350:25\n    │\n350 │         for (uint256 n; n < limit && cursor < settledEpoch; ++n) {\n    │                         ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:480:9\n    │\n480 │         rewards().recordSales(1);\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/FarmCore.sol:481:9\n    │\n481 │         season().recordSpend(msg.sender, price, true);\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/FarmCore.sol:482:14\n    │\n482 │         id = ITokenPacks(packs()).tokenPack(msg.sender);\n    │              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:123:22\n    │\n123 │         return ICore(registry.module(2));\n    │                      ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:359:60\n    │\n359 │         (uint256 raw, uint256 productive, uint256 power) = core().process(p, id);\n    │                                                            ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:139:16\n    │\n139 │         return registry.launchTime();\n    │                ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:425:9\n    │\n425 │         core().autoRepair(p, id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:119:27\n    │\n119 │         return RewardPool(registry.module(0));\n    │                           ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:446:26\n    │\n446 │         if (unused != 0) pool().recycle(unused);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:449:28\n    │\n449 │             if (dust != 0) pool().recycle(dust);\n    │                            ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:431:13\n    │\n431 │             core().activity(p, id, o.gross, o.net);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:433:17\n    │\n433 │                 core().grantDrop(p, keccak256(abi.encode(e.seed, p, \"item\")));\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:135:24\n    │\n135 │         return ISeason(registry.module(8));\n    │                        ━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:435:13\n    │\n435 │             season().recordActivity(p, week, o.gross, weight);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:380:13\n    │\n380 │             season().complete(p, week);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/FarmCore.sol:490:17\n    │\n490 │             if (token().balanceOf(router) - before_ != amount) revert InvalidValue();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/FarmRewards.sol:477:13\n    │\n477 │             emit Credited(p, e, 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/FarmRewards.sol:488:9\n    │\n488 │         emit Credited(p, e, 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/FarmRewards.sol:450:13\n    │\n450 │             emit EpochSettled(id, e.spent, dust);\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/FarmRewards.sol:422:35\n    │\n422 │         if (spent > o.allocation) revert InvalidValue();\n    │                                   ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/V4Market.sol:472:31\n    │\n472 │         received = abi.decode(manager.unlock(abi.encode(msg.value, minOut, recipient)), (uint256));\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/FarmRewards.sol:475:13\n    │\n475 │         if (block.timestamp >= at + 7 days) {\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/FarmCore.sol:492:13\n    │\n492 │             rewards().spendTo(p, amount, router);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:485:19\n    │\n485 │         v.epoch = uint64(e);\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/FarmRewards.sol:486:48\n    │\n486 │         if (at > v.at || v.amount == 0) v.at = uint64(at);\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/FarmCore.sol:494:9\n    │\n494 │         FeeRouter(payable(router)).routeTokens(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/FarmCore.sol:501:9\n    │\n501 │         season().recordSpend(msg.sender, amount, true);\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/FarmCore.sol:502:9\n    │\n502 │         grid().tokenLobby(msg.sender, amount);\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/FarmRewards.sol:514:25\n    │\n514 │         for (uint256 n; n < 32 && amount != 0; ++n) {\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/FarmRewards.sol:503:36\n    │\n503 │             if (old.amount != 0 && block.timestamp >= uint256(old.at) + 7 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/FarmRewards.sol:520:45\n    │\n520 │             if (taxed) tax += used * taxBps(block.timestamp > v.at ? block.timestamp - v.at : 0) / 10000;\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/FarmCore.sol:513:9\n    │\n513 │         items().destroy(id);\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/FarmCore.sol:514:26\n    │\n514 │         uint256 earned = rewards().scrap(msg.sender, hash, minimum);\n    │                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmCore.sol:512:24\n    │\n512 │         uint256 hash = ItemMath.baseHash(x.rarity) * (x.kind < 3 ? 10000 : 6000) / 10000 * x.durability / 10000;\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/FarmCore.sol:515:9\n    │\n515 │         emit Scrapped(msg.sender, id, earned);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmCore.sol:535:14\n    │\n535 │         if (!occupied) return (0, 0, 0);\n    │              ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:546:28\n    │\n546 │             if (id != 0 && items().data(id).holder == address(0)) _remove(f, id);\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/FarmCore.sol:578:14\n    │\n578 │         id = items().mintDrop(msg.sender, seed);\n    │              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/PackSale.sol:206:13\n    │\n206 │         if (t.balanceOf(address(fees())) - before_ != cost) revert InvalidValue();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/PackSale.sol:212:25\n    │\n212 │         if (paused() || block.timestamp < opensAt()) revert TooEarly();\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:232:25\n    │\n232 │         uint64 target = uint64(ChainClock.number() + 2);\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/PackSale.sol:256:9\n    │\n256 │         fees().payWork(keeper, Params.Key.EntropyBounty, 1, startGas - gasleft());\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:270:20\n    │\n270 │         c.target = uint64(ChainClock.number() + 2);\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/PackSale.sol:289:13\n    │\n289 │             items().mint(c.player, k, r, c.guaranteed);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:87:26\n   │\n87 │         return FarmItems(registry.module(3));\n   │                          ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:289:13\n    │\n289 │             items().mint(c.player, k, r, c.guaranteed);\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/PackSale.sol:291:9\n    │\n291 │         emit PackOpened(id, n, c.expired);\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/PackSale.sol:289:13\n    │\n289 │             items().mint(c.player, k, r, c.guaranteed);\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/FarmRewards.sol:359:60\n    │\n359 │         (uint256 raw, uint256 productive, uint256 power) = core().process(p, id);\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/FarmRewards.sol:380:13\n    │\n380 │             season().complete(p, week);\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/FarmRewards.sol:425:9\n    │\n425 │         core().autoRepair(p, id);\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/FarmRewards.sol:431:13\n    │\n431 │             core().activity(p, id, o.gross, o.net);\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/FarmRewards.sol:433:17\n    │\n433 │                 core().grantDrop(p, keccak256(abi.encode(e.seed, p, \"item\")));\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/FarmRewards.sol:435:13\n    │\n435 │             season().recordActivity(p, week, o.gross, weight);\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/FarmRewards.sol:446:26\n    │\n446 │         if (unused != 0) pool().recycle(unused);\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/FarmRewards.sol:449:28\n    │\n449 │             if (dust != 0) pool().recycle(dust);\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/FarmRewards.sol:533:9\n    │\n533 │         pool().pay(msg.sender, net);\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/FarmRewards.sol:293:9\n    │\n293 │         emit Committed(p, weight, epoch + 1, expiry);\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/FarmRewards.sol:534:9\n    │\n534 │         emit Claimed(msg.sender, amount, tax);\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/FarmRewards.sol:542:9\n    │\n542 │         emit Spent(p, consumed);\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/FarmRewards.sol:553:9\n    │\n553 │         emit Spent(p, amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:63:39\n   │\n63 │             FarmItems.Item memory x = inventory.data(id);\n   │                                       ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:95:45\n   │\n95 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                             ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:95:35\n   │\n95 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:87:45\n   │\n87 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                             ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/FarmRewards.sol:556:80\n    │\n556 │     function scrap(address p, uint256 hash, uint256 minimum) external onlyCore nonReentrant returns (uint256 amount) {\n    │                                                                                ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:87:35\n   │\n87 │         FarmItems.Item memory x = FarmItems(registry.module(3)).data(id);\n   │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:52:30\n   │\n52 │         return IYieldRewards(registry.module(1));\n   │                              ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:91:64\n   │\n91 │         return Math.mulDiv(hash * 4, Math.max(HASH_RATE_FLOOR, rewards().lastYieldPerHash()), 1 ether);\n   │                                                                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:99:30\n   │\n99 │             missing * Params(registry.params()).get(Params.Key.RepairHours),\n   │                              ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:99:23\n   │\n99 │             missing * Params(registry.params()).get(Params.Key.RepairHours),\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/FarmRewards.sol:570:9\n    │\n570 │         pool().recycle(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:66:17\n   │\n66 │             if (reward.pending(p) < cost) continue;\n   │                 ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:67:21\n   │\n67 │             paid += reward.spend(p, cost);\n   │                     ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/Economy.sol:68:13\n   │\n68 │             inventory.maintain(id, 10000, x.overclock);\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/Economy.sol:88:37\n   │\n88 │         if (x.holder == address(0)) revert InvalidValue();\n   │                                     ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n  ╭▸ src/lib/ItemMath.sol:8:25\n  │\n8 │         if (rarity > 4) revert InvalidValue();\n  │                         ━━━━━━━━━━━━━━━━━━━━━━\n  │\n  ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/lib/EconomyMath.sol:19:39\n   │\n19 │         if (level == 0 || level > 16) revert InvalidValue();\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/Economy.sol:77:27\n   │\n77 │         if (start == 0 || start > block.timestamp) revert NotConfigured();\n   │                           ━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n   ╭▸ src/Economy.sol:90:16\n   │\n90 │         hash = hash * (10000 + EconomyMath.bonus(x.overclock)) / 10000;\n   │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n   ╭▸ src/Economy.sol:91:28\n   │\n91 │         return Math.mulDiv(hash * 4, Math.max(HASH_RATE_FLOOR, rewards().lastYieldPerHash()), 1 ether);\n   │                            ━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/Economy.sol:136:9\n    │\n136 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\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/Economy.sol:149:9\n    │\n149 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\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/Economy.sol:150:9\n    │\n150 │         emit Locked(msg.sender, amount, block.timestamp + days_ * 1 days, bps);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Economy.sol:140:42\n    │\n140 │         locks[msg.sender] = Lock(amount, uint64(block.timestamp), uint64(block.timestamp + days_ * 1 days), uint16(bps));\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/Economy.sol:140:67\n    │\n140 │         locks[msg.sender] = Lock(amount, uint64(block.timestamp), uint64(block.timestamp + days_ * 1 days), uint16(bps));\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/Economy.sol:140:109\n    │\n140 │         locks[msg.sender] = Lock(amount, uint64(block.timestamp), uint64(block.timestamp + days_ * 1 days), uint16(bps));\n    │                                                                                                             ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/Economy.sol:148:13\n    │\n148 │         if (t.balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[reentrancy-no-eth]: external call can be reentered before `locks` is updated\n    ╭▸ src/Economy.sol:156:9\n    │\n156 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\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/Economy.sol:167:9\n    │\n167 │         IEconomyCore(registry.module(2)).syncFor(msg.sender);\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/Economy.sol:155:30\n    │\n155 │         if (l.amount == 0 || block.timestamp < l.end) 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/Economy.sol:169:9\n    │\n169 │         emit Unlocked(msg.sender, l.amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Economy.sol:180:23\n    │\n180 │         previous[p] = prev;\n    │                       ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Economy.sol:191:25\n    │\n191 │         for (uint256 i; i < 10 && p != address(0); ++i) {\n    │                         ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unused-return]: return value of an external call is not used\n   ╭▸ src/FarmEngine.sol:61:30\n   │\n61 │             (, uint256 hi) = params().bounds(k);\n   │                              ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:40:26\n   │\n40 │         return FarmItems(registry.module(3));\n   │                          ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:74:27\n   │\n74 │             f.clocks[i] = items().data(ids[i]).overclock;\n   │                           ━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:126:39\n    │\n126 │             FarmItems.Item memory x = items().data(id);\n    │                                       ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:160:35\n    │\n160 │         FarmItems.Item memory x = items().data(id);\n    │                                   ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:44:23\n   │\n44 │         return Params(registry.params());\n   │                       ━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:61:30\n   │\n61 │             (, uint256 hi) = params().bounds(k);\n   │                              ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:48:25\n   │\n48 │         return IRewards(registry.module(1));\n   │                         ━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:64:25\n   │\n64 │         return active ? rewards().epochParam(e, uint256(k)) : params().get(k);\n   │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:64:63\n   │\n64 │         return active ? rewards().epochParam(e, uint256(k)) : params().get(k);\n   │                                                               ━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/FarmEngine.sol:121:24\n    │\n121 │         if (room >= 4) revert InvalidValue();\n    │                        ━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:88:39\n   │\n88 │             FarmItems.Item memory x = items().data(ids[i]);\n   │                                       ━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:168:29\n    │\n168 │         a.baseProductive += raw * tier / 10000;\n    │                             ━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:169:15\n    │\n169 │         raw = raw * (10000 + EconomyMath.bonus(f.clocks[idx])) / 10000;\n    │               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:171:25\n    │\n171 │         s.productive += raw * tier / 10000;\n    │                         ━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmEngine.sol:202:32\n    │\n202 │             if (f.ids[i] != 0) occupied++;\n    │                                ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/V4Market.sol:498:31\n    │\n498 │         received = abi.decode(manager.unlock(abi.encode(amount, minOut, recipient)), (uint256));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/V4Market.sol:522:22\n    │\n522 │         (bool ok,) = recipient.call{value: net}(\"\");\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/arbitrary-send-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:506:39\n    │\n506 │             key(), SwapParams(false, -int256(amount), 1461446703485210103287273052203988822378723970341), \"\"\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/V4Market.sol:509:25\n    │\n509 │         int128 ethOut = int128(delta >> 128);\n    │                         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:510:26\n    │\n510 │         int128 tokenIn = int128(delta);\n    │                          ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:511:44\n    │\n511 │         if (ethOut <= 0 || tokenIn >= 0 || uint256(-int256(tokenIn)) != amount) revert InsufficientBalance();\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/V4Market.sol:512:25\n    │\n512 │         uint256 gross = uint256(uint128(ethOut));\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/V4Market.sol:512:33\n    │\n512 │         uint256 gross = uint256(uint128(ethOut));\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/V4Market.sol:518:9\n    │\n518 │         manager.settle();\n    │         ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:239:39\n    │\n239 │             FarmItems.Item memory x = items().data(id);\n    │                                       ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:244:21\n    │\n244 │                     items().destroy(id);\n    │                     ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:259:13\n    │\n259 │             items().maintain(id, uint16(x.durability > damage ? x.durability - damage : 0), x.overclock);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:295:39\n    │\n295 │             FarmItems.Item memory x = items().data(id);\n    │                                       ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:296:13\n    │\n296 │             items().maintain(id, x.durability > 100 ? x.durability - 100 : 0, x.overclock);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-no-eth]: external call can be reentered before `updatedAt` is updated\n    ╭▸ src/V4Market.sol:505:24\n    │\n505 │           int256 delta = manager.swap(\n    │ ┏━━━━━━━━━━━━━━━━━━━━━━━━┛\n506 │ ┃             key(), SwapParams(false, -int256(amount), 1461446703485210103287273052203988822378723970341), \"\"\n507 │ ┃         );\n    │ ┗━━━━━━━━━┛\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:221:32\n    │\n221 │                 f.theftUntil = uint64(e + 2);\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/FarmEngine.sol:252:17\n    │\n252 │                 damage += 3000 * uint256(ev.severity) / 10000 / (before_.airflow ? 2 : 1);\n    │                 ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:258:29\n    │\n258 │             f.health[idx] = uint16(f.health[idx] > damage ? f.health[idx] - damage : 0);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:259:34\n    │\n259 │             items().maintain(id, uint16(x.durability > damage ? x.durability - damage : 0), x.overclock);\n    │                                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe 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 `updatedAt` is updated\n    ╭▸ src/V4Market.sol:535:24\n    │\n535 │         int256 delta = manager.swap(key(), SwapParams(true, -int256(input), 4295128740), \"\");\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/Params.sol:176:13\n    │\n176 │         if (block.timestamp < lastChanged[k] + 1 days) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:535:62\n    │\n535 │         int256 delta = manager.swap(key(), SwapParams(true, -int256(input), 4295128740), \"\");\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/V4Market.sol:537:27\n    │\n537 │         int128 ethDelta = int128(delta >> 128);\n    │                           ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe 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/StandardAdapter.sol:46:64\n   │\n46 │         if (rate == 0 || rate > 1e40 || window < 30 minutes || at > block.timestamp || block.timestamp - at > 5 minutes)\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/StandardAdapter.sol:46:88\n   │\n46 │         if (rate == 0 || rate > 1e40 || window < 30 minutes || at > block.timestamp || block.timestamp - at > 5 minutes)\n   │                                                                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:538:29\n    │\n538 │         int128 tokenDelta = int128(delta);\n    │                             ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:540:30\n    │\n540 │             ethDelta >= 0 || uint256(-int256(ethDelta)) != input || tokenDelta <= 0\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/V4Market.sol:541:20\n    │\n541 │                 || uint256(uint128(tokenDelta)) < minOut\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/V4Market.sol:541:28\n    │\n541 │                 || uint256(uint128(tokenDelta)) < minOut\n    │                            ━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/StandardAdapter.sol:58:9\n   │\n58 │         manager.unlock(abi.encode(msg.value, minOut, recipient));\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unused-return]: return value of an external call is not used\n    ╭▸ src/V4Market.sol:546:9\n    │\n546 │         manager.settle{value: input}();\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:547:40\n    │\n547 │         manager.take(token, recipient, uint256(uint128(tokenDelta)));\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/V4Market.sol:547:48\n    │\n547 │         manager.take(token, recipient, uint256(uint128(tokenDelta)));\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/StandardAdapter.sol:58:9\n   │\n58 │         manager.unlock(abi.encode(msg.value, minOut, recipient));\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:549:27\n    │\n549 │         return abi.encode(uint256(uint128(tokenDelta)));\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/V4Market.sol:549:35\n    │\n549 │         return abi.encode(uint256(uint128(tokenDelta)));\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/StandardAdapter.sol:67:62\n   │\n67 │         int256 delta = manager.swap(key(), SwapParams(true, -int256(input), 4295128740), \"\");\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/StandardAdapter.sol:68:27\n   │\n68 │         int128 ethDelta = int128(delta >> 128);\n   │                           ━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'int128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:69:22\n   │\n69 │         int128 out = int128(delta);\n   │                      ━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'int128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:70:30\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\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/StandardAdapter.sol:70:81\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\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/StandardAdapter.sol:70:89\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\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/StandardAdapter.sol:73:9\n   │\n73 │         manager.settle{value: input}();\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:74:49\n   │\n74 │         manager.take(address(token), recipient, uint256(uint128(out)));\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/StandardAdapter.sol:74:57\n   │\n74 │         manager.take(address(token), recipient, uint256(uint128(out)));\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/StandardAdapter.sol:75:27\n   │\n75 │         return abi.encode(uint256(uint128(out)));\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/StandardAdapter.sol:75:35\n   │\n75 │         return abi.encode(uint256(uint128(out)));\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[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/EconomyV35.t.sol:152:43\n    │\n152 │         assertEq(d.economy.boostAt(alice, block.timestamp), 500);\n    │                                           ━━━━━━━━━━━━━━━\n    ‡\n156 │         vm.warp(block.timestamp + 7 days);\n    │         ───────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/EconomyV35.t.sol:156:17\n    │\n156 │         vm.warp(block.timestamp + 7 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/PhasedReleaseV36.t.sol:145:49\n    │\n145 │         assertEq(d.civic.noticeAt(ENHANCEMENT), block.timestamp + 48 hours);\n    │                                                 ━━━━━━━━━━━━━━━\n146 │         vm.warp(block.timestamp + 48 hours - 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/PhasedReleaseV36.t.sol:146:17\n    │\n146 │         vm.warp(block.timestamp + 48 hours - 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/SwarmDeskAdversarial.t.sol:157:17\n    │\n157 │         vm.warp(block.timestamp + 3 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/helpers/SwarmDeskTestFixture.sol:118:29\n    │\n118 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SwarmDeskAdversarial.t.sol:371:9\n    │\n371 │         vm.warp(block.timestamp + 6 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/SwarmDeskTestFixture.sol:119:30\n    │\n119 │         a.expiresAt = uint64(block.timestamp + 1 days);\n    │                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/SwarmDeskAdversarial.t.sol:371:9\n    │\n371 │         vm.warp(block.timestamp + 6 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/SwarmDeskAdversarial.t.sol:371:17\n    │\n371 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:210:17\n    │\n210 │         vm.warp(block.timestamp + 1 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:67:29\n    │\n 67 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n227 │         vm.warp(d.civic.noticeAt(3));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:68:30\n    │\n 68 │         a.expiresAt = uint64(block.timestamp + 6 hours);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n227 │         vm.warp(d.civic.noticeAt(3));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:220:39\n    │\n220 │         assertEq(d.civic.noticeAt(3), block.timestamp + 48 hours);\n    │                                       ━━━━━━━━━━━━━━━\n    ‡\n227 │         vm.warp(d.civic.noticeAt(3));\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:283:17\n    │\n283 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:67:29\n    │\n 67 │         a.issuedAt = uint64(block.timestamp);\n    │                             ━━━━━━━━━━━━━━━\n    ‡\n336 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:68:30\n    │\n 68 │         a.expiresAt = uint64(block.timestamp + 6 hours);\n    │                              ━━━━━━━━━━━━━━━\n    ‡\n336 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:336:17\n    │\n336 │         vm.warp(block.timestamp + 6 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/SwarmDeskV37.t.sol:606:17\n    │\n606 │         vm.warp(block.timestamp + 2 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/SwarmDeskV37.t.sol:631:17\n    │\n631 │         vm.warp(block.timestamp + 2 days);\n    │         ────────━━━━━━━━━━━━━━━────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/V34.t.sol:149:25\n    │\n149 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n152 │         vm.warp(start + 60 minutes - 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/V34.t.sol:230:17\n    │\n230 │         vm.warp(block.timestamp + 5 minutes - 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/V34.t.sol:233:17\n    │\n233 │         vm.warp(block.timestamp + 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/fork/RehearsalV311.t.sol:630:18\n    │\n630 │         vm.warp((block.timestamp / 6 hours) * 6 hours + 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":46842,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/fork/RobinhoodFork.t.sol:RobinhoodForkTest\n[SKIP] testForkArbSysAndHistoricalHash() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 1 skipped; finished in 200.66µs (87.29µs CPU time)\n\nRan 2 tests for test/Clock.t.sol:ClockTest\n[PASS] testLocalEvmFutureBlockAnd256BlockBoundary() (gas: 225376)\n[PASS] testRobinhoodUsesArbSysNotL1EstimateAndHandlesExpiry() (gas: 238560)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 1.16ms (1.02ms CPU time)\n\nRan 1 test for test/WarReviewV35.t.sol:IndependentWarReview\n[PASS] testWarWinnerCannotChangeAfterDeadline() (gas: 5734360)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.18ms (974.39µs CPU time)\n\nRan 1 test for test/YieldFloorReviewV35.t.sol:IndependentYieldFloorReview\n[PASS] testFirstEpochItemQuotesKeepNonzeroFloorAtCorrectScale() (gas: 673277)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.01ms (4.91ms CPU time)\n\nRan 3 tests for test/StandardAdapter.t.sol:StandardAdapterTest\n[PASS] testExistingHookKeyPreservedAndNoExtraFee() (gas: 330662)\n[PASS] testRequiresThirtyMinutesFreshOracleAndAuthorizedCallback() (gas: 198351)\n[PASS] testSettlementSlippageFailurePreservesCredits() (gas: 240594)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 12.25ms (1.20ms CPU time)\n\nRan 6 tests for test/EndowmentEscrowV38.t.sol:EndowmentEscrowV38Test\n[PASS] testConstructorRejectsMissingInputs() (gas: 6182)\n[PASS] testForwardRejectsBadProofs() (gas: 2663621)\n[PASS] testForwardRequiresBalance() (gas: 752051)\n[PASS] testForwardSendsWholeBalanceOnceToAuthenticatedPoolAndFundsEndowment() (gas: 1713359)\n[PASS] testForwardWithRealEndowmentActivatesDrip() (gas: 12550408)\n[PASS] testTwinWithForeignTokenCannotDrainEscrow() (gas: 12456243)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 21.17ms (11.53ms CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] testConstructorRejectsMissingInputsAndDoesNotCallExternalContracts() (gas: 3994)\n[PASS] testForeignCallerDoesNotGetAnyAuthority() (gas: 42642091)\n[PASS] testImmutableGraphAndEip170Sizes() (gas: 187323)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 31.41ms (11.13ms CPU time)\n\nRan 5 tests for test/KeeperProfit.t.sol:KeeperProfitTest\n[PASS] testPaidPackEntropyKeeperProfit() (gas: 1179133)\nLogs:\n  paid pack entropy execution gas: 139616\n  paid pack entropy bounty wei: 3380475000000\n  paid pack entropy execution plus 21000 gas cost wei: 3212320000000\n\n[PASS] testPlanEntropyKeeperProfit() (gas: 1665825)\nLogs:\n  plan entropy execution gas: 163594\n  plan entropy bounty wei: 4488125000000\n  plan entropy execution plus 21000 gas cost wei: 3691880000000\n\n[PASS] testSeasonFinalizeThreeWinnersAndPrizeKeeperProfit() (gas: 3451176)\nLogs:\n  season finalize three winners and prize execution gas: 644051\n  season finalize three winners and prize bounty wei: 15825150000000\n  season finalize three winners and prize execution plus 21000 gas cost wei: 13301020000000\n\n[PASS] testSeasonPrepareIsConstantUnpaidWork() (gas: 1342777)\n[PASS] testStarterEntropyKeeperProfit() (gas: 324553)\nLogs:\n  starter entropy execution gas: 142744\n  starter entropy bounty wei: 3380150000000\n  starter entropy execution plus 21000 gas cost wei: 3274880000000\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 33.87ms (15.89ms CPU time)\n\nRan 5 tests for test/ReviewV34.t.sol:ReviewV34Test\n[PASS] testCanonicalCompetingRegistryCannotTakeOverBinding() (gas: 9451528)\n[PASS] testDustBuyCannotConsumeGlobalBuyInterval() (gas: 336156)\n[PASS] testLateGreenEntrySettlesWithinReservedEnvelope() (gas: 4432362)\n[PASS] testMeaningfulSmallBuyCanUseLessThanMaximumBatch() (gas: 263646)\n[PASS] testSameConfigurationAtUncommittedCoordinatesCannotBind() (gas: 9538431)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 35.36ms (17.48ms CPU time)\n\nRan 3 tests for test/HookBinding.t.sol:HookBindingTest\n[PASS] testHoldBeforeGameExistsThenBindOnceAndFlushExactStreams() (gas: 43111685)\n[PASS] testLookAlikeCannotBindEvenWhenTeamCalls() (gas: 1907686)\n[PASS] testWrongRouterAndMissingCodeRejectedBeforePermanentBind() (gas: 40825860)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 40.97ms (21.29ms CPU time)\n\nRan 3 tests for test/TwinCaptureV312.t.sol:TwinCaptureV312Test\n[PASS] testHonestBindThenForwardReachesHonestPool() (gas: 6020873)\n[PASS] testTwinCaptureCannotPayAttacker() (gas: 11367879)\n[PASS] testTwinCaptureOrphansHonestGame() (gas: 11350429)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 42.28ms (17.64ms CPU time)\n\nRan 1 test for test/PredictionV34.t.sol:PredictionV34Test\n[PASS] testFullGraphPredictsPoolBeforeRegistryDeployment() (gas: 4190905)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 11.01ms (958.86µs CPU time)\n\nRan 2 tests for test/V310.t.sol:ToolchainPinsV310Test\n[PASS] testEveryModuleOfThisBuildMatchesOneToolchainPin() (gas: 167162)\n[PASS] testPinsAreOneToolchainAndRejectUnknownCode() (gas: 162929)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.70ms (1.31ms CPU time)\n\nRan 3 tests for test/PotV35.t.sol:PotV35Test\n[PASS] testPotDepositRequiresActualTokensAndAuthority() (gas: 256924)\n[PASS] testPotSplitDistinctLotteryDistrictAndRollbackOnFullInventory() (gas: 11488024)\n[PASS] testPotUnclaimedRolloverOnlyAfterFourWeeksNoDoubleClaim() (gas: 6429645)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 50.43ms (33.45ms CPU time)\n\nRan 3 tests for test/Pause.t.sol:PauseTest\n[PASS] testOnlySwarmBoundedDurationAndCannotExtendPause() (gas: 242972)\n[PASS] testSalePausedWhileEntropyClaimsWithdrawalsAndEpochsContinue() (gas: 15156588)\n[PASS] testUnpauseCannotResetNextPauseCooldown() (gas: 194647)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 54.74ms (40.15ms CPU time)\n\nRan 5 tests for test/Registry.t.sol:RegistryTest\n[PASS] testAllModulePinsMatchExactPinnedCompilerArtifacts() (gas: 1064523)\n[PASS] testAuthenticatedEnrollmentRejectsUncreatedWrongCodeAndWrongRegistry() (gas: 3270493)\n[PASS] testConstructorAcceptsEmptyGraphWithoutExternalCalls() (gas: 13657)\n[PASS] testCounterfeitRuntimeAtAnotherFactoryCannotEnroll() (gas: 1882067)\n[PASS] testCounterfeitRuntimeWithPoisonedCreditCannotEnroll() (gas: 6217486)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 13.11ms (4.60ms CPU time)\n\nRan 8 tests for test/V39.t.sol:V39Test\n[PASS] testBaseDepositsAreEntirelyRewardEth() (gas: 190166)\n[PASS] testGridAcceptsSeverityFromThreeThousandAndRejectsBelow() (gas: 2946787)\n[PASS] testHookAddsExactlyOnePercentOnBuysAndSellsAfterLaunchWindow() (gas: 2179711)\n[PASS] testHookHasNoNetworkShareRecipientOrWithdrawal() (gas: 109842)\n[PASS] testMarketFactoryConfigHasNoNetworkRecipient() (gas: 7421825)\n[PASS] testRegistryAcceptsEitherToolchainPinAndNothingElse() (gas: 930391)\n[PASS] testSellSurchargeStillProgressiveAndCappedAtFifteenPercent() (gas: 1832600)\n[PASS] testStepLaunchTaxUnchangedAndFullyToRewards() (gas: 1291729)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 58.80ms (45.62ms CPU time)\n\nRan 7 tests for test/V33.t.sol:LaunchProtectionTest\n[PASS] testBuyTaxHasImmutableSteps() (gas: 97524)\n[PASS] testLaunchTaxChargedAndRoutedEntirelyToPool() (gas: 227992)\n[PASS] testNoBuySizeLimitAtAnyLaunchStep() (gas: 1690997)\n[PASS] testNormalBuyAfterDecayHasNoLaunchTax() (gas: 1479403)\n[PASS] testSellsPayNormalFeeDuringLaunch() (gas: 339655)\n[PASS] testSnipersSplittingBuysStillPayTheCurve() (gas: 655730)\n[PASS] testViewsBeforeInitialization() (gas: 4725627)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 59.90ms (4.93ms CPU time)\n\nRan 1 test for test/StandardV4Integration.t.sol:StandardV4IntegrationTest\n[PASS] testStandardAdapterRealPoolPaysExistingHookExactlyOnce() (gas: 1948176)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 74.21ms (1.44ms CPU time)\n\nRan 14 tests for test/V34.t.sol:V34Test\n[PASS] testBestFarmCapsAbsoluteSpendAndBreaksTiesByAddress() (gas: 4665680)\n[PASS] testBestFarmNeedsTwentyEpochsAndUsesCappedAbsoluteSpend() (gas: 4144210)\n[PASS] testBuybackSlippage150BpsMaxAndIntervalCannotBeBypassed() (gas: 756168)\n[PASS] testDonationsAndOrdinaryInflowsCannotPretendToBeEndowment() (gas: 1520675)\n[PASS] testEntropyAt256BoundaryAndAt257RearmsWithoutPayOrMint() (gas: 3276985)\n[PASS] testFirstRewardStartsCurrentEpochAtHalfTimeAndSnapshotCannotBeReplaced() (gas: 4834300)\n[PASS] testFreeFarmDoesNotDiluteDistrictOrClaimPaidPrize() (gas: 4739665)\n[PASS] testGameReadinessBothChecksRollbackEthAndTokenPurchase() (gas: 3605912)\n[PASS] testHookUninitializedCannotOpenOrStartEpochAndCallerCannotStartClock() (gas: 5887799)\n[PASS] testLaunchTaxExactBoundaries() (gas: 5771057)\n[PASS] testMythicGateEvaluatedAtRevealNotAtPayment() (gas: 1620572)\n[PASS] testPackOpeningFollowsHookAndNotLegacyDeployTimestamp() (gas: 101151)\n[PASS] testRemainderTransferredToPredictedPoolBeforeDeploymentAndNoApprovalNeeded() (gas: 2800290)\n[PASS] testStarterEntropyRearmsAfterClaimWindowAndNoDoubleMint() (gas: 772300)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 94.64ms (77.15ms CPU time)\n\nRan 8 tests for test/PhasedReleaseV36.t.sol:PhasedReleaseV36Test\n[PASS] testBillboardsDisabledThenEnabled() (gas: 414502)\n[PASS] testEnableIsNoticedOnceNeverOffAndSwarmOnly() (gas: 355991)\n[PASS] testEnhancementDisabledThenEnabledOnce() (gas: 1096283)\n[PASS] testEverythingDeploysDisabledAndCoreStillWorks() (gas: 8162777)\n[PASS] testFuzzUnannouncedFeatureCannotBeEnabled(uint256) (runs: 256, μ: 30055, ~: 29938)\n[PASS] testLocksStakeAndLobbyDisabledThenEnabled() (gas: 2849495)\n[PASS] testPotDisabledFollowsV34RoutingThenEnabled() (gas: 455827)\n[PASS] testReservedEventsDisabledThenEnabled() (gas: 557613)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 65.31ms (39.24ms CPU time)\n\nRan 5 tests for test/fork/RehearsalV311.t.sol:RehearsalV311Test\n[SKIP] testRehearsalAttestedAnswerChangesPlanWithinBand() (gas: 0)\n[SKIP] testRehearsalGasPerLaunchUnderPlatformCeiling() (gas: 0)\n[SKIP] testRehearsalKeeperPassAdvancesEpochsRevealsEntropyAndClaimFeesPaysTeam() (gas: 0)\n[SKIP] testRehearsalLaunchTaxThenOnePercentAndSurcharge() (gas: 0)\n[SKIP] testRehearsalPacksOpenOneHourAfterLaunch() (gas: 0)\nSuite result: ok. 0 passed; 0 failed; 5 skipped; finished in 437.38µs (53.97µs CPU time)\n\nRan 2 tests for test/Factory.t.sol:FactoryTest\n[PASS] testFactoryInvalidSearchRange() (gas: 5016)\n[PASS] testHookFactoryFlagsImmutableConfigAndIdempotence() (gas: 17888831)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 162.33ms (152.37ms CPU time)\n\nRan 10 tests for test/Bounties.t.sol:BountiesTest\n[PASS] testBuyBountyProportionalCapNoDustCreditAndFailureRollback() (gas: 680020)\n[PASS] testEmptyRosterAndInvalidBatchReceiveNothing() (gas: 1419146)\n[PASS] testEveryWorkKindBoundedByHeartbeatAndAuthorizedProducer() (gas: 64315585)\n[PASS] testLazySettlementUnpaidAndCannotReplay() (gas: 6957525)\n[PASS] testOnlyFinalizePaidOnceAndEmptyWeekUnpaid() (gas: 2292196)\n[PASS] testPackEntropyCapturedOnceWithFullInventoryAndThroughPause() (gas: 3710376)\n[PASS] testPlanResolutionPaidOnceIncludingAdvanceForwarding() (gas: 2931539)\n[PASS] testRemovedWorkBountiesRejectedEvenFromOldProducer() (gas: 179981)\n[PASS] testStarterEntropySurvivesFullInventoryExpiryAndPauseWithoutReplayPayment() (gas: 5321268)\n[PASS] testWorkCreditRespectsZeroGasPricePriceCeilingAndUnitCap() (gas: 333726)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 181.06ms (158.22ms CPU time)\n\nRan 6 tests for test/CivicV35.t.sol:CivicV35Test\n[PASS] testBillboardsBidRefundTextRulesAndPoolOnly() (gas: 945542)\n[PASS] testBlackMarketDescendingLimitedAndPause() (gas: 3822256)\n[PASS] testCollapseSuccessAndSingleOutageFailure() (gas: 810718)\n[PASS] testDormantDisabledAndNoticeOnce() (gas: 303076)\n[PASS] testOnceSeasonBoostBoundsAndSnapshot() (gas: 1722426)\n[PASS] testWarFreezeScoresConservationAndPayoutOnlyOnce() (gas: 1365360)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 27.00ms (16.30ms CPU time)\n\nRan 6 tests for test/V4Integration.t.sol:V4IntegrationTest\n[PASS] testRealV4BuyAndSingleSwapSellTaxConserveSettlement() (gas: 2268519)\n[PASS] testRealV4ManipulatedSpotCannotInstantlySetBuybackQuote() (gas: 1909248)\n[PASS] testRealV4SmallBuyPaysPositiveKeeperMargin() (gas: 2072079)\nLogs:\n  real V4 0.2ETH buy gas: 1933207\n  real V4 buy bounty wei: 48643350000000\n\n[PASS] testRealV4SystemBuyUsesTwapAndOnlySystemFunds() (gas: 2077956)\n[PASS] testRealV4SystemSalesUseDepthTwapNormalFeesAndConserveTokens() (gas: 2246438)\n[PASS] testSystemBuybackOffsetsRecordedSellImbalance() (gas: 2508945)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 206.79ms (13.53ms CPU time)\n\nRan 6 tests for test/Endowment.t.sol:EndowmentTest\n[PASS] testDirectTransferCannotBypassOrBackdateDrip() (gas: 368166)\n[PASS] testExactFundingFullLinearDripAndConservation() (gas: 832168)\n[PASS] testFuzzCumulativePaymentsCannotExceedVestedPrincipal(uint32,uint128) (runs: 256, μ: 523099, ~: 524727)\nLogs:\n  Bound result 280140\n  Bound result 1063433030212\n\n[PASS] testNoTeamDonorOrSwarmWithdrawalOrReserveAuthority() (gas: 614309)\n[PASS] testParamsSnapshotCannotAccelerateOrRelockExistingEndowment() (gas: 303686)\n[PASS] testUnderfundingCannotActivateAndDonationsStayConserved() (gas: 453428)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 207.47ms (182.11ms CPU time)\n\nRan 20 tests for test/SwarmDeskV37.t.sol:SwarmDeskV37Test\n[PASS] testBackupFailureUnknownFailureDeadlineAndPriceCap() (gas: 751172)\n[PASS] testBackupPullsExactPriceRecordsRequestAndRestrictsBodyAndCadence() (gas: 1199464)\n[PASS] testDeskSetHeartbeatBpsMovesFeeRouterShare() (gas: 937778)\n[PASS] testEmptyChainConstructorAndAuthenticatedBindingRejectSpoofs() (gas: 12471225)\n[PASS] testEventClampingAndFallbackWithoutAnswer() (gas: 1047688)\n[PASS] testExpiredOldSlotOldEpochAndUnexecutedAnswersNeverAct() (gas: 828312)\n[PASS] testFlatConstructorRejectsUnusedPackedBits() (gas: 6688433)\n[PASS] testForgedTamperedWrongSignerWrongDomainAndCallerRejected() (gas: 345940)\n[PASS] testFutureIssueWrongTypeMalformedLengthAndPriceNeverConsume() (gas: 311556)\n[PASS] testFuzzEveryParamHardBoundsAndTenPercentStep(uint8,uint248) (runs: 256, μ: 468115, ~: 469691)\nLogs:\n  Bound result 13\n\n[PASS] testNextSlotAcceptsSameQuestionAndChangedExecutionBytesReject() (gas: 1129615)\n[PASS] testNoAdminPathsAndEntireGraphUsesDesk() (gas: 388087)\n[PASS] testNoopRegulatorAcceptedAndParamsCooldownPreserved() (gas: 444622)\n[PASS] testRegulatorClampsParamsAnnouncesPhasesAndThirtyDayCaps() (gas: 1130422)\n[PASS] testReplayDifferentSourceAndSecondAnswerSameSlotIgnored() (gas: 1051768)\n[PASS] testRobinhoodNativeClockCallbackWithin200k() (gas: 344786)\n[PASS] testScheduleDeliveryStoresUnder200kThenExecutesTwoPlans() (gas: 976035)\n[PASS] testSubmitRelayAcceptsAttestedAnswerFromAnyoneOnce() (gas: 1075619)\n[PASS] testSubmitRelayRejectsForgedWrongQuestionStaleAndMalformed() (gas: 1808092)\n[PASS] testWrongQuestionUnknownRequestWeakPanelAndWindowRejected() (gas: 364606)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 223.95ms (238.50ms CPU time)\n\nRan 1 test for test/EndowmentGame.t.sol:EndowmentGameTest\n[PASS] testRealMiningCannotSpendFutureEndowment() (gas: 130414629)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 240.53ms (225.52ms CPU time)\n\nRan 2 tests for test/GridV35.t.sol:GridV35Test\n[PASS] testGreenAndCheapBothFavorTheStableDistrict() (gas: 4116213)\n[PASS] testReservedEventsHaveZeroLaunchWeightAndPlanOnlyWhenEnabled() (gas: 721158)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 23.03ms (10.30ms CPU time)\n\nRan 18 tests for test/EconomyV35.t.sol:EconomyV35Test\n[PASS] testAllEnhancementTableEndpointsAndGlobalBonusCap() (gas: 1477953)\n[PASS] testDurabilityBoundariesAndIdleNoWear() (gas: 38102739)\n[PASS] testEnhanceBurnFailureAndLevelGate() (gas: 1218555)\n[PASS] testEnhanceCapsNoticeUpwardOnlyAndThirtyDays() (gas: 355782)\n[PASS] testEnhanceCommitCannotPlaceScrapOrRetryAndCanRearm() (gas: 1798751)\n[PASS] testFeeSalesDepthSlippageCadenceAndNormalFeePot() (gas: 1734752)\n[PASS] testFreeAllowlistOnceWindowStarterScrapAndMetadata() (gas: 2989149)\n[PASS] testFreeRootRemainsFrozenAfterSevenDays() (gas: 43976)\n[PASS] testFreeRootWindowAndIndexLimit() (gas: 55991)\n[PASS] testFuzzPriceCurveDaysBounds(uint32,uint32) (runs: 256, μ: 88662, ~: 90122)\nLogs:\n  Bound result 580\n\n[PASS] testLockBonusRedistributesWithinReservedEmission() (gas: 11653052)\n[PASS] testLockEscrowNoEarlyExitAndWalletCap() (gas: 5377416)\n[PASS] testQuoteScalesLastSettlementAndHasFloor() (gas: 4278490)\n[PASS] testRepairYieldQuoteAndAutoRepairCreditsOnly() (gas: 10789523)\n[PASS] testRoomsChargeYieldDaysAndRetainAgeGates() (gas: 2600055)\n[PASS] testSystemSellDustCannotOccupyCadenceAndCappedHeartbeatReturnsTokens() (gas: 1556688)\n[PASS] testTokenOnlyGiftSplitsNoEthPeg() (gas: 1734609)\n[PASS] testZapAtomicMinOutPauseAndRefund() (gas: 1438033)\nSuite result: ok. 18 passed; 0 failed; 0 skipped; finished in 256.19ms (419.73ms CPU time)\n\nRan 2 tests for test/StandardMarket.t.sol:StandardMarketTest\n[PASS] testFuzzStandardSellNeverAddsProgressiveSurcharge(uint96) (runs: 256, μ: 1809630, ~: 1813971)\nLogs:\n  Bound result 13503034970049869\n\n[PASS] testStandardBuyOnePercentAllToRewards() (gas: 1673242)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 413.64ms (372.98ms CPU time)\n\nRan 6 tests for test/Regression.t.sol:RegressionTest\n[PASS] testCableRepairRestoresOnlyRemainingHalfEpoch() (gas: 11794355)\n[PASS] testEmptyEpochPreservesLastSettledRateButResetsScrapAllowance() (gas: 10984120)\n[PASS] testFuzzCableRepairBlendHandlesNonMonotonicRarityBonuses(uint16) (runs: 256, μ: 1374184, ~: 1374014)\nLogs:\n  Bound result 333\n\n[PASS] testRegisterOnlyAccountsDoNotAddSettlementWorkAndEmptyFarmCanRetire() (gas: 2025433)\n[PASS] testRepairAndPaidPackCannotRetroactivelyBoostEpoch() (gas: 9542820)\n[PASS] testUnlimitedFreshPacksCannotDrainPoolByScrapping() (gas: 9641657)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 654.71ms (687.69ms CPU time)\n\nRan 7 tests for test/HeartbeatBpsV313.t.sol:HeartbeatBpsV313Test\n[PASS] testFuzzAnyShareConservesEveryWeiAndNeverMovesTeamOrPot(uint16,uint96) (runs: 256, μ: 1420512, ~: 1639267)\nLogs:\n  Bound result 329\n  Bound result 3\n\n[PASS] testLaunchDefaultIsTwoPercentAndSplitUnchanged() (gas: 230935)\n[PASS] testLoweredShareBackToFloorAndFloorIsHard() (gas: 401104)\n[PASS] testMaximumShareWithPotEnabledIsClippedToWhatIsLeft() (gas: 1867739)\n[PASS] testOnlyTheSwarmWithinBoundsStepAndCooldownCanMoveTheShare() (gas: 341795)\n[PASS] testRaisedShareStillStopsAtTheOneEthCap() (gas: 480520)\n[PASS] testSwarmSet220CreditsTwoPointTwoPercentOfSurchargeAndTokens() (gas: 543701)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 409.72ms (404.90ms CPU time)\n\nRan 6 tests for test/Market.t.sol:MarketTest\n[PASS] testBuyChargesExactlyOnePercentAllToRewards() (gas: 1729871)\n[PASS] testFuzzTotalFeeHardCap(uint96) (runs: 256, μ: 1807645, ~: 1809170)\nLogs:\n  Bound result 13503034970049869\n\n[PASS] testOnlyManagerCorrectPoolExactInputAndHookAddress() (gas: 113403)\n[PASS] testSingleDumpIncludesItselfAndFeeDecaysWithoutGriefReset() (gas: 17162149)\n[PASS] testTwapAveragesEthPriceAcrossUnequalPrices() (gas: 2330567)\n[PASS] testTwapWarmupAndFlashManipulationResistance() (gas: 1882285)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 631.89ms (267.74ms CPU time)\n\nRan 13 tests for test/Events.t.sol:EventsTest\n[PASS] testCheapTariffAppliesCitywide() (gas: 6419970)\n[PASS] testColdPowerFireImmuneAndCleanPowerSurgeImmune() (gas: 7898411)\n[PASS] testFallbackAndExpiredSeedIndependentOfSwarmNumber() (gas: 1683539)\n[PASS] testFireNoCoolingZeroYieldColdPowerImmune() (gas: 6144568)\n[PASS] testGreenWaveRaisesDistrictMiningTenPercent() (gas: 6422047)\n[PASS] testLobbyOwnDistrictSplitDecayAndMinimumWeight() (gas: 1080859)\n[PASS] testOutageAndOffgridRoomMitigation() (gas: 7053841)\n[PASS] testPlansOnlyNextTwoOnceAndBoundedSeverity() (gas: 344816)\n[PASS] testRollingCapsAndInitialPositiveQuotaWithHostilePlans() (gas: 102235868)\n[PASS] testSurgeCanDestroyCommonButNeverLegendary() (gas: 6288094)\n[PASS] testSurgeDamagesExactlyOneItemAndCleanPowerImmune() (gas: 6294034)\n[PASS] testSurgeNeverDestroysLegendaryOrMythic() (gas: 9502005)\n[PASS] testTheftRouterDisabledAndRepairRestores() (gas: 6848091)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 528.05ms (390.58ms CPU time)\n\nRan 2 tests for test/AutoRepairReviewV35.t.sol:IndependentAutoRepairReview\n[PASS] testAutomaticRepairRecordsHistoricalWeekBeforeCompletion() (gas: 5402724)\n[PASS] testLateAutomaticRepairCannotReopenSeasonEligibility() (gas: 4266739)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 674.01ms (25.42ms CPU time)\n\nRan 6 tests for test/SeasonAudit.t.sol:SeasonAuditTest\n[PASS] testAuditThresholdStrictAndNoWhaleSoftCap() (gas: 40376130)\n[PASS] testLotteryEntitlementSurvivesFullInventory() (gas: 130888063)\n[PASS] testPackSupplyDropOnlyActiveFarmsAtDoublePace() (gas: 11727425)\n[PASS] testParameterChangesCannotChangeClosedEpochBetweenBatches() (gas: 12490901)\n[PASS] testSeasonCannotFinalizeEarlyAndExpiredLotteryMustRearm() (gas: 123852005)\n[PASS] testWeeklyThreeDistinctTicketWinnersRarePackAndBestPrize() (gas: 124081336)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 673.68ms (1.52s CPU time)\n\nRan 9 tests for test/SwarmDeskBinding.t.sol:SwarmDeskBindingTest\n[PASS] testCorrectProofAtWrongCoordinatesCannotPartiallyBind() (gas: 3673801)\n[PASS] testFuzzEachFrozenGameFieldMustMatchCommitment(uint8) (runs: 1000, μ: 2260115, ~: 2260324)\nLogs:\n  Bound result 0\n\n[PASS] testFuzzOneByteChangedCreationProofCannotBind(bool,uint256) (runs: 1000, μ: 699308, ~: 698718)\nLogs:\n  Bound result 3025\n\n[PASS] testMissingParamsCodeRejectsUntilDependencyExists() (gas: 1493981)\n[PASS] testPermissionlessBindAtIndexSevenAcrossSeparateLaunchesIsFinal() (gas: 1472715)\n[PASS] testRegistryCannotPointToOtherParamsEvenWithBothContractsFactoryCreated() (gas: 5353605)\n[PASS] testRegistryDeployedOutsideFactoryIsNotAuthenticatedByMatchingRuntime() (gas: 1493175)\n[PASS] testWrongFactoryAndCodelessRegistryCannotBind() (gas: 2197406)\n[PASS] testWrongParamsHeartbeatAndWalletCannotSubstituteForCommittedInitCode() (gas: 9155656)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 674.11ms (885.68ms CPU time)\n\nRan 3 tests for test/Gas.t.sol:GasTest\n[PASS] testGasCommonActions() (gas: 10843346)\nLogs:\n  buy token pack: 922761\n  open one pack: 514543\n  equip: 963773\n  repair wallet: 611998\n  enhancement commit: 565794\n  expand: 387774\n  token pack wallet: 652058\n  withdraw: 253137\n  unequip: 404020\n\n[PASS] testGasFullFarmLongIdleBoundedChunks() (gas: 119172460)\nLogs:\n  settle full 24-item farm eight epochs after 40 idle: 12486576\n\n[PASS] testGasTypicalFarmSettlementHasNoBounty() (gas: 8924872)\nLogs:\n  settle typical three-item farm one epoch: 919736\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 678.15ms (690.11ms CPU time)\n\nRan 11 tests for test/SwarmDeskBootstrap.t.sol:SwarmDeskBootstrapTest\n[PASS] testConstructorCannotReceiveNativeValue() (gas: 498011)\n[PASS] testConstructorRejectsDuplicateTransportsAndQuestions() (gas: 1137772)\n[PASS] testEip712DomainUsesRobinhoodAndDeployedDesk() (gas: 5114587)\n[PASS] testFactoryDeploysExactlyOneUnboundDeskWithoutExternalCalls() (gas: 5328996)\nLogs:\n  Offline SwarmDesk bootstrap (not a live deployment): 0x901160a02B2836baC903a624EE3E1146D4C022c5\n\n[PASS] testFuzzConstructorRejectsEachZeroWord(uint8) (runs: 1000, μ: 584674, ~: 588836)\nLogs:\n  Bound result 3\n\n[PASS] testFuzzConstructorRejectsReservedBitsAndPolicyBoundaries(uint8,uint16) (runs: 1000, μ: 590768, ~: 590253)\nLogs:\n  Bound result 0\n  Bound result 6\n\n[PASS] testFuzzPackedFieldsRoundTripWithoutCrossFieldContamination(uint32,uint48,uint48,uint96,uint16) (runs: 1000, μ: 5211508, ~: 5211506)\nLogs:\n  Bound result 777003\n  Bound result 281474976710655\n  Bound result 79228162514264337593543950335\n  Bound result 683\n\n[PASS] testFuzzUnboundDeskRejectsInvalidBindingCoordinates(uint8,uint8) (runs: 1000, μ: 5185384, ~: 5184153)\nLogs:\n  Bound result 0\n\n[PASS] testRuntimeSizeAndForbiddenOpcodes() (gas: 18684450)\n[PASS] testUnboundDeskRejectsEveryActionAndUnknownPrivilegeSelector() (gas: 5466143)\n[PASS] testUnboundDeskRejectsOracleAndBackupActions() (gas: 5218770)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 1.15s (1.68s CPU time)\n\nRan 24 tests for test/SwarmDeskAdversarial.t.sol:SwarmDeskAdversarialTest\n[PASS] testAcceptedScheduleSuppressesBackupAndCannotOverwriteEarlierPlan() (gas: 1262351)\n[PASS] testBackupAtSlotEndClipsDeadlineAndRejectsLateDirectAnswer() (gas: 575790)\n[PASS] testBackupFirstHourBoundaryAndStreamsHaveSeparateQuotas() (gas: 707042)\n[PASS] testDirectAnswerAtDeadlineIsIgnoredAndOneSecondBeforeIsAccepted() (gas: 733068)\n[PASS] testDirectRequestCannotBeAnsweredWithOtherStream() (gas: 765935)\n[PASS] testDuplicateOutstandingIntakeIDRollsBackOtherStreamsPayment() (gas: 594060)\n[PASS] testExecutionAtExpiryDiscardsResultWithoutChangingGame() (gas: 425862)\n[PASS] testFutureClockBeyondToleranceDoesNotBurnUUID() (gas: 408745)\n[PASS] testFuzzEachPanelConstraintRejectsSignedAnswers(uint8,uint16) (runs: 1000, μ: 187830, ~: 188007)\nLogs:\n  Bound result 0\n  Bound result 1\n\n[PASS] testFuzzEveryAttestationFieldIsAuthenticated(uint8) (runs: 1000, μ: 197055, ~: 202172)\nLogs:\n  Bound result 14\n\n[PASS] testFuzzSignedMalformedArraysNeverStore(uint8,uint8) (runs: 1000, μ: 202695, ~: 202475)\nLogs:\n  Bound result 0\n  Bound result 1\n\n[PASS] testIntakeRevertAndZeroIDRollBackPaymentApprovalAndQuota() (gas: 1141313)\n[PASS] testInvalidFailureStatusCannotClearPaidRequestOrAct() (gas: 634936)\n[PASS] testLaunchOrderInitializedMarketAllowsCapAnnouncementAfterThirtyDays() (gas: 545763)\n[PASS] testMalformedAndMalleableSignaturesCannotConsumeAnswer() (gas: 654411)\n[PASS] testMinimumPanelAndFutureClockToleranceAreInclusive() (gas: 323402)\n[PASS] testOneSecondBeforeExpiryExecutesAndSlotEndCapsValidity() (gas: 865855)\n[PASS] testOneWeiPriceAndTokenTransferFailureRollback() (gas: 573780)\n[PASS] testRepeatedParamKeyCannotCompoundTenPercentInOneAnswer() (gas: 472516)\n[PASS] testSignatureForIntakeDomainCannotAuthorizeDesk() (gas: 247623)\n[PASS] testTokenCallbackCannotReenterOtherStreamDuringBackupPayment() (gas: 541864)\n[PASS] testWeeklyAnswerOlderThanOneDayIsIgnoredWithoutBlockingFreshAnswer() (gas: 478049)\n[PASS] testZeroOracleUUIDAndZeroTransportIDAreRejected() (gas: 274854)\n[PASS] testZeroOverCapAndInsufficientBalanceCannotSpendQuota() (gas: 950990)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 1.15s (2.38s CPU time)\n\nRan 11 tests for test/Items.t.sol:ItemsTest\n[PASS] testComputeHashSupportHashAndBonusesReplaceDuo() (gas: 4700115)\n[PASS] testDurabilityWearRepairAndEnhancementMetadataPreserved() (gas: 8369228)\n[PASS] testEquipRarityGatesAndMythicGate() (gas: 4144858)\n[PASS] testFullStackRarityCapAndRoomFlags() (gas: 7638418)\n[PASS] testInventoryMintCannotExceedCapacityAndExpansionRises() (gas: 3351443)\n[PASS] testLockedItemCannotBeScrappedUntilEpochRolls() (gas: 5971291)\n[PASS] testOffgridSavings() (gas: 2701968)\n[PASS] testPaidXpCannotBypassRoomTwoAgeGate() (gas: 3734443)\n[PASS] testRoomGatesAndLevelProgression() (gas: 78345249)\n[PASS] testScrapPaysPoolYieldAndCannotRepeat() (gas: 7543503)\n[PASS] testSoulboundOnlyOwnFarmAndNoDuplicateTypes() (gas: 2254731)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 925.45ms (342.77ms CPU time)\n\nRan 2 tests for test/ReservedEventsV35.t.sol:ReservedEventsV35Test\n[PASS] testFuzzReservedFestivalCannotExceedFifteenPercent(uint16) (runs: 256, μ: 4918902, ~: 4918899)\n[PASS] testReservedHeatwaveExtraCoolingWearAndBothProtections() (gas: 10146981)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 1.03s (1.06s CPU time)\n\nRan 9 tests for test/Packs.t.sol:PacksTest\n[PASS] testExactPaymentAndFutureBlockRequired() (gas: 1667747)\n[PASS] testExactRarityThresholdsAndMythicGate() (gas: 282935)\n[PASS] testExpiryRearmsWithoutMintingAndInventoryOpeningLimit() (gas: 3790798)\n[PASS] testFuzzVrgdaAlwaysBounded(uint32,uint32) (runs: 256, μ: 61398, ~: 63041)\nLogs:\n  Bound result 580\n\n[PASS] testItemTypeDistributionExact() (gas: 626492)\n[PASS] testNoWalletGlobalOrTokenPackDailyLimit() (gas: 4377219)\n[PASS] testStarterWindowProofTokenIdOnceAndInventoryFailureRetry() (gas: 881480)\n[PASS] testTokenPackSameQuoteAndSplitWhenUsingWalletOrCredits() (gas: 76424599)\n[PASS] testVrgdaInitialStepDecayFloorCeilingAndBulkPricing() (gas: 1296506)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 1.18s (367.89ms CPU time)\n\nRan 9 tests for test/Epochs.t.sol:EpochsTest\n[PASS] testCannotAdvanceEarlyAndBountyOnce() (gas: 2510478)\n[PASS] testClaimsEveryEpochAndRedistributionIsNextEpoch() (gas: 11985703)\n[PASS] testGasAdvanceIndependentOfRoster() (gas: 893047640)\nLogs:\n  advance empty roster: 1284132\n  advance 1000 farms: 1473629\n\n[PASS] testNoCatchupEmissionDuringGap() (gas: 6257752)\n[PASS] testNoRetroactiveEquipmentAndBoundedBatches() (gas: 5780602)\n[PASS] testNoWhaleCapHashShares() (gas: 10155257)\n[PASS] testReferralOneLevelSetOnceNoSelf() (gas: 7511550)\n[PASS] testTaxCurveExactAndFloor() (gas: 34112)\n[PASS] testWithdrawFailureRollsBackAndReentrancyCannotClaimTwice() (gas: 7428870)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 5.26s (5.32s CPU time)\n\nRan 8 tests for test/FeesParams.t.sol:FeesParamsTest\n[PASS] testAllDefaultParamsWithinHardBounds() (gas: 1255771)\n[PASS] testBuyBackPoolOnlySlippageFailureRollbackAndDustGriefBlocked() (gas: 774066)\n[PASS] testExactEthSplitsHeartbeatCapAndPullPayments() (gas: 512724)\n[PASS] testFuzzNoStepAboveTenPercent(uint96) (runs: 256, μ: 45009, ~: 45115)\nLogs:\n  Bound result 6314\n\n[PASS] testFuzzSplitsConserveEveryWei(uint96) (runs: 256, μ: 209357, ~: 210856)\nLogs:\n  Bound result 13503034970049869\n\n[PASS] testHeartbeatCapFixedAtOneEth() (gas: 207904)\n[PASS] testParamsStepCooldownBoundsAuthorityAndLetter() (gas: 195823)\n[PASS] testPoolNoPublicReserveRecycleOrPayment() (gas: 135304)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 11.07s (83.55ms CPU time)\n\nRan 20 tests for test/V33.t.sol:V33Test\n[PASS] testActionBeforeExpiryMovesBucketWithoutDoubleCount() (gas: 25963547)\n[PASS] testAdvanceIsConstantInExpiringFarms() (gas: 38374918)\n[PASS] testAgeCapsAtBoundaries() (gas: 204618)\n[PASS] testClaimDoesNotRecommitWhileBehind() (gas: 37212442)\n[PASS] testClaimRecommitsAndPackRecommits() (gas: 60738557)\n[PASS] testDistrictScoreAveragePerFarmAndTenPercentWalletCap() (gas: 4607489)\n[PASS] testHeartbeatCapExcessGoesToPoolAndBaseFeeIsAllRewards() (gas: 270973)\n[PASS] testIdleFarmLeavesDenominatorAfterTwelveEpochs() (gas: 23496196)\n[PASS] testLaunchTaxDepositIsAllPoolAndMarketOnly() (gas: 137567)\n[PASS] testMergeRemoved() (gas: 512630)\n[PASS] testPackLobbySellSplit88Team10Heartbeat2() (gas: 407960)\n[PASS] testPackSaleOpensSixtyMinutesAfterLaunch() (gas: 1261148)\n[PASS] testPaidXpCannotBypassAgeGates() (gas: 58982706)\n[PASS] testPaidXpCappedPerDayActivityUncapped() (gas: 13235492)\n[PASS] testPartialRoomIsClippedNotReverted() (gas: 2148809)\n[PASS] testRewardsEarnedBeforeExpiryAreNeverLost() (gas: 47642242)\n[PASS] testSingleWhaleDistrictCannotWinAlone() (gas: 4534340)\n[PASS] testSyncRecommitsFromNextEpoch() (gas: 33350114)\n[PASS] testTokenPacksAlsoWaitForOpening() (gas: 59864)\n[PASS] testTopSpenderTrackingIsExact() (gas: 5411751)\nSuite result: ok. 20 passed; 0 failed; 0 skipped; finished in 11.07s (1.19s CPU time)\n\nRan 4 tests for test/OracleConformanceV37.t.sol:OracleConformanceV37Test\n[PASS] testAcceptsOriginalProtocolSignature() (gas: 17956)\n[PASS] testDigestMatchesUnmodifiedProtocolVector() (gas: 13636)\n[PASS] testFreshVectorSignerSignature() (gas: 30407)\n[PASS] testSelectorsExactlyMatchLiveProtocol() (gas: 3520)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 11.08s (813.94µs CPU time)\n\nRan 9 tests for test/LazyAccounting.t.sol:LazyAccountingTest\n[PASS] testAuditChargesTenPercentEvenAtHalfSeverityAndThresholdIsFrozen() (gas: 6152701)\n[PASS] testClaimCatchesUpWhilePacksPausedAndDoesNotEraseRemainingHistory() (gas: 25659680)\n[PASS] testExhaustedFarmCannotCollectRedistributionByRemainingIdle() (gas: 15152008)\n[PASS] testFuzzLazyEqualsIndependentEagerForRandomFarmsAndAllEvents(uint256) (runs: 256, μ: 45524547, ~: 45532728)\n[PASS] testGlobalAccumulatorAndWeightsAreSnapshottedBeforeMutations() (gas: 9289772)\n[PASS] testLateSeasonSettlementPaysMiningWithoutChangingFrozenWinners() (gas: 59428195)\n[PASS] testOneWeiMiningGreenCannotLockSettlementThroughEnvelopeRounding() (gas: 11045065)\n[PASS] testSparseMatureVintageConsumedBeforeRecentSlotAfterWrap() (gas: 43285171)\n[PASS] testStaleActionsRequireChunksAndNeverBlockGlobalAdvance() (gas: 40513874)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 11.05s (11.47s CPU time)\n\nRan 1 test for test/Invariants.t.sol:InvariantsTest\n[PASS]\nInvariantsTest invariants:\n[PASS] invariantAllowlistRootAndWalletLimit\n[PASS] invariantInventoryAndEthLiabilities\n[PASS] invariantLocksAndPotAlwaysBacked\n[PASS] invariantPriceAndParamsBounds\n[PASS] invariantReceiptsNeverForfeitOrFixMissingEntropy\n[PASS] invariantReservesBackedAndPendingCovered\n[PASS] invariantTokenConservationNoBurns\n InvariantsTest invariants (runs: 128, calls: 8192, reverts: 0)\n\n╭-------------+-----------+-------+---------+----------╮\n| Contract    | Selector  | Calls | Reverts | Discards |\n+======================================================+\n| GameHandler | advance   | 554   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | buy       | 593   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | claim     | 570   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | equip     | 608   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | expand    | 602   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | freeClaim | 546   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | fundPot   | 614   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | lock      | 588   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | resolve   | 580   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | rollover  | 591   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | settle    | 604   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | tokenPack | 584   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | unlock    | 592   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | unplace   | 566   | 0       | 0        |\n╰-------------+-----------+-------+---------+----------╯\n\nLogs:\n  Bound result 500000000000000\n  Bound result 18016\n  Bound result 2400\n  Bound result 107\n  Bound result 40000000000000\n  Bound result 114763011105394839764\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 37.58s (37.54s CPU time)\n\nRan 2 tests for test/SwarmDeskInvariants.t.sol:SwarmDeskInvariantsTest\n[PASS]\nSwarmDeskInvariantsTest invariants:\n[PASS] invariantBindingAuthorityAndGameBoundsNeverChange\n[PASS] invariantDonationsCanOnlyPayBoundedBackupRequests\n[PASS] invariantOracleStateMatchesIndependentLifecycle\n SwarmDeskInvariantsTest invariants (runs: 256, calls: 16384, reverts: 0)\n\n╭------------------+---------------+-------+---------+----------╮\n| Contract         | Selector      | Calls | Reverts | Discards |\n+===============================================================+\n| SwarmDeskHandler | advance       | 1474  | 0       | 0        |\n|------------------+---------------+-------+---------+----------|\n| SwarmDeskHandler | answerBackup  | 1394  | 0       | 0        |\n|------------------+---------------+-------+---------+----------|\n| SwarmDeskHandler | ask           | 1471  | 0       | 0        |\n|------------------+---------------+-------+---------+----------|\n| SwarmDeskHandler | clear         | 1473  | 0       | 0        |\n|------------------+---------------+-------+---------+----------|\n| SwarmDeskHandler | donate        | 1453  | 0       | 0        |\n|------------------+---------------+-------+---------+----------|\n| SwarmDeskHandler | execute       | 1515  | 0       | 0        |\n|------------------+---------------+-------+---------+----------|\n| SwarmDeskHandler | failure       | 1533  | 0       | 0        |\n|------------------+---------------+-------+---------+----------|\n| SwarmDeskHandler | forgedAnswer  | 1466  | 0       | 0        |\n|------------------+---------------+-------+---------+----------|\n| SwarmDeskHandler | relay         | 1549  | 0       | 0        |\n|------------------+---------------+-------+---------+----------|\n| SwarmDeskHandler | replay        | 1515  | 0       | 0        |\n|------------------+---------------+-------+---------+----------|\n| SwarmDeskHandler | tryPrivileges | 1541  | 0       | 0        |\n╰------------------+---------------+-------+---------+----------╯\n\nLogs:\n  Bound result 10569\n  Bound result 59465340051394264917\n  Bound result 4565\n  Bound result 7\n  Bound result 1814400\n  Bound result 7090745865063915097\n  Bound result 89058807758656407\n  Bound result 11000\n  Bound result 4986\n  Bound result 10000000000000000000000000\n  Bound result 0\n  Bound result 19065\n  Bound result 201\n  Bound result 16800\n\n[PASS] testHandlerReachesPaidDirectRelayExecutionFailureAndTimeout() (gas: 6386208)\nLogs:\n  Bound result 1000000000000000000\n  Bound result 500000000000000000\n  Bound result 500000000000000000\n  Bound result 21600\n  Bound result 1\n  Bound result 3600\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 46.67s (46.66s CPU time)\n\nRan 52 test suites in 46.67s (146.79s CPU time): 319 tests passed, 0 failed, 6 skipped (325 total tests)\n","passed":true},{"durationMs":215,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"Billboards.bidBillboard(uint256,uint256,string,string)\",\"Billboards.settleBillboard(uint256,uint256)\",\"Billboards.withdrawRefund()\",\"Civic.announce(uint256,string)\",\"Civic.buyLot(uint256)\",\"Civic.claimWar(uint256)\",\"Civic.consumeCityEvent()\",\"Civic.enable(uint256)\",\"Civic.finishCollapse()\",\"Civic.finishWar()\",\"Civic.fundCollapse(uint256)\",\"Civic.fundWar(uint256)\",\"Civic.grantDistrictBoost(uint256,uint16,string)\",\"Civic.listLot(uint8,uint8,uint8)\",\"Civic.startCollapse(uint256)\",\"Civic.startWar(uint8,uint8)\",\"Economy.autoRepair(address,uint256,uint256[24])\",\"Economy.lock(uint256,uint256)\",\"Economy.unlock()\",\"EndowmentEscrow.forward(address,uint64,uint256,bytes,uint64,uint256,bytes)\",\"Enhancement.activateCap()\",\"Enhancement.announceCap(uint8,string)\",\"Enhancement.capture(uint256)\",\"Enhancement.commit(uint256,uint256,bool)\",\"Enhancement.resolve(uint256)\",\"FarmCore.activity(address,uint256,uint256,uint256)\",\"FarmCore.autoRepair(address,uint256)\",\"FarmCore.buyRoom(uint256,bool)\",\"FarmCore.buyTokenPack(bool)\",\"FarmCore.civicPurchase(address,uint256)\",\"FarmCore.claimDrop()\",\"FarmCore.expand(bool)\",\"FarmCore.grantDrop(address,bytes32)\",\"FarmCore.lobby(uint256,bool)\",\"FarmCore.paidPackBought(address,uint256,uint256)\",\"FarmCore.place(uint256,uint256,uint256)\",\"FarmCore.prepareEnhancement(address,uint256,uint256,bool)\",\"FarmCore.process(address,uint256)\",\"FarmCore.register(address)\",\"FarmCore.repair(uint256,bool)\",\"FarmCore.repairCable(bool)\",\"FarmCore.retire(address)\",\"FarmCore.scrap(uint256,uint256)\",\"FarmCore.setAutoRepair(bool,uint16)\",\"FarmCore.setReferrer(address)\",\"FarmCore.sync()\",\"FarmCore.syncFor(address)\",\"FarmCore.unplace(uint256,uint256)\",\"FarmEngine.process(address,uint256,(uint256[24],uint8[24],uint16[24],bool,uint64,uint16))\",\"FarmItems.destroy(uint256)\",\"FarmItems.equip(address,uint256)\",\"FarmItems.expand(address)\",\"FarmItems.maintain(uint256,uint16,uint8)\",\"FarmItems.mint(address,uint8,uint8,bool)\",\"FarmItems.mintDrop(address,bytes32)\",\"FarmItems.safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\",\"FarmItems.safeTransferFrom(address,address,uint256,uint256,bytes)\",\"FarmItems.unequip(address,uint256)\",\"FarmRewards.advanceEpoch()\",\"FarmRewards.award(address,uint256)\",\"FarmRewards.beginMining(address,uint256)\",\"FarmRewards.claim(uint256)\",\"FarmRewards.initialize(address)\",\"FarmRewards.recordSales(uint256)\",\"FarmRewards.releasePrize(uint256)\",\"FarmRewards.scrap(address,uint256,uint256)\",\"FarmRewards.setReferrer(address,address)\",\"FarmRewards.setWeight(address,uint256)\",\"FarmRewards.settle(address,uint256)\",\"FarmRewards.spend(address,uint256)\",\"FarmRewards.spendTo(address,uint256,address)\",\"FeeRouter.depositBaseFee()\",\"FeeRouter.depositLaunchTax()\",\"FeeRouter.depositLobby()\",\"FeeRouter.depositPack()\",\"FeeRouter.depositSellTax()\",\"FeeRouter.executeBuys(uint256,uint256)\",\"FeeRouter.executePotBuys(uint256,uint256)\",\"FeeRouter.executeSells(uint256,uint256)\",\"FeeRouter.payBounty(address)\",\"FeeRouter.payWork(address,uint8,uint256,uint256)\",\"FeeRouter.receive()\",\"FeeRouter.routeTokens(uint256)\",\"FeeRouter.withdraw()\",\"FeeRouter.zapBuy(uint256,address)\",\"GameRegistry.register(uint256,uint64,uint256,bytes)\",\"GridOperator.lobbyETH()\",\"GridOperator.resolve(uint256)\",\"GridOperator.resolveFor(uint256,address)\",\"GridOperator.shift(uint256)\",\"GridOperator.submitPlan(uint256,uint8,uint16,bytes32,string)\",\"GridOperator.tokenLobby(address,uint256)\",\"MarketFactory.deploy((address,address,int24,address,address,address,bytes32),bytes32)\",\"PackSale.buyPackFor(address)\",\"PackSale.buyPacksFor(address,uint256,uint256)\",\"PackSale.buyWithETH(address,uint256,uint256,uint256)\",\"PackSale.captureEntropy(uint256)\",\"PackSale.openPack(uint256)\",\"PackSale.pause(uint256)\",\"PackSale.rearm(uint256)\",\"PackSale.resolve(uint256,uint256)\",\"PackSale.rewardPack(address)\",\"PackSale.tokenPack(address)\",\"PackSale.unpause()\",\"Params.set(uint8,uint256,string)\",\"RewardPool.donate(uint256)\",\"RewardPool.fundEndowment()\",\"RewardPool.pay(address,uint256)\",\"RewardPool.recordInflow(uint256)\",\"RewardPool.recycle(uint256)\",\"RewardPool.reserve(uint256)\",\"Season.addPrize(uint256,uint256)\",\"Season.claimBest(uint256)\",\"Season.claimDistrict(uint256)\",\"Season.claimLottery(uint256)\",\"Season.complete(address,uint256)\",\"Season.depositPot(uint256)\",\"Season.finalize(uint256)\",\"Season.prepare(uint256,uint256)\",\"Season.rearm(uint256)\",\"Season.recordActivity(address,uint256,uint256,uint256)\",\"Season.recordRepair(address,uint256,uint256)\",\"Season.recordSpend(address,uint256,bool)\",\"Season.rollover(uint256)\",\"StandardAdapter.buy(uint256,address)\",\"StandardAdapter.unlockCallback(bytes)\",\"StandardMarket.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"StandardMarket.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"StandardMarket.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"StandardMarket.bindFeeRouter(address,uint64,uint256)\",\"StandardMarket.buy(uint256,address)\",\"StandardMarket.flushFees()\",\"StandardMarket.receive()\",\"StandardMarket.sell(uint256,uint256,address)\",\"StandardMarket.unlockCallback(bytes)\",\"StarterClaim.captureEntropy(uint256)\",\"StarterClaim.claim(uint256,bytes32[])\",\"StarterClaim.claimFree(uint256,bytes32[])\",\"StarterClaim.rearm(uint256)\",\"StarterClaim.resolve(uint256)\",\"SwarmDesk.askBackup(uint8,bytes)\",\"SwarmDesk.bind(address,bytes,bytes,uint64,uint8,uint64,uint8)\",\"SwarmDesk.clearExpired(bytes32)\",\"SwarmDesk.execute(uint8,bytes)\",\"SwarmDesk.onOracleFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"SwarmDesk.onOracleResult(bytes32,(bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"SwarmDesk.submit((bytes32,uint256,bytes32,uint8,bytes,uint256,uint64,uint64,bytes32,bytes32,uint16,uint16,uint16,uint64,uint64),bytes)\",\"V4Market.afterInitialize(address,(address,address,uint24,int24,address),uint160,int24)\",\"V4Market.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"V4Market.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"V4Market.bindFeeRouter(address,uint64,uint256)\",\"V4Market.buy(uint256,address)\",\"V4Market.flushFees()\",\"V4Market.receive()\",\"V4Market.sell(uint256,uint256,address)\",\"V4Market.unlockCallback(bytes)\"],\"files\":{\".gitignore\":8,\"ADAPTATION.md\":172,\"README.md\":58,\"artifacts/build-lint-v3.txt\":2369,\"artifacts/build-v3.txt\":3,\"artifacts/economic-targets-v3.json\":9,\"artifacts/fmt-v3.txt\":0,\"artifacts/foundry-v3.txt\":845,\"artifacts/funded-sensitivity/simulation-v3.json\":13928,\"artifacts/funded-sensitivity/simulation-v3.md\":51,\"artifacts/funding-sensitivity-v3.json\":342,\"artifacts/gas-actions-v3.txt\":15,\"artifacts/policy-sensitivity-v3.json\":554,\"artifacts/python-tests-v3.txt\":18,\"artifacts/regulator-example.json\":59,\"artifacts/robinhood-fork-v3.txt\":7,\"artifacts/runtime-sizes-v3.json\":23,\"artifacts/simulation-v3.json\":13928,\"artifacts/simulation-v3.md\":51,\"artifacts/tuned-funded/simulation-v3.json\":13928,\"artifacts/tuned-funded/simulation-v3.md\":51,\"artifacts/v2/README.md\":3,\"artifacts/v2/foundry-tests.txt\":178,\"artifacts/v2/offline-tests.txt\":187,\"artifacts/v2/offline-verification.json\":21,\"artifacts/v2/previous-README.md\":108,\"artifacts/v2/previous-design.md\":120,\"artifacts/v2/previous-report.md\":75,\"artifacts/v2/previous-security-review.md\":29,\"artifacts/v2/previous-simulation-assumptions.md\":52,\"artifacts/v2/robinhood-fork.txt\":7,\"artifacts/v2/rpc-probe.json\":16,\"artifacts/v2/runtime-sizes.json\":21,\"artifacts/v2/simulation.md\":95,\"artifacts/v2/verification.json\":110,\"artifacts/v31/allocation-summary.md\":6,\"artifacts/v31/baseline-budget.md\":14,\"artifacts/v31/boundary-checks.json\":10880,\"artifacts/v31/candidate-stress/simulation.json\":32636,\"artifacts/v31/evidence/factory-prediction.json\":14,\"artifacts/v31/evidence/launch-and-cost-facts.json\":130,\"artifacts/v31/evidence/standalone-hook-build.json\":38,\"artifacts/v31/final/comparison.md\":50,\"artifacts/v31/funded/comparison.md\":52,\"artifacts/v31/funded/replay.json\":290,\"artifacts/v31/funding-comparison.md\":8,\"artifacts/v31/regulator-example.json\":73,\"artifacts/v31/stress-comparison.md\":20,\"artifacts/v31/summary.json\":13,\"artifacts/v31/validation.json\":250,\"artifacts/v310/forge-test-launch.txt\":496,\"artifacts/v310/forge-test-repo-changed-suites.txt\":115,\"artifacts/v310/forge-test-repo-full-before-new-tests.txt\":437,\"artifacts/v310/pins-check.txt\":2,\"artifacts/v311/rehearsal.log\":377,\"artifacts/v312/forge-fmt.txt\":1,\"artifacts/v312/forge-test-launch.txt\":381,\"artifacts/v312/forge-test-repo.txt\":384,\"artifacts/v312/launch-creation-hashes.txt\":5,\"artifacts/v312/node-tests.txt\":10,\"artifacts/v312/pins-check.txt\":2,\"artifacts/v312/python-tests.txt\":3,\"artifacts/v312/rehearsal.log\":368,\"artifacts/v313/forge-fmt.txt\":0,\"artifacts/v313/forge-test.txt\":468,\"artifacts/v313/launch-creation-hashes.txt\":6,\"artifacts/v313/module-pins.txt\":15,\"artifacts/v313/pins-check.txt\":2,\"artifacts/v32/contract-sizes.json\":54,\"artifacts/v32/forge-build.log\":2734,\"artifacts/v32/forge-fmt.log\":0,\"artifacts/v32/forge-test.log\":310,\"artifacts/v32/model-checks.log\":5,\"artifacts/v32/module-pins.log\":1,\"artifacts/v32/python-tests.log\":25,\"artifacts/v32/regulator-example.json\":73,\"artifacts/v32/simulation-checks.json\":11,\"artifacts/v32/simulation-checks.log\":11,\"artifacts/v32/validation.json\":61,\"artifacts/v32/verified-baseline/comparison.md\":8,\"artifacts/v32/verified-baseline/simulation.json\":22622,\"artifacts/v32/verified-sensitivities/comparison.md\":68,\"artifacts/v33/simulation.json\":116,\"artifacts/v34/build.txt\":2931,\"artifacts/v34/format.txt\":0,\"artifacts/v34/pins.txt\":1,\"artifacts/v34/python-tests.txt\":5,\"artifacts/v34/reveal-test.txt\":1,\"artifacts/v34/simulation.json\":91766,\"artifacts/v34/simulation.md\":43,\"artifacts/v34/tests.txt\":306,\"artifacts/v35/simulation.json\":22605,\"artifacts/v35/simulation.md\":104,\"artifacts/v35/verification.json\":132,\"artifacts/v36/simulation-phases.json\":179,\"artifacts/v36/simulation-phases.md\":13,\"artifacts/v37/byte-sizes.json\":131,\"artifacts/v37/verification.json\":28,\"artifacts/v39/forge-build-repo.txt\":3,\"artifacts/v39/forge-fmt.txt\":1,\"artifacts/v39/forge-test-launch.txt\":8,\"artifacts/v39/forge-test-repo.txt\":390,\"artifacts/v39/pins-check.txt\":2,\"artifacts/v39/pins.json\":68,\"artifacts/v39/runtime-sizes.json\":197,\"artifacts/v39/simulation.json\":381,\"artifacts/v39/simulation.md\":29,\"artifacts/verification-v3.json\":67,\"docs/api-v35.md\":41,\"docs/dependency-provenance.md\":9,\"docs/design.md\":69,\"docs/entropy-v34.md\":31,\"docs/launch-v31.md\":121,\"docs/launch-v34.md\":44,\"docs/launch-v35.md\":40,\"docs/lazy-accounting-v32.md\":48,\"docs/m2-trust-assumption.md\":101,\"docs/oracle-v37/event.json\":1,\"docs/oracle-v37/oracle-config.json\":21,\"docs/oracle-v37/regulator.json\":1,\"docs/params-keys-v313.md\":113,\"docs/report-v3.md\":143,\"docs/report-v31.md\":128,\"docs/report-v32.md\":138,\"docs/report-v33.md\":107,\"docs/report-v34.md\":58,\"docs/report-v36.md\":89,\"docs/report-v38.md\":83,\"docs/research/b94e6839-platform-report.md\":238,\"docs/review-v31.md\":77,\"docs/review-v32.md\":32,\"docs/review-v33.md\":19,\"docs/review-v34.md\":30,\"docs/review-v35-independent.md\":69,\"docs/review-v37-independent.md\":44,\"docs/review-v39-independent.md\":105,\"docs/security-review.md\":29,\"docs/simulation-assumptions.md\":43,\"docs/simulation-v3-historical.md\":44,\"docs/simulation-v34.md\":34,\"docs/swarm-bootstrap-v313/binding.json\":10,\"docs/swarm-bootstrap-v313/constructor-args.json\":16,\"foundry.toml\":21,\"keeper/README.md\":117,\"keeper/blackout-keeper.service\":23,\"keeper/keeper.env.example\":18,\"keeper/keeper.mjs\":537,\"keeper/lib/abi.mjs\":95,\"keeper/lib/eth.mjs\":186,\"keeper/lib/oracle.mjs\":57,\"keeper/wiring.example.json\":17,\"launch-v31.md\":3,\"launch-v36.md\":34,\"launch-v37.md\":144,\"launch-v38.md\":57,\"launch-v39.md\":292,\"launch/V4Market.sol\":1870,\"operations/dormant-v35.md\":17,\"regulator.md\":60,\"report.md\":290,\"script/Deploy.s.sol\":184,\"script/DeployMarket.s.sol\":15,\"script/PredictGame.s.sol\":49,\"script/SwarmArgs.sol\":30,\"sim/blackout_sim_v2.py\":509,\"sim/blackout_sim_v3.py\":338,\"sim/blackout_sim_v31.py\":24,\"sim/blackout_sim_v32.py\":380,\"sim/blackout_sim_v33.py\":395,\"sim/blackout_sim_v34.py\":444,\"sim/candidate_stress_v31.py\":21,\"sim/heartbeat_boundaries_v31.py\":25,\"sim/heartbeat_sweep_v31.py\":46,\"sim/policy_sensitivity_v3.py\":19,\"sim/run_v32.py\":34,\"sim/run_v33.py\":58,\"sim/run_v34.py\":54,\"sim/run_v35.py\":273,\"sim/run_v36.py\":83,\"sim/run_v39.py\":153,\"sim/tune_v3.py\":16,\"src/Billboards.sol\":135,\"src/Civic.sol\":302,\"src/Economy.sol\":207,\"src/EndowmentEscrow.sol\":112,\"src/Enhancement.sol\":126,\"src/FarmCore.sol\":597,\"src/FarmEngine.sol\":299,\"src/FarmItems.sol\":165,\"src/FarmRewards.sol\":577,\"src/FeeRouter.sol\":312,\"src/GameRegistry.sol\":102,\"src/GridOperator.sol\":261,\"src/MarketFactory.sol\":72,\"src/PackSale.sol\":293,\"src/Params.sol\":181,\"src/RewardPool.sol\":113,\"src/Season.sol\":371,\"src/StandardAdapter.sol\":77,\"src/StandardMarket.sol\":23,\"src/StarterClaim.sol\":149,\"src/SwarmDesk.sol\":479,\"src/V4Market.sol\":551,\"src/interfaces/IGame.sol\":51,\"src/interfaces/IGameRegistry.sol\":15,\"src/interfaces/ILaunchHook.sol\":7,\"src/interfaces/IV4.sol\":26,\"src/interfaces/Interfaces.sol\":20,\"src/lib/ChainClock.sol\":22,\"src/lib/EconomyMath.sol\":48,\"src/lib/Errors.sol\":13,\"src/lib/GameModule.sol\":17,\"src/lib/ItemMath.sol\":31,\"src/lib/ItemMetadata.sol\":79,\"src/lib/ModuleCode.sol\":51,\"src/lib/SwarmCode.sol\":18,\"src/oracle/OracleAttestation.sol\":221,\"src/oracle/SignatureCheckerCompat.sol\":14,\"test/AutoRepairReviewV35.t.sol\":39,\"test/Base.t.sol\":306,\"test/Bounties.t.sol\":290,\"test/CivicV35.t.sol\":224,\"test/Clock.t.sol\":54,\"test/Deployment.t.sol\":94,\"test/EconomyV35.t.sol\":389,\"test/Endowment.t.sol\":123,\"test/EndowmentEscrowV38.t.sol\":198,\"test/EndowmentGame.t.sol\":51,\"test/Epochs.t.sol\":177,\"test/Events.t.sol\":238,\"test/Factory.t.sol\":37,\"test/FeesParams.t.sol\":135,\"test/Gas.t.sol\":110,\"test/GridV35.t.sol\":66,\"test/HeartbeatBpsV313.t.sol\":149,\"test/HookBinding.t.sol\":113,\"test/Invariants.t.sol\":211,\"test/Items.t.sol\":246,\"test/KeeperProfit.t.sol\":95,\"test/LazyAccounting.t.sol\":447,\"test/Market.t.sol\":130,\"test/OracleConformanceV37.t.sol\":107,\"test/Packs.t.sol\":167,\"test/Pause.t.sol\":76,\"test/PhasedReleaseV36.t.sol\":165,\"test/PotV35.t.sol\":108,\"test/PredictionV34.t.sol\":48,\"test/Registry.t.sol\":141,\"test/Regression.t.sol\":154,\"test/ReservedEventsV35.t.sol\":41,\"test/ReviewV34.t.sol\":146,\"test/SeasonAudit.t.sol\":187,\"test/StandardAdapter.t.sol\":81,\"test/StandardMarket.t.sol\":63,\"test/StandardV4Integration.t.sol\":128,\"test/SwarmDesk-launch-notes.md\":105,\"test/SwarmDeskAdversarial.t.sol\":414,\"test/SwarmDeskBinding.t.sol\":186,\"test/SwarmDeskBootstrap.t.sol\":286,\"test/SwarmDeskInvariants.t.sol\":474,\"test/SwarmDeskV37.t.sol\":646,\"test/TwinCaptureV312.t.sol\":175,\"test/V310.t.sol\":79,\"test/V33.t.sol\":561,\"test/V34.t.sol\":315,\"test/V39.t.sol\":226,\"test/V4Integration.t.sol\":190,\"test/WarReviewV35.t.sol\":69,\"test/YieldFloorReviewV35.t.sol\":31,\"test/fixtures/keeper-v39-vectors.json\":55,\"test/fixtures/oracle-hash-vectors.json\":102,\"test/fork/RehearsalV311.t.sol\":739,\"test/fork/RobinhoodFork.t.sol\":39,\"test/helpers/SwarmDeskTestFixture.sol\":138,\"test/keeper-v39.test.mjs\":34,\"test/mocks/MockGameRegistry.sol\":52,\"test/mocks/MockMarket.sol\":67,\"test/mocks/MockSwarmIntake.sol\":67,\"test/mocks/MockToken.sol\":38,\"test/mocks/MockV4Manager.sol\":118,\"test/oracle-v310.test.mjs\":22,\"test/oracle-v37.test.mjs\":41,\"test/python/test_entropy_bot.py\":31,\"test/python/test_merkle.py\":19,\"test/python/test_regulator.py\":30,\"test/python/test_v31.py\":38,\"test/python/test_v32.py\":58,\"test/python/test_v34.py\":33,\"test/python/test_v35.py\":71,\"test/reveal.test.mjs\":24,\"test/swarm-bootstrap.test.mjs\":48,\"test/ui-v35.test.mjs\":27,\"tools/check_v32_results.py\":52,\"tools/check_v37_authority.py\":19,\"tools/entropy_bot.py\":106,\"tools/freepack_merkle.py\":20,\"tools/make_oracle_bodies.mjs\":45,\"tools/oracle_question_hash.mjs\":80,\"tools/pin_module_code.py\":103,\"tools/pin_swarm_code.py\":47,\"tools/regulator.py\":81,\"tools/rehearse_v311.sh\":25,\"tools/report_v31.py\":55,\"tools/schedule_bodies.mjs\":16,\"tools/starter_merkle.py\":72,\"tools/swarm_constructor_args.mjs\":44,\"ui/app.js\":178,\"ui/index.html\":22,\"ui/reveal.js\":34,\"ui/style.css\":3},\"excluded\":[\"vendor/\",\"node_modules/\"],\"truncated\":true}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"f32995e4b9ce3c034ba32d0a1af971c5e2599ad8947d7d7195380e92ffadc0be","verifiedTreeHash":"17886711307f0331fb20390b38cfc4477e9ce067","verifierVersion":"0.1.0+327e1e9f"}]}