#35761 [SC-Low] Unhandled smaller base decimals than 6 or bigger than the collateral's decimals
Submitted on Oct 6th 2024 at 23:28:34 UTC by @SimaoAmaro for IOP | Swaylend
Report ID: #35761
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/Swaylend/swaylend-monorepo/blob/develop/contracts/market/src/main.sw
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
The `market` converts between decimals when going from collateral to base or vice-versa (and price).
There are instances when depending on the decimal values of the collateral, base and price, it could lead to the `market` reverting to underflow or division by 0.
Vulnerability Details
`market::collateral_value_to_sell()` calculates the `scale` to go from collateral decimals to base by doing ```rust let scale = u256::from(10_u64).pow( collateral_configuration .decimals - storage .market_configuration .read() .base_token_decimals, ); ``` If the base token decimals are bigger than the collateral's decimals, this reverts.
In `market::available_to_borrow()`, the scale is calculated as ```rust let scale = u256::from(10_u64).pow( collateral_configuration .decimals + price_exponent - storage .market_configuration .read() .base_token_decimals, ); ``` which also underflows whenever the base token decimals is bigger than the collateral's + the price exponent.
Lastly, `market::update_base_principal()` gets the `accrual_descale_factor` by doing `u256::from(10_u64).pow(market_configuration.base_token_decimals) / BASE_ACCRUAL_SCALE;`, which is 0 whenever the base token decimals is smaller than 6. This will make it revert and the market becomes unusable (funds can not be supplied so no funds are stuck but it needs to be redeployed).
Impact Details
View functions (`market::collateral_value_to_sell()` and `market::available_to_borrow()` will not work or the contract has to be redeployed due to this issue.
References
https://github.com/Swaylend/swaylend-monorepo/blob/develop/contracts/market/src/main.sw?utm_source=immunefi#L716 https://github.com/Swaylend/swaylend-monorepo/blob/develop/contracts/market/src/main.sw?utm_source=immunefi#L568 https://github.com/Swaylend/swaylend-monorepo/blob/develop/contracts/market/src/main.sw?utm_source=immunefi#L1489-L1499
Proof of Concept
Proof of Concept
Change the decimals of usdc to 5 in tokens.json and run `cargo test --release main_test_no_debug -- --nocapture`. The rest fails on step 0 when supplying base due to division by 0.