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

Fees not refunded to users on position closed and funds locked/lost

Summary

User is not refunded fees when vault changes position ahead of the users transaction.

Vulnerability Details

When depositing into the vault, there are two mechanisms to which the deposit serves, which is dependent on if the vault has a position opened on GMX or closed.

function deposit(uint256 amount) external nonReentrant payable {
_noneFlow();
if (depositPaused == true) {
revert Error.Paused();
}
if (amount < minDepositAmount) {
revert Error.InsufficientAmount();
}
if (totalDepositAmount + amount > maxDepositAmount) {
revert Error.ExceedMaxDepositCap();
}
flow = FLOW.DEPOSIT;
collateralToken.safeTransferFrom(msg.sender, address(this), amount);
counter++;
depositInfo[counter] = DepositInfo(amount, 0, msg.sender, 0, block.timestamp, address(0));
totalDepositAmount += amount;
EnumerableSet.add(userDeposits[msg.sender], counter);
if (positionIsClosed) {
MarketPrices memory prices;
// @audit where is this guy updated?
_mint(counter, amount, false, prices);
_finalize(hex'');
} else {
_payExecutionFee(counter, true);
// mint share token in the NextAction to involve off-chain price data and improve security
nextAction.selector = NextActionSelector.INCREASE_ACTION;
nextAction.data = abi.encode(beenLong);
}
}

When the vault has a position open, it collects the deposit amount and fees and saves the next action as an increase action. But when it is closed, it simply mints shares to the depositing user. The challenge here is that the user depositing does not know what state the vault will be in at execution. It could be an open position or closed position.

POC

  1. The Gamma vault X is in openPosition state.

  2. Bob sends a transaction to Gamma contracts, with deposit of 100 usdc and 5 avax to pay for execution of the transaction.

  3. Since bob inputs an acceptable priority fee as is required in Avax dynamic fee model

  4. The keeper sends out a transaction same time to close the position of vault X but this time with a higher priority fee, being that the keeper operations are more time sensitive (robots/automated) there is a chance that it would want as much urgency than an average investor.

  5. The validators on avax process the keepers transaction first and the position on vault x is closed.

  6. When Bobs transaction is processed, it means that the vaults position has been closed, so bob will just be minted a share instead for his 100usd. Since the no position is open on the vault, it means bob will also loose his 5 avax permanently, as there is no mechanism to either refund bob or admin move it out.

  7. The mechanism for moving fees is only on GMXproxy and not on the vault, and bobs fees will not make it to the proxy.

Impact

User losses it fees for ever with no refund

Tools Used

manaul

Recommendations

Refund fees when the vault position is closed.

Updates

Lead Judging Commences

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

finding_no_refund_when_deposit_just_after_a_keeper_close_position

Likelihood: Low, send a deposit with execution fees but a “run” keeper is made just before to close the position. Impact: Low/Medium, no refund of the execution fee, althought they were no need for them.

Support

FAQs

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