#36158 [SC-Low] `Market.collateral_value_to_sell` will always revert if collateral_configuration
Submitted on Oct 22nd 2024 at 08:33:46 UTC by @jasonxiale for IOP | Swaylend
Report ID: #36158
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/Swaylend/swaylend-monorepo/blob/9132747331188b86dd8cbf9a1ca37b811d08dddb/contracts/market/src/main.sw
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
In Market.collateral_value_to_sell, while the function tries to calculate the scale in main.sw#L894-L900, `collateral_configuration.decimals - storage.market_configuration.base_token_decimals` is used, the issue is both `collateral_configuration.decimals` and `storage..market_configuration.base_token_decimals`'s type is u32, so if `collateral_configuration.decimals < storage..market_configuration.base_token_decimals`, the calculation will revert.
Vulnerability Details
```Rust 878 #[storage(read)] 879 fn collateral_value_to_sell(asset_id: AssetId, collateral_amount: u64) -> u64 { // decimals: base_token_decimals 880 let collateral_configuration = storage.collateral_configurations.get(asset_id).read(); 881 let market_configuration = storage.market_configuration.read(); 882 ... 894 let scale = u256::from(10_u64).pow( 895 collateral_configuration 896 .decimals - storage <<<--- here might be reverted 897 .market_configuration 898 .read() 899 .base_token_decimals, 900 ); ... 906 } ```
Impact Details
`Market.collateral_value_to_sell` will always revert if collateral_configuration.decimals < storage..market_configuration.base_token_decimals
References
Add any relevant links to documentation or code
Proof of Concept
Proof of Concept
Please put the following code in `swaylend-monorepo/contracts/market/src/main.sw` file, and run ```bash forc test -l ... Compiled contract "market" with 49 warnings. Finished debug [unoptimized + fuel] target(s) [168.928 KB] in 48.32s Running 2 tests, filtered 0 tests test test_no_revert_overflow ... ok (200.787µs, 491 gas) Decoded log value: 10, log rb: 1970142151624111756 test test_revert_overflow ... ok (111.65µs, 61 gas)
test result: OK. 2 passed; 0 failed; finished in 312.437µs ```
as the output shows, test case `test_revert_overflow` will revert because `collateral_token_decimals` is smaller than `base_token_decimals`
```Rust #[test] fn test_no_revert_overflow() { let base_token_decimals: u32 = 9; let collateral_token_decimals: u32 = 10; let scale = u256::from(10_u64).pow(collateral_token_decimals - base_token_decimals); log(scale); }
#[test(should_revert)] fn test_revert_overflow() { let base_token_decimals: u32 = 9; let collateral_token_decimals: u32 = 6; let scale = u256::from(10_u64).pow(collateral_token_decimals - base_token_decimals); log(scale); } ```