Due to the lack of a check for tickLower < tickUpper when creating a position, users can set a higher-priced tick as tickLower and a lower-priced tick as tickUpper. This can lead to severe accounting errors.
When creating a position, there is no check for low < up.
If a user selects low = 1000 and up = 1 ticks to provide liquidity, the actual range of the provided liquidity changes from [1, 1000] to [-∞, 1] ∪ [1000, +∞].
This allows them to access tick price ranges that are outside the intended bounds, violating the primary invariants of the system.
For pools with low liquidity, this can even cause the liquidity in certain ranges to become negative:
If the pool initially has 100 units of liquidity in the [1, 1000] price range and a malicious user adds 1000 units of liquidity using the method described, then as the price moves from left to right across the 1 tick, the liquidity changes as follows:
Moving past the 1 tick: liquidity changes from 0 + 100 - 1000 = -900
Moving past the 1000 tick: liquidity changes from -900 - 100 + 1000 = 0
From this, we can calculate:
The activated liquidity in the [-∞, 1] range is 900
The activated liquidity in the [1000, +∞] range is 0
The activated liquidity in the [1, 1000] range becomes negative: -900
This results in an incorrect distribution of liquidity, severely distorting the pool’s functioning and stability.
Lines of code
https://github.com/code-423n4/2024-08-superposition/blob/4528c9d2dbe1550d2660dac903a8246076044905/pkg/seawater/src/pool.rs#L75
Vulnerability details
Impact
Due to the lack of a check for
tickLower < tickUpper
when creating a position, users can set a higher-priced tick astickLower
and a lower-priced tick astickUpper
. This can lead to severe accounting errors.Proof of Concept
When creating a position, there is no check for
low < up
.If a user selects
low = 1000
andup = 1
ticks to provide liquidity, the actual range of the provided liquidity changes from[1, 1000]
to[-∞, 1] ∪ [1000, +∞]
.This allows them to access tick price ranges that are outside the intended bounds, violating the primary invariants of the system.
For pools with low liquidity, this can even cause the
liquidity
in certain ranges to become negative:If the pool initially has 100 units of liquidity in the
[1, 1000]
price range and a malicious user adds 1000 units of liquidity using the method described, then as the price moves from left to right across the 1 tick, the liquidity changes as follows:0 + 100 - 1000 = -900
-900 - 100 + 1000 = 0
From this, we can calculate:
[-∞, 1]
range is900
[1000, +∞]
range is0
[1, 1000]
range becomes negative:-900
This results in an incorrect distribution of liquidity, severely distorting the pool’s functioning and stability.
Tools Used
Manual Review
Recommended Mitigation Steps
Assessed type
Invalid Validation