{"assessments":[],"deployments":[],"fuzz":[],"identity":null,"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"052d072d-a2fc-41d2-8e3f-795035d42412","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"f115a22bb388740834cb8aa73aa521dd7d9a4c854e260c16d79f61132d18f898","dependsOn":["build_contract_project","write_foundry_tests","gas_and_size_report","manifest"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"c26edc76dc7a76e09a42c3634054429c1679c6e247747d647a03f77e5b332d7e","skillId":"adversarial-review","tools":[]},"key":"adversarial_review","kind":"code","role":"review","skillHash":"c26edc76dc7a76e09a42c3634054429c1679c6e247747d647a03f77e5b332d7e","skillId":"adversarial-review","state":"failed"},{"acceptedSubmissionHash":"6e0437d1987c249da0ffab4024d57712578cf251f917ba29bd52e31867abb17d","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"fb6887b34514bcb194265fa403f0195c6a83eaef269da1e6189e1e9c4b372a7d","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"fb6887b34514bcb194265fa403f0195c6a83eaef269da1e6189e1e9c4b372a7d","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"a148748f2bf9399ee50b969ecf86fe9db04238e2a006dbd9d2ced65bbc4f1f3c","dependsOn":["write_foundry_tests"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"5c5c99a166c3c04ccd57d2e798a955dddd4a65fac4d4ef785f15fd91193b69fe","skillId":"gas-and-size-report","tools":[]},"key":"gas_and_size_report","kind":"code","role":"tests","skillHash":"5c5c99a166c3c04ccd57d2e798a955dddd4a65fac4d4ef785f15fd91193b69fe","skillId":"gas-and-size-report","state":"failed"},{"acceptedSubmissionHash":"f036ff99e1062f9af764bcabe0331544bb21822c90c89cfb059c3f860aa29506","dependsOn":["build_contract_project","write_foundry_tests","gas_and_size_report"],"execution":{"network":false,"profile":"foundry","requires":[],"tools":[]},"key":"manifest","kind":"code","role":"integrate","skillHash":null,"skillId":null,"state":"failed"},{"acceptedSubmissionHash":"f3d9f49586f42bb6de8bf7e2ba5d879e5f28a014009b9602aecd6dfe4cbd72f5","dependsOn":["build_contract_project"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"5891004c5c81aca68ad1dcc551c7bc98f3ec10c61fce5561aee8956a26e95588","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"5891004c5c81aca68ad1dcc551c7bc98f3ec10c61fce5561aee8956a26e95588","skillId":"write-foundry-tests","state":"failed"}],"objective":"WORKFLOW CONTRACT STAGE: implement, test and review contracts and launch.json. Export ABI JSON for deployed contracts under docs/abi/ for frontend integration. The workflow handles deployment and the website after this stage. Read .imd/reads/workflow.md for the complete approved requirements; fulfill every contract, test, gas, integration and review requirement there.","parentJobId":null,"planHash":"52c14a1ac0a7a7e97ddeec89ee6181bd78959eb405e99f61a80d0ccc205098cf","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"052d072d-a2fc-41d2-8e3f-795035d42412","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/Identity-md/launch-44-volatilityguardhook-volatilityguardtoken"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[],"site":null,"snapshotHash":"df17b255f93b6147201c91b603d597a346cce284fddcda2bc07969b717afed5b","state":"cancelled","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"d0e55eb1d8d7936bf5dac986b4e5286bc235c6bfc35c808cbe25677054869346","deviceKey":"a1c5c6c3e93f5a311d26715fe81382674dca82117134c2e6f97c1bc5faea9f09","findings":[],"hash":"2019becc35d76f06eebde63129236584db7a9c00d1545e8c5e8e6970baf229db","nodeId":"666fbe10-975e-495c-b64e-8ef57c8cd74c","outcome":"completed","summary":"Implemented the complete contract-stage deliverable.\n\nKey outputs:\n\n- [VolatilityGuardHook.sol](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/666fbe10-975e-495c-b64e-8ef57c8cd74c/src/VolatilityGuardHook.sol)\n- [VolatilityGuardToken.sol](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/666fbe10-975e-495c-b64e-8ef57c8cd74c/src/VolatilityGuardToken.sol)\n- [launch.json](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/666fbe10-975e-495c-b64e-8ef57c8cd74c/launch.json)\n- [Architecture](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/666fbe10-975e-495c-b64e-8ef57c8cd74c/docs/architecture.md)\n- [Threat model](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/666fbe10-975e-495c-b64e-8ef57c8cd74c/docs/threat-model.md)\n- [Frontend integration](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/666fbe10-975e-495c-b64e-8ef57c8cd74c/docs/frontend-integration.md)\n- [Review findings](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/666fbe10-975e-495c-b64e-8ef57c8cd74c/REVIEW.md)\n- [Gas evidence](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/666fbe10-975e-495c-b64e-8ef57c8cd74c/artifacts/gas.md)\n- ABI JSON exports under `docs/abi/`\n\nVerification:\n\n- `forge fmt --check`: passed\n- `forge build --offline`: passed\n- `forge test --offline`: 13 passed\n- Two key fuzz properties: 10,000 runs each\n- Manifest and ABI JSON validated\n- Dependencies vendored as ordinary files with no nested Git repositories\n\nThe PoolManager address was cross-checked against the current [official Uniswap SDK Sepolia constants](https://github.com/Uniswap/sdks/blob/main/sdks/sdk-core/src/addresses.ts). No deployment transactions, addresses, or receipts were fabricated.","treeHash":"056ab4ae48680579fd0da1109553f56c57b7cb79","usage":{"cachedInputTokens":2996864,"inputTokens":117793,"model":null,"outputTokens":22552,"runtime":"codex","turns":5,"wallClockMs":680642}},{"artifacts":[],"attempt":2,"bundleHash":null,"deviceKey":"a1c5c6c3e93f5a311d26715fe81382674dca82117134c2e6f97c1bc5faea9f09","findings":[],"hash":"43a31db7e1ec4f5738d2aa36819a794f4adcd000c49b49b90938f955aafc34a0","nodeId":"3e62a38a-c434-423e-91f5-384d6a64b121","outcome":"failed","summary":"could not restore accepted work: accepted work conflicts with a dependency, which plan validation should have prevented: ","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"codex","turns":0,"wallClockMs":369}},{"artifacts":[],"attempt":1,"bundleHash":null,"deviceKey":"0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9","findings":[],"hash":"56ffdaed13127b09904cb3b43c096bc0469b0509f10a096669767280509b099a","nodeId":"3e62a38a-c434-423e-91f5-384d6a64b121","outcome":"failed","summary":"could not restore accepted work: accepted work conflicts with a dependency, which plan validation should have prevented: ","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"codex","turns":0,"wallClockMs":1246}},{"artifacts":[],"attempt":1,"bundleHash":"084862c2b276fdfa166b167c2d6181d9d4a3e7504625ab89a8ae16a68ae16136","deviceKey":"a1c5c6c3e93f5a311d26715fe81382674dca82117134c2e6f97c1bc5faea9f09","findings":[],"hash":"6e0437d1987c249da0ffab4024d57712578cf251f917ba29bd52e31867abb17d","nodeId":"666fbe10-975e-495c-b64e-8ef57c8cd74c","outcome":"completed","summary":"Implemented and verified all five reviewer findings.\n\nKey fixes:\n\n- Volume accounting now uses actual authenticated input deltas, including fees and partial fills.\n- Exact-output swaps are budgeted in input-currency units.\n- Band-crossing swaps revert atomically in `afterSwap`.\n- Volume buckets use `uint256`, matching advertised capacity.\n- TWAP uses a cumulative tick integral updated on every successful price change.\n- Updated ABI, launch manifest, architecture, threat model, review, and frontend integration docs.\n- Recorded all verdicts in [.imd-responses.json](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/666fbe10-975e-495c-b64e-8ef57c8cd74c/.imd-responses.json).\n\nVerification:\n\n- `forge build`: passed\n- `forge test`: 17 passed, 0 failed\n- Key fuzz tests: 10,000 runs\n- `forge fmt --check`: passed\n- Exported hook ABI matches `forge inspect` after JSON normalization\n- `git diff --check`: passed","treeHash":"3f43302b821a06b05c52fc5b041807046efd4b16","usage":{"cachedInputTokens":1118592,"inputTokens":83560,"model":null,"outputTokens":13857,"runtime":"codex","turns":4,"wallClockMs":335454}},{"artifacts":[],"attempt":3,"bundleHash":null,"deviceKey":"0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9","findings":[],"hash":"8086d5a6bf9f755813e8aaa13d3eaa4154a8c394795e4ff675599aa3d2bf6c12","nodeId":"3e62a38a-c434-423e-91f5-384d6a64b121","outcome":"failed","summary":"could not restore accepted work: accepted work conflicts with a dependency, which plan validation should have prevented: ","treeHash":null,"usage":{"cachedInputTokens":0,"inputTokens":0,"model":null,"outputTokens":0,"runtime":"codex","turns":0,"wallClockMs":1277}},{"artifacts":[],"attempt":1,"bundleHash":"f004eee8d1a268b7510d0fa3f04f0cb517044b12751a2cb14feb73d309b477fc","deviceKey":"a1c5c6c3e93f5a311d26715fe81382674dca82117134c2e6f97c1bc5faea9f09","findings":[],"hash":"a148748f2bf9399ee50b969ecf86fe9db04238e2a006dbd9d2ced65bbc4f1f3c","nodeId":"764fd37d-7168-4e41-8928-09fe4097b7d4","outcome":"completed","summary":"Completed the gas and size deliverables:\n\n- Added [.gas-snapshot](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/764fd37d-7168-4e41-8928-09fe4097b7d4/.gas-snapshot).\n- Added full ABI gas coverage in [GasSurface.t.sol](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/764fd37d-7168-4e41-8928-09fe4097b7d4/test/GasSurface.t.sol).\n- Added [gas.md](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/764fd37d-7168-4e41-8928-09fe4097b7d4/artifacts/gas.md) with every public function and deployed size.\n\nResults:\n\n- `VolatilityGuardHook`: 6,685 bytes.\n- `VolatilityGuardToken`: 1,130 bytes.\n- No EIP-170 size defect.\n- `forge build`: passed.\n- `forge test`: 27 passed, 0 failed.\n- `forge snapshot --check`: passed.\n- `forge fmt --check`: passed.\n- Key fuzz tests ran 10,000 cases.\n\nThe report flags `afterSwap` reaching 172,775 gas as the main launch-budget concern.","treeHash":"61c208975e76b581347433c23b4f8fbf5db45ccf","usage":{"cachedInputTokens":944384,"inputTokens":63916,"model":null,"outputTokens":8251,"runtime":"codex","turns":6,"wallClockMs":238230}},{"artifacts":[],"attempt":1,"bundleHash":"2aaf30a3c01039d7cd0b32c88189452723d1ec99ff18fa25280c04973764d1c4","deviceKey":"a1c5c6c3e93f5a311d26715fe81382674dca82117134c2e6f97c1bc5faea9f09","findings":[],"hash":"f036ff99e1062f9af764bcabe0331544bb21822c90c89cfb059c3f860aa29506","nodeId":"d91ad13a-ae6f-4802-9f87-cdeaca53044d","outcome":"completed","summary":"Updated [launch.json](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/d91ad13a-ae6f-4802-9f87-cdeaca53044d/launch.json) with:\n\n- Correct `univ4_hook` discriminator\n- Explicit hook permissions matching flags `4288`\n- Required ETH/VGL pool configuration and decimal `sqrtPriceX96`\n- ABI integration paths\n- Notes length: 1,872 characters\n\nVerification:\n\n- `forge build` — passed\n- `forge test` — 27 passed, 0 failed\n- Manifest structural checks — passed\n- Scope check — only `launch.json` changed","treeHash":"1739bb1f8143560c5817e12f988decde181f4f9a","usage":{"cachedInputTokens":439040,"inputTokens":58321,"model":null,"outputTokens":3310,"runtime":"codex","turns":4,"wallClockMs":108733}},{"artifacts":[],"attempt":1,"bundleHash":null,"deviceKey":"0edd2bbb66d2d014fbbda834d6ccbc278847c31414f601db126e7a1269baddd9","findings":[{"description":"The hook ignores the authenticated BalanceDelta and charges abs(amountSpecified), although PoolManager permits partial fills at sqrtPriceLimitX96. Any trader can consume the complete rolling budget without trading that volume, denying subsequent swaps in that direction until bucket expiry. A second opposite-direction partial fill can block both directions. The same accounting also mixes output-currency units into the input-currency budget for exact-output swaps. Tests always supply a zero BalanceDelta and assert requested amounts, so they enshrine rather than detect the mismatch. Check and record the actual input delta after execution; exact-output requests cannot be compared directly with an input-denominated remaining budget.","line":129,"path":"src/VolatilityGuardHook.sol","reproduction":"Initialize a static-fee-3000 pool at sqrtPriceX96=79228162514264337593543950336, tick 0, with active liquidity 1000000000000000000 across tick 0 (for example a position spanning [-887220,887220]), zero protocol fee and an empty volume ring. Through a PoolManager unlock callback call swap with zeroForOne=true, amountSpecified=-64000000000000000000, sqrtPriceLimitX96=79228162514264337593543950335 and empty hookData; settle the actual deltas. The vendored SwapMath charges 1 unit input plus 1 unit fee and returns 0 output at this price limit. Expected recorded input volume: 2. Actual rollingVolume(id,true): 64000000000000000000. A subsequent same-direction request for 1 unit reverts VolumeBudgetExceeded(true,1,0), despite virtually the entire actual-volume budget remaining. No victim approval or privileged caller is required. This reproduction is derived from the vendored Pool/SwapMath rounding and hook code, not a claimed executed integration test.","severity":"high","title":"Partial fills can exhaust the entire directional budget for two base units"},{"description":"beforeSwap checks only the starting tick. afterSwap commits an arbitrarily large price movement and sets guardedAt instead of enforcing the required per-swap deviation limit. Thus the first price shock succeeds and only later trades, including corrective trades, are blocked. Documentation acknowledges this behavior, but it does not meet the approved adaptive per-swap protection requirement. Returning no delta does not prevent validating the resulting PoolManager price and reverting the entire swap. The check should use the applicable pre-execution reference/band so the triggering swap cannot rewrite its own reference or enlarge its own limit.","line":139,"path":"src/VolatilityGuardHook.sol","reproduction":"Use fee 3000, zero protocol fee, initial price 2^96 and full-range active liquidity 1e18. Seed calm observations at timestamps 100,130,160 with tick 0, ewmaVolatility=0, count=3 and empty/negligible directional volume. At timestamp 161 submit zeroForOne=true, amountSpecified=-1e18, sqrtPriceLimitX96=4295128740 (MIN_SQRT_PRICE+1). The starting tick equals reference 0 and 1e18 is below the 64e18 budget, so beforeSwap succeeds. Vendored swap arithmetic yields sqrtPriceX96=39673591644599067397868778336 and tick -13834. Expected: reject a resulting deviation beyond the reported 120-tick band. Actual: afterSwap returns success, records the swap and sets guardedAt; even its recalculated 900-tick maximum is exceeded. The existing testShockGuardAndPermissionlessRecovery likewise explicitly accepts a 3000-tick movement. Numeric outcome is derived from vendored swap arithmetic; no live swap is claimed.","severity":"high","title":"The adaptive price band does not constrain the swap that crosses it"},{"description":"A swap occurring less than 30 seconds after the newest observation updates lastTick but is discarded from observation history. _reference subsequently weights the old sampled tick over the entire elapsed interval, even when the pool spent almost all that interval at a different tick. This is not merely a manipulable internal TWAP: it assigns time to a price that was not present. Sampling-boundary trades can distort guard decisions cheaply, and the same-block/count tests never assert elapsed-time price integration. Maintain a bounded cumulative tick integral across price changes and sample that integral, rather than dropping the changes themselves.","line":244,"path":"src/VolatilityGuardHook.sol","reproduction":"Initialize at timestamp 100 with tick 0 and liquidity 1e18. At timestamp 101 execute a budget-compliant swap ending at tick 500, then leave the pool at tick 500 until timestamp 130. The warmup precheck permits the swap; _writeObservation returns because 101-100<30. At timestamp 130, before another swap, snapshot(id) returns currentTick=500 and referenceTick=0. Expected time-weighted tick over the initialized 30-second history is trunc((0*1 + 500*29)/30)=483. Actual is 0 because observation(0) remains (100,0), despite lastTick being 500. This can also be reproduced directly using the existing StateReaderMock and authenticated callback harness with these timestamps and ticks; it follows deterministically from the stored observations.","severity":"medium","title":"Discarded within-period tick changes corrupt the time-weighted reference"}],"hash":"f115a22bb388740834cb8aa73aa521dd7d9a4c854e260c16d79f61132d18f898","nodeId":"bcbab30b-a242-4604-8730-de1998a65aa1","outcome":"completed","summary":"Wrote three findings to [.imd-findings.json](.imd-findings.json), ranked by severity:\n\n- **High:** Two-unit partial fill can exhaust the directional volume budget.\n- **High:** Swaps can exceed the adaptive price band and still succeed.\n- **Medium:** Skipped tick changes corrupt the time-weighted reference.\n\nEach includes concrete reproduction inputs. Findings use source tracing and arithmetic checks; no live transactions were executed. Implementation files remain unchanged.","treeHash":null,"usage":{"cachedInputTokens":303360,"inputTokens":88711,"model":null,"outputTokens":3673,"runtime":"codex","turns":4,"wallClockMs":129342}},{"artifacts":[],"attempt":1,"bundleHash":"364266237740c7dfb75b4a71dded3dda788b5488fc3c2c36d32549708f286c5b","deviceKey":"a1c5c6c3e93f5a311d26715fe81382674dca82117134c2e6f97c1bc5faea9f09","findings":[{"description":"The hook always uses abs(params.amountSpecified) as volume. In Uniswap v4 this is the input amount for exact-input swaps, but it is the output amount for exact-output swaps. volumeBudget documents and exposes a per-direction input-currency budget, so exact-output traffic is accounted in a different token's raw units. Pairs with unequal decimals or prices can therefore bypass or spuriously exhaust the split-resistant input budget.","line":114,"path":"src/VolatilityGuardHook.sol","reproduction":"Create a zeroForOne pool where currency0 has 18 decimals and currency1 has 6 decimals, with liquidity 1e18 and an approximately 1:1 human-unit price. Submit exact-output zeroForOne swaps with amountSpecified=+1_000_000, each of which spends approximately 1e18 currency0 base units. Expected: each swap consumes approximately 1e18 units of the currency0 directional budget. Actual: lines 114 and 129 account only 1_000_000 output base units, undercounting by about 1e12 and allowing the rolling input-volume guard to be bypassed.","severity":"medium","title":"Exact-output swaps consume the wrong currency units from the rolling budget"},{"description":"Each directional bucket is uint128, while the public limit is liquidity * 64 in uint256. For sufficiently large liquidity, multiple individually valid swaps can remain below that limit but overflow bucket.zeroForOne or bucket.oneForZero in _recordVolume. The checked addition then reverts afterSwap and consequently the whole otherwise-valid swap.","line":232,"path":"src/VolatilityGuardHook.sol","reproduction":"Set active liquidity to type(uint128).max and remain within one 75-second epoch. Complete one swap in a direction with abs(amountSpecified)=type(uint128).max, then attempt a second swap in the same direction with abs(amountSpecified)=1. Expected from volumeBudget: used=type(uint128).max, limit=64*type(uint128).max, so the second swap is accepted and recorded. Actual: beforeSwap accepts it, but afterSwap executes bucket.zeroForOne += 1 at line 232 and reverts with arithmetic overflow.","severity":"low","title":"Advertised volume budget exceeds bucket storage capacity and can revert otherwise-budgeted swaps"}],"hash":"f3d9f49586f42bb6de8bf7e2ba5d879e5f28a014009b9602aecd6dfe4cbd72f5","nodeId":"3e62a38a-c434-423e-91f5-384d6a64b121","outcome":"completed","summary":"Implemented expanded adversarial Foundry coverage in:\n\n- [VolatilityGuardHook.t.sol](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/3e62a38a-c434-423e-91f5-384d6a64b121/test/VolatilityGuardHook.t.sol)\n- [VolatilityGuardToken.t.sol](/root/.identitymd/work/052d072d-a2fc-41d2-8e3f-795035d42412/3e62a38a-c434-423e-91f5-384d6a64b121/test/VolatilityGuardToken.t.sol)\n\nCoverage now includes callback authorization, minimal permissions, amount limits, budget boundaries/expiry, rollback behavior, ring-buffer updates, allowance failures, zero-address transfers, infinite allowances, and supply conservation.\n\nReported two implementation defects in `.imd-findings.json`:\n\n- Medium: exact-output swaps are budgeted using output rather than input currency units.\n- Low: the public volume limit can exceed `uint128` bucket capacity and trigger overflow reverts.\n\nVerification:\n\n- `forge fmt --check` passed\n- `forge build` passed\n- `forge test` passed: 23 tests\n- Both fuzz tests passed 10,000 runs\n- `forge test --gas-report` passed","treeHash":"040c897395e4c9748a48ae7ba9e44fdac7b63a54","usage":{"cachedInputTokens":438912,"inputTokens":65830,"model":null,"outputTokens":6738,"runtime":"codex","turns":6,"wallClockMs":179787}}],"verification":[{"checks":[{"durationMs":9025,"exitCode":0,"name":"build","output":"Compiling 54 files with Solc 0.8.26\nSolc 0.8.26 finished in 8.75s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n  --> src/VolatilityGuardHook.sol:98:5:\n   |\n98 |     function _beforeSwap(address, PoolKey calldata key, SwapParams calldata params, bytes calldata)\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:23:9\n   │\n23 │         token.transfer(address(0xBEEF), 10 ether);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VolatilityGuardHook.sol:266:17\n    │\n266 │         stale = block.timestamp - state.observations[newest].timestamp > STALE_AFTER;\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:27:9\n   │\n27 │         token.transferFrom(address(this), address(0xBEEF), 3 ether);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:34:9\n   │\n34 │         token.transfer(address(this), 1);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:40:9\n   │\n40 │         token.transfer(recipient, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VolatilityGuardHook.sol:273:16\n    │\n273 │         return block.timestamp - state.observations[newest].timestamp > STALE_AFTER;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/VolatilityGuardHook.t.sol:20:31\n   │\n20 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/VolatilityGuardHook.t.sol:20:39\n   │\n20 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\n   │                                       ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint24' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:130:49\n    │\n130 │         _recordVolume(state, params.zeroForOne, uint128(amount));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/VolatilityGuardHook.t.sol:102:50\n    │\n102 │             _successfulSwap(key, i % 2 == 0, -1, int24(int256(i + 2)));\n    │                                                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/VolatilityGuardHook.t.sol:102:56\n    │\n102 │             _successfulSwap(key, i % 2 == 0, -1, int24(int256(i + 2)));\n    │                                                        ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:189:16\n    │\n189 │         return uint24(limit);\n    │                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:257:69\n    │\n257 │             Observation storage item = state.observations[(oldest + uint8(i)) % OBSERVATION_CAPACITY];\n    │                                                                     ━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:259:48\n    │\n259 │                 ? state.observations[(oldest + uint8(i + 1)) % OBSERVATION_CAPACITY].timestamp\n    │                                                ━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:262:45\n    │\n262 │             weighted += int256(item.tick) * int256(dt);\n    │                                             ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:267:75\n    │\n267 │         referenceTick = duration == 0 ? state.observations[newest].tick : int24(weighted / int256(duration));\n    │                                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:267:92\n    │\n267 │         referenceTick = duration == 0 ? state.observations[newest].tick : int24(weighted / int256(duration));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\n","passed":true},{"durationMs":326,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/VolatilityGuardToken.t.sol:VolatilityGuardTokenTest\n[PASS] testCannotTransferWithoutBalance() (gas: 11393)\n[PASS] testFuzzConservesSupply(address,uint96) (runs: 10000, μ: 44669, ~: 45022)\nLogs:\n  Bound result 48879\n\n[PASS] testMetadataAndFixedSupply() (gas: 17296)\n[PASS] testTransferAndAllowance() (gas: 51838)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 141.19ms (125.79ms CPU time)\n\nRan 9 tests for test/VolatilityGuardHook.t.sol:VolatilityGuardHookTest\n[PASS] testFuzzExactInputAndOutputSigns(bool,int128) (runs: 10000, μ: 61042, ~: 69438)\n[PASS] testLowLiquidityRefusesSwapButRemovalCallbackIsNotEnabled() (gas: 36915)\n[PASS] testOnlyManagerCanCall() (gas: 15771)\n[PASS] testPoolsAreIsolated() (gas: 172241)\n[PASS] testRejectedVolumeCheckDoesNotPersistAccounting() (gas: 65038)\n[PASS] testRingWrapsAndSameBlockDoesNotGrow() (gas: 1891957)\n[PASS] testShockGuardAndPermissionlessRecovery() (gas: 276887)\n[PASS] testSplitSwapsAccumulateAndDirectionIsolated() (gas: 214733)\n[PASS] testStaleHistoryReturnsToWarmup() (gas: 51665)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 141.24ms (142.66ms CPU time)\n\nRan 2 test suites in 170.16ms (282.42ms CPU time): 13 tests passed, 0 failed, 0 skipped (13 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"2019becc35d76f06eebde63129236584db7a9c00d1545e8c5e8e6970baf229db","verifiedTreeHash":"056ab4ae48680579fd0da1109553f56c57b7cb79","verifierVersion":"0.1.0+25bbf3ee"},{"checks":[{"durationMs":9513,"exitCode":0,"name":"build","output":"Compiling 54 files with Solc 0.8.26\nSolc 0.8.26 finished in 9.38s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n   --> src/VolatilityGuardHook.sol:102:5:\n    |\n102 |     function _beforeSwap(address, PoolKey calldata key, SwapParams calldata, bytes calldata)\n    |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:23:9\n   │\n23 │         token.transfer(address(0xBEEF), 10 ether);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VolatilityGuardHook.sol:281:17\n    │\n281 │         stale = block.timestamp - state.lastUpdate > STALE_AFTER;\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VolatilityGuardHook.sol:289:16\n    │\n289 │         return block.timestamp - state.lastUpdate > STALE_AFTER;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/VolatilityGuardHook.t.sol:20:31\n   │\n20 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:27:9\n   │\n27 │         token.transferFrom(address(this), address(0xBEEF), 3 ether);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:34:9\n   │\n34 │         token.transfer(address(this), 1);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:40:9\n   │\n40 │         token.transfer(recipient, amount);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:204:16\n    │\n204 │         return uint24(limit);\n    │                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/VolatilityGuardHook.t.sol:20:39\n   │\n20 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\n   │                                       ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint24' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:284:15\n    │\n284 │             : int24((int256(currentCumulative) - int256(first.tickCumulative)) / int256(duration));\n    │               ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:284:82\n    │\n284 │             : int24((int256(currentCumulative) - int256(first.tickCumulative)) / int256(duration));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:294:33\n    │\n294 │         return inputDelta < 0 ? uint256(-int256(inputDelta)) : 0;\n    │                                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/VolatilityGuardHook.t.sol:133:50\n    │\n133 │             _successfulSwap(key, i % 2 == 0, -1, int24(int256(i + 2)));\n    │                                                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/VolatilityGuardHook.t.sol:133:56\n    │\n133 │             _successfulSwap(key, i % 2 == 0, -1, int24(int256(i + 2)));\n    │                                                        ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\n","passed":true},{"durationMs":237,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/VolatilityGuardToken.t.sol:VolatilityGuardTokenTest\n[PASS] testCannotTransferWithoutBalance() (gas: 11393)\n[PASS] testFuzzConservesSupply(address,uint96) (runs: 10000, μ: 44589, ~: 45022)\nLogs:\n  Bound result 15921530961\n\n[PASS] testMetadataAndFixedSupply() (gas: 17296)\n[PASS] testTransferAndAllowance() (gas: 51838)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 98.24ms (98.18ms CPU time)\n\nRan 13 tests for test/VolatilityGuardHook.t.sol:VolatilityGuardHookTest\n[PASS] testBucketCanRepresentAdvertisedBudgetAboveUint128() (gas: 188340)\n[PASS] testExactOutputRecordsInputCurrencyDelta() (gas: 115135)\n[PASS] testFuzzExactInputAndOutputSigns(bool,int128) (runs: 10000, μ: 31050, ~: 31048)\n[PASS] testLowLiquidityRefusesSwapButRemovalCallbackIsNotEnabled() (gas: 37070)\n[PASS] testOnlyManagerCanCall() (gas: 15840)\n[PASS] testPartialFillRecordsActualInputIncludingFee() (gas: 115073)\n[PASS] testPoolsAreIsolated() (gas: 208192)\n[PASS] testRejectedVolumeCheckDoesNotPersistAccounting() (gas: 89177)\n[PASS] testRingWrapsAndSameBlockDoesNotGrow() (gas: 1693966)\n[PASS] testSplitSwapsAccumulateAndDirectionIsolated() (gas: 238798)\n[PASS] testStaleHistoryReturnsToWarmup() (gas: 51303)\n[PASS] testSwapCrossingAdaptiveBandReverts() (gas: 254875)\n[PASS] testWithinPeriodTickChangesAreIntegrated() (gas: 1676970)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 98.29ms (103.75ms CPU time)\n\nRan 2 test suites in 100.37ms (196.53ms CPU time): 17 tests passed, 0 failed, 0 skipped (17 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"6e0437d1987c249da0ffab4024d57712578cf251f917ba29bd52e31867abb17d","verifiedTreeHash":"3f43302b821a06b05c52fc5b041807046efd4b16","verifierVersion":"0.1.0+25bbf3ee"},{"checks":[{"durationMs":14546,"exitCode":0,"name":"build","output":"Compiling 55 files with Solc 0.8.26\nSolc 0.8.26 finished in 14.42s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n  --> src/VolatilityGuardHook.sol:98:5:\n   |\n98 |     function _beforeSwap(address, PoolKey calldata key, SwapParams calldata params, bytes calldata)\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/GasSurface.t.sol:21:31\n   │\n21 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:35:9\n   │\n35 │         token.transfer(address(this), 1);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VolatilityGuardHook.sol:266:17\n    │\n266 │         stale = block.timestamp - state.observations[newest].timestamp > STALE_AFTER;\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/VolatilityGuardHook.t.sol:21:31\n   │\n21 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/GasSurface.t.sol:21:39\n   │\n21 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\n   │                                       ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint24' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/VolatilityGuardHook.t.sol:21:39\n   │\n21 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\n   │                                       ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint24' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VolatilityGuardHook.sol:273:16\n    │\n273 │         return block.timestamp - state.observations[newest].timestamp > STALE_AFTER;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/VolatilityGuardHook.t.sol:182:50\n    │\n182 │             _successfulSwap(key, i % 2 == 0, -1, int24(int256(i + 2)));\n    │                                                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/VolatilityGuardHook.t.sol:182:56\n    │\n182 │             _successfulSwap(key, i % 2 == 0, -1, int24(int256(i + 2)));\n    │                                                        ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:130:49\n    │\n130 │         _recordVolume(state, params.zeroForOne, uint128(amount));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:40:9\n   │\n40 │         token.transfer(address(0), 1);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:47:9\n   │\n47 │         token.transferFrom(address(this), address(0xBEEF), 3);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:189:16\n    │\n189 │         return uint24(limit);\n    │                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:257:69\n    │\n257 │             Observation storage item = state.observations[(oldest + uint8(i)) % OBSERVATION_CAPACITY];\n    │                                                                     ━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:259:48\n    │\n259 │                 ? state.observations[(oldest + uint8(i + 1)) % OBSERVATION_CAPACITY].timestamp\n    │                                                ━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:262:45\n    │\n262 │             weighted += int256(item.tick) * int256(dt);\n    │                                             ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:267:75\n    │\n267 │         referenceTick = duration == 0 ? state.observations[newest].tick : int24(weighted / int256(duration));\n    │                                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:267:92\n    │\n267 │         referenceTick = duration == 0 ? state.observations[newest].tick : int24(weighted / int256(duration));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\n","passed":true},{"durationMs":262,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/GasSurface.t.sol:GasSurfaceTest\n[PASS] testGasDisabledHookCallbacksRevert() (gas: 37889)\n[PASS] testGasHookConstantGetters() (gas: 15190)\n[PASS] testGasHookReadSurface() (gas: 83840)\n[PASS] testGasTokenReadSurface() (gas: 14610)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.55ms (657.42µs CPU time)\n\nRan 8 tests for test/VolatilityGuardToken.t.sol:VolatilityGuardTokenTest\n[PASS] testCannotTransferToZero() (gas: 8899)\n[PASS] testCannotTransferWithoutBalance() (gas: 11393)\n[PASS] testFuzzConservesSupply(address,uint96) (runs: 10000, μ: 45147, ~: 45572)\nLogs:\n  Bound result 4461\n\n[PASS] testInfiniteAllowanceIsNotDecremented() (gas: 66204)\n[PASS] testMetadataAndFixedSupply() (gas: 17340)\n[PASS] testSelfTransferPreservesBalanceAndSupply() (gas: 16768)\n[PASS] testTransferAndAllowance() (gas: 54424)\n[PASS] testTransferFromRejectsInsufficientAllowanceWithoutMutation() (gas: 40439)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 128.62ms (129.33ms CPU time)\n\nRan 15 tests for test/VolatilityGuardHook.t.sol:VolatilityGuardHookTest\n[PASS] testAmountBoundsRejectWithoutChangingState() (gas: 70377)\n[PASS] testBudgetBoundaryIsInclusiveAndNextUnitIsRejected() (gas: 124397)\n[PASS] testExpiredVolumeBucketRestoresBudget() (gas: 111644)\n[PASS] testFuzzExactInputAndOutputSigns(bool,int128) (runs: 10000, μ: 61051, ~: 52656)\n[PASS] testLowLiquidityRefusesSwapButRemovalCallbackIsNotEnabled() (gas: 37069)\n[PASS] testOnlyManagerCanCall() (gas: 21381)\n[PASS] testPermissionsAreMinimalAndDoNotClaimDeltas() (gas: 17766)\n[PASS] testPoolsAreIsolated() (gas: 172510)\n[PASS] testPriceDeviationRevertDoesNotMutateHistoryOrRegime() (gas: 252868)\n[PASS] testRejectedVolumeCheckDoesNotPersistAccounting() (gas: 65058)\n[PASS] testRingWrapsAndSameBlockDoesNotGrow() (gas: 1895673)\n[PASS] testSameBlockUpdatesNewestObservationWithoutGrowingRing() (gas: 206622)\n[PASS] testShockGuardAndPermissionlessRecovery() (gas: 277460)\n[PASS] testSplitSwapsAccumulateAndDirectionIsolated() (gas: 215379)\n[PASS] testStaleHistoryReturnsToWarmup() (gas: 51700)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 128.66ms (145.61ms CPU time)\n\nRan 3 test suites in 130.09ms (258.83ms CPU time): 27 tests passed, 0 failed, 0 skipped (27 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"a148748f2bf9399ee50b969ecf86fe9db04238e2a006dbd9d2ced65bbc4f1f3c","verifiedTreeHash":"61c208975e76b581347433c23b4f8fbf5db45ccf","verifierVersion":"0.1.0+25bbf3ee"},{"checks":[{"durationMs":13803,"exitCode":0,"name":"build","output":"Compiling 55 files with Solc 0.8.26\nSolc 0.8.26 finished in 13.68s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n  --> src/VolatilityGuardHook.sol:98:5:\n   |\n98 |     function _beforeSwap(address, PoolKey calldata key, SwapParams calldata params, bytes calldata)\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:35:9\n   │\n35 │         token.transfer(address(this), 1);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/VolatilityGuardHook.t.sol:21:31\n   │\n21 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/VolatilityGuardHook.t.sol:21:39\n   │\n21 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\n   │                                       ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint24' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/VolatilityGuardHook.t.sol:182:50\n    │\n182 │             _successfulSwap(key, i % 2 == 0, -1, int24(int256(i + 2)));\n    │                                                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/VolatilityGuardHook.t.sol:182:56\n    │\n182 │             _successfulSwap(key, i % 2 == 0, -1, int24(int256(i + 2)));\n    │                                                        ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/GasSurface.t.sol:21:31\n   │\n21 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/GasSurface.t.sol:21:39\n   │\n21 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\n   │                                       ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint24' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VolatilityGuardHook.sol:266:17\n    │\n266 │         stale = block.timestamp - state.observations[newest].timestamp > STALE_AFTER;\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:40:9\n   │\n40 │         token.transfer(address(0), 1);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:47:9\n   │\n47 │         token.transferFrom(address(this), address(0xBEEF), 3);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VolatilityGuardHook.sol:273:16\n    │\n273 │         return block.timestamp - state.observations[newest].timestamp > STALE_AFTER;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:130:49\n    │\n130 │         _recordVolume(state, params.zeroForOne, uint128(amount));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:189:16\n    │\n189 │         return uint24(limit);\n    │                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:257:69\n    │\n257 │             Observation storage item = state.observations[(oldest + uint8(i)) % OBSERVATION_CAPACITY];\n    │                                                                     ━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:259:48\n    │\n259 │                 ? state.observations[(oldest + uint8(i + 1)) % OBSERVATION_CAPACITY].timestamp\n    │                                                ━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:262:45\n    │\n262 │             weighted += int256(item.tick) * int256(dt);\n    │                                             ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:267:75\n    │\n267 │         referenceTick = duration == 0 ? state.observations[newest].tick : int24(weighted / int256(duration));\n    │                                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:267:92\n    │\n267 │         referenceTick = duration == 0 ? state.observations[newest].tick : int24(weighted / int256(duration));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\n","passed":true},{"durationMs":252,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 4 tests for test/GasSurface.t.sol:GasSurfaceTest\n[PASS] testGasDisabledHookCallbacksRevert() (gas: 37889)\n[PASS] testGasHookConstantGetters() (gas: 15190)\n[PASS] testGasHookReadSurface() (gas: 83840)\n[PASS] testGasTokenReadSurface() (gas: 14610)\nSuite result: ok. 4 passed; 0 failed; 0 skipped; finished in 2.03ms (708.09µs CPU time)\n\nRan 8 tests for test/VolatilityGuardToken.t.sol:VolatilityGuardTokenTest\n[PASS] testCannotTransferToZero() (gas: 8899)\n[PASS] testCannotTransferWithoutBalance() (gas: 11393)\n[PASS] testFuzzConservesSupply(address,uint96) (runs: 10000, μ: 45168, ~: 45572)\nLogs:\n  Bound result 22064\n\n[PASS] testInfiniteAllowanceIsNotDecremented() (gas: 66204)\n[PASS] testMetadataAndFixedSupply() (gas: 17340)\n[PASS] testSelfTransferPreservesBalanceAndSupply() (gas: 16768)\n[PASS] testTransferAndAllowance() (gas: 54424)\n[PASS] testTransferFromRejectsInsufficientAllowanceWithoutMutation() (gas: 40439)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 124.99ms (126.24ms CPU time)\n\nRan 15 tests for test/VolatilityGuardHook.t.sol:VolatilityGuardHookTest\n[PASS] testAmountBoundsRejectWithoutChangingState() (gas: 70377)\n[PASS] testBudgetBoundaryIsInclusiveAndNextUnitIsRejected() (gas: 124397)\n[PASS] testExpiredVolumeBucketRestoresBudget() (gas: 111644)\n[PASS] testFuzzExactInputAndOutputSigns(bool,int128) (runs: 10000, μ: 61193, ~: 69525)\n[PASS] testLowLiquidityRefusesSwapButRemovalCallbackIsNotEnabled() (gas: 37069)\n[PASS] testOnlyManagerCanCall() (gas: 21381)\n[PASS] testPermissionsAreMinimalAndDoNotClaimDeltas() (gas: 17766)\n[PASS] testPoolsAreIsolated() (gas: 172510)\n[PASS] testPriceDeviationRevertDoesNotMutateHistoryOrRegime() (gas: 252868)\n[PASS] testRejectedVolumeCheckDoesNotPersistAccounting() (gas: 65058)\n[PASS] testRingWrapsAndSameBlockDoesNotGrow() (gas: 1895673)\n[PASS] testSameBlockUpdatesNewestObservationWithoutGrowingRing() (gas: 206622)\n[PASS] testShockGuardAndPermissionlessRecovery() (gas: 277460)\n[PASS] testSplitSwapsAccumulateAndDirectionIsolated() (gas: 215379)\n[PASS] testStaleHistoryReturnsToWarmup() (gas: 51700)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 125.01ms (133.56ms CPU time)\n\nRan 3 test suites in 126.23ms (252.02ms CPU time): 27 tests passed, 0 failed, 0 skipped (27 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"f036ff99e1062f9af764bcabe0331544bb21822c90c89cfb059c3f860aa29506","verifiedTreeHash":"1739bb1f8143560c5817e12f988decde181f4f9a","verifierVersion":"0.1.0+25bbf3ee"},{"checks":[{"durationMs":9688,"exitCode":0,"name":"build","output":"Compiling 54 files with Solc 0.8.26\nSolc 0.8.26 finished in 9.57s\nCompiler run successful with warnings:\nWarning (2018): Function state mutability can be restricted to view\n  --> src/VolatilityGuardHook.sol:98:5:\n   |\n98 |     function _beforeSwap(address, PoolKey calldata key, SwapParams calldata params, bytes calldata)\n   |     ^ (Relevant source part starts here and spans across multiple lines).\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VolatilityGuardHook.sol:266:17\n    │\n266 │         stale = block.timestamp - state.observations[newest].timestamp > STALE_AFTER;\n    │                 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/VolatilityGuardHook.t.sol:21:31\n   │\n21 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n   ╭▸ test/VolatilityGuardHook.t.sol:21:39\n   │\n21 │         words[base] = bytes32(uint256(uint24(tick)) << 160 | uint256(3000) << 208 | uint256(1 << 96));\n   │                                       ━━━━━━━━━━━━\n   │\n   ├ note: consider disabling this lint if you're certain the cast is safe\n   │       \n   │       // casting to 'uint24' is safe because [explain why]\n   │       // forge-lint: disable-next-line(unsafe-typecast)\n   │       \n   │       \n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[block-timestamp]: usage of `block.timestamp` in a comparison may be manipulated by validators\n    ╭▸ src/VolatilityGuardHook.sol:273:16\n    │\n273 │         return block.timestamp - state.observations[newest].timestamp > STALE_AFTER;\n    │                ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#block-timestamp\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/VolatilityGuardHook.t.sol:182:50\n    │\n182 │             _successfulSwap(key, i % 2 == 0, -1, int24(int256(i + 2)));\n    │                                                  ━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ test/VolatilityGuardHook.t.sol:182:56\n    │\n182 │             _successfulSwap(key, i % 2 == 0, -1, int24(int256(i + 2)));\n    │                                                        ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:130:49\n    │\n130 │         _recordVolume(state, params.zeroForOne, uint128(amount));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:189:16\n    │\n189 │         return uint24(limit);\n    │                ━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:257:69\n    │\n257 │             Observation storage item = state.observations[(oldest + uint8(i)) % OBSERVATION_CAPACITY];\n    │                                                                     ━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:259:48\n    │\n259 │                 ? state.observations[(oldest + uint8(i + 1)) % OBSERVATION_CAPACITY].timestamp\n    │                                                ━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'uint8' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:262:45\n    │\n262 │             weighted += int256(item.tick) * int256(dt);\n    │                                             ━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int256' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:267:75\n    │\n267 │         referenceTick = duration == 0 ? state.observations[newest].tick : int24(weighted / int256(duration));\n    │                                                                           ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n    │\n    ├ note: consider disabling this lint if you're certain the cast is safe\n    │       \n    │       // casting to 'int24' is safe because [explain why]\n    │       // forge-lint: disable-next-line(unsafe-typecast)\n    │       \n    │       \n    ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[unsafe-typecast]: typecasts that can truncate values should be checked\n    ╭▸ src/VolatilityGuardHook.sol:267:92\n    │\n267 │         referenceTick = duration == 0 ? state.observations[newest].tick : int24(weighted / int256(duration));\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://book.getfoundry.sh/reference/forge/forge-lint#unsafe-typecast\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:35:9\n   │\n35 │         token.transfer(address(this), 1);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:40:9\n   │\n40 │         token.transfer(address(0), 1);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\nwarning[erc20-unchecked-transfer]: ERC20 'transfer' and 'transferFrom' calls should check the return value\n   ╭▸ test/VolatilityGuardToken.t.sol:47:9\n   │\n47 │         token.transferFrom(address(this), address(0xBEEF), 3);\n   │         ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n   │\n   ╰ help: https://book.getfoundry.sh/reference/forge/forge-lint#erc20-unchecked-transfer\n\n","passed":true},{"durationMs":245,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 8 tests for test/VolatilityGuardToken.t.sol:VolatilityGuardTokenTest\n[PASS] testCannotTransferToZero() (gas: 8899)\n[PASS] testCannotTransferWithoutBalance() (gas: 11393)\n[PASS] testFuzzConservesSupply(address,uint96) (runs: 10000, μ: 45158, ~: 45572)\nLogs:\n  Bound result 791390191\n\n[PASS] testInfiniteAllowanceIsNotDecremented() (gas: 66204)\n[PASS] testMetadataAndFixedSupply() (gas: 17340)\n[PASS] testSelfTransferPreservesBalanceAndSupply() (gas: 16768)\n[PASS] testTransferAndAllowance() (gas: 54424)\n[PASS] testTransferFromRejectsInsufficientAllowanceWithoutMutation() (gas: 40439)\nSuite result: ok. 8 passed; 0 failed; 0 skipped; finished in 116.60ms (117.52ms CPU time)\n\nRan 15 tests for test/VolatilityGuardHook.t.sol:VolatilityGuardHookTest\n[PASS] testAmountBoundsRejectWithoutChangingState() (gas: 70377)\n[PASS] testBudgetBoundaryIsInclusiveAndNextUnitIsRejected() (gas: 124397)\n[PASS] testExpiredVolumeBucketRestoresBudget() (gas: 111644)\n[PASS] testFuzzExactInputAndOutputSigns(bool,int128) (runs: 10000, μ: 61035, ~: 52656)\n[PASS] testLowLiquidityRefusesSwapButRemovalCallbackIsNotEnabled() (gas: 37069)\n[PASS] testOnlyManagerCanCall() (gas: 21381)\n[PASS] testPermissionsAreMinimalAndDoNotClaimDeltas() (gas: 17766)\n[PASS] testPoolsAreIsolated() (gas: 172510)\n[PASS] testPriceDeviationRevertDoesNotMutateHistoryOrRegime() (gas: 252868)\n[PASS] testRejectedVolumeCheckDoesNotPersistAccounting() (gas: 65058)\n[PASS] testRingWrapsAndSameBlockDoesNotGrow() (gas: 1895673)\n[PASS] testSameBlockUpdatesNewestObservationWithoutGrowingRing() (gas: 206622)\n[PASS] testShockGuardAndPermissionlessRecovery() (gas: 277460)\n[PASS] testSplitSwapsAccumulateAndDirectionIsolated() (gas: 215379)\n[PASS] testStaleHistoryReturnsToWarmup() (gas: 51700)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 116.70ms (124.77ms CPU time)\n\nRan 2 test suites in 118.04ms (233.31ms CPU time): 23 tests passed, 0 failed, 0 skipped (23 total tests)\n","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"f3d9f49586f42bb6de8bf7e2ba5d879e5f28a014009b9602aecd6dfe4cbd72f5","verifiedTreeHash":"040c897395e4c9748a48ae7ba9e44fdac7b63a54","verifierVersion":"0.1.0+25bbf3ee"}]}