high

Users withdraw more assets than should when `mintFee` was called long ago

Contest
Reward

Total

2823.76 USDC

Selected
2823.76 USDC
Selected Submission

Users withdraw more assets than should when mintFee was called long ago

Severity

High Risk

Relevant GitHub Links

https://github.com/Cyfrin/2023-10-SteadeFi/blob/0f909e2f0917cb9ad02986f631d622376510abec/contracts/strategy/gmx/GMXWithdraw.sol#L67-L72

https://github.com/Cyfrin/2023-10-SteadeFi/blob/0f909e2f0917cb9ad02986f631d622376510abec/contracts/strategy/gmx/GMXWithdraw.sol#L101

Summary

The amount of LP-tokens to withdraw is calculated at the GMXWithdraw.withdraw before the mintFee function is called. The mintFee function increases the totalSupply amount. This way users receive more tokens than should be at the current timestamp. The longer the period since the last mintFee was called the more excess tokens the user receives.

Vulnerability Details

The protocol mints vault token shares as management fees to protocol treasury with the mintFee function. This increases the totalSupply of the shares. The amount of minted fees depends on the time since the last mintFee call.

  function mintFee() public {
    _mint(_store.treasury, GMXReader.pendingFee(_store));
    _store.lastFeeCollected = block.timestamp;
  }

While withdrawal amount of LP-token can be calculated with outdated totalSupply:

67    _wc.shareRatio = wp.shareAmt
68      * SAFE_MULTIPLIER
69      / IERC20(address(self.vault)).totalSupply();
70    _wc.lpAmt = _wc.shareRatio
71      * GMXReader.lpAmt(self)
72      / SAFE_MULTIPLIER;

101    self.vault.mintFee();

The mintFee is called only after this calculation.

Impact

Users can receive excess amounts of tokens during withdrawal. Other users and the protocol management lose value of their shares.

Tools used

Manual Review

Recommendations

Consider calling the mintFee before the _wc.shareRatio calculation.