Summary
wTokens are created upon the registration of a collateral token, done by the owner. For operations in the system, the codebase has checks to make sure that the inputted tokens are indeed registered first.
However, in the _redeemWToken function this check is missing.
Vulnerability Details
https://github.com/Cyfrin/2025-01-diva/blob/1b6543768c341c2334cdff87b6dd627ee2f62c89/contracts/src/AaveDIVAWrapperCore.sol#L314
Here is an example from the _redeemPositionToken function, that does implement the check:
function _redeemPositionToken(
address _positionToken,
uint256 _positionTokenAmount,
address _recipient
) internal returns (uint256) {
.
.
if (_wTokenToCollateralToken[_pool.collateralToken] == address(0)) {
revert CollateralTokenNotRegistered();
}
.
.
}
Impact
This is not exactly exploitable, however this does not comply with the intended design of the codebase. Therefore, it is a LOW severity issue.
Tools Used
Manual Review
Recommendation
Consider adding the same check found in _redeemPositionToken:
function _redeemWToken(address _wToken, uint256 _wTokenAmount, address _recipient) internal returns (uint256) {
// Note: wTokens are not transferred to this contract. Instead, they are burnt from the caller's balance by this contract,
// which has the authority to do so as the owner of the wToken. Therefore, no prior approval from the caller is needed.
+ if (_wTokenToCollateralToken[_wToken] == address(0)) {
+ revert CollateralTokenNotRegistered();
+ }
// Use the user's balance if `_wTokenAmount` equals `type(uint256).max`
uint256 _userBalance = IERC20Metadata(_wToken).balanceOf(msg.sender);
uint256 _wTokenAmountToRedeem = _wTokenAmount;
if (_wTokenAmount == type(uint256).max) {
_wTokenAmountToRedeem = _userBalance;
}
// Withdraw collateral token from Aave, burn wTokens and transfer collateral token to `_recipient`.
// Reverts inside the wToken's burn function if the `_wTokenAmountToRedeem` exceeds the user's wToken balance.
uint256 _amountReturned = _redeemWTokenPrivate(_wToken, _wTokenAmountToRedeem, _recipient, msg.sender);
return _amountReturned;
}