SdtRewardReceiver#_withdrawRewards has incorrect slippage protection and withdraws can be sandwiched
The _min_dy parameter of poolCvgSDT.exchange is set via the poolCvgSDT.get_dy method. The problem with this is that get_dy is a relative output that is executed at runtime. This means that no matter the state of the pool, this slippage check will never work.\\nSdtRewardReceiver.sol#L229-L236\\n```\\n        if (isMint) {\\n            /// @dev Mint cvgSdt 1:1 via CvgToke contract\\n            cvgSdt.mint(receiver, rewardAmount);\\n        } else {\\n            ICrvPoolPlain _poolCvgSDT = poolCvgSDT;\\n            /// @dev Only swap if the returned amount in CvgSdt is gretear than the amount rewarded in SDT\\n            _poolCvgSDT.exchange(0, 1, rewardAmount, _poolCvgSDT.get_dy(0, 1, rewardAmount), receiver);\\n        }\\n```\\n\\nWhen swapping from SDT to cvgSDT, get_dy is used to set _min_dy inside exchange. The issue is that get_dy is the CURRENT amount that would be received when swapping as shown below:\\n```\\n@view\\n@external\\ndef get_dy(i: int128, j: int128, dx: uint256) -> uint256:\\n    """\\n    @notice Calculate the current output dy given input dx\\n    @dev Index values can be found via the `coins` public getter method\\n    @param i Index value for the coin to send\\n    @param j Index valie of the coin to recieve\\n    @param dx Amount of `i` being exchanged\\n    @return Amount of `j` predicted\\n    """\\n    rates: uint256[N_COINS] = self.rate_multipliers\\n    xp: uint256[N_COINS] = self._xp_mem(rates, self.balances)\\n\\n    x: uint256 = xp[i] + (dx * rates[i] / PRECISION)\\n    y: uint256 = self.get_y(i, j, x, xp, 0, 0)\\n    dy: uint256 = xp[j] - y - 1\\n    fee: uint256 = self.fee * dy / FEE_DENOMINATOR\\n    return (dy - fee) * PRECISION / rates[j]\\n```\\n\\nThe return value is EXACTLY the result of a regular swap, which is where the problem is. There is no way that the exchange call can ever revert. Assume the user is swapping because the current exchange ratio is 1:1.5. Now assume their withdraw is sandwich attacked. The ratio is change to 1:0.5 which is much lower than expected. When get_dy is called it will simulate the swap and return a ratio of 1:0.5. This in turn doesn't protect the user at all and their swap will execute at the poor price.
Allow the user to set _min_dy directly so they can guarantee they get the amount they want
SDT rewards will be sandwiched and can lose the entire balance
```\\n        if (isMint) {\\n            /// @dev Mint cvgSdt 1:1 via CvgToke contract\\n            cvgSdt.mint(receiver, rewardAmount);\\n        } else {\\n            ICrvPoolPlain _poolCvgSDT = poolCvgSDT;\\n            /// @dev Only swap if the returned amount in CvgSdt is gretear than the amount rewarded in SDT\\n            _poolCvgSDT.exchange(0, 1, rewardAmount, _poolCvgSDT.get_dy(0, 1, rewardAmount), receiver);\\n        }\\n```\\n