Stableswap will calculate pool share price incorrectly if an asset has greater than 18 decimals, impacting ema oracle entries #165
Labels
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
duplicate-80
grade-a
QA (Quality Assurance)
Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
🤖_80_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
Lines of code
https://github.com/code-423n4/2024-02-hydradx/blob/603187123a20e0cb8a7ea85c6a6d718429caad8d/HydraDX-node/math/src/stableswap/math.rs#L704
Vulnerability details
Impact
Stableswap will calculate pool share price incorrectly if an asset has greater than 18 decimals, impacting ema oracle entries
Proof of Concept
In stableswap, any liquidity management and trading methods will trigger a hook that writes an oracle entry in ema-oracle.
When an asset has greater than 18 decimals, the asset price will be incorrectly scaled and allowing incorrect oracle entries in ema-oracle.
The vulnerability is in
calculate_share_price()
that usessaturating_sub()
method when scaling decimals.saturating_sub()
will allow underflow to pass silently and return 0 value.In this case, when
reserves[asset_idx].decimals
is greater than 18,let p_diff = U256::from(10u128.saturating_pow(18u8.saturating_sub(reserves[asset_idx].decimals) as u32));
will simply return p_diff = 10^0=1 regardless of the exact decimals of theasset_idx
.This will incorrectly calculates
denom
of the returned share price, writing an incorrect oracle entry to ema-oracle.(https://github.com/code-423n4/2024-02-hydradx/blob/603187123a20e0cb8a7ea85c6a6d718429caad8d/HydraDX-node/math/src/stableswap/math.rs#L704)
For reference, here's the flow involved: liquidity management/trading ->
call_on_liquidity_change_hook()
/call_on_trade_hook()
->get_pool_state()
->calculate_share_price()
(math.rs)->on_liquidity_changed()
/:on_trade()
-> ema-oracle entry(OnActivityHandler
)Tools Used
Manual
Recommended Mitigation Steps
Consider handling decimal differences consistently in stableswap math. Similar to
normalize_value()
, handle both conditions when asset decimals are greater than 18 decimals or smaller than 18 decimals.OR revert when a certain condition is disallowed instead of silently returning a value.
Assessed type
Error
The text was updated successfully, but these errors were encountered: