#47309 [SC-Medium] Type mishandling allows for users to withdraw FAST from vault instead of STANDARD
Submitted on Jun 12th 2025 at 14:43:17 UTC by @Kalogerone for IOP | Paradex
Report ID: #47309
Report Type: Smart Contract
Report severity: Medium
Target: https://github.com/tradeparadex/audit-competition-may-2025/tree/main/paraclear
Impacts:
Protocol insolvency
Description
Brief/Intro
The Paraclear contract implements the get_account_free_balance(...) function which returns an account's free balance (available balance to open new positions). This value can be negative, especially when an account approaches liquidation threshold. However, the get_account_free_balance(...) function converts the integer amount to felt, which is always positive.
Vulnerability Details
This is the get_account_free_balance(...) implementation:
fn get_account_free_balance(self: @ContractState, account: ContractAddress) -> felt252 {
let account_state = self._load_account_v2(account);
account_state.free_balance().into()
}We can notice that it returns a felt252 type and it calls free_balance() which returns i128 type:
If a negative value is returned from free_balance(), the way that cairo handles this conversion, the get_account_free_balance(...) function will return the felt252 max - the negative number.
This function is used by the Vaults and this type mishandling can mess up the withdrawals.
As we can see, during withdrawal the vault checks the free balance of the assets holder. If the account has a negative free balance, the get_account_free_balance(...) function will return a huge positive value. This will result in this check to fail if assets_paraclear == 0 || assets_paraclear > paraclear_free_balance.into() (since paraclear_free_balance will be a huge number) and the withdrawal mode will be set to WITHDRAWAL_MODE_FAST, which is not intended. Withdrawing from an account with negative free balance can get the account closer to liquidation.
The transaction will succeed since the account_transfer_partial(...) checks that the excess balance is greater than 0.
Impact Details
Users will be able to withdraw fast from a vault with no free balance and possibly get it closer to liquidation.
References
https://book.cairo-lang.org/ch02-02-data-types.html#felt-type
https://github.com/tradeparadex/audit-competition-may-2025/blob/main/vaults/src/vault/vault.cairo
https://github.com/tradeparadex/audit-competition-may-2025/blob/main/paraclear/src/paraclear/paraclear.cairo#L839
Proof of Concept
Proof of Concept
Using the following test we can see in the console that:
Was this helpful?