{"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":"5ce56cbc-1158-455f-9c37-453120687a3a","kind":"skill:build-contract-project","nodes":[{"acceptedSubmissionHash":"df7bea7106eb1364697d08d9e3a91c7ebd20764fe8a64bfdcdc6c84969f6ff86","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: rework the contracts from job 80dc62dc (repo identity-md-launches/launch-1269-reports-v1-job-b9e37680-814c-4f17-b4bc-6) to the v3 design below. Build + tests + Robinhood fork + re-run sim. NO DEPLOY. Where v3 differs from the current code, v3 wins. Keep: no owner, no upgrades, bounded Params (max 10% step per 24h), pull payments, CEI, reentrancy guards, constructor-param addresses, team address 0x6d51cBE774aeAe4dd40bCA2560E9bc2695A0d007.\n\n1. EPOCHS (autonomous)\n- Epoch = 6h. A new epoch starts only when anyone calls advanceEpoch(); no mining accrues between epoch end and the call. Caller gets a bounty (default 0.001 ETH, Params 0.0005-0.003) from the heartbeat balance.\n- Swarm submits plans for the next 2 epochs: event type, severity within bounds, swarm random number, letter. Event randomness = hash(swarm number, block hash after the shift). No plan = contract picks the event from a fixed fallback table. Swarm never picks a player or district.\n- Claims available every epoch. Regulator script (dry run) + rule table: keep reward pool runway >= 14 days by tuning emission, tariff, pack pace and event mix within bounds.\n\n2. NO BURNS. Remove BurnVault. Every token spend (token packs, repair, electricity, overclock, merge, inventory expansion, token lobby) goes 100% to the reward pool. Withdrawal tax goes 100% to active farms next epoch.\n\n3. ETH SPLITS (fixed): packs 85% reward-pool buy / 13% team / 2% heartbeat. ETH lobby and progressive sell surcharge: same 85/13/2. Heartbeat balance capped at 1 ETH, excess to reward-pool buy. Generator removed.\n\n4. SWAP FEE. Preferred (if IMD launch allows a custom hook): 2% project fee = 1% team + 1% reward-pool buy, plus 0.25% network, plus the progressive sell surcharge (total cap 15%). Fallback (standard IMD hook): 1% split 0.5% team / 0.5% reward-pool buy, no surcharge. Build both paths, document which applies.\n\n5. PACKS. No quantity limits at all (remove wallet, global, token-pack daily limits). VRGDA price: start 0.010 ETH, floor 0.006, ceiling 0.03, target ~20 packs/hour, +1% per pack above pace at launch, ~2%/hour decay below pace (all Params). Token pack = current ETH price converted by 30-min TWAP with 10% discount. 3 items per pack, future block hash N+2, expiry fallback 3 Common GPUs.\nRarity: Common 70, Rare 22, Epic 6.7, Legendary 1, Mythic 0.3 (Mythic only for account level 10+, else that 0.3 goes to Common). Hash 10/28/80/250/800.\n\n6. ITEMS: 12 soulbound types (no transfers except into/out of own farm). Compute (100% of rarity hash): GPU 16%, ASIC 15%, FPGA 12%. Others mine at 60%: Power Supply 9, Battery 7, Solar Panel 7 (power); Fan 9, Liquid Cooling 6 (cooling); Router 6 (network); Motherboard 5, Server Rack 4, Surge Protector 4 (infra).\nRoom = 6 slots, any items, no duplicate type. Combos per room (hash bonuses add, cap +40%, values in Params):\nCompute Duo GPU+ASIC +10%; Triple Core GPU+ASIC+FPGA +20% (replaces Duo); Full Stack all 5 tags +15%; Airflow Fan+Server Rack +5% and fire halved; Cold Power PSU+Liquid Cooling electricity -15% and fire immune; Off-grid Solar+Battery electricity -20% and outage loses 50% not 100%; Clean Power Surge Protector+PSU surge immune; Locked Rack Router+Server Rack cable theft immune; rarity set 3+ same rarity +5/10/20/30% (R/E/L/M, highest only).\n\n7. INVENTORY, ROOMS, LEVELS\n- Inventory 15 slots; full inventory blocks opening packs. Exits: scrap item for ~1h of its yield (from pool), merge 3 identical into next rarity (up to Legendary), expand +5 slots for rising token price (to pool).\n- Items only in rooms. Room 1 at start, room 2 when farm is 3 days old, room 3 at level 7, room 4 at level 10. Remove room keys.\n- Account XP from active epochs, packs bought, tokens spent in game. Targets: level 3 ~1 day, level 5 ~48h, level 10 ~1 week. Equip gates: Epic level 3, Legendary level 5, Mythic level 10.\n\n8. MINING: emission from pool only (start 3.5%/day, sim picks bounds), per epoch by hashrate. Remove the 2% whale soft cap. Internal balance per player; in-game spend no tax +5% bonus; withdraw tax max(5%, 20% - 15%*age/7d). Durability 100, -0.5 per epoch, yield x durability, repair with tokens anytime. Overclock +10%/level up to 5. Electricity tariff start 15% of yield, bounds 10-30%.\n\n9. EVENTS (one per epoch or Calm; per-20-epoch caps: each negative <= 4, positives >= 4; same district outage cooldown 2 days):\nOutage: 30% of district farms get 0 this epoch. Power surge: 10% of district farms, random item -50 durability, 2% chance destroyed (never Legendary/Mythic). Server fire: rooms without cooling yield 0 this epoch, items -30 durability. Cable theft: 20% of district farms lose Router effects for 2 epochs or until token repair. Tax audit: top 10% farms by hash give 10% of this epoch's mining to the pool. Green wave: district +10% mining. Cheap tariff: city electricity -50% this epoch.\nAutomatic supply drop: if epoch pack sales >= 2x target pace, 5% random active farms get a free Common or Rare item (minted).\nLobby: ETH or token for own district lowers negative odds (min weight 0.40, 3-day half-life) and raises Green wave odds. Herald letter for every event and Params change.\n\n10. WEEKLY SEASON (permissionless finalize): best district by spend (packs+lobby+repairs) -> every active farm there gets a free Rare-guaranteed pack; lottery: 3 random active farms (tickets = active epochs) get an Epic+ item; best farm (in-game spend / yield) gets 1% of weekly emission.\n\n11. KEEP: referrals 5% of invitee mining on top, one level, set once, no self. Identity MD holders: only 1 free starter pack per tokenId, snapshot at token launch block, window hour 48 to day 16, Rare 92 / Epic 8, 50% mining until a paid pack. Remove all other holder perks.\n\n12. SIM (35 days, 6h steps, steady/hype/weak; ~900 NFT holders sell 35/50/65% of the swarm 10% in 14 days). Tune to: week-1 joiner payback <= 10 days in steady; game alive >= 3 weeks in steady and hype; event losses <= 10% of average farm weekly yield. Report payback by join week, stall day, team and heartbeat ETH, both swap-fee paths.\n\n13. TESTS: unit, fuzz, invariants (token conservation, no burns, splits, caps, level gates, inventory limit, soulbound, epoch cannot advance early, bounty paid once, fallback events, VRGDA bounds), Robinhood fork smoke, gas per action incl. advanceEpoch with many farms (must stay bounded).\n\n14. Ask a second contributor with fresh context to review; fix high and medium.\n\nDeliver: updated repo, report.md (what changed vs 80dc62dc, Params table with bounds, sim results, review findings, open questions), regulator.md.","parentJobId":"80dc62dc-0e0b-42ea-bc28-5128fc6eff2a","planHash":"deb1360dd775014bb47bc727a0f71b434e169f6680e362365e7cf36d8e66c444","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":"51475","feedbackHash":"19c74a9f4b7c6c053ae9a3c847c9231e5ab6b121ea3a483fba9357cbba5a3560","nodeKey":"build_contract_project","submissionHash":"df7bea7106eb1364697d08d9e3a91c7ebd20764fe8a64bfdcdc6c84969f6ff86","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"0a5470964706c52c73d56802e0dc132484ebf151522c4c08e84db509097f88cb","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"7c482e1ff65b4df97fa4ac4a78136ef95df77dbf35322bd5c45f9aa390642cda","device":"4d218e2d11a36af4","findings":[],"hash":"df7bea7106eb1364697d08d9e3a91c7ebd20764fe8a64bfdcdc6c84969f6ff86","nodeId":"c8396a82-e228-4d89-94bc-c4c80855caa2","outcome":"completed","summary":"Implemented BLACKOUT v3 with [report.md](report.md) and [regulator.md](regulator.md).\n\n- Build, formatting and 86 tests pass; Robinhood fork smoke passes separately.\n- Fresh review’s high and medium findings are fixed.\n- No deployment occurred.\n\nThe unfunded simulation misses economic targets. The explicitly documented **40 ETH funded scenario** meets them; that funding remains an assumption, not an authorized commitment.","treeHash":"13637b7e7cf3dc574cc05d9ba501ebb8c30e6eef","usage":{"cachedInputTokens":9334656,"inputTokens":331140,"model":"gpt-6-astra","outputTokens":135466,"runtime":"codex","turns":12,"wallClockMs":5167739}}],"verification":[{"checks":[{"durationMs":70114,"exitCode":0,"name":"build","output":"Compiling 129 files with Solc 0.8.26\nSolc 0.8.26 finished in 69.95s\nCompiler run successful!\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/Params.sol:135:13\n    │\n135 │         if (block.timestamp < lastChanged[k] + 1 days) revert TooEarly();\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:101:19\n    │\n101 │             raw = raw * (10 + f.clocks[idx]) / 10;\n    │                   ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:161:9\n    │\n161 │         f.serial = nextSerial++;\n    │         ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[divide-before-multiply]: division before multiplication may lose precision\n    ╭▸ src/FarmEngine.sol:105:29\n    │\n105 │             s.productive += raw * f.health[idx] / 10000;\n    │                             ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/divide-before-multiply\n\nwarning[missing-events-access-control]: `farms` is changed without an event but is used for access control\n    ╭▸ src/FarmCore.sol:174:9\n    │\n174 │         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:423:9\n    │\n423 │         farms[p].xp += 100;\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-access-control\n\nwarning[uninitialized-local]: local variable is read before being initialized\n   ╭▸ src/FarmEngine.sol:83:41\n   │\n83 │             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:98:13\n   │\n98 │             tags |= 1 << ItemMath.tag(x.kind);\n   │             ━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:82:39\n   │\n82 │             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:95:39\n   │\n95 │             FarmItems.Item memory x = items.data(id);\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/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/FarmCore.sol:139:53\n    │\n139 │         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[missing-events-access-control]: `lotteryClaimed` is changed without an event but is used for access control\n    ╭▸ src/Season.sol:197:9\n    │\n197 │         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:68:13\n   │\n68 │         if (block.timestamp < launchTime) revert TooEarly();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:160:18\n    │\n160 │         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:181:39\n    │\n181 │             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:175:25\n    │\n175 │         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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/FarmRewards.sol:113:30\n    │\n113 │         return epoch != 0 && block.timestamp < epochs[epoch].end;\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `epoch` is updated\n    ╭▸ src/FarmRewards.sol:129:13\n    │\n129 │             grid.resolve(epoch);\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:136:13\n    │\n136 │             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 `_status` is updated\n    ╭▸ src/FarmRewards.sol:151:9\n    │\n151 │         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:152:9\n    │\n152 │         fees.payBounty(msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/FarmRewards.sol:125:13\n    │\n125 │         if (block.timestamp < launchTime || !ready() || (epoch != 0 && block.timestamp < epochs[epoch].end)) {\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/StarterClaim.sol:45:9\n   │\n45 │         farm.register(msg.sender);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/FarmRewards.sol:125:72\n    │\n125 │         if (block.timestamp < launchTime || !ready() || (epoch != 0 && block.timestamp < epochs[epoch].end)) {\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:38:13\n   │\n38 │         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:38:56\n   │\n38 │         if (block.timestamp < launchTime + 48 hours || block.timestamp >= launchTime + 16 days) revert TooEarly();\n   │                                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:147:36\n    │\n147 │             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/StarterClaim.sol:46:9\n   │\n46 │         emit StarterCommitted(tokenId, msg.sender, target);\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:137:13\n    │\n137 │             emit EpochClosed(epoch, old.budget, old.roster);\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:153:9\n    │\n153 │         emit EpochStarted(epoch, e.start, e.end, msg.sender);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StarterClaim.sol:43:25\n   │\n43 │         uint64 target = uint64(ChainClock.number() + 2);\n   │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint64' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:131:26\n    │\n131 │             old.roster = uint64(core.count());\n    │                          ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-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:141:19\n    │\n141 │         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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/StarterClaim.sol:59:13\n   │\n59 │             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[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:142:17\n    │\n142 │         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[calls-loop]: external call inside a loop\n   ╭▸ src/StarterClaim.sol:59:13\n   │\n59 │             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:61:9\n   │\n61 │         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:59:13\n   │\n59 │             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[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n   ╭▸ src/RewardPool.sol:36:13\n   │\n36 │         if (token.balanceOf(address(this)) - before_ != amount) revert InvalidValue();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[non-reentrant-not-first]: `nonReentrant` is not the first modifier\n   ╭▸ src/RewardPool.sol:51:67\n   │\n51 │     function pay(address to, uint256 amount) external onlyRewards nonReentrant {\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/FarmCore.sol:192:9\n    │\n192 │         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:193:9\n    │\n193 │         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:226:9\n    │\n226 │         items.equip(msg.sender, id);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Season.sol:111:25\n    │\n111 │         for (uint256 n; n < limit && cursor < s.participants; ++n) {\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:124:13\n    │\n124 │             emit SeasonPrepared(w, s.target);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmCore.sol:219:29\n    │\n219 │             if (old != 0 && items.data(old).kind == x.kind) revert InvalidValue();\n    │                             ━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:123:24\n    │\n123 │             s.target = uint64(ChainClock.number() + 2);\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/FarmCore.sol:227:9\n    │\n227 │         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:219:61\n    │\n219 │             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:237:9\n    │\n237 │         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:238:9\n    │\n238 │         emit Unplaced(msg.sender, id, room, slot);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/Season.sol:163:39\n    │\n163 │             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:164:18\n    │\n164 │             else rewards.releasePrize(s.prize);\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n    ╭▸ src/FarmCore.sol:246:56\n    │\n246 │             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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/Season.sol:154:25\n    │\n154 │         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:166:9\n    │\n166 │         emit SeasonFinalized(w, s.winnerDistrict, s.best, s.seed);\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:281:9\n    │\n281 │         emit Spent(p, kind, paid, nominal);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:151:92\n    │\n151 │             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[incorrect-strict-equality]: dangerous strict equality check on an externally-influenced value\n    ╭▸ src/FarmCore.sol:272:17\n    │\n272 │             if (token.balanceOf(pool) - before_ != paid) revert InvalidValue();\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/incorrect-strict-equality\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/Season.sol:172:20\n    │\n172 │         s.target = uint64(ChainClock.number() + 2);\n    │                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `farms` is updated\n    ╭▸ src/FarmCore.sol:274:20\n    │\n274 │             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/Season.sol:192:14\n    │\n192 │         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/FarmCore.sol:280:9\n    │\n280 │         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:291:9\n    │\n291 │         items.maintain(id, 10000, x.overclock);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/Season.sol:201:14\n    │\n201 │         id = items.mint(msg.sender, k, r, false);\n    │              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmCore.sol:300:32\n    │\n300 │         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:301:29\n    │\n301 │         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:310:9\n    │\n310 │         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:318:9\n    │\n318 │         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:280:9\n    │\n280 │         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:327:9\n    │\n327 │         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:328:14\n    │\n328 │         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:334:9\n    │\n334 │         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:353:13\n    │\n353 │             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:356:18\n    │\n356 │         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:342:39\n    │\n342 │             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:353:13\n    │\n353 │             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:357:9\n    │\n357 │         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:346:15\n    │\n346 │             ) 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:348:39\n    │\n348 │                 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:366:9\n    │\n366 │         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:367:26\n    │\n367 │         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:364:24\n    │\n364 │         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:368:9\n    │\n368 │         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:380:39\n    │\n380 │             FarmItems.Item memory x = items.data(snap.ids[i]);\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:162:31\n    │\n162 │         uint256 x = shares[e][core.playerAt(a)].raw;\n    │                               ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:163:31\n    │\n163 │         uint256 y = shares[e][core.playerAt(b)].raw;\n    │                               ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmRewards.sol:185:16\n    │\n185 │         while (i * 2 + 1 < h.length) {\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/V4Market.sol:118:13\n    │\n118 │             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:131:9\n    │\n131 │         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:125:38\n    │\n125 │             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:128:23\n    │\n128 │         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:123:13\n    │\n123 │         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:123:27\n    │\n123 │         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:124:38\n    │\n124 │         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:126:53\n    │\n126 │             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:137:50\n    │\n137 │         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:144:35\n    │\n144 │         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:158:13\n    │\n158 │         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:164:13\n    │\n164 │         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:160:24\n    │\n160 │             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:166:24\n    │\n166 │             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:169:24\n    │\n169 │             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:170:24\n    │\n170 │             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:172:23\n    │\n172 │             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:173:23\n    │\n173 │             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:184:17\n    │\n184 │                 b += shortVolumes[i].buys;\n    │                 ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/V4Market.sol:183:17\n    │\n183 │                 s += shortVolumes[i].sells;\n    │                 ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmCore.sol:406:48\n    │\n406 │         (raw, productive, power, theftUntil) = engine.process(p, e, snap);\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/V4Market.sol:182:17\n    │\n182 │             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:192:17\n    │\n192 │             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/FarmCore.sol:402:14\n    │\n402 │         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:410:28\n    │\n410 │             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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/V4Market.sol:210:13\n    │\n210 │         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:209:13\n    │\n209 │         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:215:27\n    │\n215 │         uint256 decayed = storedFeeWad > fall ? storedFeeWad - fall : projectBps() * 1 ether;\n    │                           ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `scrapAllowance` is updated\n    ╭▸ src/FarmRewards.sol:263:42\n    │\n263 │                 if (scrapAllowance != 0) pool.recycle(scrapAllowance);\n    │                                          ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `settledEpoch` is updated\n    ╭▸ src/FarmRewards.sol:246:17\n    │\n246 │                 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 `settledEpoch` is updated\n    ╭▸ src/FarmRewards.sol:248:21\n    │\n248 │                     core.grantDrop(p, keccak256(abi.encode(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 `settledEpoch` is updated\n    ╭▸ src/FarmRewards.sol:250:17\n    │\n250 │                 season.recordActivity(p, (e.start - launchTime) / 7 days, gross);\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `settledEpoch` is updated\n    ╭▸ src/FarmRewards.sol:255:33\n    │\n255 │                 if (prize != 0) season.addPrize((e.start - launchTime) / 7 days, prize);\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[reentrancy-no-eth]: external call can be reentered before `settledEpoch` is updated\n    ╭▸ src/FarmRewards.sol:266:35\n    │\n266 │                 if (recycle != 0) pool.recycle(recycle);\n    │                                   ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:229:25\n    │\n229 │         uint256 ethIn = uint256(-p.amountSpecified);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmRewards.sol:203:68\n    │\n203 │                 (uint256 raw, uint256 productive, uint256 power) = core.process(p, id);\n    │                                                                    ━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:231:19\n    │\n231 │         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:231:27\n    │\n231 │         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:233:43\n    │\n233 │         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[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmRewards.sol:225:29\n    │\n225 │             for (uint256 n; n < limit && e.cursor < e.roster; ++n) {\n    │                             ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmRewards.sol:245:42\n    │\n245 │                 e.spent += net + redis + referral;\n    │                                          ━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmRewards.sol:201:29\n    │\n201 │             for (uint256 n; n < limit && e.cursor < e.roster; ++n) {\n    │                             ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmRewards.sol:216:29\n    │\n216 │             for (uint256 n; n < limit && e.cursor < e.audited; ++n) {\n    │                             ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:202:29\n    │\n202 │                 address p = core.playerAt(e.cursor);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:203:68\n    │\n203 │                 (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:217:28\n    │\n217 │                 shares[id][core.playerAt(_pop(id))].audit = true;\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:226:29\n    │\n226 │                 address p = core.playerAt(e.cursor++);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/FarmRewards.sol:246:17\n    │\n246 │                 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:248:21\n    │\n248 │                     core.grantDrop(p, keccak256(abi.encode(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:250:17\n    │\n250 │                 season.recordActivity(p, (e.start - launchTime) / 7 days, gross);\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:303:9\n    │\n303 │         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:270:17\n    │\n270 │                 emit EpochSettled(id, e.mining, recycle);\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:258:9\n    │\n258 │         emit SellFee(sender, output, bps, hour, day, dev);\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:199:69\n    │\n199 │         (GridOperator.Kind kind, uint16 severity,, bytes32 seed,) = grid.eventAt(id);\n    │                                                                     ━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:244:27\n    │\n244 │         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:247:28\n    │\n247 │             _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:251:26\n    │\n251 │         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:251:34\n    │\n251 │         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:259:42\n    │\n259 │         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:259:49\n    │\n259 │         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[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/PackSale.sol:55:27\n   │\n55 │         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:57:24\n   │\n57 │         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:57:50\n   │\n57 │         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:60:30\n   │\n60 │             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:62:30\n   │\n62 │             exponent = wadLn(int256(1 ether - params.get(Params.Key.PriceDecayBps) * 1e14)) * (-ahead) / int256(target)\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:62:106\n   │\n62 │             exponent = wadLn(int256(1 ether - params.get(Params.Key.PriceDecayBps) * 1e14)) * (-ahead) / int256(target)\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:67:49\n   │\n67 │         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:56:26\n   │\n56 │         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:60:47\n   │\n60 │             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:62:47\n   │\n62 │             exponent = wadLn(int256(1 ether - params.get(Params.Key.PriceDecayBps) * 1e14)) * (-ahead) / int256(target)\n   │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/PackSale.sol:67:13\n   │\n67 │         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:68:23\n   │\n68 │         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:69:24\n   │\n69 │         uint256 high = params.get(Params.Key.PriceCeiling);\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:443:14\n    │\n443 │         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[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/PackSale.sol:88:9\n   │\n88 │         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:89:9\n   │\n89 │         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:86:13\n   │\n86 │         if (block.timestamp < launchTime || msg.value != quote(n)) revert InvalidValue();\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/V4Market.sol:275:31\n    │\n275 │         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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/PackSale.sol:109:9\n    │\n109 │         emit PackCommitted(id, p, n, target, guaranteed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/GridOperator.sol:93:13\n   │\n93 │         if (halves >= 128) 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/GridOperator.sol:109:9\n    │\n109 │         season.recordSpend(msg.sender, msg.value, true);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:300:19\n    │\n300 │         v.epoch = uint64(e);\n    │                   ━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmRewards.sol:301:48\n    │\n301 │         if (at > v.at || v.amount == 0) v.at = uint64(at);\n    │                                                ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/FarmRewards.sol:320:25\n    │\n320 │         for (uint256 n; n < 32 && amount != 0; ++n) {\n    │                         ━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/FarmRewards.sol:326:45\n    │\n326 │             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/GridOperator.sol:120:52\n    │\n120 │         lobbies[d] = Lobby(lobbyAmount(d) + value, uint64(block.timestamp));\n    │                                                    ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmRewards.sol:335:9\n    │\n335 │         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:336:9\n    │\n336 │         emit Claimed(msg.sender, amount, tax);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:100:33\n    │\n100 │         uint256 reduction = a * params.get(Params.Key.LobbyKBps) / (1 ether + a);\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:138:32\n    │\n138 │             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:170:21\n    │\n170 │                     damage += 3000 * uint256(severity) / 10000 / (before_.airflow ? 2 : 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/FarmEngine.sol:160:30\n    │\n160 │                 if (surge && cursor == target && !before_.clean) {\n    │                              ━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/GridOperator.sol:102:25\n    │\n102 │         uint256 floor = params.get(Params.Key.LobbyMinWeight);\n    │                         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[calls-loop]: external call inside a loop\n   ╭▸ src/FarmEngine.sol:55:25\n   │\n55 │         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:55:61\n   │\n55 │         return active ? rewards.epochParam(e, uint256(k)) : params.get(k);\n   │                                                             ━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/GridOperator.sol:128:20\n    │\n128 │         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:129:21\n    │\n129 │         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[calls-loop]: external call inside a loop\n    ╭▸ src/FarmEngine.sol:157:43\n    │\n157 │                 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:162:25\n    │\n162 │                         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:173:17\n    │\n173 │                 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:194:43\n    │\n194 │                 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:195:17\n    │\n195 │                 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[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/FarmEngine.sol:75:24\n   │\n75 │         if (room >= 4) revert InvalidValue();\n   │                        ━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/FarmEngine.sol:150:32\n    │\n150 │                 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:172:33\n    │\n172 │                 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:173:36\n    │\n173 │                 items.maintain(id, uint16(x.durability > damage ? x.durability - damage : 0), x.overclock);\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint16' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/GridOperator.sol:158:27\n    │\n158 │             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:173:13\n    │\n173 │             sum += w;\n    │             ━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[uninitialized-local]: local variable is read before being initialized\n    ╭▸ src/GridOperator.sol:157:57\n    │\n157 │             if (old == Kind.Green || old == Kind.Cheap) positives++;\n    │                                                         ━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/uninitialized-local\n\nwarning[reentrancy-no-eth]: external call can be reentered before `initializedAt` is updated\n    ╭▸ src/V4Market.sol:287:24\n    │\n287 │         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/GridOperator.sol:181:34\n    │\n181 │                     x.district = uint8(d);\n    │                                  ━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/StandardAdapter.sol:46:64\n   │\n46 │         if (rate == 0 || rate > 1e40 || window < 30 minutes || at > block.timestamp || block.timestamp - at > 5 minutes)\n   │                                                                ━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/StandardAdapter.sol:46:88\n   │\n46 │         if (rate == 0 || rate > 1e40 || window < 30 minutes || at > block.timestamp || block.timestamp - at > 5 minutes)\n   │                                                                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n   ╭▸ src/StandardAdapter.sol:58:9\n   │\n58 │         manager.unlock(abi.encode(msg.value, minOut, recipient));\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:287:62\n    │\n287 │         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:289:27\n    │\n289 │         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[unused-return]: return value of an external call is not used\n   ╭▸ src/StandardAdapter.sol:58:9\n   │\n58 │         manager.unlock(abi.encode(msg.value, minOut, recipient));\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/V4Market.sol:290:29\n    │\n290 │         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:292:30\n    │\n292 │             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:293:20\n    │\n293 │                 || 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:293:28\n    │\n293 │                 || 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:297:9\n    │\n297 │         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:298:40\n    │\n298 │         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:298:48\n    │\n298 │         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:301:27\n    │\n301 │         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:301:35\n    │\n301 │         return abi.encode(uint256(uint128(tokenDelta)));\n    │                                   ━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:67:62\n   │\n67 │         int256 delta = manager.swap(key(), SwapParams(true, -int256(input), 4295128740), \"\");\n   │                                                              ━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'int256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:68:27\n   │\n68 │         int128 ethDelta = int128(delta >> 128);\n   │                           ━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'int128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-eth]: uncapped ETH transfer can be reentered before `_status` is updated\n    ╭▸ src/V4Market.sol:308:22\n    │\n308 │         (bool ok,) = networkRecipient.call{value: amount}(\"\");\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-eth\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[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/V4Market.sol:310:9\n    │\n310 │         emit NetworkPaid(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:70:81\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\n   │                                                                                 ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:70:89\n   │\n70 │         if (ethDelta >= 0 || uint256(-int256(ethDelta)) != input || out <= 0 || uint256(uint128(out)) < minimum) {\n   │                                                                                         ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unused-return]: return value of an external call is not used\n   ╭▸ src/StandardAdapter.sol:73:9\n   │\n73 │         manager.settle{value: input}();\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:74:49\n   │\n74 │         manager.take(address(token), recipient, uint256(uint128(out)));\n   │                                                 ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:74:57\n   │\n74 │         manager.take(address(token), recipient, uint256(uint128(out)));\n   │                                                         ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:75:27\n   │\n75 │         return abi.encode(uint256(uint128(out)));\n   │                           ━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/StandardAdapter.sol:75:35\n   │\n75 │         return abi.encode(uint256(uint128(out)));\n   │                                   ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[encode-packed-collision]: `abi.encodePacked()` called with multiple dynamic type arguments; hash collisions possible\n   ╭▸ src/MarketFactory.sol:20:13\n   │\n20 │ ┏             abi.encodePacked(\n21 │ ┃                 type(V4Market).creationCode,\n22 │ ┃                 abi.encode(c.manager, c.token, c.params, c.fees, c.networkRecipient, uint24(0), c.tickSpacing)\n23 │ ┃             )\n   │ ┗━━━━━━━━━━━━━┛\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/encode-packed-collision\n\nwarning[reentrancy-eth]: uncapped ETH transfer can be reentered before `_status` is updated\n    ╭▸ src/FeeRouter.sol:106:22\n    │\n106 │         (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/MarketFactory.sol:58:9\n   │\n58 │         emit MarketDeployed(address(market), salt);\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:108:9\n    │\n108 │         emit Withdrawn(msg.sender, a);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/PackSale.sol:107:25\n    │\n107 │         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-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/FeeRouter.sol:125:9\n    │\n125 │         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:122:9\n    │\n122 │         market.buy{value: ethAmount}(minOut, rewardPool);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/PackSale.sol:131:13\n    │\n131 │             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:130:47\n    │\n130 │             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:131:34\n    │\n131 │             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:131:13\n    │\n131 │             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:133:9\n    │\n133 │         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:131:13\n    │\n131 │             items.mint(c.player, k, r, false);\n    │             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/unused-return\n\nwarning[reentrancy-no-eth]: external call can be reentered before `_status` is updated\n    ╭▸ src/FarmRewards.sol:342:9\n    │\n342 │         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:339:66\n    │\n339 │     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:343:9\n    │\n343 │         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:346:80\n    │\n346 │     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:360:9\n    │\n360 │         pool.recycle(amount);\n    │         ━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-no-eth\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/Base.t.sol:27:18\n   │\n27 │         launch = block.timestamp;\n   │                  ━━━━━━━━━━━━━━━\n   │\n   ⸬  test/StandardV4Integration.t.sol:72:9\n   │\n72 │         vm.warp(vm.getBlockTimestamp() + 31 minutes);\n   │         ──────────────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":4741,"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 161.77µs (63.01µ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 436.86µs (355.35µs CPU time)\n\nRan 3 tests for test/StandardAdapter.t.sol:StandardAdapterTest\n[PASS] testExistingHookKeyPreservedAndNoExtraFee() (gas: 295704)\n[PASS] testRequiresThirtyMinutesFreshOracleAndAuthorizedCallback() (gas: 194045)\n[PASS] testSettlementSlippageFailurePreservesCredits() (gas: 239300)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.06ms (549.60µs CPU time)\n\nRan 3 tests for test/Deployment.t.sol:DeploymentTest\n[PASS] testConstructorRejectsMissingInputsAndDoesNotCallExternalContracts() (gas: 4046)\n[PASS] testForeignCallerDoesNotGetAnyAuthority() (gas: 19111034)\n[PASS] testImmutableGraphAndEip170Sizes() (gas: 114866)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.37ms (1.29ms CPU time)\n\nRan 9 tests for test/Packs.t.sol:PacksTest\n[PASS] testExactPaymentAndFutureBlockRequired() (gas: 978532)\n[PASS] testExactRarityThresholdsAndMythicGate() (gas: 270970)\n[PASS] testExpiryThreeCommonGpusAndInventoryOpeningLimit() (gas: 2123946)\n[PASS] testFuzzVrgdaAlwaysBounded(uint32,uint32) (runs: 256, μ: 36203, ~: 36137)\nLogs:\n  Bound result 4072\n\n[PASS] testItemTypeDistributionExact() (gas: 591721)\n[PASS] testNoWalletGlobalOrTokenPackDailyLimit() (gas: 2453933)\n[PASS] testStarterWindowProofTokenIdOnceAndInventoryFailureRetry() (gas: 473707)\n[PASS] testTokenPackDiscountAllToPoolAndBonusWhenInternal() (gas: 5456996)\n[PASS] testVrgdaInitialStepDecayFloorCeilingAndBulkPricing() (gas: 688679)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 19.43ms (18.64ms CPU time)\n\nRan 2 tests for test/StandardMarket.t.sol:StandardMarketTest\n[PASS] testFuzzStandardSellNeverAddsProgressiveSurcharge(uint96) (runs: 256, μ: 1707978, ~: 1714787)\nLogs:\n  Bound result 28873124826275252573\n\n[PASS] testStandardBuyOnePercentEvenSplitAndNetworkQuarterPercent() (gas: 1602014)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 22.88ms (19.99ms CPU time)\n\nRan 6 tests for test/Market.t.sol:MarketTest\n[PASS] testBuyChargesOnlyBaseAndNetworkPullPayment() (gas: 233154)\n[PASS] testFuzzTotalFeeHardCap(uint96) (runs: 256, μ: 1851431, ~: 1860787)\nLogs:\n  Bound result 38567175727474567177\n\n[PASS] testOnlyManagerCorrectPoolExactInputAndHookAddress() (gas: 112641)\n[PASS] testSingleDumpIncludesItselfAndFeeDecaysWithoutGriefReset() (gas: 16442236)\n[PASS] testTwapAveragesEthPriceAcrossUnequalPrices() (gas: 2400704)\n[PASS] testTwapWarmupAndFlashManipulationResistance() (gas: 1929668)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 27.58ms (36.43ms CPU time)\n\nRan 11 tests for test/Items.t.sol:ItemsTest\n[PASS] testComputeHashSupportHashAndBonusesReplaceDuo() (gas: 2135951)\n[PASS] testDurabilityDecayRepairAndOverclockPreserved() (gas: 5803917)\n[PASS] testEquipRarityGatesAndMythicGate() (gas: 3808778)\n[PASS] testFullStackRarityCapAndRoomFlags() (gas: 2792466)\n[PASS] testInventoryMintCannotExceedCapacityAndExpansionRises() (gas: 1905995)\n[PASS] testMergeThreeIdenticalAndNoLegendaryMergeOrLockedExit() (gas: 5888888)\n[PASS] testOffgridSavings() (gas: 1204933)\n[PASS] testPaidXpCannotBypassRoomTwoAgeGate() (gas: 2376738)\n[PASS] testRoomGatesAndLevelProgression() (gas: 54018095)\n[PASS] testScrapPaysPoolYieldAndCannotRepeat() (gas: 5496630)\n[PASS] testSoulboundOnlyOwnFarmAndNoDuplicateTypes() (gas: 959222)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 27.50ms (54.54ms CPU time)\n\nRan 3 tests for test/V4Integration.t.sol:V4IntegrationTest\n[PASS] testRealV4BuyAndSingleSwapSellTaxConserveSettlement() (gas: 2206147)\n[PASS] testRealV4ManipulatedSpotCannotInstantlySetBuybackQuote() (gas: 1892041)\n[PASS] testRealV4SystemBuyUsesTwapAndOnlySystemFunds() (gas: 1863927)\nSuite result: ok. 3 passed; 0 failed; 0 skipped; finished in 32.09ms (1.26ms CPU time)\n\nRan 2 tests for test/Factory.t.sol:FactoryTest\n[PASS] testFactoryInvalidSearchRange() (gas: 5114)\n[PASS] testHookFactoryFlagsImmutableConfigAndIdempotence() (gas: 3365319)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 69.83ms (4.68ms CPU time)\n\nRan 2 tests for test/Gas.t.sol:GasTest\n[PASS] testGasCommonActions() (gas: 6233899)\nLogs:\n  buy ETH pack: 507970\n  open one pack: 309797\n  equip: 201533\n  repair wallet: 248172\n  overclock: 106453\n  expand: 120067\n  token pack internal: 235348\n  withdraw: 113740\n  unequip: 102797\n\n[PASS] testGasEightFullFarmsSettlementStaysBounded() (gas: 74576645)\nLogs:\n  measure eight full 24-item farms: 14477149\n  credit eight full farms: 3047132\n\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 70.12ms (58.55ms CPU time)\n\nRan 6 tests for test/SeasonAudit.t.sol:SeasonAuditTest\n[PASS] testAuditExactTopDecileNoWhaleSoftCap() (gas: 19590005)\n[PASS] testLotteryEntitlementSurvivesFullInventory() (gas: 85832379)\n[PASS] testPackSupplyDropOnlyActiveFarmsAtDoublePace() (gas: 8416778)\n[PASS] testParameterChangesCannotChangeClosedEpochBetweenBatches() (gas: 7156781)\n[PASS] testSeasonCannotFinalizeEarlyAndExpiredLotteryMustRearm() (gas: 84173635)\n[PASS] testWeeklyThreeDistinctTicketWinnersRarePackAndBestPrize() (gas: 84770789)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 69.36ms (209.54ms CPU time)\n\nRan 7 tests for test/FeesParams.t.sol:FeesParamsTest\n[PASS] testAllDefaultParamsWithinHardBounds() (gas: 661072)\n[PASS] testBuyBackPoolOnlySlippageFailureRollbackAndDustGriefBlocked() (gas: 721039)\n[PASS] testExactEthSplitsHeartbeatCapAndPullPayments() (gas: 396675)\n[PASS] testFuzzNoStepAboveTenPercent(uint96) (runs: 256, μ: 44621, ~: 44717)\nLogs:\n  Bound result 9690\n\n[PASS] testFuzzSplitsConserveEveryWei(uint96) (runs: 256, μ: 143970, ~: 146580)\nLogs:\n  Bound result 28873124826275252573\n\n[PASS] testParamsStepCooldownBoundsAuthorityAndLetter() (gas: 195336)\n[PASS] testPoolNoPublicReserveRecycleOrPayment() (gas: 104773)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 82.02ms (147.63ms CPU time)\n\nRan 13 tests for test/Events.t.sol:EventsTest\n[PASS] testCheapTariffAppliesCitywide() (gas: 4917452)\n[PASS] testColdPowerFireImmuneAndCleanPowerSurgeImmune() (gas: 3125554)\n[PASS] testFallbackAndExpiredSeedIndependentOfSwarmNumber() (gas: 1292258)\n[PASS] testFireNoCoolingZeroYieldColdPowerImmune() (gas: 2507566)\n[PASS] testGreenWaveRaisesDistrictMiningTenPercent() (gas: 4918787)\n[PASS] testLobbyOwnDistrictSplitDecayAndMinimumWeight() (gas: 403885)\n[PASS] testOutageAndOffgridRoomMitigation() (gas: 2794703)\n[PASS] testPlansOnlyNextTwoOnceAndBoundedSeverity() (gas: 279307)\n[PASS] testRollingCapsAndInitialPositiveQuotaWithHostilePlans() (gas: 80678394)\n[PASS] testSurgeCanDestroyCommonButNeverLegendary() (gas: 2631941)\n[PASS] testSurgeDamagesExactlyOneItemAndCleanPowerImmune() (gas: 2523891)\n[PASS] testSurgeNeverDestroysLegendaryOrMythic() (gas: 4399315)\n[PASS] testTheftRouterDisabledAndRepairRestores() (gas: 2761865)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 82.20ms (64.26ms CPU time)\n\nRan 6 tests for test/Regression.t.sol:RegressionTest\n[PASS] testCableRepairRestoresOnlyRemainingHalfEpoch() (gas: 8671123)\n[PASS] testEmptyEpochResetsScrapRateAndAllowance() (gas: 8487190)\n[PASS] testFuzzCableRepairBlendHandlesNonMonotonicRarityBonuses(uint16) (runs: 256, μ: 909467, ~: 909412)\nLogs:\n  Bound result 2397\n\n[PASS] testRegisterOnlyAccountsDoNotAddSettlementWorkAndEmptyFarmCanRetire() (gas: 838684)\n[PASS] testRepairAndPaidPackCannotRetroactivelyBoostEpoch() (gas: 6905315)\n[PASS] testUnlimitedFreshPacksCannotDrainPoolByScrapping() (gas: 6475901)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 82.19ms (89.02ms CPU time)\n\nRan 1 test for test/StandardV4Integration.t.sol:StandardV4IntegrationTest\n[PASS] testStandardAdapterRealPoolPaysExistingHookExactlyOnce() (gas: 1936415)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 97.65ms (304.08µs CPU time)\n\nRan 9 tests for test/Epochs.t.sol:EpochsTest\n[PASS] testCannotAdvanceEarlyAndBountyOnce() (gas: 1687992)\n[PASS] testClaimsEveryEpochAndRedistributionIsNextEpoch() (gas: 9122842)\n[PASS] testGasAdvanceIndependentOfRoster() (gas: 413502878)\nLogs:\n  advance empty roster: 819200\n  advance 1000 farms: 821766\n\n[PASS] testNoCatchupEmissionDuringGap() (gas: 4953402)\n[PASS] testNoRetroactiveEquipmentAndBoundedBatches() (gas: 4573166)\n[PASS] testNoWhaleCapHashShares() (gas: 6852499)\n[PASS] testReferralOneLevelSetOnceNoSelf() (gas: 5294752)\n[PASS] testTaxCurveExactAndFloor() (gas: 27038)\n[PASS] testWithdrawFailureRollsBackAndReentrancyCannotClaimTwice() (gas: 5471769)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 1.47s (1.49s 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   | 1026  | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | buy       | 1021  | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | claim     | 997   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | equip     | 1058  | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | expand    | 992   | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | resolve   | 1050  | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | tokenPack | 1069  | 0       | 0        |\n|-------------+-----------+-------+---------+----------|\n| GameHandler | unplace   | 979   | 0       | 0        |\n╰-------------+-----------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 4.64s (4.63s CPU time)\n\nRan 18 test suites in 4.64s (6.80s CPU time): 86 tests passed, 0 failed, 1 skipped (87 total tests)\n","passed":true},{"durationMs":74,"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.processEpoch(uint256)\",\"FarmRewards.recordSales(uint256)\",\"FarmRewards.releasePrize(uint256)\",\"FarmRewards.scrap(address,uint256,uint256)\",\"FarmRewards.setReferrer(address,address)\",\"FarmRewards.spend(address,uint256)\",\"FeeRouter.depositBaseFee()\",\"FeeRouter.depositLobby()\",\"FeeRouter.depositPack()\",\"FeeRouter.depositSellTax()\",\"FeeRouter.executeBuys(uint256,uint256)\",\"FeeRouter.payBounty(address)\",\"FeeRouter.receive()\",\"FeeRouter.withdraw()\",\"GridOperator.lobbyETH()\",\"GridOperator.resolve(uint256)\",\"GridOperator.shift(uint256)\",\"GridOperator.submitPlan(uint256,uint8,uint16,bytes32,string)\",\"GridOperator.tokenLobby(address,uint256)\",\"MarketFactory.deploy((address,address,address,address,address,int24),bytes32)\",\"PackSale.openPack(uint256)\",\"PackSale.resolve(uint256,uint256)\",\"PackSale.rewardPack(address)\",\"PackSale.tokenPack(address)\",\"Params.set(uint8,uint256,string)\",\"RewardPool.donate(uint256)\",\"RewardPool.pay(address,uint256)\",\"RewardPool.recycle(uint256)\",\"RewardPool.reserve(uint256)\",\"Season.addPrize(uint256,uint256)\",\"Season.claimDistrict(uint256)\",\"Season.claimLottery(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.buy(uint256,address)\",\"StandardMarket.receive()\",\"StandardMarket.unlockCallback(bytes)\",\"StandardMarket.withdrawNetwork()\",\"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.buy(uint256,address)\",\"V4Market.receive()\",\"V4Market.unlockCallback(bytes)\",\"V4Market.withdrawNetwork()\"],\"files\":{\".gitignore\":6,\"README.md\":77,\"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/verification-v3.json\":67,\"docs/dependency-provenance.md\":9,\"docs/design.md\":65,\"docs/security-review.md\":29,\"docs/simulation-assumptions.md\":44,\"foundry.toml\":20,\"regulator.md\":32,\"report.md\":143,\"script/Deploy.s.sol\":65,\"script/DeployMarket.s.sol\":15,\"sim/blackout_sim_v2.py\":509,\"sim/blackout_sim_v3.py\":286,\"sim/policy_sensitivity_v3.py\":19,\"sim/tune_v3.py\":16,\"src/FarmCore.sol\":462,\"src/FarmEngine.sol\":200,\"src/FarmItems.sol\":115,\"src/FarmRewards.sol\":367,\"src/FeeRouter.sol\":127,\"src/GridOperator.sol\":203,\"src/MarketFactory.sol\":60,\"src/PackSale.sol\":135,\"src/Params.sol\":140,\"src/RewardPool.sol\":57,\"src/Season.sol\":203,\"src/StandardAdapter.sol\":77,\"src/StandardMarket.sol\":23,\"src/StarterClaim.sol\":63,\"src/V4Market.sol\":312,\"src/interfaces/IGame.sol\":37,\"src/interfaces/IV4.sol\":25,\"src/interfaces/Interfaces.sol\":14,\"src/lib/ChainClock.sol\":22,\"src/lib/Errors.sol\":12,\"src/lib/ItemMath.sol\":31,\"test/Base.t.sol\":105,\"test/Clock.t.sol\":50,\"test/Deployment.t.sol\":57,\"test/Epochs.t.sol\":178,\"test/Events.t.sol\":239,\"test/Factory.t.sol\":31,\"test/FeesParams.t.sol\":119,\"test/Gas.t.sol\":92,\"test/Invariants.t.sol\":125,\"test/Items.t.sol\":265,\"test/Market.t.sol\":120,\"test/Packs.t.sol\":160,\"test/Regression.t.sol\":152,\"test/SeasonAudit.t.sol\":176,\"test/StandardAdapter.t.sol\":88,\"test/StandardMarket.t.sol\":62,\"test/StandardV4Integration.t.sol\":123,\"test/V4Integration.t.sol\":132,\"test/fork/RobinhoodFork.t.sol\":39,\"test/mocks/MockMarket.sol\":37,\"test/mocks/MockToken.sol\":38,\"test/mocks/MockV4Manager.sol\":64,\"test/python/test_merkle.py\":19,\"test/python/test_regulator.py\":25,\"tools/regulator.py\":47,\"tools/starter_merkle.py\":72},\"excluded\":[\"vendor/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":14040,"exitCode":0,"name":"slither","output":"[high/medium] weak-prng at src/V4Market.sol:154: V4Market._record(bool,uint256) (src/V4Market.sol#154-175) uses a weak PRNG: \"b = longVolumes[p % 24] (src/V4Market.sol#163)\"\n[high/medium] weak-prng at src/V4Market.sol:154: V4Market._record(bool,uint256) (src/V4Market.sol#154-175) uses a weak PRNG: \"delete longVolumes[p % 24] (src/V4Market.sol#165)\"\n[high/medium] weak-prng at src/V4Market.sol:154: V4Market._record(bool,uint256) (src/V4Market.sol#154-175) uses a weak PRNG: \"delete shortVolumes[p % 12] (src/V4Market.sol#159)\"\n[high/medium] weak-prng at src/V4Market.sol:154: V4Market._record(bool,uint256) (src/V4Market.sol#154-175) uses a weak PRNG: \"a = shortVolumes[p % 12] (src/V4Market.sol#157)\"\n[high/medium] weak-prng at src/V4Market.sol:134: V4Market._cumulativeAt(uint256) (src/V4Market.sol#134-141) uses a weak PRNG: \"o = observations[minute % 32] (src/V4Market.sol#138)\"\n[high/medium] weak-prng at src/GridOperator.sol:89: GridOperator.lobbyAmount(uint256) (src/GridOperator.sol#89-96) uses a weak PRNG: \"a * 259200 / (259200 + dt % 259200) (src/GridOperator.sol#95)\"\n[high/medium] weak-prng at src/V4Market.sol:112: V4Market._observe(uint256) (src/V4Market.sol#112-132) uses a weak PRNG: \"observations[minute % 32] = Observation(uint64(minute),c) (src/V4Market.sol#126)\"\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:32: Reentrancy in RewardPool.donate(uint256) (src/RewardPool.sol#32-38):\n[high/medium] reentrancy-balance at src/FarmCore.sol:266: Reentrancy in FarmCore._charge(address,uint256,bool,uint8) (src/FarmCore.sol#266-282):\n[high/medium] reentrancy-balance at src/FeeRouter.sol:111: Reentrancy in FeeRouter.executeBuys(uint256,uint256) (src/FeeRouter.sol#111-126):\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:321: Reentrancy in FarmCore.buyTokenPack(bool) (src/FarmCore.sol#321-329):\n[high/medium] reentrancy-eth at src/FarmCore.sol:294: Reentrancy in FarmCore.repairCable(bool) (src/FarmCore.sol#294-302):\n[high/high] uninitialized-state at src/FarmRewards.sol:167: FarmRewards.heaps (src/FarmRewards.sol#72) is never initialized. It is used in:\n[medium/medium] divide-before-multiply at src/V4Market.sol:134: V4Market._cumulativeAt(uint256) (src/V4Market.sol#134-141) 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/FarmEngine.sol:74: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256) (src/FarmEngine.sol#74-122) 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:112: V4Market._observe(uint256) (src/V4Market.sol#112-132) 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:112: V4Market._observe(uint256) (src/V4Market.sol#112-132) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/FarmCore.sol:360: FarmCore.scrap(uint256,uint256) (src/FarmCore.sol#360-369) 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:74: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256) (src/FarmEngine.sol#74-122) performs a multiplication on the result of a division:\n[medium/medium] divide-before-multiply at src/FarmCore.sol:360: FarmCore.scrap(uint256,uint256) (src/FarmCore.sol#360-369) 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/high] incorrect-equality at src/GridOperator.sol:140: GridOperator.resolve(uint256) (src/GridOperator.sol#140-193) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/FarmCore.sol:360: FarmCore.scrap(uint256,uint256) (src/FarmCore.sol#360-369) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/FarmCore.sol:196: FarmCore.setReferrer(address) (src/FarmCore.sol#196-200) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/V4Market.sol:204: V4Market._sellFee(uint256) (src/V4Market.sol#204-219) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/V4Market.sol:112: V4Market._observe(uint256) (src/V4Market.sol#112-132) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/V4Market.sol:143: V4Market.twap() (src/V4Market.sol#143-148) uses a dangerous strict equality:\n[medium/high] incorrect-equality at src/GridOperator.sol:140: GridOperator.resolve(uint256) (src/GridOperator.sol#140-193) uses a dangerous strict equality:\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:195: Reentrancy in FarmRewards.processEpoch(uint256) (src/FarmRewards.sol#195-273):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:195: Reentrancy in FarmRewards.processEpoch(uint256) (src/FarmRewards.sol#195-273):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:195: Reentrancy in FarmRewards.processEpoch(uint256) (src/FarmRewards.sol#195-273):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:124: Reentrancy in FarmRewards.advanceEpoch() (src/FarmRewards.sol#124-154):\n[medium/medium] reentrancy-no-eth at src/V4Market.sol:279: Reentrancy in V4Market.unlockCallback(bytes) (src/V4Market.sol#279-302):\n[medium/medium] reentrancy-no-eth at src/FarmCore.sol:387: Reentrancy in FarmCore.process(address,uint256) (src/FarmCore.sol#387-412):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:124: Reentrancy in FarmRewards.advanceEpoch() (src/FarmRewards.sol#124-154):\n[medium/medium] reentrancy-no-eth at src/FarmRewards.sol:195: Reentrancy in FarmRewards.processEpoch(uint256) (src/FarmRewards.sol#195-273):\n[medium/medium] uninitialized-local at src/FarmCore.sol:374: FarmCore.roomStats(address,uint256).snap (src/FarmCore.sol#374) is a local variable never initialized\n[medium/medium] uninitialized-local at src/GridOperator.sol:167: GridOperator.resolve(uint256).weights (src/GridOperator.sol#167) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:76: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256).mask (src/FarmEngine.sol#76) is a local variable never initialized\n[medium/medium] uninitialized-local at src/GridOperator.sol:168: GridOperator.resolve(uint256).sum (src/GridOperator.sol#168) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:136: FarmEngine.process(address,uint256,FarmEngine.Snapshot).occupied (src/FarmEngine.sol#136) is a local variable never initialized\n[medium/medium] uninitialized-local at src/PackSale.sol:127: PackSale.resolve(uint256,uint256).k (src/PackSale.sol#127) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmRewards.sol:237: FarmRewards.processEpoch(uint256).referral (src/FarmRewards.sol#237) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:141: FarmEngine.process(address,uint256,FarmEngine.Snapshot).cursor (src/FarmEngine.sol#141) is a local variable never initialized\n[medium/medium] uninitialized-local at src/V4Market.sol:207: V4Market._sellFee(uint256).average (src/V4Market.sol#207) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:78: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256).rarity (src/FarmEngine.sol#78) is a local variable never initialized\n[medium/medium] uninitialized-local at src/GridOperator.sol:153: GridOperator.resolve(uint256).repeated (src/GridOperator.sol#153) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:159: FarmEngine.process(address,uint256,FarmEngine.Snapshot).damage (src/FarmEngine.sol#159) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:142: FarmEngine.process(address,uint256,FarmEngine.Snapshot).baseline (src/FarmEngine.sol#142) is a local variable never initialized\n[medium/medium] uninitialized-local at src/V4Market.sol:178: V4Market.imbalances().s (src/V4Market.sol#178) is a local variable never initialized\n[medium/medium] uninitialized-local at src/PackSale.sol:128: PackSale.resolve(uint256,uint256).r (src/PackSale.sol#128) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmEngine.sol:77: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256).tags (src/FarmEngine.sol#77) is a local variable never initialized\n[medium/medium] uninitialized-local at src/V4Market.sol:179: V4Market.imbalances().b (src/V4Market.sol#179) is a local variable never initialized\n[medium/medium] uninitialized-local at src/FarmCore.sol:395: FarmCore.process(address,uint256).occupied (src/FarmCore.sol#395) is a local variable never initialized\n[medium/medium] uninitialized-local at src/GridOperator.sol:152: GridOperator.resolve(uint256).positives (src/GridOperator.sol#152) 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/StarterClaim.sol:49: StarterClaim.resolve(uint256) (src/StarterClaim.sol#49-62) ignores return value by items.mint(c.player,k,r,true) (src/StarterClaim.sol#59)\n[medium/medium] unused-return at src/FeeRouter.sol:111: FeeRouter.executeBuys(uint256,uint256) (src/FeeRouter.sol#111-126) ignores return value by market.buy{value: ethAmount}(minOut,rewardPool) (src/FeeRouter.sol#122)\n[medium/medium] unused-return at src/FarmRewards.sol:195: FarmRewards.processEpoch(uint256) (src/FarmRewards.sol#195-273) ignores return value by (kind,severity,None,seed,None) = grid.eventAt(id) (src/FarmRewards.sol#199)\n[medium/medium] unused-return at src/Season.sol:195: Season.claimLottery(uint256) (src/Season.sol#195-202) ignores return value by (k,None) = ItemMath.draw(seed,false,false) (src/Season.sol#199)\n[medium/medium] unused-return at src/StarterClaim.sol:49: StarterClaim.resolve(uint256) (src/StarterClaim.sol#49-62) ignores return value by items.mint(c.player,0,1,true) (src/StarterClaim.sol#59)\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[medium/medium] unused-return at src/PackSale.sol:113: PackSale.resolve(uint256,uint256) (src/PackSale.sol#113-134) ignores return value by items.mint(c.player,k,r,false) (src/PackSale.sol#131)\n[medium/medium] unused-return at src/V4Market.sol:279: V4Market.unlockCallback(bytes) (src/V4Market.sol#279-302) ignores return value by manager.settle{value: input}() (src/V4Market.sol#297)\n[low/medium] events-maths at src/PackSale.sol:85: PackSale.openPack(uint256) (src/PackSale.sol#85-92) should emit an event for: \n[low/medium] events-maths at src/FarmRewards.sol:346: FarmRewards.scrap(address,uint256,uint256) (src/FarmRewards.sol#346-352) should emit an event for: \n[low/medium] calls-loop at src/FarmCore.sol:171: FarmCore._roll(address,uint256) (src/FarmCore.sol#171-185) has external calls inside a loop: x = items.data(f.active[i]) (src/FarmCore.sol#181)\n[low/medium] calls-loop at src/FarmEngine.sol:74: FarmEngine._stats(FarmEngine.Snapshot,uint256,bool,uint256) (src/FarmEngine.sol#74-122) has external calls inside a loop: x_scope_2 = items.data(id_scope_1) (src/FarmEngine.sol#95)\n[low/medium] calls-loop at src/FarmEngine.sol:124: FarmEngine.process(address,uint256,FarmEngine.Snapshot) (src/FarmEngine.sol#124-199) has external calls inside a loop: items.maintain(id,uint16(x.durability - damage),x.overclock) (src/FarmEngine.sol#173)\n[low/medium] calls-loop at src/GridOperator.sol:98: GridOperator.lobbyWeight(uint256) (src/GridOperator.sol#98-104) has external calls inside a loop: floor = params.get(Params.Key.LobbyMinWeight) (src/GridOperator.sol#102)\n[low/medium] calls-loop at src/FarmEngine.sol:124: FarmEngine.process(address,uint256,FarmEngine.Snapshot) (src/FarmEngine.sol#124-199) has external calls inside a loop: items.maintain(id_scope_3,x_scope_4.durability - 50,x_scope_4.overclock) (src/FarmEngine.sol#195)\n[low/medium] calls-loop at src/FarmCore.sol:387: FarmCore.process(address,uint256) (src/FarmCore.sol#387-412) has external calls inside a loop: id != 0 && items.data(id).holder == address(0) (src/FarmCore.sol#410)\n[low/medium] calls-loop at src/StarterClaim.sol:49: StarterClaim.resolve(uint256) (src/StarterClaim.sol#49-62) has external calls inside a loop: items.mint(c.player,0,1,true) (src/StarterClaim.sol#59)\n[low/medium] calls-loop at src/FarmCore.sol:171: FarmCore._roll(address,uint256) (src/FarmCore.sol#171-185) has external calls inside a loop: x = items.data(f.active[i]) (src/FarmCore.sol#181)\n[low/medium] calls-loop at src/FarmCore.sol:171: FarmCore._roll(address,uint256) (src/FarmCore.sol#171-185) has external calls inside a loop: x = items.data(f.active[i]) (src/FarmCore.sol#181)\n[low/medium] calls-loop at src/FarmRewards.sol:124: FarmRewards.advanceEpoch() (src/FarmRewards.sol#124-154) has external calls inside a loop: epochParam[epoch][k] = params.get(Params.Key(k)) (src/FarmRewards.sol#147)\n[low/medium] calls-loop at src/PackSale.sol:54: PackSale.priceAt(uint256) (src/PackSale.sol#54-72) has external calls inside a loop: p = params.get(Params.Key.PriceStart) * uint256(wadExp(exponent)) / 1000000000000000000 (src/PackSale.sol#67)\n[low/medium] calls-loop at src/PackSale.sol:54: PackSale.priceAt(uint256) (src/PackSale.sol#54-72) has external calls inside a loop: exponent = wadLn(int256(1000000000000000000 + params.get(Params.Key.PriceStepBps) * 1e14)) * ahead / 1","passed":true},{"durationMs":764,"exitCode":0,"name":"aderyn","output":"[high] abi-encode-packed-hash-collision at src/MarketFactory.sol:20: `abi.encodePacked()` Hash Collision\n[high] contract-locks-ether at src/GridOperator.sol:10: Contract locks Ether without a withdraw function (3 places)\n[high] eth-send-unchecked-address at src/FeeRouter.sol:102: ETH transferred without address checks (3 places)\n[high] reentrancy-state-change at src/FarmCore.sol:211: Reentrancy: State change after external call (42 places)\n[high] unprotected-initializer at src/MarketFactory.sol:18: Unprotected initializer\n[low] costly-loop at src/FarmCore.sol:179: Costly operations inside loop (17 places)\n[low] division-before-multiplication at src/FarmCore.sol:364: Incorrect Order of Division and Multiplication\n[low] large-numeric-literal at src/FarmCore.sol:287: Large Numeric Literal (73 places)\n[low] literal-instead-of-constant at src/FarmCore.sol:112: Literal Instead of Constant (357 places)\n[low] local-variable-shadowing at src/FarmRewards.sol:44: Local Variable Shadows State Variable (2 places)\n[low] non-reentrant-not-first at src/FarmRewards.sol:339: `nonReentrant` is Not the First Modifier (3 places)\n[low] require-revert-in-loop at src/FarmCore.sol:217: Loop Contains `require`/`revert` (10 places)\n[low] state-change-without-event at src/FarmCore.sol:387: State Change Without Event (14 places)\n[low] unchecked-return at src/FarmCore.sol:290: Unchecked Return (12 places)\n[low] uninitialized-local-variable at src/FarmCore.sol:217: Uninitialized Local Variable (34 places)\n[low] unused-public-function at src/FarmCore.sol:144: Public Function Not Used Internally (3 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"df7bea7106eb1364697d08d9e3a91c7ebd20764fe8a64bfdcdc6c84969f6ff86","verifiedTreeHash":"13637b7e7cf3dc574cc05d9ba501ebb8c30e6eef","verifierVersion":"0.1.0+0e08a464"}]}