#35724 [SC-Low] Users can withdraw collateral even when the admin pauses the contract.
Submitted on Oct 5th 2024 at 00:13:01 UTC by @SeveritySquad for IOP | Swaylend
Report ID: #35724
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/Swaylend/swaylend-monorepo/blob/develop/abis/market_abi/src/abi.sw
Impacts:
Users can interact with some critical functionalities the protocol when paused
Description
Brief/Intro
the admin is allowed to pause the contract or certain collaterals whenever there might be an issue in the system to avoid exploits or for protocol-known reasons, however, users will still be able to withdraw their collateral when the contract markets functionalities are paused.
Vulnerability Details
with the
`pause_collateral_asset()`
`pause()`
The admin is allowed to stop functionalities of the protocol. For instance on the call to supply_collateral() ```sway // ## 3.1 Supply Collateral #[payable, storage(write)] fn supply_collateral() { // Only allow supplying collateral if paused flag is not set require(!storage.pause_config.supply_paused.read(), Error::Paused); // code let asset_id: AssetId = msg_asset_id(); let collateral_configuration = storage.collateral_configurations.get(asset_id).read();//@audit ere require(!collateral_configuration.paused, Error::Paused); // code // Log user supply collateral event log(UserSupplyCollateralEvent { account: caller, asset_id, amount, }); } ``` if ensures that collateral cannot be supplied if the admin pauses the market, however, the opposite is the case for `withdraw_collateral()` ```sway #[payable, storage(write)] fn withdraw_collateral( asset_id: AssetId, amount: u64, price_data_update: PriceDataUpdate, ) { // no checks against withdrawal when the protocol is paused. reentrancy_guard();
```
Mitigation
Apply same checks in `supply_collateral()` for the `withraw_collateral()`
Impact Details
Here, users will be able to bypass the sanctions put by the admin on the market allowing for exploits to continue even tho the contract is paused.
References
https://github.com/Swaylend/swaylend-monorepo/blob/63e7b1163216d1400b9436c8d256f0f0e043e225/contracts/market/src/main.sw#L304C1-L338C6
Proof of Concept
```rust use std::str::FromStr;
use fuels::accounts::ViewOnlyAccount; use market::PriceDataUpdate; use market_sdk::parse_units;
const AMOUNT_COEFFICIENT: u64 = 10u64.pow(0); const SCALE_6: f64 = 10u64.pow(6) as f64; const SCALE_9: f64 = 10u64.pow(9) as f64; use crate::utils::{setup, TestData}; use fuels::types::{ContractId, U256}; use market::{CollateralConfiguration, PauseConfiguration}; use market_sdk::get_market_config;
#[tokio::test] async fn test_withdraw_when_paused() { let TestData { admin, admin_account, alice, alice_account, bob, bob_account, market, assets, usdc, oracle, price_feed_ids, publish_time, prices, usdc_contract, uni, uni_contract, .. } = setup().await;
}
```
Last updated
Was this helpful?