Improper Decimal Scaling in Cross-Price Calculation
Summary
The original code for calculating the cross-price between the base and quote tokens improperly scales the base_price by the quote_decimal without accounting for the base_decimal.
This results in over-scaling and inaccurate cross-price calculations.
Vulnerability Detail
In the original code, the base_price is scaled by 10 ** quote_decimal, but the base decimals is not properly accounted for.
This leads to over-scaling of the base_price when both the base and quote tokens already have their own decimal precision. Additionally, the result is not adjusted for the base decimals after the division, leading to inflated or incorrect values.
let base_price = pyth_result.price as u128;
let quote_price = quote_price_result.price as u128;
let quote_decimal = quote_price_result.exponent.abs().try_into().unwrap();
let clo_price = base_price
.checked_mul(10_u128.pow(quote_decimal)) // Scales base_price by quote decimals
.unwrap()
.checked_div(quote_price)
.unwrap();
Impact
The over-scaling of base_price leads to an incorrect cross-price calculation and potentially marking the price as out-of-bound in this check here:
To fix this issue, ensure that the base_price is properly scaled by the difference between base_decimal and quote_decimal and that the result is adjusted for base_decimal after the division. Here's one of the approaches:
let base_price = pyth_result.price as u128;
let quote_price = quote_price_result.price as u128;
let base_decimal = pyth_result.exponent.abs().try_into().unwrap();
let quote_decimal = quote_price_result.exponent.abs().try_into().unwrap();
// Normalize the base price to the precision of the quote price
let normalized_base_price = base_price.checked_mul(10_u128.pow(quote_decimal)).unwrap();
// Calculate the cross-price and adjust for base decimals
let clo_price = normalized_base_price
.checked_div(quote_price)
.unwrap()
.checked_div(10_u128.pow(base_decimal)) // Adjust for base decimals
.unwrap();
Not valid for this one
The meaning of this calc is to transit from BaseToken/USD to BaseToken/QuoteToken
like SOL/USD to SOL/USDC
if SOL's price is 150, decimal is 6, need give out 150000000, not 150.
Fast Sand Millipede
High
Improper Decimal Scaling in Cross-Price Calculation
Summary
The original code for calculating the cross-price between the base and quote tokens improperly scales the
base_price
by thequote_decimal
without accounting for thebase_decimal
.This results in over-scaling and inaccurate cross-price calculations.
Vulnerability Detail
In the original code, the
base_price
is scaled by10 ** quote_decimal
, but the base decimals is not properly accounted for.This leads to over-scaling of the
base_price
when both the base and quote tokens already have their own decimal precision. Additionally, the result is not adjusted for the base decimals after the division, leading to inflated or incorrect values.Impact
The over-scaling of
base_price
leads to an incorrect cross-price calculation and potentially marking the price as out-of-bound in this check here:Code Snippet
https://github.com/sherlock-audit/2024-08-woofi-solana-deployment/blob/main/WOOFi_Solana/programs/woofi/src/instructions/get_price.rs#L64-L71
Tool used
Manual Review
Recommendation
To fix this issue, ensure that the
base_price
is properly scaled by the difference betweenbase_decimal
andquote_decimal
and that the result is adjusted forbase_decimal
after the division. Here's one of the approaches: