← Back to home

UniV4Backtester

An institutional grade UniV4 backtester that faithfully replays UniV3 events (Swap, Mint, Burn), and see how a hypothetical position would have performed over a time window.

Screenshots

UniV4Backtester screenshot 1
UniV4Backtester screenshot 2
UniV4Backtester screenshot 3
UniV4Backtester screenshot 4
UniV4Backtester screenshot 5

Problem Statement

Uniswap v4 introduces the concept of hooks which allows DEX builders to customize behaviors throughout the swap lifecycle, i.e. before/after every swap and liquidity management actions. A UniV4 pool is usually equipped with the concentrated liquidity curve of UniV3, but the hooks contract can customize how fees accrue to liquidity providers, among many others things, which can have a profound impact on LP profitability.As UniV4 gets ready for production and as more and more hooks are being developed, it is essential to build fast and robust tools that can help analyze how a hooks implementation affects traders and liquidity providers. In that spirit, we introduce our UniV4 backtester.Our UniV4 backtester fetches liquidity events from a specified UniV3 pool, and then replays these events (Swap, Increase Liquidity, Remove Liquidity) in a hypothetical UniV4 pool which may come with specified hooks.This setup enables institutional grade backtesting analyses on how a UniV4 pool would have performed using the exact liquidity events of a real-world CLMM pool, rather than using aggregated (hourly or daily) historical data which will result in inaccurate and unrealistic results.The backtester is able to set up a hypothetical position, and backtests the position’s performance through a specified time window.

Solution

We used a variety of technologies to make this backtester: Viem (NodeJS) to fetch UniV3 pool events; Foundry to fork the Sepolia testnet and execute the backtest.--- UniV3 Event Fetching --- UniV3 events are fetched from an Ethereum RPC node througheth_getLogscalls on the UniV3 pool contract. For the demo, we fetched early events of the WBTC-WETH 0.3% pool on Ethereum mainnet. Since eacheth_getLogscall only supports a limited block range, we have to fetch events in batches. Retry mechanism has been implemented to make event fetching more robust against temporary communication issues with the rpc node.Details of Swap, Mint, Burn are recorded. Collect events are skipped as they do not affect the pool’s liquidity state.--- Backtester Engine --- We use Foundry to create a fork of the Ethereum Sepolia network where UniV4 is deployed. First, the specified UniV4 pool is created on the fork. Two dummy token contracts are deployed since production tokens are not available on testnet. A large amount of tokens are minted to an arbitrary whale address.Liquidity events are replayed:Swap: the whale making a swap in the direction and amount recorded in the eventMint: the whale creates a position (if one doesn’t already exist) or increases liquidity to the existing position with the magnitude recorded in the eventBurn: the whale decreases liquidityThe hypothetical position is set up atstartTime, and its state (how much currency0 and currency1 can be collected) atendTimeis returned as output at the end of the backtest.

Hackathon

ETHGlobal San Francisco

2024

Prizes

  • 🏆

    Integrations, Research, and Experiments1st place

    Uniswap Foundation

  • 🏆

    🏆 ETHGlobal San Francisco 2024 Finalist

    ETHGlobal

Contributors