{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"9c938888-9ff8-4a30-9337-3bd742175193","kind":"skill:build-contract-project","nodes":[{"acceptedSubmissionHash":"41b030c4ab02ed6b563381381440cc4fe6526d15a7bea934c59ab9b88b9ae10d","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"6b8d2c2ebd3301cff2be8edb1e1cc6ba65c858c02fe7247be81722b969842265","skillId":"build-contract-project","state":"accepted"}],"objective":"BLACKOUT v3.2: update the v3.1 contracts from job 14e753f9 (same repo) and re-run the sim. NO DEPLOY. Keep v3.1 unless changed below.\n\nGOAL: remove the keeper cost problem. v3.1 needs ~9 ETH of bounties per 35 days because farms are measured and credited by keepers every epoch, which forced a 31% heartbeat share and slowed payback.\n\n1. LAZY ACCOUNTING (no per-farm keeper work)\n- advanceEpoch only snapshots global state: emission, total effective hash, event type/district/seed, tariff. O(1), no farm loops.\n- Each farm settles itself lazily when its owner (or anyone, optional) interacts: claim, install, repair, pack, withdraw. Use a global reward-per-hash accumulator per epoch (MasterChef style) with per-district and per-event adjustments.\n- Event effects on a farm are derived on settle from the epoch seed and the farm id (e.g. hit = hash(seed, farmId) < threshold), so no keeper selects farms. Durability and combo protections apply at settle.\n- Tax audit: replace \"top 10% by hash\" with a hash threshold Param (farms above it pay 10% of that epoch's mining), computed on settle.\n- Cap lazy catch-up: a farm idle for many epochs settles in bounded batches; the owner can settle stale epochs in chunks.\n- Weekly season: scores accumulate on settle; finalize uses bounded work with a small bounty.\n\n2. HEARTBEAT back to 2% (cap 1 ETH, excess to reward pool). Only bounties left: advanceEpoch, entropy capture, buyback, season finalize. Confirm 2% covers them in all scenarios; if not, give the smallest share that does.\n\n3. KEEP: 20% endowment (poolBps 7000), 42-day drip, custom hook with one-time FeeRouter bind, 2 launches (8+4) with GameRegistry, team address 0x6d51cBE774aeAe4dd40bCA2560E9bc2695A0d007.\n\n4. SIM: steady/hype/weak, 20% and 25% endowment, 42-day drip. Report week-1 payback, stall day, price drawdown, team ETH, bounty cost vs heartbeat income. Then list the 3 strongest remaining levers to shorten payback (with numbers), without adding ETH capital.\n\n5. TESTS AND REVIEW: equivalence tests (lazy result == eager reference model for random farms/events), gas per action incl. long idle catch-up, invariants (conservation, no double credit), full suite. A second contributor with fresh context reviews; fix high and medium.\n\nDeliver: updated repo, report.md, updated launch-v31.md deploy steps.\n\nUpgrades and pausing: Not upgradeable. Only PackSale can be paused, by the swarm role, auto-unpause after max 72h. Claims, withdrawals, advanceEpoch and keeper calls can never be paused. The hook has no owner; its only privileged action is the one-time bind to FeeRouter by the team address.","parentJobId":"14e753f9-5e78-4130-84d0-17d862a4ad7d","planHash":"ecba074e72fb75f2d723be73cd56992654f3fb9f37a2bf798f014766bfb04db0","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"21248c45-9e6e-4e68-bf90-de66eeac77cd","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1269-reports-v1-job-b9e37680-814c-4f17-b4bc-6"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51732","feedbackHash":"ff96f6021fa48eecb772327af80a71b22c9fcdfe90c4a3188cc7132edfd43a70","nodeKey":"build_contract_project","submissionHash":"41b030c4ab02ed6b563381381440cc4fe6526d15a7bea934c59ab9b88b9ae10d","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"939db854cb6297ea8dcf2df9549b81d52dfaf5ce65ca15a7ae4b5712277d3d17","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"c4b6679ab47bf80e130f1282d8e5d1e151795cacd45a01660d21e4d98bf37dd0","device":"75474cc326e8a817","findings":[],"hash":"41b030c4ab02ed6b563381381440cc4fe6526d15a7bea934c59ab9b88b9ae10d","nodeId":"7112a202-bc69-4894-a889-2b6af6008f94","outcome":"completed","summary":"Implemented BLACKOUT v3.2. No deployment.\n\n- Lazy settlement, O(1) epochs, 2% heartbeat and bounded season finalization.\n- Build, tests and formatting pass: **132 passed, 0 failed, 1 optional skip**.\n- Independent review completed; high/medium findings fixed.\n- All 72 simulations fund bounties at 2%. Steady payback remains **28.5 days**.\n\n[Report](report.md) · [Updated launch steps](launch-v31.md)","treeHash":"72bcd42cc82eaa4d6192d17c514a21fd36febccc","usage":{"cachedInputTokens":12542464,"inputTokens":303079,"model":"gpt-6-astra","outputTokens":76770,"runtime":"codex","turns":17,"wallClockMs":3034697}}],"verification":[{"checks":[{"durationMs":105154,"exitCode":0,"name":"build","output":"Compiling 142 files with Solc 0.8.26\nSolc 0.8.26 finished in 104.89s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to pure\n   --> src/FarmRewards.sol:124:5:\n    |\n124 |     function ready() public view returns (bool) {\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/RewardPool.sol:50:33\n   │\n50 │         if (endowment() == 0 || block.timestamp >= dripStart + dripPeriod) return 0;\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/StarterClaim.sol:61:9\n   │\n61 │         farm().register(msg.sender);\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:305:9\n    │\n305 │         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/StarterClaim.sol:54:13\n   │\n54 │         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:54:58\n   │\n54 │         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[missing-events-arithmetic]: `heldSellTax` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:306:9\n    │\n306 │         heldSellTax += excess;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/RewardPool.sol:65:13\n   │\n65 │         if (token().balanceOf(address(this)) - before_ != endowment()) 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/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-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/StarterClaim.sol:62:9\n   │\n62 │         emit StarterCommitted(tokenId, msg.sender, target);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[missing-events-arithmetic]: `heldBase` is changed without an event but is used in arithmetic\n    ╭▸ src/V4Market.sol:342:9\n    │\n342 │         heldBase += base;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StarterClaim.sol:59:25\n   │\n59 │         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[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/RewardPool.sol:89:13\n   │\n89 │         if (token().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 `_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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/StarterClaim.sol:77:9\n   │\n77 │         fees().payWork(keeper, Params.Key.EntropyBounty, 1, startGas - gasleft());\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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/RewardPool.sol:96:9\n   │\n96 │         emit Reserved(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/FarmRewards.sol:129:30\n    │\n129 │         return epoch != 0 && block.timestamp < epochs[epoch].end;\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/RewardPool.sol:104:67\n    │\n104 │     function pay(address to, uint256 amount) external onlyRewards nonReentrant {\n    │                                                                   ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\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[reentrancy-no-eth]: external call can be reentered before `scrapAllowance` is updated\n    ╭▸ src/FarmRewards.sol:143:13\n    │\n143 │             pool().recycle(scrapAllowance);\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: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[encode-packed-collision]: `abi.encodePacked()` called with multiple dynamic type arguments; hash collisions possible\n   ╭▸ src/MarketFactory.sol:18:13\n   │\n18 │ ┏             abi.encodePacked(\n19 │ ┃                 type(V4Market).creationCode,\n20 │ ┃                 abi.encode(c.manager, c.token, c.networkRecipient, uint24(0), c.tickSpacing)\n21 │ ┃             )\n   │ ┗━━━━━━━━━━━━━┛\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/encode-packed-collision\n\nwarning[reentrancy-no-eth]: external call can be reentered before `epoch` is updated\n    ╭▸ src/FarmRewards.sol:147:13\n    │\n147 │             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:157:17\n    │\n157 │                 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:164:33\n    │\n164 │                 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:189:9\n    │\n189 │         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:190:9\n    │\n190 │         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/MarketFactory.sol:56:9\n   │\n56 │         emit MarketDeployed(address(market), salt);\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:141:13\n    │\n141 │         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:141:62\n    │\n141 │         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:93:23\n   │\n93 │         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:185:36\n    │\n185 │             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:173:13\n    │\n173 │             emit EpochClosed(epoch, old.budget, old.raw);\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:173:13\n    │\n173 │         if (block.timestamp < lastChanged[k] + 1 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/FarmRewards.sol:191:9\n    │\n191 │         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:149:13\n    │\n149 │             (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:177:19\n    │\n177 │         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:178:17\n    │\n178 │         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[unused-return]: return value of an external call is not used\n   ╭▸ src/FarmEngine.sol:60:30\n   │\n60 │             (, 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:39:26\n   │\n39 │         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:73:27\n   │\n73 │             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:105:39\n    │\n105 │             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:118:39\n    │\n118 │             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/PackSale.sol:33:16\n   │\n33 │         return block.timestamp < pausedUntil;\n   │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:43:23\n   │\n43 │         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:60:30\n   │\n60 │             (, 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/PackSale.sol:39:13\n   │\n39 │         if (block.timestamp < nextPauseAt) revert TooEarly();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:47:25\n   │\n47 │         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:63:25\n   │\n63 │         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:63:63\n   │\n63 │         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:98:24\n   │\n98 │         if (room >= 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/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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/PackSale.sol:86:27\n   │\n86 │         uint256 elapsed = block.timestamp > launchTime() ? block.timestamp - launchTime() : 0;\n   │                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/PackSale.sol:88:24\n   │\n88 │         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:88:50\n   │\n88 │         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:91:30\n   │\n91 │             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:93:30\n   │\n93 │             exponent = wadLn(int256(1 ether - params().get(Params.Key.PriceDecayBps) * 1e14)) * (-ahead)\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[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:124:19\n    │\n124 │             raw = raw * (10 + f.clocks[idx]) / 10;\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:128:29\n    │\n128 │             s.productive += raw * f.health[idx] / 10000;\n    │                             ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/PackSale.sol:94:19\n   │\n94 │                 / 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:98:51\n   │\n98 │         p = params().get(Params.Key.PriceStart) * 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:78:16\n   │\n78 │         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/PackSale.sol:62:23\n   │\n62 │         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:87:26\n   │\n87 │         uint256 target = params().get(Params.Key.DemandTarget);\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:47\n   │\n91 │             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:93:47\n   │\n93 │             exponent = wadLn(int256(1 ether - params().get(Params.Key.PriceDecayBps) * 1e14)) * (-ahead)\n   │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:98:13\n   │\n98 │         p = params().get(Params.Key.PriceStart) * uint256(wadExp(exponent)) / 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:99:23\n   │\n99 │         uint256 low = params().get(Params.Key.PriceFloor);\n   │                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/PackSale.sol:100:24\n    │\n100 │         uint256 high = params().get(Params.Key.PriceCeiling);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmEngine.sol:106:41\n    │\n106 │             if (x.holder != address(0)) mask |= 1 << x.kind;\n    │                                         ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmEngine.sol:121:13\n    │\n121 │             tags |= 1 << ItemMath.tag(x.kind);\n    │             ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/PackSale.sol:122:9\n    │\n122 │         fees().depositPack{value: msg.value}();\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/StarterClaim.sol:91:13\n   │\n91 │             items().mint(c.player, h == bytes32(0) ? 0 : k, h == bytes32(0) ? 1 : 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:42:26\n   │\n42 │         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:91:13\n   │\n91 │             items().mint(c.player, h == bytes32(0) ? 0 : k, h == bytes32(0) ? 1 : 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:93:9\n   │\n93 │         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:91:13\n   │\n91 │             items().mint(c.player, h == bytes32(0) ? 0 : k, h == bytes32(0) ? 1 : r, true);\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[encode-packed-collision]: `abi.encodePacked()` called with multiple dynamic type arguments; hash collisions possible\n   ╭▸ src/GameRegistry.sol:76:58\n   │\n76 │             factory.predictContract(launchNumber, index, abi.encodePacked(creationCode, abi.encode(address(this))));\n   │                                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/encode-packed-collision\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/PackSale.sol:119:9\n    │\n119 │         farm().register(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:120:9\n    │\n120 │         farm().paidPackBought(msg.sender, n, msg.value);\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:117:25\n    │\n117 │         if (paused() || block.timestamp < launchTime() || msg.value != quote(n)) revert InvalidValue();\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:141:9\n    │\n141 │         emit PackCommitted(id, p, n, target, guaranteed);\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:147:22\n    │\n147 │         (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:149:9\n    │\n149 │         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:164:9\n    │\n164 │         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/FeeRouter.sol:170:9\n    │\n170 │         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:171:9\n    │\n171 │         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:164:9\n    │\n164 │         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/PackSale.sol:139:25\n    │\n139 │         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:159:9\n    │\n159 │         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:176:13\n    │\n176 │             items().mint(c.player, k, r, false);\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/PackSale.sol:175:47\n    │\n175 │             if (c.guaranteed && i % 3 == 0 && r < 1) r = 1;\n    │                                               ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/PackSale.sol:176:36\n    │\n176 │             items().mint(c.player, k, r, false);\n    │                                    ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:58:26\n   │\n58 │         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:176:13\n    │\n176 │             items().mint(c.player, k, r, false);\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:178:9\n    │\n178 │         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:176:13\n    │\n176 │             items().mint(c.player, k, r, false);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[missing-events-access-control]: `lotteryClaimed` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:219:9\n    │\n219 │         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/Season.sol:86:13\n   │\n86 │         if (block.timestamp < launchTime()) 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/FarmRewards.sol:244:25\n    │\n244 │         for (uint256 n; n < limit && cursor < settledEpoch; ++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/Season.sol:107:13\n    │\n107 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:101:22\n    │\n101 │         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:253:60\n    │\n253 │         (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:117:16\n    │\n117 │         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:97:27\n   │\n97 │         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:291:30\n    │\n291 │             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:294:32\n    │\n294 │                 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:298:17\n    │\n298 │                 core().activity(p, id, gross, 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:300:21\n    │\n300 │                     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:113:24\n    │\n113 │         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:302:17\n    │\n302 │                 season().recordActivity(p, week, gross);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:307:13\n    │\n307 │             season().complete(p, week);\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/Season.sol:115:13\n    │\n115 │         if (block.timestamp >= deadline(w) || completed[w][p]) return;\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:334:13\n    │\n334 │             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:345:9\n    │\n345 │         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:295:17\n    │\n295 │                 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:279:37\n    │\n279 │             if (spent > 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/Season.sol:141:42\n    │\n141 │         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:144:20\n    │\n144 │         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/GridOperator.sol:102:13\n    │\n102 │         if (halves >= 128) return 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/FarmRewards.sol:277:43\n    │\n277 │             uint256 spent = net + redis + referral;\n    │                                           ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[arbitrary-send-eth]: ETH is sent to a user-controlled destination; restrict the destination or the caller\n    ╭▸ src/GridOperator.sol:121:9\n    │\n121 │         fees().depositLobby{value: msg.value}();\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/GridOperator.sol:120:9\n    │\n120 │         season().recordSpend(msg.sender, msg.value, 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/Season.sol:184:39\n    │\n184 │             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:185:18\n    │\n185 │             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:187:34\n    │\n187 │         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/FarmRewards.sol:332:13\n    │\n332 │         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:342:19\n    │\n342 │         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/GridOperator.sol:131:52\n    │\n131 │         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[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:343:48\n    │\n343 │         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/Season.sol:175:25\n    │\n175 │         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:188:9\n    │\n188 │         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:172:92\n    │\n172 │             if (s.districtSpend[d] > s.districtSpend[s.winnerDistrict]) 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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmRewards.sol:371:25\n    │\n371 │         for (uint256 n; n < 32 && amount != 0; ++n) {\n    │                         ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/GridOperator.sol:62:23\n   │\n62 │         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/GridOperator.sol:109:33\n    │\n109 │         uint256 reduction = a * params().get(Params.Key.LobbyKBps) / (1 ether + a);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:111:25\n    │\n111 │         uint256 floor = params().get(Params.Key.LobbyMinWeight);\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:360:36\n    │\n360 │             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:377:45\n    │\n377 │             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[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:194:20\n    │\n194 │         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[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:139:20\n    │\n139 │         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:140:21\n    │\n140 │         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/Season.sol:214:14\n    │\n214 │         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:223:14\n    │\n223 │         id = items().mint(msg.sender, k, r, false);\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/GridOperator.sol:214:9\n    │\n214 │         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:178:57\n    │\n178 │             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:179:27\n    │\n179 │             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:194:13\n    │\n194 │             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:202:34\n    │\n202 │                     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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmRewards.sol:253:60\n    │\n253 │         (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:291:30\n    │\n291 │             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:294:32\n    │\n294 │                 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:298:17\n    │\n298 │                 core().activity(p, id, gross, 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:300:21\n    │\n300 │                     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:302:17\n    │\n302 │                 season().recordActivity(p, week, gross);\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:307:13\n    │\n307 │             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:387:9\n    │\n387 │         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:388:9\n    │\n388 │         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/FarmRewards.sol:394:9\n    │\n394 │         pool().recycle(consumed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n    ╭▸ src/FarmRewards.sol:391:66\n    │\n391 │     function spend(address p, uint256 nominal) external onlyCore nonReentrant returns (uint256 consumed) {\n    │                                                                  ━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/non-reentrant-not-first\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:395:9\n    │\n395 │         emit Spent(p, consumed);\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:398:80\n    │\n398 │     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:412:9\n    │\n412 │         pool().recycle(amount);\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:167:9\n    │\n167 │         f.serial = nextSerial++;\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:187:9\n    │\n187 │         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:437:9\n    │\n437 │         farms[p].xp += 100;\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:145:53\n    │\n145 │         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:169:9\n    │\n169 │         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:166:18\n    │\n166 │         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:66:26\n   │\n66 │         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:194:39\n    │\n194 │             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:188:25\n    │\n188 │         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[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:168:9\n    │\n168 │         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:175:13\n    │\n175 │         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:181:9\n    │\n181 │         rewards().setWeight(p, engine().allocationHash(farms[p].loadout, farms[p].paid != 0));\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:206:9\n    │\n206 │         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:207:9\n    │\n207 │         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:168:9\n    │\n168 │         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:175:13\n    │\n175 │         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:181:9\n    │\n181 │         rewards().setWeight(p, engine().allocationHash(farms[p].loadout, farms[p].paid != 0));\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:213:9\n    │\n213 │         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:240:9\n    │\n240 │         items().equip(msg.sender, id);\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:233:29\n    │\n233 │             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:242:9\n    │\n242 │         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:233:63\n    │\n233 │             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:252:9\n    │\n252 │         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:254:9\n    │\n254 │         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:271:9\n    │\n271 │         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:262:56\n    │\n262 │             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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/FarmCore.sol:297:9\n    │\n297 │         emit Spent(p, kind, paid, nominal);\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/FarmCore.sol:288:17\n    │\n288 │             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 `farms` is updated\n    ╭▸ src/FarmCore.sol:290:20\n    │\n290 │             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:296:9\n    │\n296 │         season().recordSpend(p, value, 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/FarmCore.sol:307:9\n    │\n307 │         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:316:32\n    │\n316 │         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:317:29\n    │\n317 │         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:326:9\n    │\n326 │         items().maintain(id, x.durability, x.overclock + 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:335:9\n    │\n335 │         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:296:9\n    │\n296 │         season().recordSpend(p, value, 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/FarmCore.sol:345:9\n    │\n345 │         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:346:14\n    │\n346 │         id = ITokenPacks(packs()).tokenPack(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/FarmCore.sol:352:9\n    │\n352 │         grid().tokenLobby(msg.sender, Math.mulDiv(paid, 1 ether, market().quote(1 ether)));\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:371:13\n    │\n371 │             items().destroy(ids[i]);\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:374:18\n    │\n374 │         result = items().mint(msg.sender, x.kind, x.rarity + 1, false);\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:360:39\n    │\n360 │             FarmItems.Item memory y = items().data(ids[i]);\n    │                                       ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:371:13\n    │\n371 │             items().destroy(ids[i]);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/FarmCore.sol:375:9\n    │\n375 │         emit Merged(msg.sender, result);\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:364:15\n    │\n364 │             ) 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/FarmCore.sol:366:39\n    │\n366 │                 if (ids[i] == ids[j]) 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:384:9\n    │\n384 │         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:385:26\n    │\n385 │         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:382:24\n    │\n382 │         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:386:9\n    │\n386 │         emit Scrapped(msg.sender, id, earned);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:398:39\n    │\n398 │             FarmItems.Item memory x = items().data(snap.ids[i]);\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmCore.sol:416:14\n    │\n416 │         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:424:28\n    │\n424 │             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:457:14\n    │\n457 │         id = items().mint(msg.sender, k, r == 0 ? 0 : 1, false);\n    │              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[missing-events-access-control]: `fees` is changed without an event but is used for access control\n   ╭▸ src/V4Market.sol:95:9\n   │\n95 │         fees = candidate;\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:108:24\n    │\n108 │         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:109:26\n    │\n109 │         if (excess != 0) fees.depositSellTax{value: excess}();\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:110:9\n    │\n110 │         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:158:13\n    │\n158 │             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:171:9\n    │\n171 │         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:165:38\n    │\n165 │             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:168:23\n    │\n168 │         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:163:13\n    │\n163 │         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:163:27\n    │\n163 │         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:164:38\n    │\n164 │         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:166:53\n    │\n166 │             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:177:50\n    │\n177 │         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:184:35\n    │\n184 │         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:198:13\n    │\n198 │         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:204:13\n    │\n204 │         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:200:24\n    │\n200 │             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:206:24\n    │\n206 │             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:209:24\n    │\n209 │             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:210:24\n    │\n210 │             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:212:23\n    │\n212 │             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:213:23\n    │\n213 │             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:223:17\n    │\n223 │                 s += shortVolumes[i].sells;\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:224:17\n    │\n224 │                 b += shortVolumes[i].buys;\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:222:17\n    │\n222 │             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:232:17\n    │\n232 │             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:250:13\n    │\n250 │         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:249:13\n    │\n249 │         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:255:27\n    │\n255 │         uint256 decayed = storedFeeWad > fall ? storedFeeWad - fall : projectBps() * 1 ether;\n    │                           ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:269:25\n    │\n269 │         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:271:19\n    │\n271 │         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:271:27\n    │\n271 │         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:273:43\n    │\n273 │         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:298:9\n    │\n298 │         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:284:27\n    │\n284 │         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:287:28\n    │\n287 │             _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:291:26\n    │\n291 │         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:291:34\n    │\n291 │         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:299:42\n    │\n299 │         return (this.afterSwap.selector, int128(int256(base + excess + network)));\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:299:49\n    │\n299 │         return (this.afterSwap.selector, int128(int256(base + excess + network)));\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/V4Market.sol:316:31\n    │\n316 │         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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmEngine.sol:161:32\n    │\n161 │             if (f.ids[i] != 0) occupied++;\n    │                                ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmEngine.sol:183:30\n    │\n183 │                 if (surge && cursor == target && !before_.clean) {\n    │                              ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmEngine.sol:193:21\n    │\n193 │                     damage += 3000 * uint256(severity) / 10000 / (before_.airflow ? 2 : 1);\n    │                     ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:180:43\n    │\n180 │                 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:185:25\n    │\n185 │                         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:196:17\n    │\n196 │                 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:217:43\n    │\n217 │                 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:218:17\n    │\n218 │                 items().maintain(id, x.durability > 50 ? x.durability - 50 : 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:173:32\n    │\n173 │                 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[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:195:33\n    │\n195 │                 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:196:38\n    │\n196 │                 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 `initializedAt` is updated\n    ╭▸ src/V4Market.sol:328:24\n    │\n328 │         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:328:62\n    │\n328 │         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:330:27\n    │\n330 │         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:331:29\n    │\n331 │         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:333:30\n    │\n333 │             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:334:20\n    │\n334 │                 || 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:334:28\n    │\n334 │                 || 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:339:9\n    │\n339 │         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:340:40\n    │\n340 │         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:340:48\n    │\n340 │         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:343:27\n    │\n343 │         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:343:35\n    │\n343 │         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-eth]: uncapped ETH transfer can be reentered before `_status` is updated\n    ╭▸ src/V4Market.sol:350:22\n    │\n350 │         (bool ok,) = networkRecipient.call{value: amount}(\"\");\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/V4Market.sol:352:9\n    │\n352 │         emit NetworkPaid(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\n","passed":true},{"durationMs":30757,"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 245.56µs (86.21µs CPU time)\n\nRan 2 tests for test/Clock.t.sol:ClockTest\n[PASS] testLocalEvmFutureBlockAnd256BlockBoundary() (gas: 220367)\n[PASS] testRobinhoodUsesArbSysNotL1EstimateAndHandlesExpiry() (gas: 443925)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 447.03µs (387.51µs CPU time)\n\nRan 5 tests for test/Registry.t.sol:RegistryTest\n[PASS] testAllModulePinsMatchExactPinnedCompilerArtifacts() (gas: 247240)\n[PASS] testAuthenticatedEnrollmentRejectsUncreatedWrongCodeAndWrongRegistry() (gas: 2709707)\n[PASS] testConstructorAcceptsEmptyGraphWithoutExternalCalls() (gas: 10041)\n[PASS] testCounterfeitRuntimeAtAnotherFactoryCannotEnroll() (gas: 1469262)\n[PASS] testCounterfeitRuntimeWithPoisonedCreditCannotEnroll() (gas: 3128634)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 7.04ms (4.04ms CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] testConstructorRejectsMissingInputsAndDoesNotCallExternalContracts() (gas: 4154)\n[PASS] testForeignCallerDoesNotGetAnyAuthority() (gas: 23508247)\n[PASS] testImmutableGraphAndEip170Sizes() (gas: 153681)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 8.18ms (3.28ms CPU time)\n\nRan 2 tests for test/Factory.t.sol:FactoryTest\n[PASS] testFactoryInvalidSearchRange() (gas: 4984)\n[PASS] testHookFactoryFlagsImmutableConfigAndIdempotence() (gas: 2294505)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 10.56ms (2.59ms CPU time)\n\nRan 3 tests for test/StandardAdapter.t.sol:StandardAdapterTest\n[PASS] testExistingHookKeyPreservedAndNoExtraFee() (gas: 325352)\n[PASS] testRequiresThirtyMinutesFreshOracleAndAuthorizedCallback() (gas: 194045)\n[PASS] testSettlementSlippageFailurePreservesCredits() (gas: 256375)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 12.67ms (1.69ms CPU time)\n\nRan 5 tests for test/KeeperProfit.t.sol:KeeperProfitTest\n[PASS] testPaidPackEntropyKeeperProfit() (gas: 853700)\nLogs:\n  paid pack entropy execution gas: 134284\n  paid pack entropy bounty wei: 3324700000000\n  paid pack entropy execution plus 21000 gas cost wei: 3105680000000\n\n[PASS] testPlanEntropyKeeperProfit() (gas: 1358390)\nLogs:\n  plan entropy execution gas: 155141\n  plan entropy bounty wei: 4349475000000\n  plan entropy execution plus 21000 gas cost wei: 3522820000000\n\n[PASS] testSeasonFinalizeThreeWinnersAndPrizeKeeperProfit() (gas: 2830238)\nLogs:\n  season finalize three winners and prize execution gas: 586797\n  season finalize three winners and prize bounty wei: 14487525000000\n  season finalize three winners and prize execution plus 21000 gas cost wei: 12155940000000\n\n[PASS] testSeasonPrepareIsConstantUnpaidWork() (gas: 1168241)\n[PASS] testStarterEntropyKeeperProfit() (gas: 306021)\nLogs:\n  starter entropy execution gas: 136851\n  starter entropy bounty wei: 3317175000000\n  starter entropy execution plus 21000 gas cost wei: 3157020000000\n\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 18.31ms (10.65ms CPU time)\n\nRan 3 tests for test/HookBinding.t.sol:HookBindingTest\n[PASS] testFlushFailureRestoresEscrowAndDoesNotStopSwaps() (gas: 555019)\n[PASS] testHoldBeforeGameExistsThenBindOnceAndFlushExactStreams() (gas: 1967729)\n[PASS] testWrongRouterAndMissingCodeRejectedBeforePermanentBind() (gas: 1059719)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 39.35ms (2.85ms CPU time)\n\nRan 9 tests for test/Packs.t.sol:PacksTest\n[PASS] testExactPaymentAndFutureBlockRequired() (gas: 1271082)\n[PASS] testExactRarityThresholdsAndMythicGate() (gas: 270970)\n[PASS] testExpiryThreeCommonGpusAndInventoryOpeningLimit() (gas: 2651118)\n[PASS] testFuzzVrgdaAlwaysBounded(uint32,uint32) (runs: 256, μ: 44580, ~: 44574)\nLogs:\n  Bound result 2080\n\n[PASS] testItemTypeDistributionExact() (gas: 591753)\n[PASS] testNoWalletGlobalOrTokenPackDailyLimit() (gas: 4233045)\n[PASS] testStarterWindowProofTokenIdOnceAndInventoryFailureRetry() (gas: 606172)\n[PASS] testTokenPackDiscountAllToPoolAndBonusWhenInternal() (gas: 5727162)\n[PASS] testVrgdaInitialStepDecayFloorCeilingAndBulkPricing() (gas: 957042)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 104.56ms (165.97ms CPU time)\n\nRan 10 tests for test/Bounties.t.sol:BountiesTest\n[PASS] testBuyBountyProportionalCapNoDustCreditAndFailureRollback() (gas: 715763)\n[PASS] testEmptyRosterAndInvalidBatchReceiveNothing() (gas: 1119109)\n[PASS] testEveryWorkKindBoundedByHeartbeatAndAuthorizedProducer() (gas: 61784693)\n[PASS] testLazySettlementUnpaidAndCannotReplay() (gas: 4557884)\n[PASS] testOnlyFinalizePaidOnceAndEmptyWeekUnpaid() (gas: 2129282)\n[PASS] testPackEntropyCapturedOnceWithFullInventoryAndThroughPause() (gas: 2553958)\n[PASS] testPlanResolutionPaidOnceIncludingAdvanceForwarding() (gas: 2314432)\n[PASS] testRemovedWorkBountiesRejectedEvenFromOldProducer() (gas: 168649)\n[PASS] testStarterEntropySurvivesFullInventoryExpiryAndPauseWithoutReplayPayment() (gas: 3839366)\n[PASS] testWorkCreditRespectsZeroGasPricePriceCeilingAndUnitCap() (gas: 319984)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 116.38ms (127.31ms CPU time)\n\nRan 1 test for test/EndowmentGame.t.sol:EndowmentGameTest\n[PASS] testRealMiningCannotSpendFutureEndowment() (gas: 92462632)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 119.22ms (113.54ms CPU time)\n\nRan 5 tests for test/V4Integration.t.sol:V4IntegrationTest\n[PASS] testRealV4BuyAndSingleSwapSellTaxConserveSettlement() (gas: 2251961)\n[PASS] testRealV4ManipulatedSpotCannotInstantlySetBuybackQuote() (gas: 1850204)\n[PASS] testRealV4SmallBuyPaysPositiveKeeperMargin() (gas: 1973585)\nLogs:\n  real V4 0.2ETH buy gas: 1837743\n  real V4 buy bounty wei: 46320350000000\n\n[PASS] testRealV4SystemBuyUsesTwapAndOnlySystemFunds() (gas: 1999728)\n[PASS] testSystemBuybackOffsetsRecordedSellImbalance() (gas: 2405344)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 140.78ms (8.33ms CPU time)\n\nRan 8 tests for test/FeesParams.t.sol:FeesParamsTest\n[PASS] testAllDefaultParamsWithinHardBounds() (gas: 913820)\n[PASS] testBuyBackPoolOnlySlippageFailureRollbackAndDustGriefBlocked() (gas: 823448)\n[PASS] testExactEthSplitsHeartbeatCapAndPullPayments() (gas: 441727)\n[PASS] testFuzzNoStepAboveTenPercent(uint96) (runs: 256, μ: 44612, ~: 44717)\nLogs:\n  Bound result 5285\n\n[PASS] testFuzzSplitsConserveEveryWei(uint96) (runs: 256, μ: 160724, ~: 162408)\nLogs:\n  Bound result 64964225\n\n[PASS] testHeartbeatCapFixedAtOneEth() (gas: 173793)\n[PASS] testParamsStepCooldownBoundsAuthorityAndLetter() (gas: 195336)\n[PASS] testPoolNoPublicReserveRecycleOrPayment() (gas: 126725)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 165.65ms (148.53ms CPU time)\n\nRan 6 tests for test/Market.t.sol:MarketTest\n[PASS] testBuyChargesOnlyBaseAndNetworkPullPayment() (gas: 285313)\n[PASS] testFuzzTotalFeeHardCap(uint96) (runs: 256, μ: 1815650, ~: 1819598)\nLogs:\n  Bound result 64964225\n\n[PASS] testOnlyManagerCorrectPoolExactInputAndHookAddress() (gas: 108671)\n[PASS] testSingleDumpIncludesItselfAndFeeDecaysWithoutGriefReset() (gas: 16839752)\n[PASS] testTwapAveragesEthPriceAcrossUnequalPrices() (gas: 2335354)\n[PASS] testTwapWarmupAndFlashManipulationResistance() (gas: 1888831)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 185.98ms (216.64ms CPU time)\n\nRan 1 test for test/StandardV4Integration.t.sol:StandardV4IntegrationTest\n[PASS] testStandardAdapterRealPoolPaysExistingHookExactlyOnce() (gas: 2053595)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 186.04ms (1.79ms CPU time)\n\nRan 6 tests for test/Endowment.t.sol:EndowmentTest\n[PASS] testDirectTransferCannotBypassOrBackdateDrip() (gas: 364462)\n[PASS] testExactFundingFullLinearDripAndConservation() (gas: 803798)\n[PASS] testFuzzCumulativePaymentsCannotExceedVestedPrincipal(uint32,uint128) (runs: 256, μ: 519692, ~: 521620)\nLogs:\n  Bound result 55\n  Bound result 1364218338695317536\n\n[PASS] testNoTeamDonorOrSwarmWithdrawalOrReserveAuthority() (gas: 621434)\n[PASS] testParamsSnapshotCannotAccelerateOrRelockExistingEndowment() (gas: 320979)\n[PASS] testUnderfundingCannotActivateAndDonationsStayConserved() (gas: 440979)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 226.93ms (145.79ms CPU time)\n\nRan 11 tests for test/Items.t.sol:ItemsTest\n[PASS] testComputeHashSupportHashAndBonusesReplaceDuo() (gas: 3435369)\n[PASS] testDurabilityDecayRepairAndOverclockPreserved() (gas: 7772663)\n[PASS] testEquipRarityGatesAndMythicGate() (gas: 6809454)\n[PASS] testFullStackRarityCapAndRoomFlags() (gas: 5429099)\n[PASS] testInventoryMintCannotExceedCapacityAndExpansionRises() (gas: 2288790)\n[PASS] testMergeThreeIdenticalAndNoLegendaryMergeOrLockedExit() (gas: 6346638)\n[PASS] testOffgridSavings() (gas: 1902555)\n[PASS] testPaidXpCannotBypassRoomTwoAgeGate() (gas: 4111706)\n[PASS] testRoomGatesAndLevelProgression() (gas: 53369264)\n[PASS] testScrapPaysPoolYieldAndCannotRepeat() (gas: 5754076)\n[PASS] testSoulboundOnlyOwnFarmAndNoDuplicateTypes() (gas: 1687142)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 226.78ms (401.18ms CPU time)\n\nRan 3 tests for test/Pause.t.sol:PauseTest\n[PASS] testOnlySwarmBoundedDurationAndCannotExtendPause() (gas: 234226)\n[PASS] testSalePausedWhileEntropyClaimsWithdrawalsAndEpochsContinue() (gas: 10573514)\n[PASS] testUnpauseCannotResetNextPauseCooldown() (gas: 187697)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 326.80ms (33.11ms CPU time)\n\nRan 13 tests for test/Events.t.sol:EventsTest\n[PASS] testCheapTariffAppliesCitywide() (gas: 4900830)\n[PASS] testColdPowerFireImmuneAndCleanPowerSurgeImmune() (gas: 5547135)\n[PASS] testFallbackAndExpiredSeedIndependentOfSwarmNumber() (gas: 1364649)\n[PASS] testFireNoCoolingZeroYieldColdPowerImmune() (gas: 4373856)\n[PASS] testGreenWaveRaisesDistrictMiningTenPercent() (gas: 4902171)\n[PASS] testLobbyOwnDistrictSplitDecayAndMinimumWeight() (gas: 485821)\n[PASS] testOutageAndOffgridRoomMitigation() (gas: 4945296)\n[PASS] testPlansOnlyNextTwoOnceAndBoundedSeverity() (gas: 334410)\n[PASS] testRollingCapsAndInitialPositiveQuotaWithHostilePlans() (gas: 82025201)\n[PASS] testSurgeCanDestroyCommonButNeverLegendary() (gas: 4474358)\n[PASS] testSurgeDamagesExactlyOneItemAndCleanPowerImmune() (gas: 4410828)\n[PASS] testSurgeNeverDestroysLegendaryOrMythic() (gas: 7686446)\n[PASS] testTheftRouterDisabledAndRepairRestores() (gas: 4919600)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 358.72ms (253.26ms CPU time)\n\nRan 6 tests for test/Regression.t.sol:RegressionTest\n[PASS] testCableRepairRestoresOnlyRemainingHalfEpoch() (gas: 8966282)\n[PASS] testEmptyEpochResetsScrapRateAndAllowance() (gas: 8766561)\n[PASS] testFuzzCableRepairBlendHandlesNonMonotonicRarityBonuses(uint16) (runs: 256, μ: 1014480, ~: 1014418)\nLogs:\n  Bound result 782\n\n[PASS] testRegisterOnlyAccountsDoNotAddSettlementWorkAndEmptyFarmCanRetire() (gas: 1549619)\n[PASS] testRepairAndPaidPackCannotRetroactivelyBoostEpoch() (gas: 7073594)\n[PASS] testUnlimitedFreshPacksCannotDrainPoolByScrapping() (gas: 7312719)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 358.88ms (394.39ms CPU time)\n\nRan 6 tests for test/SeasonAudit.t.sol:SeasonAuditTest\n[PASS] testAuditThresholdStrictAndNoWhaleSoftCap() (gas: 24517517)\n[PASS] testLotteryEntitlementSurvivesFullInventory() (gas: 102704179)\n[PASS] testPackSupplyDropOnlyActiveFarmsAtDoublePace() (gas: 11327162)\n[PASS] testParameterChangesCannotChangeClosedEpochBetweenBatches() (gas: 8116010)\n[PASS] testSeasonCannotFinalizeEarlyAndExpiredLotteryMustRearm() (gas: 97534702)\n[PASS] testWeeklyThreeDistinctTicketWinnersRarePackAndBestPrize() (gas: 98194838)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 398.77ms (1.04s CPU time)\n\nRan 3 tests for test/Gas.t.sol:GasTest\n[PASS] testGasCommonActions() (gas: 7369531)\nLogs:\n  buy ETH pack: 719243\n  open one pack: 374384\n  equip: 433011\n  repair wallet: 389611\n  overclock: 338663\n  expand: 287492\n  token pack internal: 543476\n  withdraw: 197423\n  unequip: 308125\n\n[PASS] testGasFullFarmLongIdleBoundedChunks() (gas: 139514481)\nLogs:\n  settle full 24-item farm eight epochs after 40 idle: 11339205\n\n[PASS] testGasTypicalFarmSettlementHasNoBounty() (gas: 5945310)\nLogs:\n  settle typical three-item farm one epoch: 941756\n\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 762.60ms (817.11ms CPU time)\n\nRan 9 tests for test/Epochs.t.sol:EpochsTest\n[PASS] testCannotAdvanceEarlyAndBountyOnce() (gas: 1916412)\n[PASS] testClaimsEveryEpochAndRedistributionIsNextEpoch() (gas: 9386503)\n[PASS] testGasAdvanceIndependentOfRoster() (gas: 658848371)\nLogs:\n  advance empty roster: 985099\n  advance 1000 farms: 975024\n\n[PASS] testNoCatchupEmissionDuringGap() (gas: 4867316)\n[PASS] testNoRetroactiveEquipmentAndBoundedBatches() (gas: 4499455)\n[PASS] testNoWhaleCapHashShares() (gas: 7679225)\n[PASS] testReferralOneLevelSetOnceNoSelf() (gas: 5850018)\n[PASS] testTaxCurveExactAndFloor() (gas: 27174)\n[PASS] testWithdrawFailureRollsBackAndReentrancyCannotClaimTwice() (gas: 5605354)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 5.07s (5.15s CPU time)\n\nRan 2 tests for test/StandardMarket.t.sol:StandardMarketTest\n[PASS] testFuzzStandardSellNeverAddsProgressiveSurcharge(uint96) (runs: 256, μ: 1781342, ~: 1789787)\nLogs:\n  Bound result 64964225\n\n[PASS] testStandardBuyOnePercentEvenSplitAndNetworkQuarterPercent() (gas: 1665539)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 8.74s (8.73s CPU time)\n\nRan 9 tests for test/LazyAccounting.t.sol:LazyAccountingTest\n[PASS] testAuditChargesTenPercentEvenAtHalfSeverityAndThresholdIsFrozen() (gas: 4594609)\n[PASS] testClaimCatchesUpWhilePacksPausedAndDoesNotEraseRemainingHistory() (gas: 20075369)\n[PASS] testExhaustedFarmCannotCollectRedistributionByRemainingIdle() (gas: 11742210)\n[PASS] testFuzzLazyEqualsIndependentEagerForRandomFarmsAndAllEvents(uint256) (runs: 256, μ: 36451563, ~: 36459471)\n[PASS] testGlobalAccumulatorAndWeightsAreSnapshottedBeforeMutations() (gas: 6802013)\n[PASS] testLateSeasonSettlementPaysMiningWithoutChangingFrozenWinners() (gas: 63326757)\n[PASS] testOneWeiMiningGreenCannotLockSettlementThroughEnvelopeRounding() (gas: 8914983)\n[PASS] testSparseMatureVintageConsumedBeforeRecentSlotAfterWrap() (gas: 33410240)\n[PASS] testStaleActionsRequireChunksAndNeverBlockGlobalAdvance() (gas: 35888430)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 8.74s (9.27s CPU time)\n\nRan 1 test for test/Invariants.t.sol:InvariantsTest\n[PASS]\nInvariantsTest invariants:\n[PASS] invariantInventoryAndEthLiabilities\n[PASS] invariantPriceAndParamsBounds\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   | 901   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | buy       | 888   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | claim     | 942   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | equip     | 947   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | expand    | 871   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | resolve   | 919   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | settle    | 955   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | tokenPack | 872   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | unplace   | 897   | 0       | 0        |\n╰-------------+-----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 30.61s (30.59s CPU time)\n\nRan 26 test suites in 30.61s (56.92s CPU time): 132 tests passed, 0 failed, 1 skipped (133 total tests)\n","passed":true},{"durationMs":142,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"FarmCore.activity(address,uint256,uint256,uint256)\",\"FarmCore.buyTokenPack(bool)\",\"FarmCore.claimDrop()\",\"FarmCore.expand(bool)\",\"FarmCore.grantDrop(address,bytes32)\",\"FarmCore.lobby(uint256,bool)\",\"FarmCore.merge(uint256[3],bool)\",\"FarmCore.overclock(uint256,bool)\",\"FarmCore.paidPackBought(address,uint256,uint256)\",\"FarmCore.place(uint256,uint256,uint256)\",\"FarmCore.process(address,uint256)\",\"FarmCore.register(address)\",\"FarmCore.repair(uint256,bool)\",\"FarmCore.repairCable(bool)\",\"FarmCore.retire(address)\",\"FarmCore.scrap(uint256,uint256)\",\"FarmCore.setReferrer(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.safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)\",\"FarmItems.safeTransferFrom(address,address,uint256,uint256,bytes)\",\"FarmItems.unequip(address,uint256)\",\"FarmRewards.advanceEpoch()\",\"FarmRewards.award(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)\",\"FeeRouter.depositBaseFee()\",\"FeeRouter.depositLobby()\",\"FeeRouter.depositPack()\",\"FeeRouter.depositSellTax()\",\"FeeRouter.executeBuys(uint256,uint256)\",\"FeeRouter.payBounty(address)\",\"FeeRouter.payWork(address,uint8,uint256,uint256)\",\"FeeRouter.receive()\",\"FeeRouter.withdraw()\",\"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,address,int24),bytes32)\",\"PackSale.captureEntropy(uint256)\",\"PackSale.openPack(uint256)\",\"PackSale.pause(uint256)\",\"PackSale.resolve(uint256,uint256)\",\"PackSale.rewardPack(address)\",\"PackSale.tokenPack(address)\",\"PackSale.unpause()\",\"Params.set(uint8,uint256,string)\",\"RewardPool.activateEndowment()\",\"RewardPool.donate(uint256)\",\"RewardPool.fundEndowment()\",\"RewardPool.pay(address,uint256)\",\"RewardPool.recycle(uint256)\",\"RewardPool.reserve(uint256)\",\"Season.addPrize(uint256,uint256)\",\"Season.claimDistrict(uint256)\",\"Season.claimLottery(uint256)\",\"Season.complete(address,uint256)\",\"Season.finalize(uint256)\",\"Season.prepare(uint256,uint256)\",\"Season.rearm(uint256)\",\"Season.recordActivity(address,uint256,uint256)\",\"Season.recordSpend(address,uint256,bool)\",\"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)\",\"StandardMarket.buy(uint256,address)\",\"StandardMarket.flushFees()\",\"StandardMarket.receive()\",\"StandardMarket.unlockCallback(bytes)\",\"StandardMarket.withdrawNetwork()\",\"StarterClaim.captureEntropy(uint256)\",\"StarterClaim.claim(uint256,bytes32[])\",\"StarterClaim.resolve(uint256)\",\"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)\",\"V4Market.buy(uint256,address)\",\"V4Market.flushFees()\",\"V4Market.receive()\",\"V4Market.unlockCallback(bytes)\",\"V4Market.withdrawNetwork()\"],\"files\":{\".gitignore\":6,\"README.md\":51,\"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/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/verification-v3.json\":67,\"docs/dependency-provenance.md\":9,\"docs/design.md\":69,\"docs/launch-v31.md\":108,\"docs/lazy-accounting-v32.md\":48,\"docs/report-v3.md\":143,\"docs/report-v31.md\":128,\"docs/review-v31.md\":77,\"docs/review-v32.md\":32,\"docs/security-review.md\":29,\"docs/simulation-assumptions.md\":43,\"docs/simulation-v3-historical.md\":44,\"foundry.toml\":20,\"launch-v31.md\":3,\"launch/V4Market.sol\":889,\"regulator.md\":52,\"report.md\":138,\"script/Deploy.s.sol\":142,\"script/DeployMarket.s.sol\":15,\"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/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/tune_v3.py\":16,\"src/FarmCore.sol\":476,\"src/FarmEngine.sol\":223,\"src/FarmItems.sol\":118,\"src/FarmRewards.sol\":419,\"src/FeeRouter.sol\":173,\"src/GameRegistry.sol\":82,\"src/GridOperator.sol\":225,\"src/MarketFactory.sol\":58,\"src/PackSale.sol\":180,\"src/Params.sol\":178,\"src/RewardPool.sol\":110,\"src/Season.sol\":225,\"src/StandardAdapter.sol\":77,\"src/StandardMarket.sol\":26,\"src/StarterClaim.sol\":95,\"src/V4Market.sol\":354,\"src/interfaces/IGame.sol\":43,\"src/interfaces/IGameRegistry.sol\":13,\"src/interfaces/IV4.sol\":25,\"src/interfaces/Interfaces.sol\":14,\"src/lib/ChainClock.sol\":22,\"src/lib/Errors.sol\":12,\"src/lib/GameModule.sol\":14,\"src/lib/ItemMath.sol\":31,\"src/lib/ModuleCode.sol\":19,\"test/Base.t.sol\":152,\"test/Bounties.t.sol\":287,\"test/Clock.t.sol\":50,\"test/Deployment.t.sol\":71,\"test/Endowment.t.sol\":123,\"test/EndowmentGame.t.sol\":47,\"test/Epochs.t.sol\":177,\"test/Events.t.sol\":236,\"test/Factory.t.sol\":30,\"test/FeesParams.t.sol\":130,\"test/Gas.t.sol\":103,\"test/HookBinding.t.sol\":117,\"test/Invariants.t.sol\":129,\"test/Items.t.sol\":265,\"test/KeeperProfit.t.sol\":95,\"test/LazyAccounting.t.sol\":409,\"test/Market.t.sol\":114,\"test/Packs.t.sol\":160,\"test/Pause.t.sol\":73,\"test/Registry.t.sol\":125,\"test/Regression.t.sol\":152,\"test/SeasonAudit.t.sol\":182,\"test/StandardAdapter.t.sol\":80,\"test/StandardMarket.t.sol\":56,\"test/StandardV4Integration.t.sol\":114,\"test/V4Integration.t.sol\":152,\"test/fork/RobinhoodFork.t.sol\":39,\"test/mocks/MockGameRegistry.sol\":47,\"test/mocks/MockMarket.sol\":37,\"test/mocks/MockToken.sol\":38,\"test/mocks/MockV4Manager.sol\":62,\"test/python/test_merkle.py\":19,\"test/python/test_regulator.py\":25,\"test/python/test_v31.py\":38,\"test/python/test_v32.py\":58,\"tools/check_v32_results.py\":52,\"tools/pin_module_code.py\":23,\"tools/regulator.py\":63,\"tools/report_v31.py\":55,\"tools/starter_merkle.py\":72},\"excluded\":[\"vendor/\",\"node_modules/\"],\"truncated\":true}","passed":true},{"durationMs":20342,"exitCode":0,"name":"slither","output":"[high/medium] arbitrary-send-eth at src/V4Market.sol:101: V4Market.flushFees() (src/V4Market.sol#101-111) sends eth to arbitrary user\n[high/medium] weak-prng at src/V4Market.sol:194: V4Market._record(bool,uint256) (src/V4Market.sol#194-215) uses a weak PRNG: \"delete longVolumes[p % 24] (src/V4Market.sol#205)\"\n[high/medium] weak-prng at src/V4Market.sol:152: V4Market._observe(uint256) (src/V4Market.sol#152-172) uses a weak PRNG: \"observations[minute % 32] = Observation(uint64(minute),c) (src/V4Market.sol#166)\"\n[high/medium] weak-prng at src/V4Market.sol:174: V4Market._cumulativeAt(uint256) (src/V4Market.sol#174-181) uses a weak PRNG: \"o = observations[minute % 32] (src/V4Market.sol#178)\"\n[high/medium] weak-prng at src/V4Market.sol:194: V4Market._record(bool,uint256) (src/V4Market.sol#194-215) uses a weak PRNG: \"delete shortVolumes[p % 12] (src/V4Market.sol#199)\"\n[high/medium] weak-prng at src/V4Market.sol:194: V4Market._record(bool,uint256) (src/V4Market.sol#194-215) uses a weak PRNG: \"b = longVolumes[p % 24] (src/V4Market.sol#203)\"\n[high/medium] weak-prng at src/V4Market.sol:194: V4Market._record(bool,uint256) (src/V4Market.sol#194-215) uses a weak PRNG: \"a = shortVolumes[p % 12] (src/V4Market.sol#197)\"\n[high/medium] weak-prng at src/GridOperator.sol:98: GridOperator.lobbyAmount(uint256) (src/GridOperator.sol#98-105) uses a weak PRNG: \"a * 259200 / (259200 + dt % 259200) (src/GridOperator.sol#104)\"\n[high/medium] incorrect-exp at vendor/openzeppelin/contracts/utils/math/Math.sol:123: Math.mulDiv(uint256,uint256,uint256) (vendor/openzeppelin/contracts/utils/math/Math.sol#123-202) has bitwise-xor operator ^ instead of the exponentiation operator **: \n[high/medium] reentrancy-balance at src/RewardPool.sol:85: Reentrancy in RewardPool.donate(uint256) (src/RewardPool.sol#85-91):\n[high/medium] reentrancy-balance at src/FeeRouter.sol:152: Reentrancy in FeeRouter.executeBuys(uint256,uint256) (src/FeeRouter.sol#152-172):\n[high/medium] reentrancy-balance at src/FarmCore.sol:282: Reentrancy in FarmCore._charge(address,uint256,bool,uint8) (src/FarmCore.sol#282-298):\n[high/medium] reentrancy-balance at src/RewardPool.sol:61: Reentrancy in RewardPool.fundEndowment() (src/RewardPool.sol#61-67):\n[high/medium] reentrancy-balance at src/StandardAdapter.sol:53: Reentrancy in StandardAdapter.buy(uint256,address) (src/StandardAdapter.sol#53-62):\n[high/medium] reentrancy-eth at src/FarmCore.sol:338: Reentrancy in FarmCore.buyTokenPack(bool) (src/FarmCore.sol#338-347):\n[high/medium] reentrancy-eth at src/FarmCore.sol:310: Reentrancy in FarmCore.repairCable(bool) (src/FarmCore.sol#310-318):\n[high/medium] reentrancy-eth at src/FarmCore.sol:338: Reentrancy in FarmCore.buyTokenPack(bool) (src/FarmCore.sol#338-347):\n[medium/medium] divide-before-multiply at src/FarmCore.sol:378: FarmCore.scrap(uint256,uint256) (src/FarmCore.sol#378-387) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at vendor/openzeppelin/contracts/utils/math/Math.sol:123: Math.mulDiv(uint256,uint256,uint256) (vendor/openzeppelin/contracts/utils/math/Math.sol#123-202) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at vendor/openzeppelin/contracts/utils/math/Math.sol:123: Math.mulDiv(uint256,uint256,uint256) (vendor/openzeppelin/contracts/utils/math/Math.sol#123-202) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/V4Market.sol:152: V4Market._observe(uint256) (src/V4Market.sol#152-172) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at vendor/openzeppelin/contracts/utils/math/Math.sol:123: Math.mulDiv(uint256,uint256,uint256) (vendor/openzeppelin/contracts/utils/math/Math.sol#123-202) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at vendor/openzeppelin/contracts/utils/math/Math.sol:123: Math.mulDiv(uint256,uint256,uint256) (vendor/openzeppelin/contracts/utils/math/Math.sol#123-202) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at vendor/openzeppelin/contracts/utils/math/Math.sol:123: Math.mulDiv(uint256,uint256,uint256) (vendor/openzeppelin/contracts/utils/math/Math.sol#123-202) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at vendor/openzeppelin/contracts/utils/math/Math.sol:123: Math.mulDiv(uint256,uint256,uint256) (vendor/openzeppelin/contracts/utils/math/Math.sol#123-202) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/FarmCore.sol:378: FarmCore.scrap(uint256,uint256) (src/FarmCore.sol#378-387) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/FarmEngine.sol:97: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256) (src/FarmEngine.sol#97-145) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at vendor/openzeppelin/contracts/utils/math/Math.sol:123: Math.mulDiv(uint256,uint256,uint256) (vendor/openzeppelin/contracts/utils/math/Math.sol#123-202) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/FarmEngine.sol:97: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256) (src/FarmEngine.sol#97-145) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at vendor/openzeppelin/contracts/utils/math/Math.sol:123: Math.mulDiv(uint256,uint256,uint256) (vendor/openzeppelin/contracts/utils/math/Math.sol#123-202) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/V4Market.sol:174: V4Market._cumulativeAt(uint256) (src/V4Market.sol#174-181) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/V4Market.sol:152: V4Market._observe(uint256) (src/V4Market.sol#152-172) performs a multiplication on the result of a division:\n[medium/high] incorrect-equality at src/FarmCore.sol:378: FarmCore.scrap(uint256,uint256) (src/FarmCore.sol#378-387) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/V4Market.sol:152: V4Market._observe(uint256) (src/V4Market.sol#152-172) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/V4Market.sol:183: V4Market.twap() (src/V4Market.sol#183-188) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:251: Reentrancy in FarmRewards._settleOne(address,uint256) (src/FarmRewards.sol#251-309):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:140: Reentrancy in FarmRewards.advanceEpoch() (src/FarmRewards.sol#140-192):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:140: Reentrancy in FarmRewards.advanceEpoch() (src/FarmRewards.sol#140-192):\n[medium/medium] reentrancy-no-eth at src/V4Market.sol:320: Reentrancy in V4Market.unlockCallback(bytes) (src/V4Market.sol#320-344):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:239: Reentrancy in FarmRewards._settle(address,uint256) (src/FarmRewards.sol#239-249):\n[medium/medium] reentrancy-no-eth at src/RewardPool.sol:61: Reentrancy in RewardPool.fundEndowment() (src/RewardPool.sol#61-67):\n[medium/medium] reentrancy-no-eth at src/FarmCore.sol:245: Reentrancy in FarmCore.unplace(uint256,uint256) (src/FarmCore.sol#245-255):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:382: Reentrancy in FarmRewards.claim(uint256) (src/FarmRewards.sol#382-389):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:140: Reentrancy in FarmRewards.advanceEpoch() (src/FarmRewards.sol#140-192):\n[medium/medium] reentrancy-no-eth at src/PackSale.sol:163: Reentrancy in PackSale.resolve(uint256,uint256) (src/PackSale.sol#163-179):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:140: Reentrancy in FarmRewards.advanceEpoch() (src/FarmRewards.sol#140-192):\n[medium/medium] reentrancy-no-eth at src/FarmCore.sol:405: Reentrancy in FarmCore.process(address,uint256) (src/FarmCore.sol#405-426):\n[medium/medium] reentrancy-no-eth at src/FarmCore.sol:200: Reentrancy in FarmCore.paidPackBought(address,uint256,uint256) (src/FarmCore.sol#200-208):\n[medium/medium] reentrancy-no-eth at src/FarmCore.sol:172: Reentrancy in FarmCore._prepare(address) (src/FarmCore.sol#172-178):\n[medium/medium] reentrancy-no-eth at src/FarmCore.sol:221: Reentrancy in FarmCore.place(uint256,uint256,uint256) (src/FarmCore.sol#221-243):\n[medium/medium] uninitialized-local at src/FarmCore.sol:392: FarmCore.roomStats(address,uint256).snap (src/FarmCore.sol#392) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:99: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256).mask (src/FarmEngine.sol#99) is a local variable never initialized\n[medium/medium] uninitialized-local at src/GridOperator.sol:174: GridOperator._resolve(uint256,address).repeated (src/GridOperator.sol#174) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:159: FarmEngine.process(address,uint256,FarmEngine.Snapshot).occupied (src/FarmEngine.sol#159) is a local variable never initialized\n[medium/medium] uninitialized-local at src/PackSale.sol:172: PackSale.resolve(uint256,uint256).k (src/PackSale.sol#172) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:164: FarmEngine.process(address,uint256,FarmEngine.Snapshot).cursor (src/FarmEngine.sol#164) is a local variable never initialized\n[medium/medium] uninitialized-local at src/V4Market.sol:247: V4Market._sellFee(uint256).average (src/V4Market.sol#247) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:68: FarmEngine.allocationHash(uint256[24],bool).f (src/FarmEngine.sol#68) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmRewards.sol:268: FarmRewards._settleOne(address,uint256).referral (src/FarmRewards.sol#268) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:101: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256).rarity (src/FarmEngine.sol#101) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:182: FarmEngine.process(address,uint256,FarmEngine.Snapshot).damage (src/FarmEngine.sol#182) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:165: FarmEngine.process(address,uint256,FarmEngine.Snapshot).baseline (src/FarmEngine.sol#165) is a local variable never initialized\n[medium/medium] uninitialized-local at src/GridOperator.sol:173: GridOperator._resolve(uint256,address).positives (src/GridOperator.sol#173) is a local variable never initialized\n[medium/medium] uninitialized-local at src/V4Market.sol:218: V4Market.imbalances().s (src/V4Market.sol#218) is a local variable never initialized\n[medium/medium] uninitialized-local at src/PackSale.sol:173: PackSale.resolve(uint256,uint256).r (src/PackSale.sol#173) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:100: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256).tags (src/FarmEngine.sol#100) is a local variable never initialized\n[medium/medium] uninitialized-local at src/V4Market.sol:219: V4Market.imbalances().b (src/V4Market.sol#219) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmCore.sol:409: FarmCore.process(address,uint256).occupied (src/FarmCore.sol#409) is a local variable never initialized\n[medium/medium] uninitialized-local at src/GridOperator.sol:188: GridOperator._resolve(uint256,address).weights (src/GridOperator.sol#188) is a local variable never initialized\n[medium/medium] uninitialized-local at src/GridOperator.sol:189: GridOperator._resolve(uint256,address).sum (src/GridOperator.sol#189) is a local variable never initialized\n[medium/medium] unused-return at src/StandardAdapter.sol:53: StandardAdapter.buy(uint256,address) (src/StandardAdapter.sol#53-62) ignores return value by manager.unlock(abi.encode(msg.value,minOut,recipient)) (src/StandardAdapter.sol#58)\n[medium/medium] unused-return at src/V4Market.sol:320: V4Market.unlockCallback(bytes) (src/V4Market.sol#320-344) ignores return value by manager.settle{value: input}() (src/V4Market.sol#339)\n[medium/medium] unused-return at src/StarterClaim.sol:80: StarterClaim.resolve(uint256) (src/StarterClaim.sol#80-94) ignores return value by items().mint(c.player,0,1,true) (src/StarterClaim.sol#91)\n[medium/medium] unused-return at src/Season.sol:217: Season.claimLottery(uint256) (src/Season.sol#217-224) ignores return value by (k,None) = ItemMath.draw(seed,false,false) (src/Season.sol#221)\n[medium/medium] unused-return at src/PackSale.sol:163: PackSale.resolve(uint256,uint256) (src/PackSale.sol#163-179) ignores return value by items().mint(c.player,k,r,false) (src/PackSale.sol#176)\n[medium/medium] unused-return at src/FarmRewards.sol:140: FarmRewards.advanceEpoch() (src/FarmRewards.sol#140-192) ignores return value by (old.kind,old.severity,old.district,old.seed,None) = grid().eventAt(epoch) (src/FarmRewards.sol#149)\n[medium/medium] unused-return at src/FarmEngine.sol:58: FarmEngine._param(Params.Key,bool,uint256) (src/FarmEngine.sol#58-64) ignores return value by (None,hi) = params().bounds(k) (src/FarmEngine.sol#60)\n[medium/medium] unused-return at src/FeeRouter.sol:152: FeeRouter.executeBuys(uint256,uint256) (src/FeeRouter.sol#152-172) ignores return value by market().buy{value: ethAmount}(minOut,rewardPool()) (src/FeeRouter.sol#164)\n[medium/medium] unused-return at src/StarterClaim.sol:80: StarterClaim.resolve(uint256) (src/StarterClaim.sol#80-94) ignores return value by items().mint(c.player,k,r,true) (src/StarterClaim.sol#91)\n[medium/medium] unused-return at src/StandardAdapter.sol:64: StandardAdapter.unlockCallback(bytes) (src/StandardAdapter.sol#64-76) ignores return value by manager.settle{value: input}() (src/StandardAdapter.sol#73)\n[low/medium] events-maths at src/PackSale.sol:116: PackSale.openPack(uint256) (src/PackSale.sol#116-123) should emit an event for: \n[low/medium] events-maths at src/FarmRewards.sol:216: FarmRewards.setWeight(address,uint256) (src/FarmRewards.sol#216-223) should emit an event for: \n[low/medium] events-maths at src/FarmRewards.sol:398: FarmRewards.scrap(address,uint256,uint256) (src/FarmRewards.sol#398-404) should emit an event for: \n[low/medium] calls-loop at src/FarmRewards.sol:251: FarmRewards._settleOne(address,uint256) (src/FarmRewards.sol#251-309) has external calls inside a loop: (raw,productive,power) = core().process(p,id) (src/FarmRewards.sol#253)\n[low/medium] calls-loop at src/FarmEngine.sol:38: FarmEngine.items() (src/FarmEngine.sol#38-40) has external calls inside a loop: FarmItems(registry.module(3)) (src/FarmEngine.sol#39)\n[low/medium] calls-loop at src/PackSale.sol:85: PackSale.priceAt(uint256) (src/PackSale.sol#85-103) has external calls inside a loop: exponent = wadLn(int256(1000000000000000000 + params().get(Params.Key.PriceStepBps) * 1e14)) * ahead / 1000000000000000000 (src/PackSale.sol#91)\n[low/medium] calls-loop at src/FarmCore.sol:184: FarmCore._roll(address,uint256) (src/FarmCore.sol#184-198) has external calls inside a loop: x = items().data(f.active[i]) (src/FarmCore.sol#194)\n[low/medium] calls-loop at src/FarmEngine.sol:58: FarmEngine._param(Params.Key,bool,uint256) (src/FarmEngine.sol#58-64) has external calls inside a loop: params().get(k) (src/FarmEngine.sol#63)\n[low/medium] calls-loop at src/FarmEngine.sol:58: FarmEngine._param(Params.Key,bool,uint256) (src/FarmEngine.sol#58-64) has external calls inside a loop: params().get(k) (src/FarmEngine.sol#63)\n[low/medium] calls-loop at src/FarmRewards.sol:251: FarmRewards._settleOne(address,uint256) (src/FarmRewards.sol#251-309) has external calls inside a loop: season().complete(p,week) (src/FarmRewards.sol#307","passed":true},{"durationMs":1062,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/GameRegistry.sol:76: `abi.encodePacked()` Hash Collision (2 places)\n[high] contract-locks-ether at src/GridOperator.sol:11: Contract locks Ether without a withdraw function (3 places)\n[high] eth-send-unchecked-address at src/FeeRouter.sol:143: ETH transferred without address checks (4 places)\n[high] reentrancy-state-change at src/FarmCore.sol:225: Reentrancy: State change after external call (38 places)\n[high] unprotected-initializer at src/MarketFactory.sol:16: Unprotected initializer\n[low] costly-loop at src/FarmCore.sol:192: Costly operations inside loop (13 places)\n[low] division-before-multiplication at src/FarmCore.sol:382: Incorrect Order of Division and Multiplication\n[low] large-numeric-literal at src/FarmCore.sol:303: Large Numeric Literal (83 places)\n[low] literal-instead-of-constant at src/FarmCore.sol:62: Literal Instead of Constant (414 places)\n[low] local-variable-shadowing at src/FarmRewards.sol:33: Local Variable Shadows State Variable (3 places)\n[low] missing-inheritance at src/Params.sol:6: Missing Inheritance\n[low] non-reentrant-not-first at src/FarmRewards.sol:391: `nonReentrant` is Not the First Modifier (3 places)\n[low] require-revert-in-loop at src/FarmCore.sol:231: Loop Contains `require`/`revert` (10 places)\n[low] state-change-without-event at src/FarmCore.sol:405: State Change Without Event (19 places)\n[low] unchecked-return at src/FarmCore.sol:306: Unchecked Return (13 places)\n[low] uninitialized-local-variable at src/FarmCore.sol:231: Uninitialized Local Variable (32 places)\n[low] unused-public-function at src/FarmCore.sol:150: Public Function Not Used Internally (6 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"41b030c4ab02ed6b563381381440cc4fe6526d15a7bea934c59ab9b88b9ae10d","verifiedTreeHash":"72bcd42cc82eaa4d6192d17c514a21fd36febccc","verifierVersion":"0.1.0+0e08a464"}]}