Swaps can happen without changing the price for the next trade due to gamma = 0
Summary
When a swap happens in WoofiPool the price is updated accordingly respect to such value "gamma". However, there are some cases where the swap results to a "gamma" value of "0" which will not change the new price for the next trade.
Vulnerability Detail
This is how the quote token received and new price is calculated when given amount of base tokens are sold to the pool:
Now, let's assume:
USDC is quoteToken, 6 decimals
SOL is baseToken which has a price of 146 USDC, 9 decimals
coefficient = 100
spread = 200
baseAmount (amount of SOL are sold) = 40000;
first calculate the gamma:
(baseAmount state.price state.coeff) / decs.priceDec / decs.baseDec;
= 40000 146.00 1e8 * 100 / 1e8 / 1e9
= 0 due to round down
let's calculate the quoteAmount will be received:
quoteAmount =
(((baseAmount state.price decs.quoteDec) / decs.priceDec)
(uint256(1e18) - gamma - state.spread)) /
1e18 /
decs.baseDec;
(40000 146.00 1e8 1e6 / 1e8) * (1e18 - 0 - 200) / 1e18 / 1e9
= 5840 which is not "0".
let's calculate the new price:
newPrice = ((uint256(1e18) - gamma) state.price) / 1e18;
= (1e18 - 0) 146.00 1e8 / 1e18 = 146.00 1e8
which is the same price, no price changes!
That would also means if the "gamma" is "0", then this is the best possible swap outcome. If a user does this in a for loop multiple times in a cheap network, user can trade significant amount of tokens without changing the price.
Coded PoC (values are the same as in the above textual scenario):
As by design, the price should change after every trade irrelevant of the amount that is being traded. Also, in a cheap network the attack can be quite realistic. Hence, I'll label this as medium.
LZ_security
Medium
Swaps can happen without changing the price for the next trade due to gamma = 0
Summary
When a swap happens in WoofiPool the price is updated accordingly respect to such value "gamma". However, there are some cases where the swap results to a "gamma" value of "0" which will not change the new price for the next trade.
Vulnerability Detail
This is how the quote token received and new price is calculated when given amount of base tokens are sold to the pool:
Now, let's assume: USDC is quoteToken, 6 decimals SOL is baseToken which has a price of 146 USDC, 9 decimals coefficient = 100 spread = 200 baseAmount (amount of SOL are sold) = 40000;
first calculate the gamma: (baseAmount state.price state.coeff) / decs.priceDec / decs.baseDec; = 40000 146.00 1e8 * 100 / 1e8 / 1e9 = 0 due to round down
let's calculate the quoteAmount will be received: quoteAmount = (((baseAmount state.price decs.quoteDec) / decs.priceDec) (uint256(1e18) - gamma - state.spread)) / 1e18 / decs.baseDec; (40000 146.00 1e8 1e6 / 1e8) * (1e18 - 0 - 200) / 1e18 / 1e9 = 5840 which is not "0".
let's calculate the new price: newPrice = ((uint256(1e18) - gamma) state.price) / 1e18; = (1e18 - 0) 146.00 1e8 / 1e18 = 146.00 1e8 which is the same price, no price changes!
That would also means if the "gamma" is "0", then this is the best possible swap outcome. If a user does this in a for loop multiple times in a cheap network, user can trade significant amount of tokens without changing the price.
Coded PoC (values are the same as in the above textual scenario):
Impact
As by design, the price should change after every trade irrelevant of the amount that is being traded. Also, in a cheap network the attack can be quite realistic. Hence, I'll label this as medium.
Code Snippet
https://github.com/sherlock-audit/2024-08-woofi-solana-deployment/blob/main/WOOFi_Solana/programs/woofi/src/util/swap_math.rs#L5
Tool used
Manual Review
Recommendation
if the "gamma" is "0", then revert.