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

### [M-1] Potential approval failure in `AaveDIVAWrapperCore._registerCollateralToken` leading to Unexpected behavior

[M-1] Potential approval failure in AaveDIVAWrapperCore._registerCollateralToken leading to Unexpected behavior

Description:
The function AaveDIVAWrapperCore._registerCollateralToken uses _wTokenContract.approve(_diva, type(uint256).max); and _collateralTokenContract.approve(_aaveV3Pool, type(uint256).max); . However, some ERC20s on some chains don't return a value. Since _collateralTokenContract is an external token chosen by users, it could be a non-standard ERC20(like USDT) and might return false instead of reverting on failure. If approve() fails, the contract won’t notice, and it may lead to unexpected issues when interacting with Aave.

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;
}

impact:
If the _collateralTokenContract is a non-standard ERC20, the approve() fails silently, the contract will assume that the approval was granted, but future transactions will fail unexpectedly. This could lead to unexpected behavior in the contract. If approve() fails, the contract won’t notice, and it may lead to unexpected issues when interacting with Aave.

Proof of Concept:

Recomended Mitigation:
Use safeApprove() from OpenZeppelin.

```javascript
using SafeERC20 for IERC20Metadata;
_collateralTokenContract.safeApprove(_aaveV3Pool, type(uint256).max);
```
Updates

Lead Judging Commences

bube Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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