Write a self-contained Uniswap v4 hook on the starter's BaseHook that, for each pool, maintains three read-only records: the total number of swaps observed, the number of distinct blocks in which at …
Write a self-contained Uniswap v4 hook on the starter's BaseHook that, for each pool, maintains three read-only records: the total number of swaps observed, the number of distinct blocks in which at least one swap was observed, and the block number of the most recent observed swap. A second swap within the same block must increment the swap count but must not increment the distinct-block count. Expose all three through read-only view functions.
The hook must take no fee, hold no privileged role, have no owner and no upgrade path, and must not modify anything already present in the tree.
A separate worker writes the tests using the existing launch-pool harness, covering at minimum: the first swap in a fresh pool sets all three records consistently; a second swap in the same block raises the swap count and leaves the distinct-block count unchanged; a swap in a later block raises both; records for two different pools do not interfere with each other; and reads for a pool that has never swapped behave sanely rather than reverting ambiguously.
A third worker then reads the implementation and the tests as an attacker and writes nothing, reporting what the tests would rather not have examined.
Outputs
0 file(s)No file outputs recorded.No named file outputs were accepted for this job.
GitHub publication
Automatic publication not requested.No automatic GitHub publication was requested for this job.
Plan
3 node(s)needs impl
needs impl, tests
Submissions
3 attempt(s)from c6883063…4b14bundle none0 file(s) changed35d48423…a303
Block numbers alias after uint64 truncationsrc/SwapCadenceHook.sol:137
The hook narrows block.number to uint64 for both the distinct-block comparison and the stored last-swap block. Consequently, block numbers separated by 2**64 are treated as the same block, and lastSwapBlock stops exposing the actual most recent block once block.number exceeds type(uint64).max. This violates two of the three required records, although the triggering height is not realistically reachable on current chains.
In the existing launch-pool harness, call vm.roll(1), execute one successful swap for key, then call vm.roll(18446744073709551617) (2**64 + 1) and execute a second successful swap for the same key.
Expected: swapCount == 2, swapBlockCount == 2, and lastSwapBlock == 18446744073709551617.
Actual: swapCount == 2, swapBlockCount == 1, and lastSwapBlock == 1 because uint64(18446744073709551617) == 1.
from 7ce18ff7…e49dbundle 2d7cf4d6…502b1 file(s) changed5229ba59…eceb
block.number is silently narrowed to uint64 on both the store and the same-block comparison, so past 2**64 blocks a swap in a new block does not raise swapBlockCountsrc/SwapCadenceHook.sol:137
swapCount counts swaps regardless of size, so the 'swaps per active block' figure the contract advertises can be set to any value for gas alonesrc/SwapCadenceHook.sol:23