Assessment reports>Nibiru>High findings>Incorrect TWAP calculation
Category: Coding Mistakes

Incorrect TWAP calculation

High Severity
High Impact
High Likelihood

Description

The oracle module uses the calcTwap to compute the TWAP (time-weighted average price). Here, the maximum of snapshots[0].TimestampMs and ctx.BlockTime().UnixMilli() - twapLookBack is used as firstTimeStamp.

func (k Keeper) calcTwap(ctx sdk.Context, snapshots []types.PriceSnapshot) (price sdk.Dec, err error) {
	[...]
    firstTimeStamp := ctx.BlockTime().UnixMilli() - twapLookBack
	cumulativePrice := sdk.ZeroDec()

	firstTimeStamp = math.MaxInt64(snapshots[0].TimestampMs, firstTimeStamp)
    [...]
			nextTimestampMs = snapshots[i+1].TimestampMs
		}

		price := s.Price.MulInt64(nextTimestampMs - timestampStart)

This is not sound as it is possible for the price to be negative if timestampStart is greater than nextTimestampMs.

Impact

If timestampStart is greater than nextTimestampMs, the resulting TWAP data will be incorrect. However, this is not an issue currently since the caller for calcTwap only includes snapshots starting from ctx.BlockTime().UnixMilli() - twapLookBack.

Recommendations

Ideally, firstTimeStamp should always just be equal to the timestamp of the first snapshot.

Remediation

This issue has been acknowledged by Nibiru, and a fix was implemented in commit 53487734.

Zellic © 2024Back to top ↑