In both functions get_amount_0_delta and get_amount_1_delta, there are unchecked conversion from U256 (which the function _get_amount_0_delta or _get_amount_1_delta returns) to I256. The issue is that the value returned from _get_amount_0_delta can be greater than what I256 represents, which will result in a faulty conversion.
pub fn get_amount_0_delta(
sqrt_ratio_a_x_96: U256,
sqrt_ratio_b_x_96: U256,
liquidity: i128,
) -> Result<I256, Error> {
if liquidity < 0 {
Ok(-I256::from_raw(_get_amount_0_delta(
sqrt_ratio_a_x_96,
sqrt_ratio_b_x_96,
-liquidity as u128,
false,
)?)) //@audit-issue overflow can happen here since _get_amount_0_delta can return a number bigger than what I256 can hold
} else {
Ok(I256::from_raw(_get_amount_0_delta(
sqrt_ratio_a_x_96,
sqrt_ratio_b_x_96,
liquidity as u128,
true,
)?)) //@audit-issue overflow can happen here since _get_amount_0_delta can return a number bigger than what I256 can hold
}
}
As you can see from the function above if the overflow happens this wont revert and will silently returns 0.
Impact
The impact of this issue as we can see from the POC below, the tx wont revert or fail with overflow instead it returns 0.
Proof of Concept
You can add the test function below in pkg/seawater/src/maths/sqrt_price_maths.rs
use crate::tick_math;
#[test]
fn poc_silent_overflow() -> Result<(), Error> {
let lower_tick = 700; // large negative tick
let upper_tick = 10000; // large positive tick
// Get the sqrt ratios for these ticks
let sqrt_ratio_a = tick_math::get_sqrt_ratio_at_tick(lower_tick)?;
let sqrt_ratio_b = tick_math::get_sqrt_ratio_at_tick(upper_tick)?;
let liquidity = -2;
println!("Calculated sqrt_ratio_a: {:?}", sqrt_ratio_a);
println!("Calculated sqrt_ratio_b: {:?}", sqrt_ratio_b);
// Now call the function get_amount_0_delta
let delta = get_amount_0_delta(sqrt_ratio_a, sqrt_ratio_b, liquidity)?;
println!("Calculated delta: {:?}", delta);
Ok(())
}
Run the test with
cargo test --features testing --package seawater -- poc_silent_overflow --nocapture
Tools Used
Manual Analysis
Recommended Mitigation Steps
Dont allow values bigger than I256 to be converted instead revert.
Lines of code
https://github.com/code-423n4/2024-08-superposition/blob/main/pkg/seawater/src/maths/sqrt_price_math.rs#L203 https://github.com/code-423n4/2024-08-superposition/blob/main/pkg/seawater/src/maths/sqrt_price_math.rs#L210 https://github.com/code-423n4/2024-08-superposition/blob/main/pkg/seawater/src/maths/sqrt_price_math.rs#L227 https://github.com/code-423n4/2024-08-superposition/blob/main/pkg/seawater/src/maths/sqrt_price_math.rs#L234
Vulnerability details
Description
In both functions
get_amount_0_delta
andget_amount_1_delta
, there are unchecked conversion from U256 (which the function _get_amount_0_delta or _get_amount_1_delta returns) to I256. The issue is that the value returned from _get_amount_0_delta can be greater than what I256 represents, which will result in a faulty conversion.As you can see from the function above if the overflow happens this wont revert and will silently returns 0.
Impact
The impact of this issue as we can see from the POC below, the tx wont revert or fail with overflow instead it returns 0.
Proof of Concept
You can add the test function below in pkg/seawater/src/maths/sqrt_price_maths.rs
Run the test with
Tools Used
Manual Analysis
Recommended Mitigation Steps
Dont allow values bigger than I256 to be converted instead revert.
Assessed type
Under/Overflow