The `ezETH should be minted or redeemed based on current supply and TVL` invariant has been broken by the fix applied to H-04 which also leads to unfair loss of assets for users
Audit: 2024-06-renzo-mitigation-findings
Severity: HIGH

# Lines of code

https://github.com/code-423n4/2024-04-renzo/blob/1c7cc4e632564349b204b4b5e5f494c9b0bc631d/contracts/Withdraw/WithdrawQueue.sol#L279-L312


# Vulnerability details



## Proof Of Concept

First see H-04 from the previous contest here: https://github.com/code-423n4/2024-04-renzo-findings/issues/326

The TLDR of this report is the fact that the previous withdrawal logic allows MEV exploits of TVL changes due to it's zero-slippage zero-fee swaps, that's to say if there would be a massive change in the TVL or what not, an attacker can front run this change to place a withdrawal which would allow them game the system considering no fees are applied.

Now protocol applied a sufficient mitigation to that bug case, from this [pull request](https://github.com/Renzo-Protocol/Contracts/pull/111/files), so now an arbitraguer can't blindly frontrun a call to game the system since the profit is unsure as they do not know what the rate would be after 7 days of their requests in the withdrawal queue.

Now whereas this mitigates the previous H-04, this also leads to loss of funds for honest users, raesons explained below.

First note that the highlighted diff additions are what've been added to the previous `claim()` function, i.e
https://github.com/code-423n4/2024-04-renzo/blob/1c7cc4e632564349b204b4b5e5f494c9b0bc631d/contracts/Withdraw/WithdrawQueue.sol#L279-L312

```diff
    function claim(uint256 withdrawRequestIndex) external nonReentrant {
        // check if provided withdrawRequest Index is valid
        if (withdrawRequestIndex >= withdrawRequests[msg.sender].length)
            revert InvalidWithdrawIndex();

        WithdrawRequest memory _withdrawRequest = withdrawRequests[msg.sender][
            withdrawRequestIndex
        ];
        if (block.timestamp - _withdrawRequest.createdAt < coolDownPeriod) revert EarlyClaim();

        // subtract value from claim reserve for claim asset
        claimReserve[_withdrawRequest.collateralToken] -= _withdrawRequest.amountToRedeem;


+         // calculate the amount to redeem
+         uint256 claimAmountToRedeem = _calculateAmountToRedeem(
+             _withdrawRequest.ezETHLocked,
+             _withdrawRequest.collateralToken
+         );
+         // update withdraw request amount to redeem if lower at claim time.
+         if (claimAmountToRedeem < _withdrawRequest.amountToRedeem) {
+             _withdrawRequest.amountToRedeem = claimAmountToRedeem;
+         }
+
        // delete the withdraw request
        withdrawRequests[msg.sender][withdrawRequestIndex] = withdrawRequests[msg.sender][
            withdrawRequests[msg.sender].length - 1
        ];
        withdrawRequests[msg.sender].pop();

        // burn ezETH locked for withdraw request
        ezETH.burn(address(this), _withdrawRequest.ezETHLocked);

        // send selected redeem asset to user
        if (_withdrawRequest.collateralToken == IS_NATIVE) {
            payable(msg.sender).transfer(_withdrawRequest.amountToRedeem