HardhatDeFi
15,000 USDC
View results
Submission Details
Severity: low
Invalid

There is no function for `wToken` approval

Summary

The protocol sets unlimited approval of collateral token to AAVE V3 and wToken to DIVA protocol in registerCollateralToken function. Contract also implements _approveCollateralTokenForAave function to approve tokens for AAVE V3 in case the allowance runs out but there is no similar functionality for wTokens. The inability to update approval introduces functionality risk to the system as the wToken approval is a key step into providing liquidity in DIVA ecosystem.

Vulnerability Details

In AaveDIVAWrapperCore the initial approval is set in _registerCollateralToken.

function _registerCollateralToken(address _collateralToken) internal returns (address) {
// Verify that the collateral token is not yet registered.
if (_collateralTokenToWToken[_collateralToken] != address(0)) {
revert CollateralTokenAlreadyRegistered();
}
// Retrieve the aToken address associated with the provided collateral token from Aave V3. Reverts if
// the collateral token is not supported by Aave V3.
// Note: aTokens have the same number of decimals as the collateral token: https://discord.com/channels/602826299974877205/636902500041228309/1249607036417867810
address _aToken = _getAToken(_collateralToken);
if (_aToken == address(0)) {
revert UnsupportedCollateralToken();
}
IERC20Metadata _collateralTokenContract = IERC20Metadata(_collateralToken);
// Deploy a token that represents a wrapped version of the collateral token to be used as proxy collateral in DIVA Protocol.
// The symbol and name of the wToken are derived from the original collateral token, prefixed with 'w' (e.g., wUSDT or wUSDC).
// This naming convention helps in identifying the token as a wrapped version of the original collateral token.
// The wToken decimals are aligned with those of the collateral token and the aToken.
// This contract is set as the owner and has exclusive rights to mint and burn the wToken.
WToken _wTokenContract = new WToken(
string(abi.encodePacked("w", _collateralTokenContract.symbol())),
_collateralTokenContract.decimals(),
address(this) // wToken owner
);
address _wToken = address(_wTokenContract);
// Map collateral token to its corresponding wToken.
_collateralTokenToWToken[_collateralToken] = _wToken;
// Map wToken to its corresponding collateral token to facilitate reverse lookups.
_wTokenToCollateralToken[_wToken] = _collateralToken;
// Set unlimited approval for the wToken transfer to DIVA Protocol and the collateral token transfer to Aave V3. This setup reduces
// the need for repeated approval transactions, thereby saving on gas costs.
// The unlimited approvals are deemed safe as the `AaveDIVAWrapper` is a pass-through entity that does not hold excess wTokens or collateral tokens.
// Should a vulnerability be discovered in DIVA Protocol or Aave, users can simply stop interacting with the `AaveDIVAWrapper` contract.
//
// Note that granting an infinite allowance for wToken does not reduce the allowance on `transferFrom` as it uses a newer OpenZeppelin ERC20 implementation.
// However, this behavior may differ for collateral tokens like USDC, DAI, or WETH used in Aave. These tokens decrement the allowance with each use of
// `transferFrom`, even if an unlimited allowance is set. Consequently, though very unlikely, AaveDIVAWrapper could eventually exhaust its allowance.
// The `approveCollateralTokenForAave` function has been implemented to manually reset the allowance to unlimited.
_wTokenContract.approve(_diva, type(uint256).max);
_collateralTokenContract.approve(_aaveV3Pool, type(uint256).max);
emit CollateralTokenRegistered(_collateralToken, _wToken);
return _wToken;
}

The protocol implements the _approveCollateralTokenForAave function in case the approval ever runs out.

function _approveCollateralTokenForAave(address _collateralToken) internal {
// Ensure the collateral token is registered before setting approval.
if (_collateralTokenToWToken[_collateralToken] == address(0)) {
revert CollateralTokenNotRegistered();
}
uint256 currentAllowance = IERC20Metadata(_collateralToken).allowance(address(this), _aaveV3Pool);
// Using OpenZeppelin's `safeIncreaseAllowance` to accommodate tokens like USDT on Ethereum that
// require the approval to be set to zero before setting it to a non-zero value.
IERC20Metadata(_collateralToken).safeIncreaseAllowance(_aaveV3Pool, type(uint256).max - currentAllowance);
}

Lack of wToken approval function (for DIVA protocol) make this functionality unusable because supply can't be provided through Wrapper contract after the initial approval runs out.

Impact

Users will not be able to provide liquidity using whitelisted tokens even though it should be possible any time if the token is registered. It means that protocol will not function as it should.

Tools Used

Manual review

Recommended Mitigation

Create a function to approve wTokens for DIVA protocol as it is done with _approveCollateralTokenForAave for AAVE V3 protocol.

Updates

Lead Judging Commences

bube Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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