DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: medium
Valid

new deposits be incorrectly rejected due to false "maxCapReached" errors.

Summary

Once the vault is completely liquidated , totalDepositAmount remains unchanged.
Even when the withdrawer(deposit) tries to withdraw , totalDepositAMount is not reduced by the depositInfo[depositId].amount.

As a result new deposits be incorrectly rejected due to false "maxCapReached" errors.

Vulnerability Details

When the perpetualVault is completely liquidated in such a way the collatteralToken in the position is 0 , the currPositionKey is made 0 but the position remains open. code

function afterLiquidationExecution() external {
if (msg.sender != address(gmxProxy)) {
revert Error.InvalidCall();
}
depositPaused = true;
uint256 sizeInTokens = vaultReader.getPositionSizeInTokens(curPositionKey);
if (sizeInTokens == 0) {
delete curPositionKey;
}
....
}

This allows the the vault to continue the other user Operations like withdraw() and also the deposit() when the owner disable the depositPaused.

Now when user executes withdraw , this code willl get executed.

function _withdraw(uint256 depositId, bytes memory metadata, MarketPrices memory prices) internal {
....
else if (curPositionKey == bytes32(0)) { // vault liquidated
_handleReturn(0, true, false);
}
....
}

Inside the _handleReturn() the amount to transfer is calculated as

else {
uint256 balanceBeforeWithdrawal = collateralToken.balanceOf(address(this)) - withdrawn;
amount = withdrawn + balanceBeforeWithdrawal * shares / totalShares;
}

The balance of the contract would be 0 by this time.
=> amount = 0;

As a result the fun _transferToken() will not get executed and also the totalDepositAmount is never get reduced.

Impact

The totalDepositAmount will never get reduced once the vault is liquidated and users start withdrawing.
Hence it always show the incorrect value after on.

New deposits be incorrectly rejected due to false "maxCapReached" errors.

Protocol accounting becomes inaccurate, making it difficult to track actual assets under management

Tools Used

Manual

Recommendations

the line totalDepositAmount -= depositInfo[depositId].amount; should be put outside the transferToken() function so that it will be executed whatsoever.

Another way is to delete the totalDepositAmount once the vault is completely liquidated.

Updates

Lead Judging Commences

n0kto Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_total_liquidation_does_not_change_totalDepositAmount

Likelihood: Low/Medium, when the position is fully liquidated and the vault is full. Impact: High, _transferToken never called when the withdrawn amount is 0 on a deposit. DoS the deposit when the max cap is reached.

Appeal created

sakshamseth5 Auditor
5 months ago
riceee Auditor
5 months ago
bigsam Auditor
5 months ago
n0kto Lead Judge
5 months ago
n0kto Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_total_liquidation_does_not_change_totalDepositAmount

Likelihood: Low/Medium, when the position is fully liquidated and the vault is full. Impact: High, _transferToken never called when the withdrawn amount is 0 on a deposit. DoS the deposit when the max cap is reached.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.