{"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":"0d76ba8d-53ca-4516-955a-de72bc596ae9","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"ff61aafba230f12803dfb756f14ab8b7b128f74ac8e05ea3c198f07bc2fec765","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_economics","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"5940144f236dc4667f9cca7f6a6601da2299c66425282b9826067a85c9551977","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_flow","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"eec618657fe5c9a173f24b72c7407e19dde9369bfca71d8c46b880f27cc7f7b8","dependsOn":["build_contract_project","write_foundry_tests","manifest","audit_math","audit_permissions","audit_economics","audit_flow"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","tools":[]},"key":"audit_judge","kind":"code","role":"review","skillHash":"3014f1ea5961918ca059453a484bf4c8bcbbfc2248dbe31d94ac7c5cdf8f50bd","skillId":"audit-judge","state":"accepted"},{"acceptedSubmissionHash":"68d041e139638b034d7a1a1874c4494f329586dbfb0bce50a9864d6b027f69af","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_math","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"12558f1f2edb6d8e902760ad85ebe5c08f4c34c0743c058d196e3e7b2aa7dc6e","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","tools":[]},"key":"audit_permissions","kind":"code","role":"review","skillHash":"e5ac2cb1fd91a56aa40b16487fc230c48de0d317c8266140331dd3219bb40a85","skillId":"audit-specialist","state":"accepted"},{"acceptedSubmissionHash":"406ce00475fa08b20dc370032433fc7494bc9f5e3e6c4b930d7c687288b6dfe1","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"b6503de65ad02f845827887c23da4c3b56ccc5df7a459db263bae6e549d92f7f","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"b6503de65ad02f845827887c23da4c3b56ccc5df7a459db263bae6e549d92f7f","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"2e322b477bf8b7bfcb9515ce6d67623c15121c1b25cdb8e5459135699eafce8a","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"accepted"},{"acceptedSubmissionHash":"41a6e587d6f988b39b449f5b08906916b1e26d05919d158eda1989782c32def5","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"73431852439ad3a343f3d2b7db1c43cd363b9f48f9bb51497374a0cf6d50b223","skillId":"write-foundry-tests","state":"accepted"}],"objective":"Redeploy an already built and reviewed project: KING ($KING), a \"King of the Hill\" throne game on a Uniswap v4 hook, KING/ETH, and publish its website.\n\nSource: https://github.com/identity-md-launches/launch-814-custom-token-king-hill (launch 814). It passed every review, but its deploy was parked with \"Manifest: fee tier 3000 is not on the policy allowlist\": the launch factory now sets the pool's own trading fee (1.25%) itself.\n\nContracts:\n- Take the contracts and tests from that repository and keep every game rule, fee, address and parameter.\n- Change only what the new factory policy requires: launch.json must use the pool fee configuration the factory now expects (do not hardcode fee 3000), and the hook's beforeInitialize must accept that configuration instead of only LP fees 500/3000/10000. The factory's 1.25% pool fee is separate and on top of the hook's own fee.\n- Update the tests affected by this, run the full suite, and deploy on Robinhood Chain.\n\nWhat each contract does:\n- KING token: plain ERC-20, 1,000,000,000 supply, 18 decimals, minted once, no fees, limits, pausing or minting on transfers.\n- King hook: the Uniswap v4 hook on the KING/ETH pool. It takes the hook fee in ETH, splits it between the throne pool and the team, runs the throne game, pays the king's income and handles dethrone().\n- King router (if kept from the source): routes buys so the hook knows the real buyer and supports the \"must take the throne\" flag.\n\nGame rules (unchanged from the source, for the builders' check):\n- Hook fee 2.5% on every buy and sell, always in ETH, with anti-snipe starting at 25% and decaying linearly to 2.5% over 30 minutes.\n- Fee split: 92% to the throne pool, 8% to the team wallet 0x39E3414e7a43DE41675e9bEC52F7C9F6ae489CB6 (pull-based).\n- The game starts after anti-snipe. A single buy of at least the throne price takes the throne. Throne price: 1.2x the ETH the new king paid, then halves every hour down to a 0.01 ETH floor; empty throne = floor.\n- King income: 2% of the throne pool per hour, credited every second, claimable any time, also after losing the throne.\n- Holding rule: the king must keep the KING bought in the takeover. A sell by the king dethrones him at once; anyone can call dethrone() when balanceOf(king) is below that amount.\n- \"Must take the throne\" flag: if set and the buy is below the throne price at execution, the whole swap reverts.\n\nWhen the hook acts: on every swap in the KING/ETH pool, before and after the swap, to take the ETH fee and run the throne game. Never on plain transfers or liquidity changes.\n\nWho can call what: no owner. Anyone can buy, sell, take the throne, claim their own income, and call dethrone() when the king's balance is below the required amount. The team wallet only receives its 8% share by claiming it. Nobody can change any parameter.\n\nUpgrades and pausing: not upgradeable, not pausable.\n\nWebsite (required in this job):\n- Build a user-facing web app (frontend) for KING that reads the live contracts on Robinhood Chain and lets a connected wallet act on them.\n- Publish it as a usable website at a public URL: a static build (index.html in dist/) pinned to IPFS and served on imd.fun sites.\n- Pages: (1) Throne: current king, reign time, his income so far and per hour, throne price with countdown to the next halving, pool size, past kings with reign time and earnings. (2) Trade: buy with the \"must take the throne\" flag, normal buy and sell. (3) Claim and dethrone: claim own income, call dethrone() when the king's balance is below the required amount. (4) How it works, contract addresses with explorer links, and a \"Made by agents. Not audited by humans. Trade at your own risk.\" notice.\n- Keep all frontend files in a separate web/ folder so launch.json and the contract project stay valid.\n\nLaunch: all of the requester's share goes into liquidity (pool 90%, 0% to the requester), single-sided. Starting market cap 10 ETH.","parentJobId":null,"planHash":"644067a989b25926a9d1cf33dc18b3027dcde155b74b4522fa0ca020ea906dcd","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"0d76ba8d-53ca-4516-955a-de72bc596ae9","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-832-redeploy-already-built-reviewed"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52173","feedbackHash":"ab35cea45f609e4f8d0fc9b1a754625e92aaa4a49594a9aef8fd1dacc63eed33","nodeKey":"audit_economics","submissionHash":"ff61aafba230f12803dfb756f14ab8b7b128f74ac8e05ea3c198f07bc2fec765","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52165","feedbackHash":"504c7b07cdaddeebf7aa7d97396c158ff443421c9b61acfcc6fc5fe50618d300","nodeKey":"audit_flow","submissionHash":"5940144f236dc4667f9cca7f6a6601da2299c66425282b9826067a85c9551977","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"50986","feedbackHash":"4bc80d6c5afe6d7fdca6f0bb90af4c94a40e94572eacfa1897c46e6ca3b66638","nodeKey":"audit_judge","submissionHash":"eec618657fe5c9a173f24b72c7407e19dde9369bfca71d8c46b880f27cc7f7b8","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52159","feedbackHash":"ce049b29b8111ce1b0c3a22aff957229b9aa134146fdc87f28980d1f59a0d436","nodeKey":"audit_math","submissionHash":"68d041e139638b034d7a1a1874c4494f329586dbfb0bce50a9864d6b027f69af","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"52161","feedbackHash":"74c1b32135e7dfdb9ccbef8e0d41091683da5e7246267f8c93986b8d193657ed","nodeKey":"audit_permissions","submissionHash":"12558f1f2edb6d8e902760ad85ebe5c08f4c34c0743c058d196e3e7b2aa7dc6e","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51207","feedbackHash":"75d116ab1e0737eef5d55e87ca61340904995633237bf25fd2df7c6553cd4997","nodeKey":"build_contract_project","submissionHash":"406ce00475fa08b20dc370032433fc7494bc9f5e3e6c4b930d7c687288b6dfe1","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52010","feedbackHash":"966fde30fc32f5dcfca8a4ce3d0329637c7f92300f2b52b33eefee7387b1841c","nodeKey":"manifest","submissionHash":"2e322b477bf8b7bfcb9515ce6d67623c15121c1b25cdb8e5459135699eafce8a","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52012","feedbackHash":"af7a5ceac3497f0fa19a48bffbbae6171adb76b78275631f2d0226293acb44c6","nodeKey":"write_foundry_tests","submissionHash":"41a6e587d6f988b39b449f5b08906916b1e26d05919d158eda1989782c32def5","tag1":"verification:checks","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"40f2a6b646df856a4a76fc5b72bd4a207ba70013cd0e79ee9a84c6d20f8f8dd6","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"ca075d17c94a854b","findings":[{"citation":"resolved","description":"Trust gap (access x economics): the hook's fee, anti-snipe decay and holding checks run only inside the pool whose key names this hook (beforeSwap/afterSwap check `_poolId`). KingToken is a plain ERC-20 with no transfer restriction, and PoolManager.initialize is permissionless, so any address can initialize a second ETH/KING pool with `hooks = address(0)` (any fee tier, any tick spacing), seed it with KING bought on the official pool plus ETH, and trade KING there with zero hook fee and no throne-game observation. A sitting king can sell his entire takeover position on that pool: `pool` and the hook's ERC-6909 claims do not move, `king` stays set, and he remains king (with income still projected to him) until some later swap on the official pool, a claim() or dethrone() observes the shortfall; the unverified interval is then retained by the pool, but the trading fee itself is never collected. The README documents third-party *routers* (which still pay the fee on the official pool) but not a hookless *pool*, and the published site's rules panel states 'Every buy and sell pays an ETH hook fee', which is only true of the official pool. This is a limitation of the requested plain-token design rather than a code defect, so it is reported as low: the user-facing wording should say the fee and game apply to the official KING/ETH pool only, and the price-arbitrage between the two pools (no fee on one side) will route volume away from the throne pool.","line":28,"path":"src/KingHook.sol","reproduction":"Same PoolManager as the launch pool. 1) Anyone: `manager.initialize(PoolKey(ETH, KING, 3000, 60, IHooks(address(0))), 792281625142643375935439503360000)` succeeds (no AlreadyInitialized: the hook is not in this key). 2) Mallory, holding 50,000,000 KING and 2 ETH, adds two-sided liquidity in ticks [178200, 190200] of that pool. 3) After gameStart, Alice `router.buyExactIn{value: 1 ether}(0, true, deadline)` -> king = Alice, requiredBalance = R. 4) Alice swaps `-R` KING (exact input, oneForZero) on the hookless pool through v4-core's PoolSwapTest with empty hookData. Expected per the brief ('Hook fee 2.5% on every buy and sell', 'A sell by the king dethrones him at once'): a fee is paid and/or the king is removed. Actual: `hook.pool()` and `manager.balanceOf(hook, 0)` are unchanged, `token.balanceOf(alice) < R`, `hook.king() == alice`; one hour later `hook.king()` is still Alice and only an explicit `hook.dethrone()` clears her. Verified with a scratch Foundry test on this tree (test/scratch/HooklessPool.t.sol, passes = the bypass works).","severity":"low","snippet":"/// Fee: every buy and sell pays a fee in ETH, computed on the settled ETH delta of the swap. It starts","title":"Hook fee and holding rule bind only the official pool; anyone can open a hookless KING/ETH pool on the same PoolManager where trades pay no hook fee and a king's full exit goes unnoticed until dethron"},{"citation":"resolved","description":"Asymmetry (economics x asymmetry, documented in README 'Same king again' as accepted). `_onBuy` does not distinguish a rival from the sitting king: any router buy with `ethGross >= currentThronePrice()` and `mustTake == false` ends the running reign (`_endReign(Dethroned, 0)`, which returns all `provisionalIncome` to the pool when the reign is younger than five minutes) and opens a new one with `reignStart = now`. Because the throne price halves hourly, a king who simply adds to his position through the official router a few hours into a reign will usually cross the decayed price and be re-crowned involuntarily. Consequences for him: provisional income of a young reign is forfeited, the next five minutes of income become provisional again (lost if a rival outbids him in that window), and his reign history is split. The identical purchase through a third-party router (or a hookless pool) leaves his reign untouched, so the official router, which the site always uses, is the worse venue for a king to buy more KING. The public site's trade page shows the throne price and the must-take toggle but does not tell a connected wallet that is currently king that a buy at or above that price will restart his reign; only the claim page's general sentence about self-retakes forfeiting covers it. Informational: this is the agreed design; the fix is a wording/UI warning (or gating self-retakes behind mustTake), not a code change the brief allows.","line":580,"path":"src/KingHook.sol","reproduction":"After gameStart: Alice `buyExactIn(1 ether, false)` -> king, price 1.2 ETH. Warp +3 min, any small swap accrues: `provisionalIncome = P > 0`. Alice `router.buyExactIn{value: 1.5 ether}(0, false, deadline)` (no must-take). Expected by a user adding to a position: king unchanged, reign and income unchanged. Actual: `reignCount()` 1 -> 2, `reignStart` advances to now, `provisionalIncome == 0`, `getReign(0).forfeited == P`, `unclaimedIncome(alice) == 0`. Control: the same 1.5 ETH buy via v4-core PoolSwapTest with empty hookData during a fresh reign leaves `reignCount` and `provisionalIncome` unchanged. Verified with a scratch Foundry test on this tree (test/scratch/Asymmetry.t.sol).","severity":"info","snippet":"        if (buyer == king && requiredBalance > kingOut) kingOut = requiredBalance;\n        if (king != address(0)) _endReign(EndReason.Dethroned, 0);\n        _startReign(buyer, ethGross, kingOut, price);","title":"A sitting king's ordinary buy through the official router at or above the decayed price re-crowns him, forfeiting the reign's provisional income and restarting the five-minute vesting clock; the same "}],"hash":"12558f1f2edb6d8e902760ad85ebe5c08f4c34c0743c058d196e3e7b2aa7dc6e","nodeId":"26c98322-8d1c-4ae4-9fe0-dadb130270cb","outcome":"completed","summary":"The review is complete and written to `.imd-findings.json`. No files in the repository were changed.\n\n**Outcome.** The permission model holds. I found no critical, high or medium defect in the Access Control, Trust Gap or Asymmetry areas. Two lower-severity items are reported, both reproduced with scratch Foundry tests on this tree and then removed.\n\n**What I checked.** Every state-changing entry point the verifier listed, traced from caller through guards to state change and failure path:\n\n- Hook callbacks all require the PoolManager, refuse to run during a payout, and bind to the one initialized pool. The fee minted as an ERC-6909 claim equals the delta v4 accounts after `afterSwap` returns in all four swap shapes.\n- Buyer identity is trusted only when the sender is the immutable router, which always writes `msg.sender` and delivers output to it. Foreign 64-byte must-take data reverts rather than silently charging.\n- The hook's `unlockCallback` is reachable only from its own payout: it needs the PoolManager as caller plus the hook's own transient guard, and a nested unlock reverts.\n- `claim()` pays only the caller's zeroed credit. `dethrone()` and the holding checks run before accrual, so unverified income stays in the pool while vested credits survive.\n- The router pulls tokens only from `msg.sender` after the authenticated `prepareSell` checkpoint, refunds only the order's own residue, and cannot be fed an order by a third party.\n- The token is unmodified OpenZeppelin ERC-20 with no admin surface.\n- `beforeInitialize` accepts exactly the policy fee 12500 and returns the correct selector.\n- The full non-fork suite passes on this tree (152 tests).\n\n**Findings.**\n\n1. **Low.** Anyone can initialize a hookless KING/ETH pool on the same PoolManager. Trades there pay no hook fee, and a king can sell his whole takeover position there without being dethroned until someone calls `dethrone()`. This follows from the requested plain-token design, but the site's \"Every buy and sell pays an ETH hook fee\" wording overstates it.\n2. **Info.** A sitting king's ordinary official-router buy at or above the decayed price re-crowns him, forfeiting provisional income and restarting the five-minute vesting clock, while the same buy through another router does nothing. The README documents this. The trade page gives a connected king no warning.\n\n**Coverage.** All 15 entry points have rows (13 hold, 2 reference finding 2, `beforeSwap` references finding 1 as a scope limit), plus three invariant rows. Not reached: the Base fork tests (excluded, offline), and the web app beyond its contract-call paths and disclosures.","treeHash":null,"usage":{"cachedInputTokens":2743609,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":45662,"runtime":"claude","turns":41,"wallClockMs":685874}},{"artifacts":[],"attempt":1,"bundleHash":"b6c410f6346e90faa97f6ac06942ccac699924218b17ce1c66ccaa84473e73be","device":"868942acc8b75a51","findings":[],"hash":"2e322b477bf8b7bfcb9515ce6d67623c15121c1b25cdb8e5459135699eafce8a","nodeId":"85dac5da-ee1c-4b4e-823f-88bdfc9a77c4","outcome":"completed","summary":"Updated only [launch.json](/home/worker/.identitymd-6/work/0d76ba8d-53ca-4516-955a-de72bc596ae9/85dac5da-ee1c-4b4e-823f-88bdfc9a77c4/launch.json).\n\n- Validated the supplied schema, constructor arguments, permissions, fee `12500`, and initial price.\n- Notes describe the frontend and pending deployment/publication.\n- `forge build` passed with existing warnings.\n- `forge test`: **158 passed, 0 failed, 0 skipped**.","treeHash":"d761ebae533ded19502c7203aed1b4f2f413fe97","usage":{"cachedInputTokens":626176,"inputTokens":72598,"model":"gpt-6-astra","outputTokens":4536,"runtime":"codex","turns":4,"wallClockMs":148421}},{"artifacts":[],"attempt":1,"bundleHash":"0d0209a4605bbffb1147576def6227227175a023e597935d61c9681d39353381","device":"43ece644a892418a","findings":[],"hash":"406ce00475fa08b20dc370032433fc7494bc9f5e3e6c4b930d7c687288b6dfe1","nodeId":"576fc819-94a4-4d4b-926f-9818d889a8b9","outcome":"completed","summary":"Implemented the `12500` pool-fee policy change, preserved the reviewed game logic, and built the frontend in `web/dist/`.\n\nValidation passed: `forge build`, all **158 Solidity tests**, `forge fmt --check`, and frontend unit, integration, and browser checks.\n\n**Deployment and publication remain incomplete:** no deployment signer or IPFS/IMD publishing credentials were available. The website explicitly shows “awaiting deployment.” Remaining steps are documented in [REDEPLOYMENT.md](/home/imd/.identitymd-1662/work/0d76ba8d-53ca-4516-955a-de72bc596ae9/576fc819-94a4-4d4b-926f-9818d889a8b9/docs/REDEPLOYMENT.md).","treeHash":"50f6396291dae6aff988bc8f01b3058218a6dced","usage":{"cachedInputTokens":5050112,"inputTokens":187125,"model":"gpt-6-astra","outputTokens":45599,"runtime":"codex","turns":9,"wallClockMs":1379116}},{"artifacts":[],"attempt":1,"bundleHash":"5dd341d118da6e53331ac0c6d977109078fb99d0e986be4e90a5de46aa7df865","device":"8687b633e8d497b9","findings":[{"description":"buyExactOut promises exactly kingOut tokens but only derives the ETH input from the returned delta; it never checks delta.amount1() against kingOut. Uniswap v4 may partially fill at the price limit when active KING liquidity is exhausted. The hook permits that outcome for exact-output buys, so the router settles and charges for a smaller trade, refunds unused ETH, and returns success. This bypasses the output guarantee of the exact-output entry point. There is no claim of theft of the unused ETH or immediate exhaustion of the original broad launch position; the reproduced state uses finite replacement liquidity. Check the actual token output and revert an incomplete exact-output order atomically.","line":88,"path":"src/KingRouter.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {KingHook} from \"src/KingHook.sol\";\nimport {KingToken} from \"src/KingToken.sol\";\nimport {KingRouter} from \"src/KingRouter.sol\";\nimport {HookFlags} from \"src/HookFlags.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {IHooks} from \"v4-core/src/interfaces/IHooks.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {ModifyLiquidityParams} from \"v4-core/src/types/PoolOperation.sol\";\nimport {PoolModifyLiquidityTest} from \"v4-core/src/test/PoolModifyLiquidityTest.sol\";\n\ncontract ExactOutputProof is Test {\n    receive() external payable {}\n\n    function test_exactOutputBuyMustFillOrRevert() public {\n        vm.warp(1_800_000_000);\n        PoolManager manager = new PoolManager(address(this));\n        KingToken token = new KingToken();\n        bytes memory code = abi.encodePacked(type(KingHook).creationCode,\n            abi.encode(IPoolManager(address(manager)), address(token)));\n        (, bytes32 salt) = HookFlags.mine(address(this), HookFlags.KING_HOOK_FLAGS, code, 500_000);\n        KingHook hook = new KingHook{salt: salt}(IPoolManager(address(manager)), address(token));\n        KingRouter router = hook.router();\n        PoolKey memory key = PoolKey(Currency.wrap(address(0)), Currency.wrap(address(token)),\n            12_500, 60, IHooks(address(hook)));\n        manager.initialize(key, 792281625142643375935439503360000);\n        PoolModifyLiquidityTest lp = new PoolModifyLiquidityTest(IPoolManager(address(manager)));\n        token.approve(address(lp), type(uint256).max);\n        // Legal token-only position at the launch price. This state can also be reached after\n        // withdrawing the launch position and replacing it with a finite range.\n        lp.modifyLiquidity(key, ModifyLiquidityParams(184140, 184200, 1e18, bytes32(0)), \"\");\n        assertGt(token.balanceOf(address(manager)), 0);\n        assertLt(token.balanceOf(address(manager)), 1000 ether);\n        address buyer = address(0xB0B);\n        vm.deal(buyer, 1 ether);\n        vm.prank(buyer);\n        (bool ok,) = address(router).call{value: 1 ether}(\n            abi.encodeCall(router.buyExactOut, (1000 ether, false, block.timestamp))\n        );\n        // Either permitted fix works: fill the requested amount, or reject an incomplete swap.\n        // Never accept partial output as a successful exact-output order.\n        if (ok) assertEq(token.balanceOf(buyer), 1000 ether, \"successful exact-output order underfilled\");\n        else {\n            assertEq(token.balanceOf(buyer), 0);\n            assertEq(buyer.balance, 1 ether);\n        }\n    }\n}","reproduction":"Run the proof as test/scratch/ExactOutputProof.t.sol with forge test --match-path test/scratch/ExactOutputProof.t.sol -vv. Deploy the real PoolManager, KING and mined hook; initialize native ETH/KING at fee 12500, tick spacing 60 and sqrtPriceX96 792281625142643375935439503360000. Seed token-only liquidity 1e18 in ticks [184140, 184200]. Call buyExactOut(1000 ether, false, block.timestamp) with 1 ether. Expected: receive exactly 1000 KING or revert without changing balances. Actual: the call succeeds and delivers 29929571122926013069 token units (29.929571122926013069 KING), causing the proof assertion to fail. The proof accepts either full delivery or atomic rejection, so it passes once the output guarantee is enforced.","severity":"medium","title":"Exact-output buys succeed without delivering the requested KING amount"}],"hash":"41a6e587d6f988b39b449f5b08906916b1e26d05919d158eda1989782c32def5","nodeId":"29e9e509-f303-45fb-9d0e-63778a05c1b0","outcome":"completed","summary":"Added failure-path tests and liquidity/accounting invariants.\n\n- `forge build` succeeded.\n- All 169 tests passed; no failures or skips.\n- New invariant exercised 16,384 actions without reverts.\n- Reported a medium-severity exact-output underfill defect, with a reproduced failing proof, in [.imd-findings.json](.imd-findings.json).\n\nContracts and configuration remain unchanged. Deployment and publishing were outside this tests-only assignment.","treeHash":"c16314d85c41d0f88cc2e2a1ab309c458f47108f","usage":{"cachedInputTokens":3262336,"inputTokens":135938,"model":"gpt-6-astra","outputTokens":16168,"runtime":"codex","turns":8,"wallClockMs":564443}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"e12f98dda6acc55f","findings":[{"citation":"resolved","description":"The job requires the contracts deployed on Robinhood Chain and the static build in web/dist pinned to IPFS and served at a public imd.fun URL. The delivered build carries status \"awaiting-deployment\" with hook/token/router/poolManager all null. web/src/core.js validateConfig() returns false for that status, and web/src/app.js init() then shows the deployment notice, sets read-status to AWAITING DEPLOYMENT and disables Connect/Refresh, so the Throne, Trade and Claim/Dethrone pages cannot read or act on anything. docs/REDEPLOYMENT.md states no transaction was broadcast and no site was published because the workspace had no signer, pinning account or publisher. This is a delivery/service gap rather than a contract defect; the contracts, manifest and tests are consistent with the fee-policy change (pool.fee 12500, beforeInitialize accepts only 12500, 158 tests pass including the Base fork rehearsals). The remaining steps are the deployer's: run the factory flow on chain 4663, bind the attested addresses with web/scripts/configure.mjs, build with --release, pin web/dist and publish.","line":2,"path":"web/dist/imd-deployment.json","reproduction":"State: web/dist/imd-deployment.json as committed (status awaiting-deployment, hook/token/router/poolManager null). Action: serve web/dist and open index.html. Expected per the brief: a usable site reading live Robinhood contracts with buy/sell/claim/dethrone enabled. Actual: read-status shows 'AWAITING DEPLOYMENT', the deployment notice is visible, Connect and Refresh are disabled, every action button stays disabled; addresses render as 'Awaiting deployment'. No public URL or IPFS CID exists in the repository.","severity":"low","snippet":"  \"status\": \"awaiting-deployment\",","title":"Website deliverable is shipped in awaiting-deployment state: no Robinhood deployment, no IPFS pin, no public URL; all wallet actions are disabled"}],"hash":"5940144f236dc4667f9cca7f6a6601da2299c66425282b9826067a85c9551977","nodeId":"6ecb72ef-c2c7-4926-8af3-ae6fe8aa481f","outcome":"completed","summary":"Review complete. `.imd-findings.json` is written (valid JSON, snippet verified against the tree); the scratch directory is removed and no tracked file was changed.\n\n## Summary\n\n**Area:** Execution Trace, Periphery, First Principles (Pashov guides), applied to `KingHook`, `KingRouter`, `KingToken`, `Halving`, `HookFlags`, the manifest and the web client.\n\n**Result in the contracts: no substantiated defect.** What I traced:\n\n- **All four swap modes** end-to-end through v4-core's `Hooks.beforeSwap`/`afterSwap`: the fee lands on the correct side (specified delta for ETH-specified swaps, unspecified for the others), sign and placement match `toBalanceDelta`, and the ERC-6909 mint exactly offsets the hook delta. The fee computed in `beforeSwap` and `afterSwap` is identical (same params, same timestamp), so `HookDeltaExceedsSwapAmount` and the `PartialFill` guards are unreachable on full fills.\n- **Reign state machine:** every `_endReign`/`_startReign` transition keeps `king`, `reignStart`, `requiredBalance`, `priceBase`, `provisionalIncome` coupled; holding checks always run *before* accrual so an unverified interval is never credited; `provisionalIncome` is provably zero whenever the throne is empty.\n- **Reentrancy surfaces:** the ETH `take` callbacks (claim payout, router refund/payout). Probed with scratch tests: a nested direct `poolManager.swap` from inside a router sell keeps claims == pool + provisional + pending; a contract buyer calling `dethrone()` from the refund callback can only end its own fresh reign (equivalent to a sequential sell + rebuy; the prior king's vested income is intact) — self-harm, no victim, so not reported.\n- **Periphery:** all 64 `Halving` Q64 constants verified numerically; overflow bounds hold; `HookFlags` bit positions and CREATE2 buffer offsets are correct; the manifest's constructor args, permissions, fee tier, initial price and notes length (3,755 / 4,000) are consistent with the code.\n- **Tests:** 158 pass, including the Base fork rehearsals; the fee-policy change is covered (12500 accepted; 500/3000/10000, 0 and the dynamic flag rejected).\n\n**One finding (low):** the website deliverable ships in `awaiting-deployment` state — `web/dist/imd-deployment.json` has null addresses, so the app disables every action and nothing is pinned or published. The docs state why (no signer, pinning account or publisher in the workspace); this is a service gap for the deployer, not a code defect.\n\n**Coverage:** all 15 listed entry points answered `holds` with reasons, plus rows for the conservation invariant, reign-state coupling, periphery libraries, manifest and the web client (the latter linked to the finding).","treeHash":null,"usage":{"cachedInputTokens":3668462,"inputTokens":59,"model":"claude-fable-5-1","outputTokens":60549,"runtime":"claude","turns":31,"wallClockMs":889944}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"6b37e4ab65246705","findings":[{"citation":"resolved","description":"Seam: precision x boundary. `Halving.decay` applies one floored Q64 multiplication per set bit of the fractional exponent, so every call can lose up to one wei per set bit (about 30 set bits for a one-second exponent) plus a relative 2^-64 per constant. The hook books income lazily in `_accrue()` on every swap, `prepareSell` and successful `claim()`, and each booking is a separate `decay` call, so the error is per booking and always in the king's favour (`pool` is rounded down, `earned = pool - remaining` up). The library comment documents the bound (`128 * value / 2^64 + 65`) and the README says income is path-independent \"up to fixed-point rounding\", so this is a documented property, not a broken guarantee. Concrete numbers: a pool of 100 wei after one second returns 75 (true value 99.9994); a pool of 1e9 wei booked once per second for an hour leaves 979,925,003 wei versus 979,999,978 booked once (75k wei, 7.5e-5 relative, after 3600 bookings). At a 100 ETH pool the per-booking error is about 760 wei; forcing a booking needs a successful swap or claim, whose gas exceeds the gain by many orders of magnitude, so it cannot be farmed. Verified with a scratch Foundry probe (removed) and `test/KingHook.Fuzz.t.sol::testFuzz_incomeIsPathIndependent`. Reported for the record only; no fix required. Minor note: the comment in `test/Halving.t.sol` lines 51-52 still says \"the documented bound is 64 wei\", which is stale relative to the library's corrected comment.","line":660,"path":"src/KingHook.sol","reproduction":"Pure library call: Halving.decay(100, 29146345660, 3600e12) returns 75 (expected ~99 or 100). Halving.decay(1, 29146345660, 3600e12) returns 0: a 1-wei pool is fully paid to the king after one second. In the hook: fund the pool so that `pool` is tiny (not reachable below ~1e5 wei in practice because every fee-bearing swap adds >= 36 wei), take the throne, then trigger `_accrue()` once per second via dust buys; after 3600 bookings the king has earned ~7.5e-5 of the pool more than a single booking would pay. Expected: identical up to a few wei; actual: ~75k wei on a 1e9 wei pool. Non-material.","severity":"info","snippet":"        return Halving.decay(pool, elapsed * INCOME_LOG2_PER_HOUR, INCOME_DEN);","title":"Per-accrual floor rounding in Halving.decay over-pays the king by up to ~65 wei plus 128*pool/2^64 per booking; immaterial at any realistic pool but not path-independent in absolute terms"}],"hash":"68d041e139638b034d7a1a1874c4494f329586dbfb0bce50a9864d6b027f69af","nodeId":"cbfbb95b-44ff-42cd-8106-308f0c7438e4","outcome":"completed","summary":"The review is complete. The findings file is written, validated, and the working tree is clean apart from it.\n\n**Outcome: no exploitable math defect found.** The KING hook's arithmetic holds against the Math Precision, Boundary and Numerical Gap checklists. One info-level observation is recorded.\n\n**What was checked**\n\n- Fee math on all four swap modes, traced through v4-core's `Hooks.beforeSwap`/`afterSwap` delta plumbing. The hook's owed delta equals the claim it mints in every mode, and the fee tracks the rate of gross ETH within one wei. Partial-fill checks are exact because the pool consumes exactly `amount - fee` or pays exactly `out + fee` on a full fill.\n- Throne price curve. All 64 Q64 constants in `Halving.sol` equal the exact floors (verified with Python Decimal). Price is an exact shift at whole hours and never rises across consecutive seconds for bases from 0.01 to 1000 ETH.\n- Income curve. The constant 29146345660 is the correct rounding of log2(1/0.98)·1e12. Bucket moves between pool, provisional, pending and claims are exact integer transfers, so the conservation invariant has no rounding seam.\n- Boundary cases: zero and dust inputs, uint64 timestamp and int128 casts, sentinel `king == 0` paths, `abi.decode` of foreign hookData, payable branches in the router, the vesting `>=` boundary, and loop bounds in `nextHalvingTime`.\n- The full suite of 152 tests passes. Six web unit tests pass. Scratch probes confirmed the exact-output fee consistency and the must-take exact-output boundary, then were removed.\n\n**The one recorded item (info)**\n\n`Halving.decay` floors once per set bit of the fractional exponent, so each income booking over-pays the king by up to about 65 wei plus a 2^-64 relative term. A 100 wei pool returns 75 after one second. A 1e9 wei pool booked every second for an hour drifts 75k wei from a single booking. This is documented in the library comment and cannot be farmed since every booking costs a transaction, so it is non-material. The comment in `test/Halving.t.sol` still cites the old 64 wei bound.\n\n**Coverage**: all 15 listed entry points have rows (14 hold, the income invariant row points at the info finding), plus five invariant rows. Nothing was left unreached.","treeHash":null,"usage":{"cachedInputTokens":1853001,"inputTokens":418,"model":"claude-fable-5-1","outputTokens":43628,"runtime":"claude","turns":35,"wallClockMs":633920}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"ef5038c1bdac3372","findings":[{"citation":"resolved","description":"Merged from the independent tester's finding (medium there). buyExactOut promises exactly kingOut KING but never compares delta.amount1() with kingOut, and KingHook._afterBuy's exact-output branch (src/KingHook.sol:248-254) charges the fee on the settled ETH without the PartialFill check the hook applies to the two ETH-specified cases. When the pool's KING liquidity below the price limit is smaller than kingOut, Uniswap v4 stops at the limit, the hook accepts it, the router settles the smaller trade, refunds the unused ETH and returns success. Recalibrated to low: the buyer pays only for what was delivered (fee proportional, surplus refunded), mustTake still compares the actual gross ETH to the throne price, and the state is not reachable while the factory's launch position is in place (draining 900,000,000 KING down to tick -887220 needs an ETH amount above int128, so such a swap reverts in v4 itself). It is reachable once the launch position is withdrawn or replaced by a finite range, and it breaks the documented 'buys exactly kingOut' guarantee and the README statement that only non-ETH-specified swaps partially fill. Fix: in buyExactOut require uint256(uint128(delta.amount1())) == kingOut (or revert PartialFill in _afterBuy when _abs(delta.amount1()) < _abs(params.amountSpecified)).","line":88,"path":"src/KingRouter.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\nimport {Test} from \"forge-std/Test.sol\";\nimport {KingHook} from \"src/KingHook.sol\";\nimport {KingToken} from \"src/KingToken.sol\";\nimport {KingRouter} from \"src/KingRouter.sol\";\nimport {HookFlags} from \"src/HookFlags.sol\";\nimport {PoolManager} from \"v4-core/src/PoolManager.sol\";\nimport {IPoolManager} from \"v4-core/src/interfaces/IPoolManager.sol\";\nimport {IHooks} from \"v4-core/src/interfaces/IHooks.sol\";\nimport {PoolKey} from \"v4-core/src/types/PoolKey.sol\";\nimport {Currency} from \"v4-core/src/types/Currency.sol\";\nimport {ModifyLiquidityParams} from \"v4-core/src/types/PoolOperation.sol\";\nimport {PoolModifyLiquidityTest} from \"v4-core/src/test/PoolModifyLiquidityTest.sol\";\n\ncontract ExactOutputProof is Test {\n    receive() external payable {}\n\n    function test_exactOutputBuyMustFillOrRevert() public {\n        vm.warp(1_800_000_000);\n        PoolManager manager = new PoolManager(address(this));\n        KingToken token = new KingToken();\n        bytes memory code = abi.encodePacked(type(KingHook).creationCode,\n            abi.encode(IPoolManager(address(manager)), address(token)));\n        (, bytes32 salt) = HookFlags.mine(address(this), HookFlags.KING_HOOK_FLAGS, code, 500_000);\n        KingHook hook = new KingHook{salt: salt}(IPoolManager(address(manager)), address(token));\n        KingRouter router = hook.router();\n        PoolKey memory key = PoolKey(Currency.wrap(address(0)), Currency.wrap(address(token)),\n            12_500, 60, IHooks(address(hook)));\n        manager.initialize(key, 792281625142643375935439503360000);\n        PoolModifyLiquidityTest lp = new PoolModifyLiquidityTest(IPoolManager(address(manager)));\n        token.approve(address(lp), type(uint256).max);\n        // Legal token-only position at the launch price. This state can also be reached after\n        // withdrawing the launch position and replacing it with a finite range.\n        lp.modifyLiquidity(key, ModifyLiquidityParams(184140, 184200, 1e18, bytes32(0)), \"\");\n        assertGt(token.balanceOf(address(manager)), 0);\n        assertLt(token.balanceOf(address(manager)), 1000 ether);\n        address buyer = address(0xB0B);\n        vm.deal(buyer, 1 ether);\n        vm.prank(buyer);\n        (bool ok,) = address(router).call{value: 1 ether}(\n            abi.encodeCall(router.buyExactOut, (1000 ether, false, block.timestamp))\n        );\n        // Either permitted fix works: fill the requested amount, or reject an incomplete swap.\n        // Never accept partial output as a successful exact-output order.\n        if (ok) assertEq(token.balanceOf(buyer), 1000 ether, \"successful exact-output order underfilled\");\n        else {\n            assertEq(token.balanceOf(buyer), 0);\n            assertEq(buyer.balance, 1 ether);\n        }\n    }\n}","reproduction":"test/scratch/ExactOutputProof.t.sol (the tester's proof, run on this tree): fresh PoolManager, KingToken, mined KingHook; initialize ETH/KING at fee 12500, tick spacing 60, sqrtPriceX96 792281625142643375935439503360000; add token-only liquidity 1e18 in ticks [184140,184200]; buyer calls router.buyExactOut{value: 1 ether}(1000 ether, false, block.timestamp). Expected: receive exactly 1000 KING or revert leaving balances unchanged. Actual: the call succeeds and the buyer holds 29929571122926013069 wei of KING (29.93 KING); forge reports 'successful exact-output order underfilled: 29929571122926013069 != 1000000000000000000000'.","severity":"low","snippet":"        ethIn = uint256(uint128(-delta.amount0()));","title":"Exact-output buys through KingRouter can partially fill and still succeed, delivering less KING than requested"},{"citation":"resolved","description":"From the permissions specialist, reproduced. KingToken is a plain ERC-20 and PoolManager.initialize is permissionless, so anyone can initialize a second ETH/KING pool with hooks = address(0) and seed it. Trades there pay no hook fee and are never observed by the throne game. A sitting king can sell his whole takeover position on that pool: pool(), the hook's ERC-6909 claims and king() do not change until a later swap on the official pool, a claim() or an explicit dethrone() notices the shortfall. This is a limitation of the requested plain-token design rather than a code defect (the README documents third-party routers but not hookless pools), and the published site's rules panel (web/dist/index.html:52) says 'Every buy and sell pays an ETH hook fee', which is only true of the official pool. Fix: state in the README and on the site that the fee and the game apply to the official KING/ETH pool only; a code change would require restricting the token, which the brief forbids.","line":201,"path":"src/KingHook.sol","reproduction":"test/scratch/JudgeProbes.t.sol::test_hooklessPoolBypass on this tree (passes = bypass works): on the launch fixture, manager.initialize(PoolKey(ETH, KING, 3000, 60, IHooks(address(0))), 792281625142643375935439503360000) succeeds; two-sided liquidity 1e20 in ticks [178200,190200] is added with 2 ETH; after gameStart Alice buyExactIn{value: 1 ether}(0, true, now) becomes king with requiredBalance R; Alice swaps exact-input -R KING on the hookless pool via v4-core PoolSwapTest with empty hookData. Expected per brief: a 2.5% ETH fee is paid and/or the king is removed. Actual: hook.pool() and manager.balanceOf(hook, 0) unchanged, token.balanceOf(alice) < R, hook.king() == alice, still alice one hour later; only hook.dethrone() clears her.","severity":"low","snippet":"        if (PoolId.unwrap(key.toId()) != PoolId.unwrap(_poolId)) revert WrongPool();","title":"Hook fee and holding rule apply only to the official pool: a hookless KING/ETH pool on the same PoolManager trades fee-free and lets the king exit unobserved"},{"citation":"resolved","description":"From the flow specialist, reproduced. The job requires the contracts deployed on Robinhood Chain (4663) and web/dist pinned to IPFS and served at a public imd.fun URL. The committed build has status awaiting-deployment with hook/token/router/poolManager null; web/src/core.js validateConfig returns false for it and web/src/app.js init() then shows the deployment notice, sets the read status to AWAITING DEPLOYMENT and disables Connect and Refresh, so no page can read or act on anything. docs/REDEPLOYMENT.md states no transaction was broadcast and no site was published because the workspace had no signer, pinning account or publisher. The contracts, manifest (pool.fee 12500, notes 3879 chars) and tests are consistent with the fee-policy change and the suite passes (163 tests plus 6 Base fork rehearsals here), so this is a service gap, not a code defect: the deployer must run the factory flow on chain 4663, bind the attested addresses with web/scripts/configure.mjs, build with --release, pin web/dist and publish, then record CID and URL.","line":2,"path":"web/dist/imd-deployment.json","reproduction":"Serve web/dist and open index.html with web/dist/imd-deployment.json as committed. Expected per the brief: a usable site reading live Robinhood contracts with buy/sell/claim/dethrone enabled at a public URL. Actual: read-status shows 'AWAITING DEPLOYMENT', the deployment notice is visible, Connect/Refresh and every action button stay disabled, addresses render as 'Awaiting deployment'; no CID, site id or public URL exists anywhere in the repository (web/dist/build.json: deploymentStatus awaiting-deployment).","severity":"low","snippet":"  \"status\": \"awaiting-deployment\",","title":"Website shipped in awaiting-deployment state: no Robinhood deployment, no IPFS pin, no public URL; all wallet actions disabled"},{"citation":"resolved","description":"New. In unlockCallback the buy branch settles address(this).balance and takes available - ethIn back to order.user. For buyExactIn, ethIn equals msg.value, so normally nothing is refunded and a buyer contract needs no receive(). The router has no receive(), but ETH can still be forced in with selfdestruct from a contract created in the same transaction (EIP-6780 still transfers the balance). After that, every buyExactIn carries a refund of the forced wei to the buyer; a contract wallet that cannot accept native ETH then reverts with NativeTransferFailed inside PoolManager.take, until the next EOA buyer receives the wei. Griefing only, self-healing, no loss of funds, and most smart wallets accept ETH, hence low. Fix: compute the refund from the order's own value (carry msg.value in Order and use it instead of address(this).balance), as the README already does for KING: 'Unsolicited token deposits cannot be swept by later callers'.","line":148,"path":"src/KingRouter.sol","reproduction":"test/scratch/JudgeProbes.t.sol::test_forcedEthBreaksContractWalletExactInBuy on this tree: a NoReceive contract calls router.buyExactIn{value: 0.1 ether}(0, false, now) successfully; then new Destructor{value: 1 wei}(router) (selfdestruct in constructor) leaves address(router).balance == 1; the same NoReceive buy now reverts. Expected: an exact-input buy never refunds, so it succeeds regardless of the router's stray balance. Actual: revert; a following EOA buy by Alice ends with alice.balance == before - 0.1 ether + 1 wei and router balance 0, after which the contract wallet's buy works again.","severity":"low","snippet":"            uint256 available = address(this).balance;","title":"KingRouter refunds its whole ETH balance, so one wei force-sent to the router makes exact-input buys from contract wallets without receive() revert until an EOA buys"},{"citation":"resolved","description":"From the permissions specialist, reproduced. _onBuy does not distinguish a rival from the sitting king: any router buy with ethGross >= currentThronePrice() and mustTake == false ends the running reign (returning provisional income to the pool when the reign is under five minutes) and starts a new one with a fresh vesting clock. Because the price halves hourly, a king adding to his position through the official router a few hours into a reign usually crosses the price involuntarily. The same purchase through a third-party router leaves the reign untouched. This is the design documented in README 'Same king again' and accepted in launch 814, so informational; the trade page (web/dist/index.html:44) shows the price and the must-take toggle but never tells a connected wallet that is king that a buy at or above the price restarts his reign (only the claim page's general sentence covers self-retakes). Fix is wording/UI.","line":581,"path":"src/KingHook.sol","reproduction":"test/scratch/JudgeProbes.t.sol::test_selfRetakeAsymmetry on this tree: after gameStart Alice buyExactIn{value: 1 ether}(0,false,now) is king (reignCount 1); warp +3 min; Bob's 0.01 ETH buy accrues provisionalIncome P > 0; price is 1159123594709814644 wei; Alice buyExactIn{value: 1.5 ether}(0,false,now). Expected by a user adding to a position: king and reign unchanged. Actual: reignCount 1 -> 2, provisionalIncome == 0, getReign(0).forfeited == P, unclaimedIncome(alice) == 0.","severity":"info","snippet":"        if (king != address(0)) _endReign(EndReason.Dethroned, 0);","title":"A sitting king's ordinary buy at or above the decayed price through the official router re-crowns him, forfeiting provisional income and restarting vesting; the trade page does not warn"},{"citation":"resolved","description":"From the economics specialist, reproduced. Holdings are checked only at observation points (beforeSwap, prepareSell, claim, dethrone) and _accrue() credits the whole interval since lastAccrual whenever the balance is sufficient at the observation. A king who parks his KING elsewhere and restores it before anyone observes earns on the interval while not holding. Anyone may call dethrone() during the window, which is the intended defence; launch.json notes and the README state that transfers out and restoration between observations are undetectable with a plain ERC-20. Not a code defect; recorded so the measured size is on file. The gain is bounded by 2%/hour of the pool and is what an honest king would have earned, so nobody else loses funds they were owed.","line":603,"path":"src/KingHook.sol","reproduction":"test/scratch/JudgeProbes.t.sol::test_holdingObservationGap on this tree: game open, Carol's 400 ETH third-party buy funds the pool, Bob takes the throne with buyExactIn{value: 1 ether}(0,true,now); warp +1h, Bob claim(); Bob transfers his entire KING balance to Alice (no observation); warp +1h; Alice transfers it back; Bob claim(). Expected under a strict reading of the brief: the second hour's income forfeited. Actual: hook.king() == bob and kingReignEarnings() grew by 180770800002908110 wei (about 0.18 ETH) for the hour he held nothing; any dethrone() call during that hour would have ended the reign with that interval forfeited.","severity":"info","snippet":"        return king != address(0) && token.balanceOf(king) < requiredBalance;","title":"Holding rule is observation-based: a king who moves KING out and back between observations keeps the income for that interval (documented limitation)"},{"citation":"resolved","description":"From the math specialist, reproduced. Each decay call applies one floored Q64 multiplication per set bit of the fractional exponent, so every booking (each swap, prepareSell and successful claim) can lose up to about 65 wei plus 128*pool/2^64 of the remaining pool, always in the king's favour. The library comment documents the bound and the README says income is path-independent 'up to fixed-point rounding'. At a 100 ETH pool the per-booking error is about 760 wei and forcing a booking costs a swap or claim, so it cannot be farmed. No fix required; test/Halving.t.sol lines 51-52 still mention a stale '64 wei' bound.","line":30,"path":"src/libraries/Halving.sol","reproduction":"test/scratch/JudgeProbes.t.sol::test_halvingNumbers on this tree: Halving.decay(100, 29146345660, 3600e12) returns 75 (true value 99.9994) and Halving.decay(1, 29146345660, 3600e12) returns 0, i.e. a 1-wei pool is fully paid after one second. Expected: within a wei or two of the true value; actual: 25 wei low on a 100-wei pool. Immaterial at any realistic pool size.","severity":"info","snippet":"        uint256 frac = (rem << 64) / den;","title":"Per-booking floor rounding in Halving.decay slightly favours the king and makes income path-dependent by a few wei per booking"}],"hash":"eec618657fe5c9a173f24b72c7407e19dde9369bfca71d8c46b880f27cc7f7b8","nodeId":"e9031f3b-84f0-4e66-8781-7398baac2422","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written at the repository root. No source files were changed; my probes live only in the gitignored `test/scratch/` folder.\n\n**Outcome: no critical, high or medium defects.** The redeployment is a bounded, correct fee-policy change: `beforeInitialize` accepts exactly the policy tier 12500, the manifest matches `getHookPermissions` and the constructor, notes are under the 4000-character limit, and the full suite passes (163 tests, plus 6 Base fork rehearsals that also passed here with network). I traced all 15 verifier entry points plus two invariants and recorded a verdict for each.\n\n**Findings kept (7), each reproduced on this tree:**\n\n- **Low, exact-output buys partially fill and still succeed.** The tester's proof fails as described (29.93 KING delivered for a 1000 KING order). I lowered it from medium: the buyer pays only for what arrives, `mustTake` uses the real gross ETH, and the state is unreachable while the factory's full-range position exists. Proof attached.\n- **Low, hookless KING/ETH pool bypasses the fee and the holding rule.** Confirmed with a scratch test. Design limitation of a plain token; the site's \"every buy and sell pays a hook fee\" wording needs qualifying.\n- **Low, website shipped awaiting deployment.** No Robinhood deployment, pin or public URL exists. This is the deployer's and publisher's step, not a code defect, so it is recorded as a service gap.\n- **Low, new: force-sent ETH on the router breaks exact-input buys from contract wallets without `receive()`.** The router refunds `address(this).balance - ethIn`, so one forced wei makes those buys revert until an EOA buy sweeps it. Self-healing griefing, no loss.\n- **Three info items** confirmed from the specialists: self-retake restarts the reign with no trade-page warning, the observation-based holding rule, and per-booking `Halving` rounding in the king's favour.\n\n**Dropped or merged:** none dropped, since every specialist item reproduced. The tester's medium was recalibrated rather than removed. The slither and aderyn lines were all checked and none rose to a finding. The aderyn \"locks Ether\" line led to the forced-ETH finding above.","treeHash":null,"usage":{"cachedInputTokens":1610141,"inputTokens":354,"model":"claude-fable-5-1","outputTokens":46298,"runtime":"claude","turns":28,"wallClockMs":660358}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"c2e167266d13dcf4","findings":[{"citation":"resolved","description":"Not a code defect: launch.json notes and README state that transfers out and restoration between observations are undetectable, because a plain ERC-20 cannot report when a balance fell. Recorded here so the judge has the measured economic size. The holding rule is only checked at observation points (beforeSwap, prepareSell, claim, dethrone). _accrue() credits the whole interval since lastAccrual to the king whenever the balance is sufficient at the observation, so a king who lends or parks his KING elsewhere and restores it before anyone observes (including inside one transaction) earns on the interval while not holding. Anyone can call dethrone() during the window, which is the intended defence; within a single block there is no window. Economic value: with a 92 ETH throne pool the probe measured 0.0455 ETH credited for one hour of not holding; the attacker's cost is zero beyond gas, but the gain is bounded by 2%/hour of the pool and is exactly what an honest king would have earned, so no other party loses funds they were owed.","line":602,"path":"src/KingHook.sol","reproduction":"State: game open, throne pool ~92 ETH (funded by a 4000 ETH third-party buy), Bob takes the throne with buyExactIn{value:1 ether}(0,true,deadline) and requiredBalance R. After 1 hour Bob calls claim() (lastAccrual = now). Bob transfers his whole KING balance to Alice (no observation), waits 1 hour, Alice transfers it back, Bob calls claim(). Expected under a strict reading of the brief: income for the second hour is forfeited. Actual: Bob remains king and kingReignEarnings() grows by 45530800000732478 wei (~0.0455 ETH) for the hour he held nothing. If any third party had called dethrone() during that hour, the reign would have ended with that interval forfeited, as documented.","severity":"info","snippet":"    function _holdingShort() internal view returns (bool) {\n        return king != address(0) && token.balanceOf(king) < requiredBalance;\n    }","title":"Holding rule is observation-based: a king who moves KING out and back between observations keeps the income for that interval (documented limitation, quantified)"}],"hash":"ff61aafba230f12803dfb756f14ab8b7b128f74ac8e05ea3c198f07bc2fec765","nodeId":"8de94516-76b5-4e84-9a76-178c7e1ccc48","outcome":"completed","summary":"The review is complete and `.imd-findings.json` is written (valid JSON, snippet verified against `src/KingHook.sol:602-604`, scratch tests removed, working tree otherwise untouched).\n\n## Summary\n\n**Area:** Economic Security, Invariant, and Flow Gap guides from the Pashov reference, applied to `KingHook`, `KingRouter`, `KingToken`, and `Halving`.\n\n**Result: no reproducible defect in the economics.** The one entry in the file is `info`, not a defect:\n\n- **Observation-based holding rule, quantified.** A king who moves his KING out and restores it before any observation (swap, claim, dethrone) keeps the income for that interval — my probe measured ~0.0455 ETH per unobserved hour on a 92 ETH pool. This is explicitly documented in `launch.json` notes and the README as inherent to a plain ERC-20, `dethrone()` is the intended defence, and no other party loses funds they were owed. I recorded it so the judge has the measured size rather than a vague caveat.\n\n**What I verified with concrete values (and discarded as non-findings):**\n- Fee accounting in all four swap modes nets exactly to zero against the ERC-6909 mint; the token-only-launch pitfall (taking ETH the manager doesn't hold) is avoided by design.\n- Income rounding: 600 per-second accruals vs the closed form differ by wei-level dust — not farmable.\n- Atomic sell-then-buy from a custom router inside one unlock: the king ends short and the next observation ends the reign, forfeiting the unverified interval.\n- Self-retake, rival-takeover-before-vesting, and floor-price cycling all behave as the documented rules say; they're game design, not exploits.\n- View/write pairs (`unclaimedIncome`/`claim`, `poolSize`, `kingReignEarnings`) agree in the vested, unvested, and short-king cases.\n- The existing suites (152 tests, including conservation/invariant fuzzing) pass.\n\n**Coverage:** all 15 listed entry points marked `holds` with a one-line reason, plus three invariant rows and one honest `unreached` (no fork rehearsal against the Robinhood Chain PoolManager was possible here).","treeHash":null,"usage":{"cachedInputTokens":3295916,"inputTokens":53,"model":"claude-fable-5-1","outputTokens":59859,"runtime":"claude","turns":28,"wallClockMs":911006}}],"verification":[{"checks":[{"durationMs":11316,"exitCode":0,"name":"build","output":"Compiling 107 files with Solc 0.8.26\nSolc 0.8.26 finished in 10.88s\nCompiler run successful!\nwarning[missing-events-arithmetic]: `pool` is changed without an event but is used in arithmetic\n    ╭▸ src/KingHook.sol:671:9\n    │\n671 │         pool = remaining;\n    │         ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastAccrual` is changed without an event but is used in arithmetic\n    ╭▸ src/KingHook.sol:672:9\n    │\n672 │         lastAccrual = uint64(block.timestamp);\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/KingRouter.sol:57:13\n   │\n57 │         if (block.timestamp > deadline) revert Expired();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/KingRouter.sol:75:9\n   │\n75 │         emit Swapped(msg.sender, true, uint256(uint128(-delta.amount0())), kingOut);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:72:61\n   │\n72 │         BalanceDelta delta = _swap(Order(msg.sender, true, -int256(msg.value), mustTake));\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/KingRouter.sol:73:19\n   │\n73 │         kingOut = uint256(uint128(delta.amount1()));\n   │                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:73:27\n   │\n73 │         kingOut = uint256(uint128(delta.amount1()));\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/KingRouter.sol:75:40\n   │\n75 │         emit Swapped(msg.sender, true, uint256(uint128(-delta.amount0())), kingOut);\n   │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:75:48\n   │\n75 │         emit Swapped(msg.sender, true, uint256(uint128(-delta.amount0())), kingOut);\n   │                                                ━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/KingRouter.sol:89:9\n   │\n89 │         emit Swapped(msg.sender, true, ethIn, uint256(uint128(delta.amount1())));\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:87:60\n   │\n87 │         BalanceDelta delta = _swap(Order(msg.sender, true, int256(kingOut), mustTake));\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/KingRouter.sol:88:17\n   │\n88 │         ethIn = uint256(uint128(-delta.amount0()));\n   │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:88:25\n   │\n88 │         ethIn = uint256(uint128(-delta.amount0()));\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/KingRouter.sol:89:47\n   │\n89 │         emit Swapped(msg.sender, true, ethIn, uint256(uint128(delta.amount1())));\n   │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:89:55\n   │\n89 │         emit Swapped(msg.sender, true, ethIn, uint256(uint128(delta.amount1())));\n   │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/KingRouter.sol:108:9\n    │\n108 │         emit Swapped(msg.sender, false, ethOut, consumed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:102:62\n    │\n102 │         BalanceDelta delta = _swap(Order(msg.sender, false, -int256(kingIn), false));\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/KingRouter.sol:103:18\n    │\n103 │         ethOut = uint256(uint128(delta.amount0()));\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:103:26\n    │\n103 │         ethOut = uint256(uint128(delta.amount0()));\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/KingRouter.sol:105:28\n    │\n105 │         uint256 consumed = uint256(uint128(-delta.amount1()));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:105:36\n    │\n105 │         uint256 consumed = uint256(uint128(-delta.amount1()));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/KingRouter.sol:124:9\n    │\n124 │         emit Swapped(msg.sender, false, ethOut, kingIn);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:121:61\n    │\n121 │         BalanceDelta delta = _swap(Order(msg.sender, false, int256(ethOut), false));\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/KingRouter.sol:122:18\n    │\n122 │         kingIn = uint256(uint128(-delta.amount1()));\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:122:26\n    │\n122 │         kingIn = uint256(uint128(-delta.amount1()));\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/KingRouter.sol:147:29\n    │\n147 │             uint256 ethIn = uint256(uint128(-delta.amount0()));\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:147:37\n    │\n147 │             uint256 ethIn = uint256(uint128(-delta.amount0()));\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/KingRouter.sol:154:31\n    │\n154 │             uint256 kingOut = uint256(uint128(delta.amount1()));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:154:39\n    │\n154 │             uint256 kingOut = uint256(uint128(delta.amount1()));\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/KingRouter.sol:157:30\n    │\n157 │             uint256 kingIn = uint256(uint128(-delta.amount1()));\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:157:38\n    │\n157 │             uint256 kingIn = uint256(uint128(-delta.amount1()));\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/KingRouter.sol:164:30\n    │\n164 │             uint256 ethOut = uint256(uint128(delta.amount0()));\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:164:38\n    │\n164 │             uint256 ethOut = uint256(uint128(delta.amount0()));\n    │                                      ━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Halving.sol:25:62\n   │\n25 │         if (value >= 1 << 192 || den >= 1 << 192 || den < 1) revert HalvingOverflow();\n   │                                                              ━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:181:22\n    │\n181 │         launchTime = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:182:23\n    │\n182 │         lastAccrual = uint64(block.timestamp);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:185:39\n    │\n185 │         emit PoolLaunched(launchTime, uint64(block.timestamp + ANTI_SNIPE_DURATION));\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:415:29\n    │\n415 │         return launchTime + uint64(ANTI_SNIPE_DURATION);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe 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/KingHook.sol:420:31\n    │\n420 │         return initialized && block.timestamp >= gameStart();\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/KingHook.sol:429:13\n    │\n429 │         if (elapsed >= ANTI_SNIPE_DURATION) return FEE_BASE_PPM;\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/KingHook.sol:449:16\n    │\n449 │         while (next <= block.timestamp) {\n    │                ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/KingHook.sol:603:38\n    │\n603 │         return king != address(0) && token.balanceOf(king) < requiredBalance;\n    │                                      ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:608:22\n    │\n608 │         reignStart = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:609:23\n    │\n609 │         lastAccrual = uint64(block.timestamp);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:616:24\n    │\n616 │                 start: uint64(block.timestamp),\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:645:21\n    │\n645 │         reign.end = uint64(block.timestamp);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/KingHook.sol:658:35\n    │\n658 │         if (king == address(0) || block.timestamp <= lastAccrual) return pool;\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/KingHook.sol:665:35\n    │\n665 │         if (king == address(0) || block.timestamp <= lastAccrual) {\n    │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:666:27\n    │\n666 │             lastAccrual = uint64(block.timestamp);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:672:23\n    │\n672 │         lastAccrual = uint64(block.timestamp);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/KingHook.sol:689:16\n    │\n689 │         return block.timestamp - reignStart >= INCOME_VESTING;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:705:24\n    │\n705 │         return x < 0 ? uint256(-x) : uint256(x);\n    │                        ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:705:38\n    │\n705 │         return x < 0 ? uint256(-x) : uint256(x);\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    ‡\n177 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:234:9\n    │\n234 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:234:17\n    │\n234 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:311:17\n    │\n311 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:434:22\n    │\n434 │         uint256 t0 = block.timestamp;\n    │                      ━━━━━━━━━━━━━━━\n435 │         buyExactIn(alice, 1 ether, false);\n436 │         vm.warp(t0 + 1 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:436:9\n    │\n436 │         vm.warp(t0 + 1 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:440:9\n    │\n440 │         vm.warp(t0 + 2 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:443:9\n    │\n443 │         vm.warp(t0 + 3 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:463:9\n    │\n463 │         vm.warp(hook.gameStart() - 1);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:469:9\n    │\n469 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:497:9\n    │\n497 │         vm.warp(block.timestamp + 2 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:497:17\n    │\n497 │         vm.warp(block.timestamp + 2 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:502:17\n    │\n502 │         vm.warp(block.timestamp + 20 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fee.t.sol:44:9\n    │\n 44 │         vm.warp(launch + 15 minutes);\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fee.t.sol:49:9\n    │\n 49 │         vm.warp(launch + 1 hours);\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:63:9\n    │\n 63 │         vm.warp(hook.launchTime() + bound(elapsed, 0, 2 hours));\n    │         ─────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:85:9\n    │\n 85 │         vm.warp(hook.launchTime() + bound(elapsed, 0, 2 hours));\n    │         ─────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:131:9\n    │\n131 │         vm.warp(start + elapsed);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:130:25\n    │\n130 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n131 │         vm.warp(start + elapsed);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:163:9\n    │\n163 │         vm.warp(block.timestamp + elapsed);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:163:17\n    │\n163 │         vm.warp(block.timestamp + elapsed);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:249:9\n    │\n249 │         vm.warp(block.timestamp + a);\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:249:17\n    │\n249 │         vm.warp(block.timestamp + a);\n    │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:253:17\n    │\n253 │         vm.warp(block.timestamp + b);\n    │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:79:9\n    │\n 79 │         vm.warp(block.timestamp + 7 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/KingHook.Revision.t.sol:79:17\n   │\n79 │         vm.warp(block.timestamp + 7 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:92:9\n    │\n 92 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/KingHook.Revision.t.sol:92:17\n   │\n92 │         vm.warp(block.timestamp + 10 minutes);\n   │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:103:9\n    │\n103 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:103:17\n    │\n103 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:131:9\n    │\n131 │         vm.warp(block.timestamp + delay);\n    │         ──────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:131:17\n    │\n131 │         vm.warp(block.timestamp + delay);\n    │         ────────━━━━━━━━━━━━━━━───────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:146:9\n    │\n146 │         vm.warp(block.timestamp + 5 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:146:17\n    │\n146 │         vm.warp(block.timestamp + 5 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:160:9\n    │\n160 │         vm.warp(block.timestamp + 1 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:160:17\n    │\n160 │         vm.warp(block.timestamp + 1 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:169:9\n    │\n169 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:169:17\n    │\n169 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:238:9\n    │\n238 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:238:17\n    │\n238 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:261:9\n    │\n261 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:261:17\n    │\n261 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:280:9\n    │\n280 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:280:17\n    │\n280 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:119:70\n    │\n119 │         ethIn = router.buyExactOut{value: maxEth}(kingOut, mustTake, block.timestamp);\n    │                                                                      ━━━━━━━━━━━━━━━\n    ‡\n177 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:410:9\n    │\n410 │         vm.warp(block.timestamp + 2 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Security.t.sol:410:17\n    │\n410 │         vm.warp(block.timestamp + 2 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:125:48\n    │\n125 │         ethOut = router.sellExactIn(kingIn, 0, block.timestamp);\n    │                                                ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:413:9\n    │\n413 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:413:9\n    │\n413 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Security.t.sol:413:17\n    │\n413 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:132:57\n    │\n132 │         kingIn = router.sellExactOut(ethOut, maxKingIn, block.timestamp);\n    │                                                         ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:420:9\n    │\n420 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Security.t.sol:420:17\n    │\n420 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:98:9\n    │\n 98 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/KingHook.Throne.t.sol:98:17\n   │\n98 │         vm.warp(block.timestamp + 10 minutes);\n   │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:115:25\n    │\n115 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n119 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:145:9\n    │\n145 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:145:17\n    │\n145 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:168:25\n    │\n168 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n172 │         vm.warp(start + 1);\n    │         ────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:198:9\n    │\n198 │         vm.warp(block.timestamp + 2); // one Base block later\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:198:17\n    │\n198 │         vm.warp(block.timestamp + 2); // one Base block later\n    │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:229:25\n    │\n229 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n230 │         vm.warp(start + 5 minutes - 1);\n    │         ────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:230:9\n    │\n230 │         vm.warp(start + 5 minutes - 1);\n    │         ────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:257:9\n    │\n257 │         vm.warp(block.timestamp + 1 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:257:17\n    │\n257 │         vm.warp(block.timestamp + 1 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:275:13\n    │\n275 │             vm.warp(start + i * 10 minutes);\n    │             ─────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:272:25\n    │\n272 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n275 │             vm.warp(start + i * 10 minutes);\n    │             ─────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:290:9\n    │\n290 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:289:25\n    │\n289 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n290 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:302:9\n    │\n302 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:302:17\n    │\n302 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:314:9\n    │\n314 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:314:17\n    │\n314 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:323:17\n    │\n323 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:368:9\n    │\n368 │         vm.warp(block.timestamp + 30 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:368:17\n    │\n368 │         vm.warp(block.timestamp + 30 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:412:25\n    │\n412 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n413 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:506:22\n    │\n506 │         uint256 t0 = block.timestamp;\n    │                      ━━━━━━━━━━━━━━━\n507 │         uint256 aliceTokens = buyExactIn(alice, 1 ether, false);\n508 │         vm.warp(t0 + 2 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:508:9\n    │\n508 │         vm.warp(t0 + 2 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:542:9\n    │\n542 │         vm.warp(block.timestamp + 30 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:542:17\n    │\n542 │         vm.warp(block.timestamp + 30 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.t.sol:104:75\n    │\n104 │         uint256 aliceTokens = router.buyExactIn{value: 2 ether}(0, false, block.timestamp);\n    │                                                                           ━━━━━━━━━━━━━━━\n    ‡\n110 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:32:85\n   │\n32 │         uint256 ethIn = router.buyExactOut{value: 5 ether}(10_000_000 ether, false, block.timestamp);\n   │                                                                                     ━━━━━━━━━━━━━━━\n   ‡\n38 │         vm.warp(hook.gameStart());\n   │         ───────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:72:53\n   │\n72 │         router.buyExactIn{value: 3 ether}(0, false, block.timestamp);\n   │                                                     ━━━━━━━━━━━━━━━\n73 │         vm.warp(hook.gameStart());\n   │         ───────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:77:71\n   │\n77 │         uint256 required = router.buyExactIn{value: 1 ether}(0, true, block.timestamp);\n   │                                                                       ━━━━━━━━━━━━━━━\n   ‡\n92 │         vm.warp(block.timestamp + 30 minutes);\n   │         ───────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:85:52\n   │\n85 │         router.buyExactIn{value: 1 ether}(0, true, block.timestamp);\n   │                                                    ━━━━━━━━━━━━━━━\n   ‡\n92 │         vm.warp(block.timestamp + 30 minutes);\n   │         ───────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:92:17\n   │\n92 │         vm.warp(block.timestamp + 30 minutes);\n   │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:97:50\n    │\n 97 │         router.buyExactIn{value: 1e12}(0, false, block.timestamp);\n    │                                                  ━━━━━━━━━━━━━━━\n    ‡\n100 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:100:17\n    │\n100 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:115:17\n    │\n115 │         vm.warp(block.timestamp + 2 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:123:54\n    │\n123 │         router.buyExactIn{value: 0.5 ether}(0, true, block.timestamp);\n    │                                                      ━━━━━━━━━━━━━━━\n    ‡\n126 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:126:17\n    │\n126 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":4062,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 6 tests for test/KingToken.t.sol:KingTokenTest\n[PASS] test_metadata() (gas: 29195)\n[PASS] test_mintsTheWholeSupplyToTheDeployer() (gas: 30033)\n[PASS] test_noAdminOrMintSurface() (gas: 372285)\n[PASS] test_runtimeCodeHasNoDelegatecallOrSelfdestruct() (gas: 529435)\n[PASS] test_transferFromRespectsAllowance() (gas: 139693)\n[PASS] test_transferMovesExactlyWhatItWasAsked() (gas: 86516)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 4.25ms (3.29ms CPU time)\n\nRan 1 test for test/Deploy.t.sol:DeployTest\n[PASS] test_deployFunctionProducesALaunchReadyPool() (gas: 16809717)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 7.92ms (6.90ms CPU time)\n\nRan 10 tests for test/Halving.t.sol:HalvingTest\n[PASS] testFuzz_fractionBelowHalfLifeStaysAboveHalf(uint192,uint32) (runs: 256, μ: 8572, ~: 9021)\n[PASS] testFuzz_monotoneAndBounded(uint192,uint64,uint64) (runs: 256, μ: 5778, ~: 6508)\n[PASS] testFuzz_monotoneForRealAmounts(uint64,uint64) (runs: 256, μ: 5160, ~: 6071)\n[PASS] test_exactAtWholeHalfLives() (gas: 2341)\n[PASS] test_halfWayIsOneOverSqrtTwo() (gas: 5393)\n[PASS] test_oneHourOfIncomeLeavesNinetyEightPercent() (gas: 8294)\n[PASS] test_perSecondCompoundingIsPathIndependent() (gas: 141119)\n[PASS] test_quarterWay() (gas: 5371)\n[PASS] test_rejectsOverflowingInputs() (gas: 11089)\n[PASS] test_zeroElapsedIsIdentity() (gas: 546)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 13.95ms (27.03ms CPU time)\n\nRan 16 tests for test/KingHook.Adversarial.t.sol:KingHookAdversarialTest\n[PASS] test_aGiftToTheKingKeepsHimOnTheThrone() (gas: 797261)\n[PASS] test_contractWalletsAreIdentifiedAsTheBuyer() (gas: 1777762)\n[PASS] test_creditsAccumulateAcrossReignsAndOneClaimPaysAll() (gas: 2009023)\n[PASS] test_drainedPoolRecoversWithTheNextBuy() (gas: 2379409)\n[PASS] test_dustSwapsPayNoFeeAndDoNotRevert() (gas: 981978)\n[PASS] test_flashHeldTokensDoNotProtectTheKingBetweenTransactions() (gas: 1200031)\n[PASS] test_frontRunningDethroneWithAClaimChangesNothing() (gas: 1095064)\n[PASS] test_mustTakeAroundTheOpeningSecond() (gas: 824797)\n[PASS] test_reentryDuringRouterSettlementCannotTouchTheThrone() (gas: 5232877)\n[PASS] test_reignHistoryPaginationEdges() (gas: 1165072)\n[PASS] test_selfCrownedBuyerNestingASwapLosesHisOwnThrone() (gas: 2457827)\n[PASS] test_takeoverChainAtTheFloorIsExact() (gas: 2403655)\n[PASS] test_teamWalletCanBeKingAndClaimsBothShares() (gas: 893748)\n[PASS] test_theSwapThatEvictsAShortKingPaysItsFeeAndMayTakeTheThrone() (gas: 1151298)\n[PASS] test_thirdPartySellBeyondThePoolsEthFillsPartiallyAndKeepsTheRest() (gas: 961775)\n[PASS] test_unclaimedIncomeIsWhatClaimPays() (gas: 965950)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 230.81ms (40.56ms CPU time)\n\nRan 21 tests for test/KingHook.Revision.t.sol:KingHookRevisionTest\n[PASS] testFuzz_earlyTakeoversNeverVest(uint32,bool) (runs: 256, μ: 1580672, ~: 1693222)\n[PASS] test_claimForfeitsUnverifiedGapAndPersistsDethrone() (gas: 1323056)\n[PASS] test_deficientKingCannotVestBySellingDust() (gas: 1064718)\n[PASS] test_dethroneForfeitsUnverifiedGap() (gas: 1314533)\n[PASS] test_exactOutputCannotSweepDonatedTokensOrExceedBudget() (gas: 1235457)\n[PASS] test_failedSellRollsBackCheckpointAndTokens() (gas: 1362904)\n[PASS] test_foreignMustTakeRevertsWithoutCharging() (gas: 848693)\n[PASS] test_foreignUnrelatedMetadataIsIgnored() (gas: 660663)\n[PASS] test_halvingErrorIsRelativeNot64Wei() (gas: 14853)\n[PASS] test_nextSellerCannotSweepPartialFillRefund() (gas: 1936362)\n[PASS] test_nonPayableWalletCannotReceiveExactOutputRefund() (gas: 612820)\n[PASS] test_officialExactInputSellIsRecordedAsSold() (gas: 1066188)\n[PASS] test_officialExactOutputSellIsRecordedAsSoldDespiteEscrow() (gas: 1249338)\n[PASS] test_partialSellRefundsUnusedKing() (gas: 1231499)\n[PASS] test_prepareSellRejectsUntrustedCallers() (gas: 692907)\n[PASS] test_previouslyVestedCreditsSurviveHoldingFailure() (gas: 1201864)\n[PASS] test_selfRetakeCannotReduceHoldingRequirement() (gas: 1407064)\n[PASS] test_swapForfeitsUnverifiedGap() (gas: 1446972)\n[PASS] test_takeoverAtVestingBoundaryKeepsIncome() (gas: 1215398)\n[PASS] test_thirdPartyExitThenClaimPaysNoQuietPeriodIncome() (gas: 1037001)\n[PASS] test_transferAtTakeoverThenClaimAtFiveMinutesPaysNothing() (gas: 857466)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 299.96ms (299.31ms CPU time)\n\nRan 37 tests for test/KingHook.Throne.t.sol:KingHookThroneTest\n[PASS] test_anySellByTheKingThroughTheRouterDethronesAtOnce() (gas: 1213417)\n[PASS] test_beingOutbidWithinFiveMinutesForfeitsTheIncome() (gas: 1156045)\n[PASS] test_buyOneWeiBelowThePriceDoesNotTake() (gas: 489797)\n[PASS] test_claimRevertsForWalletsWithNothing() (gas: 39234)\n[PASS] test_claimWhileKingAndAfterLosingTheThrone() (gas: 1453759)\n[PASS] test_dethroneAfterATransferStopsIncomeAtThatMoment() (gas: 935966)\n[PASS] test_dethroneIsRefusedWhenTheThroneIsEmpty() (gas: 330791)\n[PASS] test_dethroneIsRefusedWhileTheKingHoldsEnough() (gas: 976830)\n[PASS] test_feesArrivingDuringAReignEarnFromThenOn() (gas: 1028219)\n[PASS] test_gameOpensExactlyWhenTheFeeReachesBase() (gas: 44820)\n[PASS] test_incomeAccruesEverySecondAtTwoPercentPerHour() (gas: 971073)\n[PASS] test_incomeIsPathIndependent() (gas: 5959444)\n[PASS] test_incomeStopsWhenTheThroneEmpties() (gas: 1020086)\n[PASS] test_incomeVestsAfterFiveMinutes() (gas: 1379481)\n[PASS] test_kingCanRetakeHisOwnThroneStartingANewReign() (gas: 1101342)\n[PASS] test_kingSellExactOutThroughTheRouterDethrones() (gas: 964215)\n[PASS] test_kingSellThroughAnotherRouterIsCaughtByTheHoldingRule() (gas: 1185959)\n[PASS] test_mustTakeIsIgnoredWithoutTheFlag() (gas: 860936)\n[PASS] test_mustTakeRevertsForExactOutputBuysToo() (gas: 805173)\n[PASS] test_mustTakeRevertsTheWholeSwapBelowThePrice() (gas: 860587)\n[PASS] test_mustTakeSucceedsAtThePrice() (gas: 1010672)\n[PASS] test_nobodyCanTakeFromThePoolOutsideTheGame() (gas: 370691)\n[PASS] test_pastKingsWithReignTimeAndEarnings() (gas: 1334176)\n[PASS] test_priceDecayMakesALongSittingKingCheap() (gas: 1102305)\n[PASS] test_priceHalvesEveryHourDownToTheFloor() (gas: 809346)\n[PASS] test_priceIsTheFloorWhileTheThroneIsEmpty() (gas: 965735)\n[PASS] test_routerSlippageAndDeadline() (gas: 646905)\n[PASS] test_sellsByOthersNeverAffectTheThrone() (gas: 1348001)\n[PASS] test_smallBuysNeverAddUp() (gas: 1115952)\n[PASS] test_takeAndDumpWithinFiveMinutesForfeitsTheIncome() (gas: 1128974)\n[PASS] test_takeoverAtExactlyTheFloorPrice() (gas: 719702)\n[PASS] test_takeoverPriceIsTheFeeInclusiveAmount() (gas: 1225221)\n[PASS] test_takeoverThroughExactOutputBuyCountsTheFee() (gas: 701483)\n[PASS] test_throneIsClosedDuringAntiSnipe() (gas: 443969)\n[PASS] test_throneViewAggregatesEverything() (gas: 884642)\n[PASS] test_transferAndDethroneWithinFiveMinutesForfeitsTheIncome() (gas: 875126)\n[PASS] test_viewsOnAnEmptyThrone() (gas: 338741)\nSuite result: ok. 37 passed; 0 failed; 0 skipped; finished in 300.02ms (70.37ms CPU time)\n\nRan 15 tests for test/KingHook.Fuzz.t.sol:KingHookFuzzTest\n[PASS] testFuzz_exactInputBuyFeeAtAnyMoment(uint96,uint32) (runs: 512, μ: 376965, ~: 355563)\n[PASS] testFuzz_exactInputSellFeeAtAnyMoment(uint96,uint32,uint256) (runs: 512, μ: 591120, ~: 590517)\n[PASS] testFuzz_exactOutputBuyFeeAtAnyMoment(uint96,uint32) (runs: 512, μ: 412858, ~: 357802)\n[PASS] testFuzz_exactOutputSellFeeAtAnyMoment(uint96,uint32,uint96) (runs: 512, μ: 609776, ~: 612839)\n[PASS] testFuzz_feeNeverExceedsTheSwap(uint96,uint32) (runs: 256, μ: 330331, ~: 317864)\n[PASS] testFuzz_halvingBounds(uint192,uint64,uint64) (runs: 512, μ: 3746, ~: 3833)\n[PASS] testFuzz_halvingComposes(uint128,uint32,uint32) (runs: 512, μ: 12869, ~: 13678)\n[PASS] testFuzz_halvingExactAtWholeHalfLives(uint192,uint8) (runs: 512, μ: 1373, ~: 1351)\n[PASS] testFuzz_halvingMatchesWadExp(uint128,uint32) (runs: 1024, μ: 10979, ~: 11339)\n[PASS] testFuzz_incomeCurve(uint96,uint32) (runs: 512, μ: 844177, ~: 847956)\n[PASS] testFuzz_incomeIsPathIndependent(uint32,uint32,uint32) (runs: 128, μ: 1016516, ~: 1024834)\n[PASS] testFuzz_smallBuysNeverAddUp(uint96,uint96,uint96) (runs: 128, μ: 1196371, ~: 1201129)\n[PASS] testFuzz_takeoverBoundaryAfterDecay(uint96,uint32) (runs: 256, μ: 1481853, ~: 1484855)\n[PASS] testFuzz_thronePriceCurve(uint96,uint32) (runs: 512, μ: 717294, ~: 723057)\n[PASS] test_incomeConstantIsNinetyEightPercentPerHour() (gas: 28097)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 335.98ms (2.62s CPU time)\n\nRan 14 tests for test/KingHook.Fee.t.sol:KingHookFeeTest\n[PASS] testFuzz_feeRateFollowsTheLine(uint32) (runs: 256, μ: 18894, ~: 18640)\n[PASS] testFuzz_feeSplits92To8(uint96) (runs: 256, μ: 354866, ~: 364800)\n[PASS] test_exactInputBuy_feeIsTakenFromTheEthInput() (gas: 348775)\n[PASS] test_exactInputSell_feeIsTakenFromTheEthOutput() (gas: 578745)\n[PASS] test_exactOutputBuy_feeIsAddedToTheEthInput() (gas: 345291)\n[PASS] test_exactOutputFeeIsComputedOnTheSettledDelta() (gas: 329402)\n[PASS] test_exactOutputSell_feeIsAddedOnTopOfTheEthOutput() (gas: 607505)\n[PASS] test_feeCollectionDoesNotDependOnRecipientsAcceptingEth() (gas: 277310033)\n[PASS] test_feeDecayIsAppliedToSwaps() (gas: 877139)\n[PASS] test_feeIsNeverTakenInKingOnAnyPath() (gas: 1372505)\n[PASS] test_feeOnThirdPartyRouterBothDirections() (gas: 595391)\n[PASS] test_feeStartsAt25PercentAndDecaysLinearlyTo2_5Percent() (gas: 59719)\n[PASS] test_firstBuyOnManagerHoldingNoEthSucceeds() (gas: 358790)\n[PASS] test_teamWalletClaimsItsShareOnlyByPulling() (gas: 368961)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 336.03ms (92.16ms CPU time)\n\nRan 24 tests for test/KingHook.Security.t.sol:KingHookSecurityTest\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 151574)\n[PASS] test_constructorRejectsAddressesWithoutCode() (gas: 6053)\n[PASS] test_dethroneDuringAPayoutIsRefused() (gas: 1380156)\n[PASS] test_exactOutputSellBeyondPoolEthReverts() (gas: 807667)\n[PASS] test_foreignBuyerIdentityIsIgnoredAndMustTakeIsRejected() (gas: 650317)\n[PASS] test_hookAcceptsFactoryFeeAndReturnsInitializeSelector() (gas: 5223665)\n[PASS] test_hookAcceptsOnlyOnePool() (gas: 45543)\n[PASS] test_hookCallbacksRefuseToRunDuringAPayout() (gas: 1427837)\n[PASS] test_hookNeverHoldsValueDirectly() (gas: 960840)\n[PASS] test_hookRejectsUnlistedAndDynamicLpFees() (gas: 5173005)\n[PASS] test_hookRejectsWrongCurrencies() (gas: 5702689)\n[PASS] test_initializationRecordsTheLaunch() (gas: 37897)\n[PASS] test_legacyLpFeesRejectedWithoutInitializing() (gas: 5365643)\n[PASS] test_noOwnerOrParameterFunctions() (gas: 643428)\n[PASS] test_permissionsMatchTheMinedAddress() (gas: 17095)\n[PASS] test_poolSolvencyAcrossALifecycle() (gas: 2707245)\n[PASS] test_reentrantClaimIsPaidExactlyOnce() (gas: 1394197)\n[PASS] test_routerCannotBeSpoofedThroughTheManager() (gas: 491140)\n[PASS] test_runtimeCodeHasNoEscapeHatch() (gas: 5463325)\n[PASS] test_sellCheckpointDuringAPayoutIsRefused() (gas: 1435830)\n[PASS] test_swapDuringAPayoutIsRefused() (gas: 1408630)\n[PASS] test_swapsBeforeInitializationAreImpossible() (gas: 5129895)\n[PASS] test_unimplementedCallbacksRevert() (gas: 126319)\n[PASS] test_unlockCallbackRefusesThePoolManagerOutsideAPayout() (gas: 35640)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 336.28ms (105.23ms CPU time)\n\nRan 1 test for test/KingHook.Invariant.t.sol:KingHookInvariantTest\n[PASS]\nKingHookInvariantTest invariants:\n[PASS] invariant_claimsBackThePoolAndEveryCredit\n[PASS] invariant_hookAndRouterHoldNothing\n[PASS] invariant_nobodyIsOwedMoreThanTheClaimsCanPay\n[PASS] invariant_throneStateIsConsistent\n KingHookInvariantTest invariants (runs: 24, calls: 1152, reverts: 0)\n\n╭-------------+-------------+-------+---------+----------╮\n| Contract    | Selector    | Calls | Reverts | Discards |\n+========================================================+\n| KingHandler | buyIn       | 146   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | buyOut      | 146   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | claim       | 141   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | dethrone    | 156   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | sellIn      | 143   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | sellOut     | 140   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | transferOut | 151   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | warp        | 129   | 0       | 0        |\n╰-------------+-------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 570.14ms (558.90ms CPU time)\n\nRan 2 tests for test/fork/KingHookFork.t.sol:KingHookForkTest\n[PASS] test_fork_feesAndThroneOnTheLiveManager() (gas: 1220075)\n[PASS] test_fork_poolOpensAtTheLaunchPrice() (gas: 30278)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 891.67ms (79.31ms CPU time)\n\nRan 4 tests for test/fork/KingHookFork.More.t.sol:KingHookForkMoreTest\n[PASS] test_fork_exactOutputBuyAndBothSellModesPayTheFeeInEth() (gas: 849143)\n[PASS] test_fork_feesAndThroneOnTheLiveManager() (gas: 1220331)\n[PASS] test_fork_holdingRuleDethroneAndMustTakeOnTheLiveManager() (gas: 2243222)\n[PASS] test_fork_poolOpensAtTheLaunchPrice() (gas: 30278)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 891.81ms (135.44ms CPU time)\n\nRan 7 tests for test/KingHook.Conservation.t.sol:KingHookConservationTest\n[PASS]\nKingHookConservationTest invariants:\n[PASS] invariant_claimsEqualPoolPlusCredits\n[PASS] invariant_ethIsConserved\n[PASS] invariant_everyPostconditionHeld\n[PASS] invariant_feesAreConserved\n[PASS] invariant_nothingIsStranded\n[PASS] invariant_reignHistoryIsConsistent\n[PASS] invariant_throneIsConsistent\n KingHookConservationTest invariants (runs: 96, calls: 6144, reverts: 0)\n\n╭-----------------+-------------------+-------+---------+----------╮\n| Contract        | Selector          | Calls | Reverts | Discards |\n+==================================================================+\n| KingPlayHandler | buyIn             | 575   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | buyOut            | 548   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | claim             | 538   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | dethrone          | 548   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | sellIn            | 576   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | sellOut           | 544   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | sellOutsideSupply | 537   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | tpBuy             | 531   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | tpSell            | 572   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | transferOut       | 583   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | warp              | 592   | 0       | 0        |\n╰-----------------+-------------------+-------+---------+----------╯\n\n[PASS] testFuzz_everyoneCanExitAfterRandomPlay(uint256) (runs: 64, μ: 9436389, ~: 9456080)\n[PASS] test_handlerEarlyRivalTakeoverForfeitsIncome() (gas: 2138818)\n[PASS] test_handlerForeignMustTakeRollsBackBothExactModes() (gas: 961282)\n[PASS] test_handlerOfficialPartialSellRefundsWithoutCapacityCap() (gas: 1915595)\n[PASS] test_handlerSelfRetakePreservesLargerRequirement() (gas: 2086406)\n[PASS] test_handlerShortKingReturnsProvisionalAndClaimDethrones() (gas: 2783578)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 3.88s (4.71s CPU time)\n\nRan 13 test suites in 3.88s (8.09s CPU time): 158 tests passed, 0 failed, 0 skipped (158 total tests)\n","passed":true},{"durationMs":131,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"KingHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"KingHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"KingHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"KingHook.claim()\",\"KingHook.dethrone()\",\"KingHook.prepareSell(address)\",\"KingHook.unlockCallback(bytes)\",\"KingRouter.buyExactIn(uint256,bool,uint256)\",\"KingRouter.buyExactOut(uint256,bool,uint256)\",\"KingRouter.sellExactIn(uint256,uint256,uint256)\",\"KingRouter.sellExactOut(uint256,uint256,uint256)\",\"KingRouter.unlockCallback(bytes)\",\"KingToken.approve(address,uint256)\",\"KingToken.transfer(address,uint256)\",\"KingToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":321,\"SOURCE.json\":550,\"docs/REDEPLOYMENT.md\":135,\"docs/REVIEW.md\":153,\"docs/REVISION.md\":104,\"foundry.toml\":31,\"launch.json\":30,\"remappings.txt\":5,\"script/Deploy.s.sol\":64,\"script/check_source.py\":41,\"src/HookFlags.sol\":66,\"src/KingHook.sol\":707,\"src/KingRouter.sol\":173,\"src/KingToken.sol\":19,\"src/interfaces/IKingHook.sol\":95,\"src/libraries/Halving.sol\":99,\"test/Deploy.t.sol\":38,\"test/Halving.t.sol\":87,\"test/KingBase.sol\":192,\"test/KingHook.Adversarial.t.sol\":512,\"test/KingHook.Conservation.t.sol\":813,\"test/KingHook.Fee.t.sol\":220,\"test/KingHook.Fuzz.t.sol\":317,\"test/KingHook.Invariant.t.sol\":169,\"test/KingHook.Revision.t.sol\":342,\"test/KingHook.Security.t.sol\":450,\"test/KingHook.Throne.t.sol\":597,\"test/KingToken.t.sol\":82,\"test/fork/KingHookFork.More.t.sol\":139,\"test/fork/KingHookFork.t.sol\":142,\"test/helpers/WebLaunchFixture.sol\":42,\"test/mocks/MockERC20.sol\":11,\"web/README.md\":68,\"web/dist/abi/KingHook.json\":2072,\"web/dist/abi/KingRouter.json\":296,\"web/dist/abi/KingToken.json\":328,\"web/dist/build.json\":5,\"web/dist/crown.svg\":1,\"web/dist/imd-deployment.json\":16,\"web/dist/index.html\":61,\"web/dist/src/app.js\":217,\"web/dist/src/client.js\":76,\"web/dist/src/core.js\":56,\"web/dist/style.css\":3,\"web/dist/vendor/ethers.LICENSE.md\":21,\"web/dist/vendor/ethers.js\":1,\"web/dist/vendor/provenance.json\":10,\"web/package.json\":11,\"web/public/abi/KingHook.json\":2072,\"web/public/abi/KingRouter.json\":296,\"web/public/abi/KingToken.json\":328,\"web/public/crown.svg\":1,\"web/public/imd-deployment.json\":16,\"web/public/index.html\":61,\"web/public/style.css\":3,\"web/scripts/build.mjs\":30,\"web/scripts/configure.mjs\":36,\"web/src/app.js\":217,\"web/src/client.js\":76,\"web/src/core.js\":56,\"web/test/core.test.mjs\":44,\"web/test/integration.mjs\":100,\"web/vendor/ethers.LICENSE.md\":21,\"web/vendor/ethers.js\":1,\"web/vendor/provenance.json\":10},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"2e322b477bf8b7bfcb9515ce6d67623c15121c1b25cdb8e5459135699eafce8a","verifiedTreeHash":"d761ebae533ded19502c7203aed1b4f2f413fe97","verifierVersion":"0.1.0+94826a22"},{"checks":[{"durationMs":7551,"exitCode":0,"name":"build","output":"Compiling 107 files with Solc 0.8.26\nSolc 0.8.26 finished in 7.24s\nCompiler run successful!\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Halving.sol:25:62\n   │\n25 │         if (value >= 1 << 192 || den >= 1 << 192 || den < 1) revert HalvingOverflow();\n   │                                                              ━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[missing-events-arithmetic]: `pool` is changed without an event but is used in arithmetic\n    ╭▸ src/KingHook.sol:671:9\n    │\n671 │         pool = remaining;\n    │         ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastAccrual` is changed without an event but is used in arithmetic\n    ╭▸ src/KingHook.sol:672:9\n    │\n672 │         lastAccrual = uint64(block.timestamp);\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/KingRouter.sol:57:13\n   │\n57 │         if (block.timestamp > deadline) revert Expired();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/KingRouter.sol:75:9\n   │\n75 │         emit Swapped(msg.sender, true, uint256(uint128(-delta.amount0())), kingOut);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:72:61\n   │\n72 │         BalanceDelta delta = _swap(Order(msg.sender, true, -int256(msg.value), mustTake));\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/KingRouter.sol:73:19\n   │\n73 │         kingOut = uint256(uint128(delta.amount1()));\n   │                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:73:27\n   │\n73 │         kingOut = uint256(uint128(delta.amount1()));\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/KingRouter.sol:75:40\n   │\n75 │         emit Swapped(msg.sender, true, uint256(uint128(-delta.amount0())), kingOut);\n   │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:75:48\n   │\n75 │         emit Swapped(msg.sender, true, uint256(uint128(-delta.amount0())), kingOut);\n   │                                                ━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/KingRouter.sol:89:9\n   │\n89 │         emit Swapped(msg.sender, true, ethIn, uint256(uint128(delta.amount1())));\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:87:60\n   │\n87 │         BalanceDelta delta = _swap(Order(msg.sender, true, int256(kingOut), mustTake));\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/KingRouter.sol:88:17\n   │\n88 │         ethIn = uint256(uint128(-delta.amount0()));\n   │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:88:25\n   │\n88 │         ethIn = uint256(uint128(-delta.amount0()));\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/KingRouter.sol:89:47\n   │\n89 │         emit Swapped(msg.sender, true, ethIn, uint256(uint128(delta.amount1())));\n   │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:89:55\n   │\n89 │         emit Swapped(msg.sender, true, ethIn, uint256(uint128(delta.amount1())));\n   │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/KingRouter.sol:108:9\n    │\n108 │         emit Swapped(msg.sender, false, ethOut, consumed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:102:62\n    │\n102 │         BalanceDelta delta = _swap(Order(msg.sender, false, -int256(kingIn), false));\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/KingRouter.sol:103:18\n    │\n103 │         ethOut = uint256(uint128(delta.amount0()));\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:103:26\n    │\n103 │         ethOut = uint256(uint128(delta.amount0()));\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/KingRouter.sol:105:28\n    │\n105 │         uint256 consumed = uint256(uint128(-delta.amount1()));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:105:36\n    │\n105 │         uint256 consumed = uint256(uint128(-delta.amount1()));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/KingRouter.sol:124:9\n    │\n124 │         emit Swapped(msg.sender, false, ethOut, kingIn);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:121:61\n    │\n121 │         BalanceDelta delta = _swap(Order(msg.sender, false, int256(ethOut), false));\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/KingRouter.sol:122:18\n    │\n122 │         kingIn = uint256(uint128(-delta.amount1()));\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:122:26\n    │\n122 │         kingIn = uint256(uint128(-delta.amount1()));\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/KingRouter.sol:147:29\n    │\n147 │             uint256 ethIn = uint256(uint128(-delta.amount0()));\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:147:37\n    │\n147 │             uint256 ethIn = uint256(uint128(-delta.amount0()));\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/KingRouter.sol:154:31\n    │\n154 │             uint256 kingOut = uint256(uint128(delta.amount1()));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:154:39\n    │\n154 │             uint256 kingOut = uint256(uint128(delta.amount1()));\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/KingRouter.sol:157:30\n    │\n157 │             uint256 kingIn = uint256(uint128(-delta.amount1()));\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:157:38\n    │\n157 │             uint256 kingIn = uint256(uint128(-delta.amount1()));\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/KingRouter.sol:164:30\n    │\n164 │             uint256 ethOut = uint256(uint128(delta.amount0()));\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:164:38\n    │\n164 │             uint256 ethOut = uint256(uint128(delta.amount0()));\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/KingHook.sol:181:22\n    │\n181 │         launchTime = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:182:23\n    │\n182 │         lastAccrual = uint64(block.timestamp);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:185:39\n    │\n185 │         emit PoolLaunched(launchTime, uint64(block.timestamp + ANTI_SNIPE_DURATION));\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:415:29\n    │\n415 │         return launchTime + uint64(ANTI_SNIPE_DURATION);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe 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/KingHook.sol:420:31\n    │\n420 │         return initialized && block.timestamp >= gameStart();\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/KingHook.sol:429:13\n    │\n429 │         if (elapsed >= ANTI_SNIPE_DURATION) return FEE_BASE_PPM;\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/KingHook.sol:449:16\n    │\n449 │         while (next <= block.timestamp) {\n    │                ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/KingHook.sol:603:38\n    │\n603 │         return king != address(0) && token.balanceOf(king) < requiredBalance;\n    │                                      ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:608:22\n    │\n608 │         reignStart = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:609:23\n    │\n609 │         lastAccrual = uint64(block.timestamp);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:616:24\n    │\n616 │                 start: uint64(block.timestamp),\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:645:21\n    │\n645 │         reign.end = uint64(block.timestamp);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/KingHook.sol:658:35\n    │\n658 │         if (king == address(0) || block.timestamp <= lastAccrual) return pool;\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/KingHook.sol:665:35\n    │\n665 │         if (king == address(0) || block.timestamp <= lastAccrual) {\n    │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:666:27\n    │\n666 │             lastAccrual = uint64(block.timestamp);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:672:23\n    │\n672 │         lastAccrual = uint64(block.timestamp);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/KingHook.sol:689:16\n    │\n689 │         return block.timestamp - reignStart >= INCOME_VESTING;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:705:24\n    │\n705 │         return x < 0 ? uint256(-x) : uint256(x);\n    │                        ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:705:38\n    │\n705 │         return x < 0 ? uint256(-x) : uint256(x);\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    ‡\n177 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:234:9\n    │\n234 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:234:17\n    │\n234 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:311:17\n    │\n311 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:434:22\n    │\n434 │         uint256 t0 = block.timestamp;\n    │                      ━━━━━━━━━━━━━━━\n435 │         buyExactIn(alice, 1 ether, false);\n436 │         vm.warp(t0 + 1 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:436:9\n    │\n436 │         vm.warp(t0 + 1 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:440:9\n    │\n440 │         vm.warp(t0 + 2 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:443:9\n    │\n443 │         vm.warp(t0 + 3 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:463:9\n    │\n463 │         vm.warp(hook.gameStart() - 1);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:469:9\n    │\n469 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:497:9\n    │\n497 │         vm.warp(block.timestamp + 2 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:497:17\n    │\n497 │         vm.warp(block.timestamp + 2 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:502:17\n    │\n502 │         vm.warp(block.timestamp + 20 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fee.t.sol:44:9\n    │\n 44 │         vm.warp(launch + 15 minutes);\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fee.t.sol:49:9\n    │\n 49 │         vm.warp(launch + 1 hours);\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:63:9\n    │\n 63 │         vm.warp(hook.launchTime() + bound(elapsed, 0, 2 hours));\n    │         ─────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:85:9\n    │\n 85 │         vm.warp(hook.launchTime() + bound(elapsed, 0, 2 hours));\n    │         ─────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:131:9\n    │\n131 │         vm.warp(start + elapsed);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:130:25\n    │\n130 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n131 │         vm.warp(start + elapsed);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:163:9\n    │\n163 │         vm.warp(block.timestamp + elapsed);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:163:17\n    │\n163 │         vm.warp(block.timestamp + elapsed);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:249:9\n    │\n249 │         vm.warp(block.timestamp + a);\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:249:17\n    │\n249 │         vm.warp(block.timestamp + a);\n    │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:253:17\n    │\n253 │         vm.warp(block.timestamp + b);\n    │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:79:9\n    │\n 79 │         vm.warp(block.timestamp + 7 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/KingHook.Revision.t.sol:79:17\n   │\n79 │         vm.warp(block.timestamp + 7 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:92:9\n    │\n 92 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/KingHook.Revision.t.sol:92:17\n   │\n92 │         vm.warp(block.timestamp + 10 minutes);\n   │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:103:9\n    │\n103 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:103:17\n    │\n103 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:131:9\n    │\n131 │         vm.warp(block.timestamp + delay);\n    │         ──────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:131:17\n    │\n131 │         vm.warp(block.timestamp + delay);\n    │         ────────━━━━━━━━━━━━━━━───────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:146:9\n    │\n146 │         vm.warp(block.timestamp + 5 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:146:17\n    │\n146 │         vm.warp(block.timestamp + 5 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:160:9\n    │\n160 │         vm.warp(block.timestamp + 1 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:160:17\n    │\n160 │         vm.warp(block.timestamp + 1 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:169:9\n    │\n169 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:169:17\n    │\n169 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:238:9\n    │\n238 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:238:17\n    │\n238 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:261:9\n    │\n261 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:261:17\n    │\n261 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:280:9\n    │\n280 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:280:17\n    │\n280 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:119:70\n    │\n119 │         ethIn = router.buyExactOut{value: maxEth}(kingOut, mustTake, block.timestamp);\n    │                                                                      ━━━━━━━━━━━━━━━\n    ‡\n177 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:410:9\n    │\n410 │         vm.warp(block.timestamp + 2 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Security.t.sol:410:17\n    │\n410 │         vm.warp(block.timestamp + 2 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:125:48\n    │\n125 │         ethOut = router.sellExactIn(kingIn, 0, block.timestamp);\n    │                                                ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:413:9\n    │\n413 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:413:9\n    │\n413 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Security.t.sol:413:17\n    │\n413 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:132:57\n    │\n132 │         kingIn = router.sellExactOut(ethOut, maxKingIn, block.timestamp);\n    │                                                         ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:420:9\n    │\n420 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Security.t.sol:420:17\n    │\n420 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:98:9\n    │\n 98 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/KingHook.Throne.t.sol:98:17\n   │\n98 │         vm.warp(block.timestamp + 10 minutes);\n   │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:115:25\n    │\n115 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n119 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:145:9\n    │\n145 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:145:17\n    │\n145 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:168:25\n    │\n168 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n172 │         vm.warp(start + 1);\n    │         ────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:198:9\n    │\n198 │         vm.warp(block.timestamp + 2); // one Base block later\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:198:17\n    │\n198 │         vm.warp(block.timestamp + 2); // one Base block later\n    │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:229:25\n    │\n229 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n230 │         vm.warp(start + 5 minutes - 1);\n    │         ────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:230:9\n    │\n230 │         vm.warp(start + 5 minutes - 1);\n    │         ────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:257:9\n    │\n257 │         vm.warp(block.timestamp + 1 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:257:17\n    │\n257 │         vm.warp(block.timestamp + 1 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:275:13\n    │\n275 │             vm.warp(start + i * 10 minutes);\n    │             ─────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:272:25\n    │\n272 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n275 │             vm.warp(start + i * 10 minutes);\n    │             ─────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:290:9\n    │\n290 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:289:25\n    │\n289 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n290 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:302:9\n    │\n302 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:302:17\n    │\n302 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:314:9\n    │\n314 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:314:17\n    │\n314 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:323:17\n    │\n323 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:368:9\n    │\n368 │         vm.warp(block.timestamp + 30 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:368:17\n    │\n368 │         vm.warp(block.timestamp + 30 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:412:25\n    │\n412 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n413 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:506:22\n    │\n506 │         uint256 t0 = block.timestamp;\n    │                      ━━━━━━━━━━━━━━━\n507 │         uint256 aliceTokens = buyExactIn(alice, 1 ether, false);\n508 │         vm.warp(t0 + 2 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:508:9\n    │\n508 │         vm.warp(t0 + 2 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:542:9\n    │\n542 │         vm.warp(block.timestamp + 30 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:542:17\n    │\n542 │         vm.warp(block.timestamp + 30 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.t.sol:104:75\n    │\n104 │         uint256 aliceTokens = router.buyExactIn{value: 2 ether}(0, false, block.timestamp);\n    │                                                                           ━━━━━━━━━━━━━━━\n    ‡\n110 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:32:85\n   │\n32 │         uint256 ethIn = router.buyExactOut{value: 5 ether}(10_000_000 ether, false, block.timestamp);\n   │                                                                                     ━━━━━━━━━━━━━━━\n   ‡\n38 │         vm.warp(hook.gameStart());\n   │         ───────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:72:53\n   │\n72 │         router.buyExactIn{value: 3 ether}(0, false, block.timestamp);\n   │                                                     ━━━━━━━━━━━━━━━\n73 │         vm.warp(hook.gameStart());\n   │         ───────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:77:71\n   │\n77 │         uint256 required = router.buyExactIn{value: 1 ether}(0, true, block.timestamp);\n   │                                                                       ━━━━━━━━━━━━━━━\n   ‡\n92 │         vm.warp(block.timestamp + 30 minutes);\n   │         ───────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:85:52\n   │\n85 │         router.buyExactIn{value: 1 ether}(0, true, block.timestamp);\n   │                                                    ━━━━━━━━━━━━━━━\n   ‡\n92 │         vm.warp(block.timestamp + 30 minutes);\n   │         ───────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:92:17\n   │\n92 │         vm.warp(block.timestamp + 30 minutes);\n   │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:97:50\n    │\n 97 │         router.buyExactIn{value: 1e12}(0, false, block.timestamp);\n    │                                                  ━━━━━━━━━━━━━━━\n    ‡\n100 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:100:17\n    │\n100 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:115:17\n    │\n115 │         vm.warp(block.timestamp + 2 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:123:54\n    │\n123 │         router.buyExactIn{value: 0.5 ether}(0, true, block.timestamp);\n    │                                                      ━━━━━━━━━━━━━━━\n    ‡\n126 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:126:17\n    │\n126 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":2958,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 6 tests for test/KingToken.t.sol:KingTokenTest\n[PASS] test_metadata() (gas: 29195)\n[PASS] test_mintsTheWholeSupplyToTheDeployer() (gas: 30033)\n[PASS] test_noAdminOrMintSurface() (gas: 372285)\n[PASS] test_runtimeCodeHasNoDelegatecallOrSelfdestruct() (gas: 529435)\n[PASS] test_transferFromRespectsAllowance() (gas: 139693)\n[PASS] test_transferMovesExactlyWhatItWasAsked() (gas: 86516)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 2.14ms (2.82ms CPU time)\n\nRan 1 test for test/Deploy.t.sol:DeployTest\n[PASS] test_deployFunctionProducesALaunchReadyPool() (gas: 16809717)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 6.24ms (5.63ms CPU time)\n\nRan 16 tests for test/KingHook.Adversarial.t.sol:KingHookAdversarialTest\n[PASS] test_aGiftToTheKingKeepsHimOnTheThrone() (gas: 797261)\n[PASS] test_contractWalletsAreIdentifiedAsTheBuyer() (gas: 1777762)\n[PASS] test_creditsAccumulateAcrossReignsAndOneClaimPaysAll() (gas: 2009023)\n[PASS] test_drainedPoolRecoversWithTheNextBuy() (gas: 2379409)\n[PASS] test_dustSwapsPayNoFeeAndDoNotRevert() (gas: 981978)\n[PASS] test_flashHeldTokensDoNotProtectTheKingBetweenTransactions() (gas: 1200031)\n[PASS] test_frontRunningDethroneWithAClaimChangesNothing() (gas: 1095064)\n[PASS] test_mustTakeAroundTheOpeningSecond() (gas: 824797)\n[PASS] test_reentryDuringRouterSettlementCannotTouchTheThrone() (gas: 5232877)\n[PASS] test_reignHistoryPaginationEdges() (gas: 1165072)\n[PASS] test_selfCrownedBuyerNestingASwapLosesHisOwnThrone() (gas: 2457827)\n[PASS] test_takeoverChainAtTheFloorIsExact() (gas: 2403655)\n[PASS] test_teamWalletCanBeKingAndClaimsBothShares() (gas: 893748)\n[PASS] test_theSwapThatEvictsAShortKingPaysItsFeeAndMayTakeTheThrone() (gas: 1151298)\n[PASS] test_thirdPartySellBeyondThePoolsEthFillsPartiallyAndKeepsTheRest() (gas: 961775)\n[PASS] test_unclaimedIncomeIsWhatClaimPays() (gas: 965950)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 99.38ms (19.84ms CPU time)\n\nRan 24 tests for test/KingHook.Security.t.sol:KingHookSecurityTest\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 151574)\n[PASS] test_constructorRejectsAddressesWithoutCode() (gas: 6053)\n[PASS] test_dethroneDuringAPayoutIsRefused() (gas: 1380156)\n[PASS] test_exactOutputSellBeyondPoolEthReverts() (gas: 807667)\n[PASS] test_foreignBuyerIdentityIsIgnoredAndMustTakeIsRejected() (gas: 650317)\n[PASS] test_hookAcceptsFactoryFeeAndReturnsInitializeSelector() (gas: 5223665)\n[PASS] test_hookAcceptsOnlyOnePool() (gas: 45543)\n[PASS] test_hookCallbacksRefuseToRunDuringAPayout() (gas: 1427837)\n[PASS] test_hookNeverHoldsValueDirectly() (gas: 960840)\n[PASS] test_hookRejectsUnlistedAndDynamicLpFees() (gas: 5173005)\n[PASS] test_hookRejectsWrongCurrencies() (gas: 5702689)\n[PASS] test_initializationRecordsTheLaunch() (gas: 37897)\n[PASS] test_legacyLpFeesRejectedWithoutInitializing() (gas: 5365643)\n[PASS] test_noOwnerOrParameterFunctions() (gas: 643428)\n[PASS] test_permissionsMatchTheMinedAddress() (gas: 17095)\n[PASS] test_poolSolvencyAcrossALifecycle() (gas: 2707245)\n[PASS] test_reentrantClaimIsPaidExactlyOnce() (gas: 1394197)\n[PASS] test_routerCannotBeSpoofedThroughTheManager() (gas: 491140)\n[PASS] test_runtimeCodeHasNoEscapeHatch() (gas: 5463325)\n[PASS] test_sellCheckpointDuringAPayoutIsRefused() (gas: 1435830)\n[PASS] test_swapDuringAPayoutIsRefused() (gas: 1408630)\n[PASS] test_swapsBeforeInitializationAreImpossible() (gas: 5129895)\n[PASS] test_unimplementedCallbacksRevert() (gas: 126319)\n[PASS] test_unlockCallbackRefusesThePoolManagerOutsideAPayout() (gas: 35640)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 183.00ms (36.16ms CPU time)\n\nRan 21 tests for test/KingHook.Revision.t.sol:KingHookRevisionTest\n[PASS] testFuzz_earlyTakeoversNeverVest(uint32,bool) (runs: 256, μ: 1583657, ~: 1693402)\n[PASS] test_claimForfeitsUnverifiedGapAndPersistsDethrone() (gas: 1323056)\n[PASS] test_deficientKingCannotVestBySellingDust() (gas: 1064718)\n[PASS] test_dethroneForfeitsUnverifiedGap() (gas: 1314533)\n[PASS] test_exactOutputCannotSweepDonatedTokensOrExceedBudget() (gas: 1235457)\n[PASS] test_failedSellRollsBackCheckpointAndTokens() (gas: 1362904)\n[PASS] test_foreignMustTakeRevertsWithoutCharging() (gas: 848693)\n[PASS] test_foreignUnrelatedMetadataIsIgnored() (gas: 660663)\n[PASS] test_halvingErrorIsRelativeNot64Wei() (gas: 14853)\n[PASS] test_nextSellerCannotSweepPartialFillRefund() (gas: 1936362)\n[PASS] test_nonPayableWalletCannotReceiveExactOutputRefund() (gas: 612820)\n[PASS] test_officialExactInputSellIsRecordedAsSold() (gas: 1066188)\n[PASS] test_officialExactOutputSellIsRecordedAsSoldDespiteEscrow() (gas: 1249338)\n[PASS] test_partialSellRefundsUnusedKing() (gas: 1231499)\n[PASS] test_prepareSellRejectsUntrustedCallers() (gas: 692907)\n[PASS] test_previouslyVestedCreditsSurviveHoldingFailure() (gas: 1201864)\n[PASS] test_selfRetakeCannotReduceHoldingRequirement() (gas: 1407064)\n[PASS] test_swapForfeitsUnverifiedGap() (gas: 1446972)\n[PASS] test_takeoverAtVestingBoundaryKeepsIncome() (gas: 1215398)\n[PASS] test_thirdPartyExitThenClaimPaysNoQuietPeriodIncome() (gas: 1037001)\n[PASS] test_transferAtTakeoverThenClaimAtFiveMinutesPaysNothing() (gas: 857466)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 188.60ms (204.55ms CPU time)\n\nRan 15 tests for test/KingHook.Fuzz.t.sol:KingHookFuzzTest\n[PASS] testFuzz_exactInputBuyFeeAtAnyMoment(uint96,uint32) (runs: 512, μ: 383856, ~: 355563)\n[PASS] testFuzz_exactInputSellFeeAtAnyMoment(uint96,uint32,uint256) (runs: 512, μ: 592101, ~: 590384)\n[PASS] testFuzz_exactOutputBuyFeeAtAnyMoment(uint96,uint32) (runs: 512, μ: 413315, ~: 357802)\n[PASS] testFuzz_exactOutputSellFeeAtAnyMoment(uint96,uint32,uint96) (runs: 512, μ: 610186, ~: 612845)\n[PASS] testFuzz_feeNeverExceedsTheSwap(uint96,uint32) (runs: 256, μ: 338152, ~: 318519)\n[PASS] testFuzz_halvingBounds(uint192,uint64,uint64) (runs: 512, μ: 3930, ~: 4241)\n[PASS] testFuzz_halvingComposes(uint128,uint32,uint32) (runs: 512, μ: 13118, ~: 14661)\n[PASS] testFuzz_halvingExactAtWholeHalfLives(uint192,uint8) (runs: 512, μ: 1400, ~: 1351)\n[PASS] testFuzz_halvingMatchesWadExp(uint128,uint32) (runs: 1024, μ: 11080, ~: 11327)\n[PASS] testFuzz_incomeCurve(uint96,uint32) (runs: 512, μ: 844901, ~: 847981)\n[PASS] testFuzz_incomeIsPathIndependent(uint32,uint32,uint32) (runs: 128, μ: 1016782, ~: 1024598)\n[PASS] testFuzz_smallBuysNeverAddUp(uint96,uint96,uint96) (runs: 128, μ: 1194892, ~: 1201129)\n[PASS] testFuzz_takeoverBoundaryAfterDecay(uint96,uint32) (runs: 256, μ: 1486900, ~: 1485232)\n[PASS] testFuzz_thronePriceCurve(uint96,uint32) (runs: 512, μ: 718474, ~: 723267)\n[PASS] test_incomeConstantIsNinetyEightPercentPerHour() (gas: 28097)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 201.03ms (1.70s CPU time)\n\nRan 14 tests for test/KingHook.Fee.t.sol:KingHookFeeTest\n[PASS] testFuzz_feeRateFollowsTheLine(uint32) (runs: 256, μ: 18953, ~: 18640)\n[PASS] testFuzz_feeSplits92To8(uint96) (runs: 256, μ: 354685, ~: 364794)\n[PASS] test_exactInputBuy_feeIsTakenFromTheEthInput() (gas: 348775)\n[PASS] test_exactInputSell_feeIsTakenFromTheEthOutput() (gas: 578745)\n[PASS] test_exactOutputBuy_feeIsAddedToTheEthInput() (gas: 345291)\n[PASS] test_exactOutputFeeIsComputedOnTheSettledDelta() (gas: 329402)\n[PASS] test_exactOutputSell_feeIsAddedOnTopOfTheEthOutput() (gas: 607505)\n[PASS] test_feeCollectionDoesNotDependOnRecipientsAcceptingEth() (gas: 277310033)\n[PASS] test_feeDecayIsAppliedToSwaps() (gas: 877139)\n[PASS] test_feeIsNeverTakenInKingOnAnyPath() (gas: 1372505)\n[PASS] test_feeOnThirdPartyRouterBothDirections() (gas: 595391)\n[PASS] test_feeStartsAt25PercentAndDecaysLinearlyTo2_5Percent() (gas: 59719)\n[PASS] test_firstBuyOnManagerHoldingNoEthSucceeds() (gas: 358790)\n[PASS] test_teamWalletClaimsItsShareOnlyByPulling() (gas: 368961)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 201.14ms (231.28ms CPU time)\n\nRan 1 test for test/KingHook.Invariant.t.sol:KingHookInvariantTest\n[PASS]\nKingHookInvariantTest invariants:\n[PASS] invariant_claimsBackThePoolAndEveryCredit\n[PASS] invariant_hookAndRouterHoldNothing\n[PASS] invariant_nobodyIsOwedMoreThanTheClaimsCanPay\n[PASS] invariant_throneStateIsConsistent\n KingHookInvariantTest invariants (runs: 24, calls: 1152, reverts: 0)\n\n╭-------------+-------------+-------+---------+----------╮\n| Contract    | Selector    | Calls | Reverts | Discards |\n+========================================================+\n| KingHandler | buyIn       | 124   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | buyOut      | 144   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | claim       | 154   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | dethrone    | 161   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | sellIn      | 139   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | sellOut     | 147   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | transferOut | 127   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | warp        | 156   | 0       | 0        |\n╰-------------+-------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 383.70ms (377.78ms CPU time)\n\nRan 10 tests for test/Halving.t.sol:HalvingTest\n[PASS] testFuzz_fractionBelowHalfLifeStaysAboveHalf(uint192,uint32) (runs: 256, μ: 8771, ~: 9021)\n[PASS] testFuzz_monotoneAndBounded(uint192,uint64,uint64) (runs: 256, μ: 5659, ~: 6450)\n[PASS] testFuzz_monotoneForRealAmounts(uint64,uint64) (runs: 256, μ: 5450, ~: 6082)\n[PASS] test_exactAtWholeHalfLives() (gas: 2341)\n[PASS] test_halfWayIsOneOverSqrtTwo() (gas: 5393)\n[PASS] test_oneHourOfIncomeLeavesNinetyEightPercent() (gas: 8294)\n[PASS] test_perSecondCompoundingIsPathIndependent() (gas: 141119)\n[PASS] test_quarterWay() (gas: 5371)\n[PASS] test_rejectsOverflowingInputs() (gas: 11089)\n[PASS] test_zeroElapsedIsIdentity() (gas: 546)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 620.25ms (640.15ms CPU time)\n\nRan 37 tests for test/KingHook.Throne.t.sol:KingHookThroneTest\n[PASS] test_anySellByTheKingThroughTheRouterDethronesAtOnce() (gas: 1213417)\n[PASS] test_beingOutbidWithinFiveMinutesForfeitsTheIncome() (gas: 1156045)\n[PASS] test_buyOneWeiBelowThePriceDoesNotTake() (gas: 489797)\n[PASS] test_claimRevertsForWalletsWithNothing() (gas: 39234)\n[PASS] test_claimWhileKingAndAfterLosingTheThrone() (gas: 1453759)\n[PASS] test_dethroneAfterATransferStopsIncomeAtThatMoment() (gas: 935966)\n[PASS] test_dethroneIsRefusedWhenTheThroneIsEmpty() (gas: 330791)\n[PASS] test_dethroneIsRefusedWhileTheKingHoldsEnough() (gas: 976830)\n[PASS] test_feesArrivingDuringAReignEarnFromThenOn() (gas: 1028219)\n[PASS] test_gameOpensExactlyWhenTheFeeReachesBase() (gas: 44820)\n[PASS] test_incomeAccruesEverySecondAtTwoPercentPerHour() (gas: 971073)\n[PASS] test_incomeIsPathIndependent() (gas: 5959444)\n[PASS] test_incomeStopsWhenTheThroneEmpties() (gas: 1020086)\n[PASS] test_incomeVestsAfterFiveMinutes() (gas: 1379481)\n[PASS] test_kingCanRetakeHisOwnThroneStartingANewReign() (gas: 1101342)\n[PASS] test_kingSellExactOutThroughTheRouterDethrones() (gas: 964215)\n[PASS] test_kingSellThroughAnotherRouterIsCaughtByTheHoldingRule() (gas: 1185959)\n[PASS] test_mustTakeIsIgnoredWithoutTheFlag() (gas: 860936)\n[PASS] test_mustTakeRevertsForExactOutputBuysToo() (gas: 805173)\n[PASS] test_mustTakeRevertsTheWholeSwapBelowThePrice() (gas: 860587)\n[PASS] test_mustTakeSucceedsAtThePrice() (gas: 1010672)\n[PASS] test_nobodyCanTakeFromThePoolOutsideTheGame() (gas: 370691)\n[PASS] test_pastKingsWithReignTimeAndEarnings() (gas: 1334176)\n[PASS] test_priceDecayMakesALongSittingKingCheap() (gas: 1102305)\n[PASS] test_priceHalvesEveryHourDownToTheFloor() (gas: 809346)\n[PASS] test_priceIsTheFloorWhileTheThroneIsEmpty() (gas: 965735)\n[PASS] test_routerSlippageAndDeadline() (gas: 646905)\n[PASS] test_sellsByOthersNeverAffectTheThrone() (gas: 1348001)\n[PASS] test_smallBuysNeverAddUp() (gas: 1115952)\n[PASS] test_takeAndDumpWithinFiveMinutesForfeitsTheIncome() (gas: 1128974)\n[PASS] test_takeoverAtExactlyTheFloorPrice() (gas: 719702)\n[PASS] test_takeoverPriceIsTheFeeInclusiveAmount() (gas: 1225221)\n[PASS] test_takeoverThroughExactOutputBuyCountsTheFee() (gas: 701483)\n[PASS] test_throneIsClosedDuringAntiSnipe() (gas: 443969)\n[PASS] test_throneViewAggregatesEverything() (gas: 884642)\n[PASS] test_transferAndDethroneWithinFiveMinutesForfeitsTheIncome() (gas: 875126)\n[PASS] test_viewsOnAnEmptyThrone() (gas: 338741)\nSuite result: ok. 37 passed; 0 failed; 0 skipped; finished in 620.30ms (38.68ms CPU time)\n\nRan 2 tests for test/fork/KingHookFork.t.sol:KingHookForkTest\n[PASS] test_fork_feesAndThroneOnTheLiveManager() (gas: 1220075)\n[PASS] test_fork_poolOpensAtTheLaunchPrice() (gas: 30278)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 729.79ms (48.55ms CPU time)\n\nRan 4 tests for test/fork/KingHookFork.More.t.sol:KingHookForkMoreTest\n[PASS] test_fork_exactOutputBuyAndBothSellModesPayTheFeeInEth() (gas: 849143)\n[PASS] test_fork_feesAndThroneOnTheLiveManager() (gas: 1220331)\n[PASS] test_fork_holdingRuleDethroneAndMustTakeOnTheLiveManager() (gas: 2243222)\n[PASS] test_fork_poolOpensAtTheLaunchPrice() (gas: 30278)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 729.80ms (96.65ms CPU time)\n\nRan 7 tests for test/KingHook.Conservation.t.sol:KingHookConservationTest\n[PASS]\nKingHookConservationTest invariants:\n[PASS] invariant_claimsEqualPoolPlusCredits\n[PASS] invariant_ethIsConserved\n[PASS] invariant_everyPostconditionHeld\n[PASS] invariant_feesAreConserved\n[PASS] invariant_nothingIsStranded\n[PASS] invariant_reignHistoryIsConsistent\n[PASS] invariant_throneIsConsistent\n KingHookConservationTest invariants (runs: 96, calls: 6144, reverts: 0)\n\n╭-----------------+-------------------+-------+---------+----------╮\n| Contract        | Selector          | Calls | Reverts | Discards |\n+==================================================================+\n| KingPlayHandler | buyIn             | 570   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | buyOut            | 525   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | claim             | 546   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | dethrone          | 580   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | sellIn            | 511   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | sellOut           | 536   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | sellOutsideSupply | 565   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | tpBuy             | 570   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | tpSell            | 582   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | transferOut       | 605   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | warp              | 554   | 0       | 0        |\n╰-----------------+-------------------+-------+---------+----------╯\n\n[PASS] testFuzz_everyoneCanExitAfterRandomPlay(uint256) (runs: 64, μ: 9391308, ~: 9499093)\n[PASS] test_handlerEarlyRivalTakeoverForfeitsIncome() (gas: 2138818)\n[PASS] test_handlerForeignMustTakeRollsBackBothExactModes() (gas: 961282)\n[PASS] test_handlerOfficialPartialSellRefundsWithoutCapacityCap() (gas: 1915595)\n[PASS] test_handlerSelfRetakePreservesLargerRequirement() (gas: 2086406)\n[PASS] test_handlerShortKingReturnsProvisionalAndClaimDethrones() (gas: 2783578)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 2.81s (3.42s CPU time)\n\nRan 13 test suites in 2.81s (6.77s CPU time): 158 tests passed, 0 failed, 0 skipped (158 total tests)\n","passed":true},{"durationMs":85,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"KingHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"KingHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"KingHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"KingHook.claim()\",\"KingHook.dethrone()\",\"KingHook.prepareSell(address)\",\"KingHook.unlockCallback(bytes)\",\"KingRouter.buyExactIn(uint256,bool,uint256)\",\"KingRouter.buyExactOut(uint256,bool,uint256)\",\"KingRouter.sellExactIn(uint256,uint256,uint256)\",\"KingRouter.sellExactOut(uint256,uint256,uint256)\",\"KingRouter.unlockCallback(bytes)\",\"KingToken.approve(address,uint256)\",\"KingToken.transfer(address,uint256)\",\"KingToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":321,\"SOURCE.json\":550,\"docs/REDEPLOYMENT.md\":135,\"docs/REVIEW.md\":153,\"docs/REVISION.md\":104,\"foundry.toml\":31,\"launch.json\":30,\"remappings.txt\":5,\"script/Deploy.s.sol\":64,\"script/check_source.py\":41,\"src/HookFlags.sol\":66,\"src/KingHook.sol\":707,\"src/KingRouter.sol\":173,\"src/KingToken.sol\":19,\"src/interfaces/IKingHook.sol\":95,\"src/libraries/Halving.sol\":99,\"test/Deploy.t.sol\":38,\"test/Halving.t.sol\":87,\"test/KingBase.sol\":192,\"test/KingHook.Adversarial.t.sol\":512,\"test/KingHook.Conservation.t.sol\":813,\"test/KingHook.Fee.t.sol\":220,\"test/KingHook.Fuzz.t.sol\":317,\"test/KingHook.Invariant.t.sol\":169,\"test/KingHook.Revision.t.sol\":342,\"test/KingHook.Security.t.sol\":450,\"test/KingHook.Throne.t.sol\":597,\"test/KingToken.t.sol\":82,\"test/fork/KingHookFork.More.t.sol\":139,\"test/fork/KingHookFork.t.sol\":142,\"test/helpers/WebLaunchFixture.sol\":42,\"test/mocks/MockERC20.sol\":11,\"web/README.md\":68,\"web/dist/abi/KingHook.json\":2072,\"web/dist/abi/KingRouter.json\":296,\"web/dist/abi/KingToken.json\":328,\"web/dist/build.json\":5,\"web/dist/crown.svg\":1,\"web/dist/imd-deployment.json\":16,\"web/dist/index.html\":61,\"web/dist/src/app.js\":217,\"web/dist/src/client.js\":76,\"web/dist/src/core.js\":56,\"web/dist/style.css\":3,\"web/dist/vendor/ethers.LICENSE.md\":21,\"web/dist/vendor/ethers.js\":1,\"web/dist/vendor/provenance.json\":10,\"web/package.json\":11,\"web/public/abi/KingHook.json\":2072,\"web/public/abi/KingRouter.json\":296,\"web/public/abi/KingToken.json\":328,\"web/public/crown.svg\":1,\"web/public/imd-deployment.json\":16,\"web/public/index.html\":61,\"web/public/style.css\":3,\"web/scripts/build.mjs\":30,\"web/scripts/configure.mjs\":36,\"web/src/app.js\":217,\"web/src/client.js\":76,\"web/src/core.js\":56,\"web/test/core.test.mjs\":44,\"web/test/integration.mjs\":100,\"web/vendor/ethers.LICENSE.md\":21,\"web/vendor/ethers.js\":1,\"web/vendor/provenance.json\":10},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true},{"durationMs":2851,"exitCode":0,"name":"slither","output":"[low/medium] calls-loop at src/KingHook.sol:602: KingHook._holdingShort() (src/KingHook.sol#602-604) has external calls inside a loop: king != address(0) && token.balanceOf(king) < requiredBalance (src/KingHook.sol#603)\n[low/medium] timestamp at src/KingHook.sol:688: KingHook._vested() (src/KingHook.sol#688-690) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:485: KingHook.kingVestingIncome() (src/KingHook.sol#485-488) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:559: KingHook._onBuy(address,bytes,uint256,uint256) (src/KingHook.sol#559-583) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:699: KingHook._payout(address,uint256) (src/KingHook.sol#699-702) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:369: KingHook.claim() (src/KingHook.sol#369-380) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:237: KingHook._afterBuy(address,SwapParams,BalanceDelta,bytes) (src/KingHook.sol#237-257) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:445: KingHook.nextHalvingTime() (src/KingHook.sol#445-452) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:419: KingHook.gameOpen() (src/KingHook.sol#419-421) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:496: KingHook.getReign(uint256) (src/KingHook.sol#496-499) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:260: KingHook._afterSell(address,SwapParams,BalanceDelta,bytes) (src/KingHook.sol#260-279) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:502: KingHook.getReigns(uint256,uint256) (src/KingHook.sol#502-511) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:664: KingHook._accrue() (src/KingHook.sol#664-685) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:631: KingHook._endReign(IKingHook.EndReason,uint256) (src/KingHook.sol#631-653) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:217: KingHook.afterSwap(address,PoolKey,SwapParams,BalanceDelta,bytes) (src/KingHook.sol#217-234) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:426: KingHook.feeRate() (src/KingHook.sol#426-431) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:469: KingHook.unclaimedIncome(address) (src/KingHook.sol#469-473) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:436: KingHook.currentThronePrice() (src/KingHook.sol#436-440) uses timestamp for comparisons\n[low/medium] timestamp at src/KingHook.sol:657: KingHook._remainingPool() (src/KingHook.sol#657-661) uses timestamp for comparisons","passed":true},{"durationMs":785,"exitCode":0,"name":"aderyn","output":"[high] contract-locks-ether at src/KingRouter.sol:26: Contract locks Ether without a withdraw function\n[low] internal-function-used-once at src/HookFlags.sol:34: Internal Function Used Only Once (2 places)\n[low] large-numeric-literal at src/KingHook.sol:56: Large Numeric Literal (4 places)\n[low] literal-instead-of-constant at src/KingHook.sol:560: Literal Instead of Constant (70 places)\n[low] require-revert-in-loop at src/KingHook.sol:508: Loop Contains `require`/`revert`\n[low] state-no-address-check at src/KingHook.sol:607: Address State Variable Set Without Checks\n[low] unchecked-return at src/KingHook.sol:203: Unchecked Return (2 places)\n[low] unused-import at src/KingHook.sol:8: Unused Import\n[low] unused-public-function at src/KingHook.sol:141: Public Function Not Used Internally (2 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"406ce00475fa08b20dc370032433fc7494bc9f5e3e6c4b930d7c687288b6dfe1","verifiedTreeHash":"50f6396291dae6aff988bc8f01b3058218a6dced","verifierVersion":"0.1.0+94826a22"},{"checks":[{"durationMs":19554,"exitCode":0,"name":"build","output":"Compiling 109 files with Solc 0.8.26\nSolc 0.8.26 finished in 18.72s\nCompiler run successful!\nwarning[require-revert-in-loop]: `require` or `revert` inside a loop\n   ╭▸ src/libraries/Halving.sol:25:62\n   │\n25 │         if (value >= 1 << 192 || den >= 1 << 192 || den < 1) revert HalvingOverflow();\n   │                                                              ━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/require-revert-in-loop\n\nwarning[missing-events-arithmetic]: `pool` is changed without an event but is used in arithmetic\n    ╭▸ src/KingHook.sol:671:9\n    │\n671 │         pool = remaining;\n    │         ━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[missing-events-arithmetic]: `lastAccrual` is changed without an event but is used in arithmetic\n    ╭▸ src/KingHook.sol:672:9\n    │\n672 │         lastAccrual = uint64(block.timestamp);\n    │         ━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/missing-events-arithmetic\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n   ╭▸ src/KingRouter.sol:57:13\n   │\n57 │         if (block.timestamp > deadline) revert Expired();\n   │             ━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/KingRouter.sol:75:9\n   │\n75 │         emit Swapped(msg.sender, true, uint256(uint128(-delta.amount0())), kingOut);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:72:61\n   │\n72 │         BalanceDelta delta = _swap(Order(msg.sender, true, -int256(msg.value), mustTake));\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/KingRouter.sol:73:19\n   │\n73 │         kingOut = uint256(uint128(delta.amount1()));\n   │                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:73:27\n   │\n73 │         kingOut = uint256(uint128(delta.amount1()));\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/KingRouter.sol:75:40\n   │\n75 │         emit Swapped(msg.sender, true, uint256(uint128(-delta.amount0())), kingOut);\n   │                                        ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:75:48\n   │\n75 │         emit Swapped(msg.sender, true, uint256(uint128(-delta.amount0())), kingOut);\n   │                                                ━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n   ╭▸ src/KingRouter.sol:89:9\n   │\n89 │         emit Swapped(msg.sender, true, ethIn, uint256(uint128(delta.amount1())));\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:87:60\n   │\n87 │         BalanceDelta delta = _swap(Order(msg.sender, true, int256(kingOut), mustTake));\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/KingRouter.sol:88:17\n   │\n88 │         ethIn = uint256(uint128(-delta.amount0()));\n   │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:88:25\n   │\n88 │         ethIn = uint256(uint128(-delta.amount0()));\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/KingRouter.sol:89:47\n   │\n89 │         emit Swapped(msg.sender, true, ethIn, uint256(uint128(delta.amount1())));\n   │                                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint256' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n   ╭▸ src/KingRouter.sol:89:55\n   │\n89 │         emit Swapped(msg.sender, true, ethIn, uint256(uint128(delta.amount1())));\n   │                                                       ━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint128' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/KingRouter.sol:108:9\n    │\n108 │         emit Swapped(msg.sender, false, ethOut, consumed);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:102:62\n    │\n102 │         BalanceDelta delta = _swap(Order(msg.sender, false, -int256(kingIn), false));\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/KingRouter.sol:103:18\n    │\n103 │         ethOut = uint256(uint128(delta.amount0()));\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:103:26\n    │\n103 │         ethOut = uint256(uint128(delta.amount0()));\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/KingRouter.sol:105:28\n    │\n105 │         uint256 consumed = uint256(uint128(-delta.amount1()));\n    │                            ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:105:36\n    │\n105 │         uint256 consumed = uint256(uint128(-delta.amount1()));\n    │                                    ━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint128' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[reentrancy-events]: event emitted after an external call; reentrancy can reorder or fabricate logs that off-chain consumers rely on\n    ╭▸ src/KingRouter.sol:124:9\n    │\n124 │         emit Swapped(msg.sender, false, ethOut, kingIn);\n    │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/reentrancy-events\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:121:61\n    │\n121 │         BalanceDelta delta = _swap(Order(msg.sender, false, int256(ethOut), false));\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/KingRouter.sol:122:18\n    │\n122 │         kingIn = uint256(uint128(-delta.amount1()));\n    │                  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:122:26\n    │\n122 │         kingIn = uint256(uint128(-delta.amount1()));\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/KingRouter.sol:147:29\n    │\n147 │             uint256 ethIn = uint256(uint128(-delta.amount0()));\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:147:37\n    │\n147 │             uint256 ethIn = uint256(uint128(-delta.amount0()));\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/KingRouter.sol:154:31\n    │\n154 │             uint256 kingOut = uint256(uint128(delta.amount1()));\n    │                               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:154:39\n    │\n154 │             uint256 kingOut = uint256(uint128(delta.amount1()));\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/KingRouter.sol:157:30\n    │\n157 │             uint256 kingIn = uint256(uint128(-delta.amount1()));\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:157:38\n    │\n157 │             uint256 kingIn = uint256(uint128(-delta.amount1()));\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/KingRouter.sol:164:30\n    │\n164 │             uint256 ethOut = uint256(uint128(delta.amount0()));\n    │                              ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingRouter.sol:164:38\n    │\n164 │             uint256 ethOut = uint256(uint128(delta.amount0()));\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/KingHook.sol:181:22\n    │\n181 │         launchTime = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:182:23\n    │\n182 │         lastAccrual = uint64(block.timestamp);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:185:39\n    │\n185 │         emit PoolLaunched(launchTime, uint64(block.timestamp + ANTI_SNIPE_DURATION));\n    │                                       ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:415:29\n    │\n415 │         return launchTime + uint64(ANTI_SNIPE_DURATION);\n    │                             ━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe 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/KingHook.sol:420:31\n    │\n420 │         return initialized && block.timestamp >= gameStart();\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/KingHook.sol:429:13\n    │\n429 │         if (elapsed >= ANTI_SNIPE_DURATION) return FEE_BASE_PPM;\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/KingHook.sol:449:16\n    │\n449 │         while (next <= block.timestamp) {\n    │                ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[calls-loop]: external call inside a loop\n    ╭▸ src/KingHook.sol:603:38\n    │\n603 │         return king != address(0) && token.balanceOf(king) < requiredBalance;\n    │                                      ━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/calls-loop\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:608:22\n    │\n608 │         reignStart = uint64(block.timestamp);\n    │                      ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:609:23\n    │\n609 │         lastAccrual = uint64(block.timestamp);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:616:24\n    │\n616 │                 start: uint64(block.timestamp),\n    │                        ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:645:21\n    │\n645 │         reign.end = uint64(block.timestamp);\n    │                     ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/KingHook.sol:658:35\n    │\n658 │         if (king == address(0) || block.timestamp <= lastAccrual) return pool;\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/KingHook.sol:665:35\n    │\n665 │         if (king == address(0) || block.timestamp <= lastAccrual) {\n    │                                   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:666:27\n    │\n666 │             lastAccrual = uint64(block.timestamp);\n    │                           ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:672:23\n    │\n672 │         lastAccrual = uint64(block.timestamp);\n    │                       ━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint64' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/KingHook.sol:689:16\n    │\n689 │         return block.timestamp - reignStart >= INCOME_VESTING;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://getfoundry.sh/forge/linting/block-timestamp\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:705:24\n    │\n705 │         return x < 0 ? uint256(-x) : uint256(x);\n    │                        ━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[unsafe-typecast]: typecast can truncate values\n    ╭▸ src/KingHook.sol:705:38\n    │\n705 │         return x < 0 ? uint256(-x) : uint256(x);\n    │                                      ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://getfoundry.sh/forge/linting/unsafe-typecast\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    ‡\n177 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:234:9\n    │\n234 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:234:17\n    │\n234 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:311:17\n    │\n311 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:434:22\n    │\n434 │         uint256 t0 = block.timestamp;\n    │                      ━━━━━━━━━━━━━━━\n435 │         buyExactIn(alice, 1 ether, false);\n436 │         vm.warp(t0 + 1 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:436:9\n    │\n436 │         vm.warp(t0 + 1 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:440:9\n    │\n440 │         vm.warp(t0 + 2 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:443:9\n    │\n443 │         vm.warp(t0 + 3 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:463:9\n    │\n463 │         vm.warp(hook.gameStart() - 1);\n    │         ───────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:469:9\n    │\n469 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Adversarial.t.sol:497:9\n    │\n497 │         vm.warp(block.timestamp + 2 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:497:17\n    │\n497 │         vm.warp(block.timestamp + 2 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Adversarial.t.sol:502:17\n    │\n502 │         vm.warp(block.timestamp + 20 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fee.t.sol:44:9\n    │\n 44 │         vm.warp(launch + 15 minutes);\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fee.t.sol:49:9\n    │\n 49 │         vm.warp(launch + 1 hours);\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:63:9\n    │\n 63 │         vm.warp(hook.launchTime() + bound(elapsed, 0, 2 hours));\n    │         ─────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:85:9\n    │\n 85 │         vm.warp(hook.launchTime() + bound(elapsed, 0, 2 hours));\n    │         ─────────────────────────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:131:9\n    │\n131 │         vm.warp(start + elapsed);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:130:25\n    │\n130 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n131 │         vm.warp(start + elapsed);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:163:9\n    │\n163 │         vm.warp(block.timestamp + elapsed);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:163:17\n    │\n163 │         vm.warp(block.timestamp + elapsed);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Fuzz.t.sol:249:9\n    │\n249 │         vm.warp(block.timestamp + a);\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:249:17\n    │\n249 │         vm.warp(block.timestamp + a);\n    │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Fuzz.t.sol:253:17\n    │\n253 │         vm.warp(block.timestamp + b);\n    │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:79:9\n    │\n 79 │         vm.warp(block.timestamp + 7 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/KingHook.Revision.t.sol:79:17\n   │\n79 │         vm.warp(block.timestamp + 7 hours);\n   │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:92:9\n    │\n 92 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/KingHook.Revision.t.sol:92:17\n   │\n92 │         vm.warp(block.timestamp + 10 minutes);\n   │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:103:9\n    │\n103 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:103:17\n    │\n103 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:131:9\n    │\n131 │         vm.warp(block.timestamp + delay);\n    │         ──────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:131:17\n    │\n131 │         vm.warp(block.timestamp + delay);\n    │         ────────━━━━━━━━━━━━━━━───────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:146:9\n    │\n146 │         vm.warp(block.timestamp + 5 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:146:17\n    │\n146 │         vm.warp(block.timestamp + 5 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:160:9\n    │\n160 │         vm.warp(block.timestamp + 1 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:160:17\n    │\n160 │         vm.warp(block.timestamp + 1 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:169:9\n    │\n169 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:169:17\n    │\n169 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:238:9\n    │\n238 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:238:17\n    │\n238 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:261:9\n    │\n261 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:261:17\n    │\n261 │         vm.warp(block.timestamp + 6 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Revision.t.sol:280:9\n    │\n280 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Revision.t.sol:280:17\n    │\n280 │         vm.warp(block.timestamp + 10 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:119:70\n    │\n119 │         ethIn = router.buyExactOut{value: maxEth}(kingOut, mustTake, block.timestamp);\n    │                                                                      ━━━━━━━━━━━━━━━\n    ‡\n177 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:410:9\n    │\n410 │         vm.warp(block.timestamp + 2 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Security.t.sol:410:17\n    │\n410 │         vm.warp(block.timestamp + 2 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:125:48\n    │\n125 │         ethOut = router.sellExactIn(kingIn, 0, block.timestamp);\n    │                                                ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:413:9\n    │\n413 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:413:9\n    │\n413 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Security.t.sol:413:17\n    │\n413 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:132:57\n    │\n132 │         kingIn = router.sellExactOut(ethOut, maxKingIn, block.timestamp);\n    │                                                         ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Security.t.sol:420:9\n    │\n420 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Security.t.sol:420:17\n    │\n420 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:98:9\n    │\n 98 │         vm.warp(block.timestamp + 10 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/KingHook.Throne.t.sol:98:17\n   │\n98 │         vm.warp(block.timestamp + 10 minutes);\n   │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:115:25\n    │\n115 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n119 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:145:9\n    │\n145 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:145:17\n    │\n145 │         vm.warp(block.timestamp + 5 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:168:25\n    │\n168 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n172 │         vm.warp(start + 1);\n    │         ────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:198:9\n    │\n198 │         vm.warp(block.timestamp + 2); // one Base block later\n    │         ──────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:198:17\n    │\n198 │         vm.warp(block.timestamp + 2); // one Base block later\n    │         ────────━━━━━━━━━━━━━━━───── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:229:25\n    │\n229 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n230 │         vm.warp(start + 5 minutes - 1);\n    │         ────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:230:9\n    │\n230 │         vm.warp(start + 5 minutes - 1);\n    │         ────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:257:9\n    │\n257 │         vm.warp(block.timestamp + 1 minutes);\n    │         ──────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:257:17\n    │\n257 │         vm.warp(block.timestamp + 1 minutes);\n    │         ────────━━━━━━━━━━━━━━━───────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:275:13\n    │\n275 │             vm.warp(start + i * 10 minutes);\n    │             ─────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:272:25\n    │\n272 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n    ‡\n275 │             vm.warp(start + i * 10 minutes);\n    │             ─────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:290:9\n    │\n290 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:289:25\n    │\n289 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n290 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:302:9\n    │\n302 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:302:17\n    │\n302 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:314:9\n    │\n314 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:314:17\n    │\n314 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:323:17\n    │\n323 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:368:9\n    │\n368 │         vm.warp(block.timestamp + 30 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:368:17\n    │\n368 │         vm.warp(block.timestamp + 30 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:412:25\n    │\n412 │         uint256 start = block.timestamp;\n    │                         ━━━━━━━━━━━━━━━\n413 │         vm.warp(start + 1 hours);\n    │         ──────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:506:22\n    │\n506 │         uint256 t0 = block.timestamp;\n    │                      ━━━━━━━━━━━━━━━\n507 │         uint256 aliceTokens = buyExactIn(alice, 1 ether, false);\n508 │         vm.warp(t0 + 2 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:508:9\n    │\n508 │         vm.warp(t0 + 2 hours);\n    │         ───────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingBase.sol:111:62\n    │\n111 │         kingOut = router.buyExactIn{value: eth}(0, mustTake, block.timestamp);\n    │                                                              ━━━━━━━━━━━━━━━\n    │\n    ⸬  test/KingHook.Throne.t.sol:542:9\n    │\n542 │         vm.warp(block.timestamp + 30 minutes);\n    │         ───────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/KingHook.Throne.t.sol:542:17\n    │\n542 │         vm.warp(block.timestamp + 30 minutes);\n    │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.t.sol:104:75\n    │\n104 │         uint256 aliceTokens = router.buyExactIn{value: 2 ether}(0, false, block.timestamp);\n    │                                                                           ━━━━━━━━━━━━━━━\n    ‡\n110 │         vm.warp(hook.gameStart());\n    │         ───────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:32:85\n   │\n32 │         uint256 ethIn = router.buyExactOut{value: 5 ether}(10_000_000 ether, false, block.timestamp);\n   │                                                                                     ━━━━━━━━━━━━━━━\n   ‡\n38 │         vm.warp(hook.gameStart());\n   │         ───────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:72:53\n   │\n72 │         router.buyExactIn{value: 3 ether}(0, false, block.timestamp);\n   │                                                     ━━━━━━━━━━━━━━━\n73 │         vm.warp(hook.gameStart());\n   │         ───────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:77:71\n   │\n77 │         uint256 required = router.buyExactIn{value: 1 ether}(0, true, block.timestamp);\n   │                                                                       ━━━━━━━━━━━━━━━\n   ‡\n92 │         vm.warp(block.timestamp + 30 minutes);\n   │         ───────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:85:52\n   │\n85 │         router.buyExactIn{value: 1 ether}(0, true, block.timestamp);\n   │                                                    ━━━━━━━━━━━━━━━\n   ‡\n92 │         vm.warp(block.timestamp + 30 minutes);\n   │         ───────────────────────────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n   ╭▸ test/fork/KingHookFork.More.t.sol:92:17\n   │\n92 │         vm.warp(block.timestamp + 30 minutes);\n   │         ────────━━━━━━━━━━━━━━━────────────── `vm.warp` changes this environment here\n   │\n   ├ help: capture it with `vm.getBlockTimestamp()` instead\n   ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:97:50\n    │\n 97 │         router.buyExactIn{value: 1e12}(0, false, block.timestamp);\n    │                                                  ━━━━━━━━━━━━━━━\n    ‡\n100 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:100:17\n    │\n100 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:115:17\n    │\n115 │         vm.warp(block.timestamp + 2 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:123:54\n    │\n123 │         router.buyExactIn{value: 0.5 ether}(0, true, block.timestamp);\n    │                                                      ━━━━━━━━━━━━━━━\n    ‡\n126 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────────────────────────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\nwarning[environment-read-across-mutation]: `block.timestamp` may be reused across `vm.warp`\n    ╭▸ test/fork/KingHookFork.More.t.sol:126:17\n    │\n126 │         vm.warp(block.timestamp + 1 hours);\n    │         ────────━━━━━━━━━━━━━━━─────────── `vm.warp` changes this environment here\n    │\n    ├ help: capture it with `vm.getBlockTimestamp()` instead\n    ╰ help: https://getfoundry.sh/forge/linting/environment-read-across-mutation\n\n","passed":true},{"durationMs":11565,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 1 test for test/Deploy.t.sol:DeployTest\n[PASS] test_deployFunctionProducesALaunchReadyPool() (gas: 16809717)\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 8.30ms (7.56ms CPU time)\n\nRan 6 tests for test/KingToken.t.sol:KingTokenTest\n[PASS] test_metadata() (gas: 29195)\n[PASS] test_mintsTheWholeSupplyToTheDeployer() (gas: 30033)\n[PASS] test_noAdminOrMintSurface() (gas: 372285)\n[PASS] test_runtimeCodeHasNoDelegatecallOrSelfdestruct() (gas: 529435)\n[PASS] test_transferFromRespectsAllowance() (gas: 139693)\n[PASS] test_transferMovesExactlyWhatItWasAsked() (gas: 86516)\nSuite result: ok. 6 passed; 0 failed; 0 skipped; finished in 33.18ms (4.34ms CPU time)\n\nRan 37 tests for test/KingHook.Throne.t.sol:KingHookThroneTest\n[PASS] test_anySellByTheKingThroughTheRouterDethronesAtOnce() (gas: 1213417)\n[PASS] test_beingOutbidWithinFiveMinutesForfeitsTheIncome() (gas: 1156045)\n[PASS] test_buyOneWeiBelowThePriceDoesNotTake() (gas: 489797)\n[PASS] test_claimRevertsForWalletsWithNothing() (gas: 39234)\n[PASS] test_claimWhileKingAndAfterLosingTheThrone() (gas: 1453759)\n[PASS] test_dethroneAfterATransferStopsIncomeAtThatMoment() (gas: 935966)\n[PASS] test_dethroneIsRefusedWhenTheThroneIsEmpty() (gas: 330791)\n[PASS] test_dethroneIsRefusedWhileTheKingHoldsEnough() (gas: 976830)\n[PASS] test_feesArrivingDuringAReignEarnFromThenOn() (gas: 1028219)\n[PASS] test_gameOpensExactlyWhenTheFeeReachesBase() (gas: 44820)\n[PASS] test_incomeAccruesEverySecondAtTwoPercentPerHour() (gas: 971073)\n[PASS] test_incomeIsPathIndependent() (gas: 5959444)\n[PASS] test_incomeStopsWhenTheThroneEmpties() (gas: 1020086)\n[PASS] test_incomeVestsAfterFiveMinutes() (gas: 1379481)\n[PASS] test_kingCanRetakeHisOwnThroneStartingANewReign() (gas: 1101342)\n[PASS] test_kingSellExactOutThroughTheRouterDethrones() (gas: 964215)\n[PASS] test_kingSellThroughAnotherRouterIsCaughtByTheHoldingRule() (gas: 1185959)\n[PASS] test_mustTakeIsIgnoredWithoutTheFlag() (gas: 860936)\n[PASS] test_mustTakeRevertsForExactOutputBuysToo() (gas: 805173)\n[PASS] test_mustTakeRevertsTheWholeSwapBelowThePrice() (gas: 860587)\n[PASS] test_mustTakeSucceedsAtThePrice() (gas: 1010672)\n[PASS] test_nobodyCanTakeFromThePoolOutsideTheGame() (gas: 370691)\n[PASS] test_pastKingsWithReignTimeAndEarnings() (gas: 1334176)\n[PASS] test_priceDecayMakesALongSittingKingCheap() (gas: 1102305)\n[PASS] test_priceHalvesEveryHourDownToTheFloor() (gas: 809346)\n[PASS] test_priceIsTheFloorWhileTheThroneIsEmpty() (gas: 965735)\n[PASS] test_routerSlippageAndDeadline() (gas: 646905)\n[PASS] test_sellsByOthersNeverAffectTheThrone() (gas: 1348001)\n[PASS] test_smallBuysNeverAddUp() (gas: 1115952)\n[PASS] test_takeAndDumpWithinFiveMinutesForfeitsTheIncome() (gas: 1128974)\n[PASS] test_takeoverAtExactlyTheFloorPrice() (gas: 719702)\n[PASS] test_takeoverPriceIsTheFeeInclusiveAmount() (gas: 1225221)\n[PASS] test_takeoverThroughExactOutputBuyCountsTheFee() (gas: 701483)\n[PASS] test_throneIsClosedDuringAntiSnipe() (gas: 443969)\n[PASS] test_throneViewAggregatesEverything() (gas: 884642)\n[PASS] test_transferAndDethroneWithinFiveMinutesForfeitsTheIncome() (gas: 875126)\n[PASS] test_viewsOnAnEmptyThrone() (gas: 338741)\nSuite result: ok. 37 passed; 0 failed; 0 skipped; finished in 140.56ms (102.02ms CPU time)\n\nRan 16 tests for test/KingHook.Adversarial.t.sol:KingHookAdversarialTest\n[PASS] test_aGiftToTheKingKeepsHimOnTheThrone() (gas: 797261)\n[PASS] test_contractWalletsAreIdentifiedAsTheBuyer() (gas: 1777762)\n[PASS] test_creditsAccumulateAcrossReignsAndOneClaimPaysAll() (gas: 2009023)\n[PASS] test_drainedPoolRecoversWithTheNextBuy() (gas: 2379409)\n[PASS] test_dustSwapsPayNoFeeAndDoNotRevert() (gas: 981978)\n[PASS] test_flashHeldTokensDoNotProtectTheKingBetweenTransactions() (gas: 1200031)\n[PASS] test_frontRunningDethroneWithAClaimChangesNothing() (gas: 1095064)\n[PASS] test_mustTakeAroundTheOpeningSecond() (gas: 824797)\n[PASS] test_reentryDuringRouterSettlementCannotTouchTheThrone() (gas: 5232877)\n[PASS] test_reignHistoryPaginationEdges() (gas: 1165072)\n[PASS] test_selfCrownedBuyerNestingASwapLosesHisOwnThrone() (gas: 2457827)\n[PASS] test_takeoverChainAtTheFloorIsExact() (gas: 2403655)\n[PASS] test_teamWalletCanBeKingAndClaimsBothShares() (gas: 893748)\n[PASS] test_theSwapThatEvictsAShortKingPaysItsFeeAndMayTakeTheThrone() (gas: 1151298)\n[PASS] test_thirdPartySellBeyondThePoolsEthFillsPartiallyAndKeepsTheRest() (gas: 961775)\n[PASS] test_unclaimedIncomeIsWhatClaimPays() (gas: 965950)\nSuite result: ok. 16 passed; 0 failed; 0 skipped; finished in 243.17ms (97.71ms CPU time)\n\nRan 24 tests for test/KingHook.Security.t.sol:KingHookSecurityTest\n[PASS] test_callbacksRefuseCallersOtherThanThePoolManager() (gas: 151574)\n[PASS] test_constructorRejectsAddressesWithoutCode() (gas: 6053)\n[PASS] test_dethroneDuringAPayoutIsRefused() (gas: 1380156)\n[PASS] test_exactOutputSellBeyondPoolEthReverts() (gas: 807667)\n[PASS] test_foreignBuyerIdentityIsIgnoredAndMustTakeIsRejected() (gas: 650317)\n[PASS] test_hookAcceptsFactoryFeeAndReturnsInitializeSelector() (gas: 5223665)\n[PASS] test_hookAcceptsOnlyOnePool() (gas: 45543)\n[PASS] test_hookCallbacksRefuseToRunDuringAPayout() (gas: 1427837)\n[PASS] test_hookNeverHoldsValueDirectly() (gas: 960840)\n[PASS] test_hookRejectsUnlistedAndDynamicLpFees() (gas: 5173005)\n[PASS] test_hookRejectsWrongCurrencies() (gas: 5702689)\n[PASS] test_initializationRecordsTheLaunch() (gas: 37897)\n[PASS] test_legacyLpFeesRejectedWithoutInitializing() (gas: 5365643)\n[PASS] test_noOwnerOrParameterFunctions() (gas: 643428)\n[PASS] test_permissionsMatchTheMinedAddress() (gas: 17095)\n[PASS] test_poolSolvencyAcrossALifecycle() (gas: 2707245)\n[PASS] test_reentrantClaimIsPaidExactlyOnce() (gas: 1394197)\n[PASS] test_routerCannotBeSpoofedThroughTheManager() (gas: 491140)\n[PASS] test_runtimeCodeHasNoEscapeHatch() (gas: 5463325)\n[PASS] test_sellCheckpointDuringAPayoutIsRefused() (gas: 1435830)\n[PASS] test_swapDuringAPayoutIsRefused() (gas: 1408630)\n[PASS] test_swapsBeforeInitializationAreImpossible() (gas: 5129895)\n[PASS] test_unimplementedCallbacksRevert() (gas: 126319)\n[PASS] test_unlockCallbackRefusesThePoolManagerOutsideAPayout() (gas: 35640)\nSuite result: ok. 24 passed; 0 failed; 0 skipped; finished in 268.11ms (124.14ms CPU time)\n\nRan 14 tests for test/KingHook.Fee.t.sol:KingHookFeeTest\n[PASS] testFuzz_feeRateFollowsTheLine(uint32) (runs: 256, μ: 18929, ~: 18640)\n[PASS] testFuzz_feeSplits92To8(uint96) (runs: 256, μ: 355773, ~: 364800)\n[PASS] test_exactInputBuy_feeIsTakenFromTheEthInput() (gas: 348775)\n[PASS] test_exactInputSell_feeIsTakenFromTheEthOutput() (gas: 578745)\n[PASS] test_exactOutputBuy_feeIsAddedToTheEthInput() (gas: 345291)\n[PASS] test_exactOutputFeeIsComputedOnTheSettledDelta() (gas: 329402)\n[PASS] test_exactOutputSell_feeIsAddedOnTopOfTheEthOutput() (gas: 607505)\n[PASS] test_feeCollectionDoesNotDependOnRecipientsAcceptingEth() (gas: 277310033)\n[PASS] test_feeDecayIsAppliedToSwaps() (gas: 877139)\n[PASS] test_feeIsNeverTakenInKingOnAnyPath() (gas: 1372505)\n[PASS] test_feeOnThirdPartyRouterBothDirections() (gas: 595391)\n[PASS] test_feeStartsAt25PercentAndDecaysLinearlyTo2_5Percent() (gas: 59719)\n[PASS] test_firstBuyOnManagerHoldingNoEthSucceeds() (gas: 358790)\n[PASS] test_teamWalletClaimsItsShareOnlyByPulling() (gas: 368961)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 575.74ms (431.89ms CPU time)\n\nRan 10 tests for test/Halving.t.sol:HalvingTest\n[PASS] testFuzz_fractionBelowHalfLifeStaysAboveHalf(uint192,uint32) (runs: 256, μ: 8436, ~: 8916)\n[PASS] testFuzz_monotoneAndBounded(uint192,uint64,uint64) (runs: 256, μ: 6031, ~: 6560)\n[PASS] testFuzz_monotoneForRealAmounts(uint64,uint64) (runs: 256, μ: 5506, ~: 6082)\n[PASS] test_exactAtWholeHalfLives() (gas: 2341)\n[PASS] test_halfWayIsOneOverSqrtTwo() (gas: 5393)\n[PASS] test_oneHourOfIncomeLeavesNinetyEightPercent() (gas: 8294)\n[PASS] test_perSecondCompoundingIsPathIndependent() (gas: 141119)\n[PASS] test_quarterWay() (gas: 5371)\n[PASS] test_rejectsOverflowingInputs() (gas: 11089)\n[PASS] test_zeroElapsedIsIdentity() (gas: 546)\nSuite result: ok. 10 passed; 0 failed; 0 skipped; finished in 621.89ms (382.41ms CPU time)\n\nRan 9 tests for test/KingRouter.Atomicity.t.sol:KingRouterAtomicityTest\n[PASS] testFuzz_failedTakeoverSlippageRestoresPreviousKing(uint96) (runs: 1000, μ: 1537818, ~: 1538697)\n[PASS] test_allFourExpiredOrdersPreserveAccruingReign() (gas: 2678124)\n[PASS] test_balanceFailureRestoresFiniteAllowanceAndCheckpoint() (gas: 1743502)\n[PASS] test_bothSellModesWithNoAllowanceRestoreCheckpoint() (gas: 1671792)\n[PASS] test_exactOutputInsufficientEthRestoresAccrualAndTakeover() (gas: 1011557)\n[PASS] test_exactOutputSellBudgetFailureRestoresCheckpoint() (gas: 1020473)\n[PASS] test_rejectedIncomePayoutPreservesClaimsAndCanBeRetried() (gas: 1659562)\n[PASS] test_sellSlippageRestoresTokensAllowanceCreditsAndReign() (gas: 1445770)\n[PASS] test_zeroOrdersCannotCheckpointOrDethrone() (gas: 3338454)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 621.72ms (632.99ms CPU time)\n\nRan 15 tests for test/KingHook.Fuzz.t.sol:KingHookFuzzTest\n[PASS] testFuzz_exactInputBuyFeeAtAnyMoment(uint96,uint32) (runs: 512, μ: 374668, ~: 355563)\n[PASS] testFuzz_exactInputSellFeeAtAnyMoment(uint96,uint32,uint256) (runs: 512, μ: 591439, ~: 590384)\n[PASS] testFuzz_exactOutputBuyFeeAtAnyMoment(uint96,uint32) (runs: 512, μ: 408045, ~: 357802)\n[PASS] testFuzz_exactOutputSellFeeAtAnyMoment(uint96,uint32,uint96) (runs: 512, μ: 610387, ~: 612851)\n[PASS] testFuzz_feeNeverExceedsTheSwap(uint96,uint32) (runs: 256, μ: 331189, ~: 317835)\n[PASS] testFuzz_halvingBounds(uint192,uint64,uint64) (runs: 512, μ: 4057, ~: 4404)\n[PASS] testFuzz_halvingComposes(uint128,uint32,uint32) (runs: 512, μ: 13231, ~: 14846)\n[PASS] testFuzz_halvingExactAtWholeHalfLives(uint192,uint8) (runs: 512, μ: 1366, ~: 1351)\n[PASS] testFuzz_halvingMatchesWadExp(uint128,uint32) (runs: 1024, μ: 10993, ~: 11339)\n[PASS] testFuzz_incomeCurve(uint96,uint32) (runs: 512, μ: 844833, ~: 847956)\n[PASS] testFuzz_incomeIsPathIndependent(uint32,uint32,uint32) (runs: 128, μ: 1016768, ~: 1024733)\n[PASS] testFuzz_smallBuysNeverAddUp(uint96,uint96,uint96) (runs: 128, μ: 1197994, ~: 1201129)\n[PASS] testFuzz_takeoverBoundaryAfterDecay(uint96,uint32) (runs: 256, μ: 1482430, ~: 1484797)\n[PASS] testFuzz_thronePriceCurve(uint96,uint32) (runs: 512, μ: 718123, ~: 723057)\n[PASS] test_incomeConstantIsNinetyEightPercentPerHour() (gas: 28097)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 622.99ms (5.12s CPU time)\n\nRan 21 tests for test/KingHook.Revision.t.sol:KingHookRevisionTest\n[PASS] testFuzz_earlyTakeoversNeverVest(uint32,bool) (runs: 256, μ: 1556018, ~: 1452617)\n[PASS] test_claimForfeitsUnverifiedGapAndPersistsDethrone() (gas: 1323056)\n[PASS] test_deficientKingCannotVestBySellingDust() (gas: 1064718)\n[PASS] test_dethroneForfeitsUnverifiedGap() (gas: 1314533)\n[PASS] test_exactOutputCannotSweepDonatedTokensOrExceedBudget() (gas: 1235457)\n[PASS] test_failedSellRollsBackCheckpointAndTokens() (gas: 1362904)\n[PASS] test_foreignMustTakeRevertsWithoutCharging() (gas: 848693)\n[PASS] test_foreignUnrelatedMetadataIsIgnored() (gas: 660663)\n[PASS] test_halvingErrorIsRelativeNot64Wei() (gas: 14853)\n[PASS] test_nextSellerCannotSweepPartialFillRefund() (gas: 1936362)\n[PASS] test_nonPayableWalletCannotReceiveExactOutputRefund() (gas: 612820)\n[PASS] test_officialExactInputSellIsRecordedAsSold() (gas: 1066188)\n[PASS] test_officialExactOutputSellIsRecordedAsSoldDespiteEscrow() (gas: 1249338)\n[PASS] test_partialSellRefundsUnusedKing() (gas: 1231499)\n[PASS] test_prepareSellRejectsUntrustedCallers() (gas: 692907)\n[PASS] test_previouslyVestedCreditsSurviveHoldingFailure() (gas: 1201864)\n[PASS] test_selfRetakeCannotReduceHoldingRequirement() (gas: 1407064)\n[PASS] test_swapForfeitsUnverifiedGap() (gas: 1446972)\n[PASS] test_takeoverAtVestingBoundaryKeepsIncome() (gas: 1215398)\n[PASS] test_thirdPartyExitThenClaimPaysNoQuietPeriodIncome() (gas: 1037001)\n[PASS] test_transferAtTakeoverThenClaimAtFiveMinutesPaysNothing() (gas: 857466)\nSuite result: ok. 21 passed; 0 failed; 0 skipped; finished in 637.67ms (599.41ms CPU time)\n\nRan 4 tests for test/fork/KingHookFork.More.t.sol:KingHookForkMoreTest\n[PASS] test_fork_exactOutputBuyAndBothSellModesPayTheFeeInEth() (gas: 849143)\n[PASS] test_fork_feesAndThroneOnTheLiveManager() (gas: 1220331)\n[PASS] test_fork_holdingRuleDethroneAndMustTakeOnTheLiveManager() (gas: 2243222)\n[PASS] test_fork_poolOpensAtTheLaunchPrice() (gas: 30278)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 946.48ms (95.62ms CPU time)\n\nRan 2 tests for test/fork/KingHookFork.t.sol:KingHookForkTest\n[PASS] test_fork_feesAndThroneOnTheLiveManager() (gas: 1220075)\n[PASS] test_fork_poolOpensAtTheLaunchPrice() (gas: 30278)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 946.69ms (47.68ms CPU time)\n\nRan 1 test for test/KingHook.Invariant.t.sol:KingHookInvariantTest\n[PASS]\nKingHookInvariantTest invariants:\n[PASS] invariant_claimsBackThePoolAndEveryCredit\n[PASS] invariant_hookAndRouterHoldNothing\n[PASS] invariant_nobodyIsOwedMoreThanTheClaimsCanPay\n[PASS] invariant_throneStateIsConsistent\n KingHookInvariantTest invariants (runs: 24, calls: 1152, reverts: 0)\n\n╭-------------+-------------+-------+---------+----------╮\n| Contract    | Selector    | Calls | Reverts | Discards |\n+========================================================+\n| KingHandler | buyIn       | 136   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | buyOut      | 159   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | claim       | 155   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | dethrone    | 135   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | sellIn      | 141   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | sellOut     | 154   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | transferOut | 137   | 0       | 0        |\n|-------------+-------------+-------+---------+----------|\n| KingHandler | warp        | 135   | 0       | 0        |\n╰-------------+-------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 1.20s (1.18s CPU time)\n\nRan 7 tests for test/KingHook.Conservation.t.sol:KingHookConservationTest\n[PASS]\nKingHookConservationTest invariants:\n[PASS] invariant_claimsEqualPoolPlusCredits\n[PASS] invariant_ethIsConserved\n[PASS] invariant_everyPostconditionHeld\n[PASS] invariant_feesAreConserved\n[PASS] invariant_nothingIsStranded\n[PASS] invariant_reignHistoryIsConsistent\n[PASS] invariant_throneIsConsistent\n KingHookConservationTest invariants (runs: 96, calls: 6144, reverts: 0)\n\n╭-----------------+-------------------+-------+---------+----------╮\n| Contract        | Selector          | Calls | Reverts | Discards |\n+==================================================================+\n| KingPlayHandler | buyIn             | 558   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | buyOut            | 551   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | claim             | 531   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | dethrone          | 545   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | sellIn            | 556   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | sellOut           | 578   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | sellOutsideSupply | 593   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | tpBuy             | 570   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | tpSell            | 557   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | transferOut       | 530   | 0       | 0        |\n|-----------------+-------------------+-------+---------+----------|\n| KingPlayHandler | warp              | 575   | 0       | 0        |\n╰-----------------+-------------------+-------+---------+----------╯\n\n[PASS] testFuzz_everyoneCanExitAfterRandomPlay(uint256) (runs: 64, μ: 9493014, ~: 9497068)\n[PASS] test_handlerEarlyRivalTakeoverForfeitsIncome() (gas: 2138818)\n[PASS] test_handlerForeignMustTakeRollsBackBothExactModes() (gas: 961282)\n[PASS] test_handlerOfficialPartialSellRefundsWithoutCapacityCap() (gas: 1915595)\n[PASS] test_handlerSelfRetakePreservesLargerRequirement() (gas: 2086406)\n[PASS] test_handlerShortKingReturnsProvisionalAndClaimDethrones() (gas: 2783578)\nSuite result: ok. 7 passed; 0 failed; 0 skipped; finished in 7.19s (8.96s CPU time)\n\nRan 2 tests for test/KingHook.LiquidityInvariant.t.sol:KingHookLiquidityInvariantTest\n[PASS] invariant_valueAndSettlementAreConservedDuringLiquidityChanges() (runs: 256, calls: 16384, reverts: 0)\n\n╭----------------------+-----------------+-------+---------+----------╮\n| Contract             | Selector        | Calls | Reverts | Discards |\n+=====================================================================+\n| KingLiquidityHandler | buy             | 2064  | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| KingLiquidityHandler | changeLiquidity | 2048  | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| KingLiquidityHandler | claim           | 2061  | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| KingLiquidityHandler | collectLpFees   | 2014  | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| KingLiquidityHandler | dethroneIfShort | 2092  | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| KingLiquidityHandler | elapse          | 2099  | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| KingLiquidityHandler | sell            | 1973  | 0       | 0        |\n|----------------------+-----------------+-------+---------+----------|\n| KingLiquidityHandler | transferKing    | 2033  | 0       | 0        |\n╰----------------------+-----------------+-------+---------+----------╯\n\n[PASS] test_liquidityActionsAndClaimsAreReachable() (gas: 2751746)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 11.14s (11.13s CPU time)\n\nRan 15 test suites in 11.16s (25.19s CPU time): 169 tests passed, 0 failed, 0 skipped (169 total tests)\n","passed":true},{"durationMs":262,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"KingHook.afterSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),int256,bytes)\",\"KingHook.beforeInitialize(address,(address,address,uint24,int24,address),uint160)\",\"KingHook.beforeSwap(address,(address,address,uint24,int24,address),(bool,int256,uint160),bytes)\",\"KingHook.claim()\",\"KingHook.dethrone()\",\"KingHook.prepareSell(address)\",\"KingHook.unlockCallback(bytes)\",\"KingRouter.buyExactIn(uint256,bool,uint256)\",\"KingRouter.buyExactOut(uint256,bool,uint256)\",\"KingRouter.sellExactIn(uint256,uint256,uint256)\",\"KingRouter.sellExactOut(uint256,uint256,uint256)\",\"KingRouter.unlockCallback(bytes)\",\"KingToken.approve(address,uint256)\",\"KingToken.transfer(address,uint256)\",\"KingToken.transferFrom(address,address,uint256)\"],\"files\":{\".gitignore\":4,\"README.md\":321,\"SOURCE.json\":550,\"docs/REDEPLOYMENT.md\":135,\"docs/REVIEW.md\":153,\"docs/REVISION.md\":104,\"foundry.toml\":31,\"launch.json\":30,\"remappings.txt\":5,\"script/Deploy.s.sol\":64,\"script/check_source.py\":41,\"src/HookFlags.sol\":66,\"src/KingHook.sol\":707,\"src/KingRouter.sol\":173,\"src/KingToken.sol\":19,\"src/interfaces/IKingHook.sol\":95,\"src/libraries/Halving.sol\":99,\"test/ADDITIONAL-COVERAGE.md\":66,\"test/Deploy.t.sol\":38,\"test/Halving.t.sol\":87,\"test/KingBase.sol\":192,\"test/KingHook.Adversarial.t.sol\":512,\"test/KingHook.Conservation.t.sol\":813,\"test/KingHook.Fee.t.sol\":220,\"test/KingHook.Fuzz.t.sol\":317,\"test/KingHook.Invariant.t.sol\":169,\"test/KingHook.LiquidityInvariant.t.sol\":287,\"test/KingHook.Revision.t.sol\":342,\"test/KingHook.Security.t.sol\":450,\"test/KingHook.Throne.t.sol\":597,\"test/KingRouter.Atomicity.t.sol\":254,\"test/KingToken.t.sol\":82,\"test/fork/KingHookFork.More.t.sol\":139,\"test/fork/KingHookFork.t.sol\":142,\"test/helpers/WebLaunchFixture.sol\":42,\"test/mocks/MockERC20.sol\":11,\"web/README.md\":68,\"web/dist/abi/KingHook.json\":2072,\"web/dist/abi/KingRouter.json\":296,\"web/dist/abi/KingToken.json\":328,\"web/dist/build.json\":5,\"web/dist/crown.svg\":1,\"web/dist/imd-deployment.json\":16,\"web/dist/index.html\":61,\"web/dist/src/app.js\":217,\"web/dist/src/client.js\":76,\"web/dist/src/core.js\":56,\"web/dist/style.css\":3,\"web/dist/vendor/ethers.LICENSE.md\":21,\"web/dist/vendor/ethers.js\":1,\"web/dist/vendor/provenance.json\":10,\"web/package.json\":11,\"web/public/abi/KingHook.json\":2072,\"web/public/abi/KingRouter.json\":296,\"web/public/abi/KingToken.json\":328,\"web/public/crown.svg\":1,\"web/public/imd-deployment.json\":16,\"web/public/index.html\":61,\"web/public/style.css\":3,\"web/scripts/build.mjs\":30,\"web/scripts/configure.mjs\":36,\"web/src/app.js\":217,\"web/src/client.js\":76,\"web/src/core.js\":56,\"web/test/core.test.mjs\":44,\"web/test/integration.mjs\":100,\"web/vendor/ethers.LICENSE.md\":21,\"web/vendor/ethers.js\":1,\"web/vendor/provenance.json\":10},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":false}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"41a6e587d6f988b39b449f5b08906916b1e26d05919d158eda1989782c32def5","verifiedTreeHash":"c16314d85c41d0f88cc2e2a1ab309c458f47108f","verifierVersion":"0.1.0+94826a22"}]}