#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?