Open c4-bot-2 opened 7 months ago
Picodes marked the issue as primary issue
othernet-global (sponsor) confirmed
Now rounds down for negative ticks as suggested.
https://github.com/othernet-global/salty-io/commit/4625393e9bd010778003a1424201513885068800
Picodes marked the issue as satisfactory
Picodes marked the issue as selected for report
The stablecoin framework: /stablecoin, /price_feed, WBTC/WETH collateral, PriceAggregator, price feeds and USDS have been removed: https://github.com/othernet-global/salty-io/commit/88b7fd1f3f5e037a155424a85275efd79f3e9bf9
Lines of code
https://github.com/code-423n4/2024-01-salty/blob/f742b554e18ae1a07cb8d4617ec8aa50db037c1c/src/price_feed/CoreUniswapFeed.sol#L49-L75
Vulnerability details
Proof of Concept
Take a look at https://github.com/code-423n4/2024-01-salty/blob/f742b554e18ae1a07cb8d4617ec8aa50db037c1c/src/price_feed/CoreUniswapFeed.sol#L49-L75
This function is used to get twap price tick using uniswap oracle. it uses
pool.observe()
to gettickCumulatives
array which is then used to calculateint24 tick
.The problem is that in case if
int24(tickCumulatives[1] - tickCumulatives[0])
is negative, then the tick should be rounded down as it's done in the uniswap library.As result, in case if
int24(tickCumulatives[1] - tickCumulatives[0])
is negative and(tickCumulatives[1] - tickCumulatives[0]) % secondsAgo != 0
, then returned tick will be bigger then it should be, which opens possibility for some price manipulations and arbitrage opportunities.Impact
In case if
int24(tickCumulatives[1] - tickCumulatives[0])
is negative and((tickCumulatives[1] - tickCumulatives[0]) % secondsAgo != 0
, then returned tick will be bigger than it should be which places protocol wanting prices to be right not be able to achieve this goal, note that where as protocol still relies on multiple sources of price, they still come down and end on weighing the differences between the prices and reverting if a certain limit is passed, effectively causing the pricing logic to be unavailable and also reverting on important functions likeCollateralAndLiquidity::liquidate()
cause a call tounderlyingTokenValueInUSD()
is made which would not be available.Recommended Mitigation Steps
Add this line.
if (tickCumulatives[1] - tickCumulatives[0] < 0 && (tickCumulatives[1] - tickCumulatives[0]) % secondsAgo != 0) timeWeightedTick --;
Assessed type
Math