Assessment reports>Beefy UniswapV3>Discussion>Observation cardinality

Observation cardinality bigger than needed

The StrategyPassiveManagerUniswap contract makes use of the time-weighted average tick from the Uniswap pool over the last 60 seconds:

/** 
 * @notice The twap of the last minute from the pool.
 * @return twapTick The twap of the last minute from the pool.
*/
function twap() public view returns (int56 twapTick) {
    uint32[] memory secondsAgo = new uint32[](2);
    secondsAgo[0] = 60;
    secondsAgo[1] = 0;

    (int56[] memory tickCuml,) = IUniswapV3Pool(pool).observe(secondsAgo);
    twapTick = (tickCuml[1] - tickCuml[0]) / 60;
}

When Uniswap pools get created, they start out with only a single observation checkpoint for calculating time-weighted average tick. However, by calling increaseObservationCardinalityNext, it is possible to increase the number of observation checkpoints. This is what the strategy contract's initializer does:

// Since Uniswap V3 pools init with a 1 observation cardinality we need to increase it to 60 to get more accurate twap, if not already increased.
(,,,uint16 cardinality,,,) = IUniswapV3Pool(pool).slot0();
if (cardinality < 60) IUniswapV3Pool(pool).increaseObservationCardinalityNext(60);

The Uniswap pool only stores at most one checkpoint on each block, however. So to cover seconds, the observation cardinality needed is about , where is the time passing between two blocks. For the Ethereum Mainnet, is about 12 seconds, so no more than six observation checkpoints would be expected to be needed for a 60-second period under normal conditions. On other blockchains with less time between blocks or more variance in block timings, more would be needed.

Zellic © 2024Back to top ↑