Missing lower<upper
check in mint_position
#149
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
H-03
primary issue
Highest quality submission among a set of duplicates
🤖_primary
AI based primary recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2024-08-superposition/blob/29726230b13f1cf36c925d732d3eca459af1aff5/pkg/seawater/src/lib.rs#L506-L513
Vulnerability details
Details
The current implementation does not perform a check for
lower < upper
duringmint_position
, while many other functions assumelower < upper
. This discrepancy allows malicious actors to exploit inconsistencies in handling undefined behavior in other parts of the code for their benefit.Case when
lower = upper
:In the
StorageTicks::update
function, liquidity can be added without issue because only one boundary and the current tick need to be passed, meaning it should function correctly even if the current tick equals the boundary. However, when calculating the amount of tokens required from the user, due tolower = upper
, the calculation can only fall into the first and third branches. Here,sqrt_ratio_a_x_96 = sqrt_ratio_a_x_96
, and the difference between these two values multiplies the result, leading to a token amount of 0 regardless of liquidity. A malicious user can exploit this implementation discrepancy to open a position with arbitrary liquidity value without consuming any tokens.While the attacker cannot directly profit by closing the position, these positions affect fee calculations. For example, in the provided PoC, the attacker can create a large number of empty positions within their liquidity range to collect significant fees from swapping users, inflating what would normally be a fee of 6 to 1605.
Case when
lower > upper
:Unlike the previous case, when
lower > upper
, it is possible to create a position with both liquidity and balance. However, the potential issue arises when calling theget_fee_growth_inside
function to calculate fees. This function also assumeslower < upper
in its calculations, and passinglower > upper
results in incorrect fee calculations, allowing the attacker to steal fees from other liquidity providers. However, the current implementation ofget_fee_growth_inside
has a bug where it does not correctly handle overflow as per the Uniswap V3 specification, rendering this exploit temporarily unusable.Proof of Concept
Tools Used
Manual analysis
Recommended Mitigation Steps
Add
assert_or!(lower < upper, Error::InvalidTick)
check.Assessed type
Invalid Validation
The text was updated successfully, but these errors were encountered: