from ETHGlobal Paris 2023, built with Uniswap v4 Hooks π¦
Why not use TWAP? lower-liquidity pools are prone to manipulation!
Algorithm | Gas (Read) |
---|---|
Quickselect | comically a lot (hundreds of thousands) |
Frugal-2U | comically a lot (but less than QS) |
Running Frugal-2U | 4812 |
Quickselect Time-weighted | TBD |
Frugal-2U Time-weighted | TBD |
Methodology: obtain 50 unique tick observations by running swaps in both directions. Each swap is spaced 12 seconds apart. Use
gasleft()
before and after reading the median
The classic: given a sequence of unordered ticks, fetch the median with the quickselect algorithm
- Uses an O(logn) algorithm on-read
- Depends on tick observations written to storage
Approximates the median using Frugal-2U
from a sequence of numbers (naive implementation)
Frugal median algorithm compares new numbers against the current approximation and updates the approximation according to a dynamic step
- Uses the frugal median-approximation algorithm
- Depends on tick observations written to storage
The gas-optimized implementation of the frugal median approximation: calculating an on-going approximation of the median
- Uses the frugal median-approxiation algorithm
- Stores the running median (approximated) in direct storage
- additional researchβ’οΈ required for windowed support
In the frugal median algorithm, the dynamic step can be modified to favor stabilization or responsiveness/accuracy. The repo uses 1-tick as a step, but the implementation is set up for additional experimentation
The repo is in its early stages and did not have sufficient time to implement time-weighted medians. Time-weighted medians are likely to better represent the price since they account for the duration of a tick (price observation). The repo currently treats unique price observations as having equivalent durations.
src/
βββ RunningFrugalMedianHook.sol Running median approximation
βββ TickObserver.sol store tick observations for windowed median reads
βββ lens
β βββ FrugalMedianLens.sol read TickObserver and approximate median
β βββ MedianLens.sol read TickObserver and calculate true median
βββ lib
βββ FrugalMedianLibrary.sol median approximation library
βββ MedianLibrary.sol median calculation library (quickselect)
βββ RingBufferLibrary.sol optimized ring buffer for price observations
test/
βββ FrugalMedianLens.t.sol test the naive frugal median
βββ MedianLens.t.sol test the true median (quickselect)
βββ RunningMedian.t.sol test the running median approximation
βββ TickObserver.t.sol test the tick observer
βββ implementation
β βββ ... Uniswap overrides for testing
βββ median
β βββ FrugalMedianTest.t.sol test frugal median algo
β βββ MedianLibrary.t.sol test quickselect algo
βββ utils
βββ HookTest.sol
βββ RingBuffer.t.sol test ring buffer
Additional resources:
v4-periphery contains advanced hook implementations that serve as a great reference
requires foundry
forge install
forge test
Credits