The current implementation prevents users from withdrawing their funds if their margin falls below the initial margin requirement, even when they are allowed to reduce their position size as long as they are above the maintenance margin. This restriction makes funds that should be available for withdrawal effectively inaccessible, which contradicts the intended behavior described in the documentation.
https://docs.zaros.fi/overview/resources/faq#:~:text=Can I withdraw,available for withdrawal.
When a position is reduced, the required margin should switch from the initial margin requirement to the maintenance margin requirement. However, the current implementation uses the initial margin requirement when validating withdrawals, preventing users from accessing their available funds if their margin falls below the initial margin requirement but is still above the maintenance margin requirement.
### Key Points:
1. **Current Behavior**:
- Users cannot withdraw funds if their margin balance falls below the initial margin requirement, even if they have reduced their position and are above the maintenance margin.
2. **Issue**:
- Funds that should be available for withdrawal are not accessible, causing inconvenience and financial constraints for users. Contradicts docs - https://docs.zaros.fi/overview/resources/faq#:~:text=Can I withdraw,available for withdrawal. Available funds from closed positions should be withdrawable.
*Code Snippet with Practical Examples:**
1. User A opens a $3000 position:
- Initial margin: $2000.
- Required margin: $1000.
- Balance: $3000.
- PnL: -$1200.
2. User A decides to reduce his position by $795:
- Balance: $3000 - $1200 = $1800.
- New position size: $3000 - $795 = $2205.
- Below initial margin: $2000.
3. User opens a trade to reduce his debt by half to $795:
- This triggers a market order and the following checks are made:
```solidity
(requiredInitialMarginUsdX18, requiredMaintenanceMarginUsdX18, ctx.accountTotalUnrealizedPnlUsdX18) =
tradingAccount.getAccountMarginRequirementUsdAndUnrealizedPnlUsd(marketId, ctx.sizeDeltaX18);
@audit>> new balance>>> marginBalanceUsdX18 = tradingAccount.getMarginBalanceUsd(ctx.accountTotalUnrealizedPnlUsdX18);
@audit>> previous margin>>> (, ctx.previousRequiredMaintenanceMarginUsdX18,) =
tradingAccount.getAccountMarginRequirementUsdAndUnrealizedPnlUsd(0, SD59x18_ZERO);
@audit >> ensures buffer >>> if (TradingAccount.isLiquidatable(ctx.previousRequiredMaintenanceMarginUsdX18, marginBalanceUsdX18)) {
revert Errors.AccountIsLiquidatable(tradingAccountId);
}
```
4. Comparison of balance with previous required maintenance margin:
- Previous maintenance margin: $1000
- New balance: $1800 - $795 = $1005
5. User A new position
- New position: $3000 - $795 = $2205
- New initial margin: $1468 (66.6% of position size)
- New maintenance margin: $734
- New balance: $2205 - $1200 = $1005
-Withdrawalable amount = balance $1005 + closed position $795 - New initial margin $1468 = $332
Lock fund = $795 - $332 = $463
User A will not be able to withdraw $463 from his closed position even though he reduced his position and his New Maintenance margin is buffered enough preventing liquidation anytime soon.
Users should be able to withdraw this fund unto their funds unto their previous Maintenance Margin.
3. **Desired Behavior**:
- Users should be able to withdraw funds when their margin balance is above the maintenance margin requirement, even if it is below the initial margin requirement, as long as they have reduced their position size.
Yet the funds from the closed position are now available in the balance but cannot be withdrawn.
This issue prevents users from accessing funds that should be available for withdrawal.
- Solidity code analysis
- Review of Order Branch, margin and withdrawal logic
- Review of developer comments and documentation
**Track Position-Specific Margin Requirements of each account in their trading ID**: Implement a state variable to track the Requiredmargin requirements for each position, allowing users to withdraw funds when they have reduced their position size and are above their Previous maintenance margin requirement.
**Update Withdrawal Logic**: Modify the withdrawal function to use the Requiredmargin(use initial or maintance whatever value it is) requirement based on the account state when validating withdrawals for reduced positions.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.