Summary
An issue has been identified in the AaveDIVAWrapper::claimYield
function , when the recipient of the collateral is blacklisted by the issuer of the collateral token (e.g., USDC). This results in a transaction failure during the withdrawal process from Aave.
Vulnerability Details
When an Owner attempts to claim Yield , the process involves withdrawing the underlying collateral from Aave and transferring it to the specified recipient. If this recipient is blacklisted by the collateral token issuer, the transaction will revert .
The Owner can set recipent
to a blacklisted/prohibited address for the underlying token, such as 0x0E6b8E34dC115a2848F585851AF23D99D09b8463
, which is blacklisted in polygon USDC contract. the withdraw
operation on line 344 in AaveDIVAWrappeeCore::_claimYield
may revert, as is the case with USDC:
https://github.com/Cyfrin/2025-01-diva/blob/1b6543768c341c2334cdff87b6dd627ee2f62c89/contracts/src/AaveDIVAWrapperCore.sol#L344
In AaveDIVAWrappeeCore::_claimYield
function _claimYield(address _collateralToken, address _recipient) internal returns (uint256) {
if (_collateralTokenToWToken[_collateralToken] == address(0)) {
revert CollateralTokenNotRegistered();
}
if (_recipient == address(0)) revert ZeroAddress();
@> uint256 _amountReturned = IAave(_aaveV3Pool).withdraw(
_collateralToken,
_getAccruedYieldPrivate(_collateralToken),
@> _recipient
);
emit YieldClaimed(owner(), _recipient, _collateralToken, _amountReturned);
return _amountReturned;
}
Impact
In `test/AaveDIVAWrapper.t.sol`
pragma solidity ^0.8.26;
import "forge-std/Test.sol";
import {IAaveDIVAWrapper} from "../src/interfaces/IAaveDIVAWrapper.sol";
import {IAave} from "../src/interfaces/IAave.sol";
import {IDIVA} from "../src/interfaces/IDIVA.sol";
import "../src/AaveDIVAWrapper.sol";
import "../src/interfaces/IDIVA.sol";
import "lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol";
interface IUSDC {
function approve(address spender, uint256 amount) external;
function transfer(address recipient, uint256 amount) external;
function mint(address account, uint256 amount) external;
function balanceOf(address) external view returns (uint256);
function transferFrom(address sender, address recipient, uint256 amount) external;
function decimals() external view returns (uint8);
}
contract AaveDIVAWrapperTest is Test {
AaveDIVAWrapperCore wrapper;
address trader = address(0x4D8336bDa6C11BD2a805C291Ec719BaeDD10AcB9);
address blacklistedUser = address(0x0E6b8E34dC115a2848F585851AF23D99D09b8463);
address shortRecipient;
address longRecipient;
bytes32 poolId;
IAave _aavePool = IAave(0x794a61358D6845594F94dc1DB02A252b5b4814aD);
IDIVA _diva = IDIVA(0x2C9c47E7d254e493f02acfB410864b9a86c28e1D);
IUSDC USDC = IUSDC(0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359);
function setUp() public {
wrapper = new AaveDIVAWrapper(address(_diva),address(_aavePool),address(this));
shortRecipient = address(0x1);
longRecipient = address(0x2);
vm.startPrank(trader);
IUSDC(USDC).approve(address(this), type(uint256).max);
vm.stopPrank();
IUSDC(USDC).transferFrom(trader, address(this), 100* 10**USDC.decimals());
wrapper.registerCollateralToken(address(USDC));
}
modifier createPool {
USDC.approve(address(wrapper), type(uint256).max);
poolId = wrapper.createContingentPool(IAaveDIVAWrapper.PoolParams({
referenceAsset: "BTC/USD",
expiryTime: uint96(block.timestamp + 86400),
floor: 100,
inflection: 150,
cap: 200,
gradient: uint256(5 * 10 ** (USDC.decimals()-1)),
collateralAmount: 10 * 10**USDC.decimals(),
collateralToken: address(USDC),
dataProvider: address(0x11),
capacity: type(uint256).max,
longRecipient: longRecipient,
shortRecipient: shortRecipient,
permissionedERC721Token: address(0)
}));
_;
}
modifier addliquidity {
vm.startPrank(trader);
USDC.approve(address(wrapper), type(uint256).max);
wrapper.addLiquidity(poolId,100 *10**USDC.decimals() , longRecipient, shortRecipient);
vm.stopPrank();
_;
}
function testClaimYieldRevertInBlacklistedRecipient() external createPool addliquidity{
wrapper.claimYield(address(USDC),blacklistedUser);
}
Run This Command :
$ forge test --mt testClaimYieldRevertInBlacklistedRecipient --fork-url https:
Output :
├─ [71586] AaveDIVAWrapper::claimYield(0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359, 0x0E6b8E34dC115a2848F585851AF23D99D09b8463)
│ ├─ [12291] 0x794a61358D6845594F94dc1DB02A252b5b4814aD::getReserveData(0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359) [staticcall]
│ │ ├─ [11693] 0x5DFb8c777C19d3cEdcDc7398d2EeF1FB0b9b05c9::getReserveData(0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359) [delegatecall]
│ │ │ ├─ [2488] 0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb::getAddress(0x4d4f434b5f535441424c455f4445425400000000000000000000000000000000) [staticcall]
│ │ │ │ └─ ← [Return] 0x000000000000000000000000d94112b5b62d53c9402e7a60289c6810def1dc9b
│ │ │ └─ ← [Return] ReserveDataLegacy({ configuration: ReserveConfigurationMap({ data: 7237005577332262213973186942896412476039334390506525738199614521317852192076 [7.237e75] }), liquidityIndex: 1093702697531922623236877552 [1.093e27], currentLiquidityRate: 71642763956374963462186029 [7.164e25], variableBorrowIndex: 1115727771297863082559753035 [1.115e27], currentVariableBorrowRate: 103023020768912840293438392 [1.03e26], currentStableBorrowRate: 0, lastUpdateTimestamp: 1738316247 [1.738e9], id: 20, aTokenAddress: 0xA4D94019934D8333Ef880ABFFbF2FDd611C762BD, stableDebtTokenAddress: 0xd94112B5B62d53C9402e7A60289c6810dEF1dC9B, variableDebtTokenAddress: 0xE701126012EC0290822eEA17B794454d1AF8b030, interestRateStrategyAddress: 0x56076f960980d453b5B749CB6A1c4D2E4e138B1A, accruedToTreasury: 161681639 [1.616e8], unbacked: 0, isolationModeTotalDebt: 0 })
│ │ └─ ← [Return] ReserveDataLegacy({ configuration: ReserveConfigurationMap({ data: 7237005577332262213973186942896412476039334390506525738199614521317852192076 [7.237e75] }), liquidityIndex: 1093702697531922623236877552 [1.093e27], currentLiquidityRate: 71642763956374963462186029 [7.164e25], variableBorrowIndex: 1115727771297863082559753035 [1.115e27], currentVariableBorrowRate: 103023020768912840293438392 [1.03e26], currentStableBorrowRate: 0, lastUpdateTimestamp: 1738316247 [1.738e9], id: 20, aTokenAddress: 0xA4D94019934D8333Ef880ABFFbF2FDd611C762BD, stableDebtTokenAddress: 0xd94112B5B62d53C9402e7A60289c6810dEF1dC9B, variableDebtTokenAddress: 0xE701126012EC0290822eEA17B794454d1AF8b030, interestRateStrategyAddress: 0x56076f960980d453b5B749CB6A1c4D2E4e138B1A, accruedToTreasury: 161681639 [1.616e8], unbacked: 0, isolationModeTotalDebt: 0 })
│ ├─ [5306] 0xA4D94019934D8333Ef880ABFFbF2FDd611C762BD::balanceOf(AaveDIVAWrapper: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f]) [staticcall]
│ │ ├─ [4698] 0xCf85FF1c37c594a10195F7A9Ab85CBb0a03f69dE::balanceOf(AaveDIVAWrapper: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f]) [delegatecall]
│ │ │ ├─ [1419] 0x794a61358D6845594F94dc1DB02A252b5b4814aD::getReserveNormalizedIncome(0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359) [staticcall]
│ │ │ │ ├─ [867] 0x5DFb8c777C19d3cEdcDc7398d2EeF1FB0b9b05c9::getReserveNormalizedIncome(0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359) [delegatecall]
│ │ │ │ │ └─ ← [Return] 0x00000000000000000000000000000000000000000388b08e092eab1a5d0b2cf0
│ │ │ │ └─ ← [Return] 0x00000000000000000000000000000000000000000388b08e092eab1a5d0b2cf0
│ │ │ └─ ← [Return] 110000001 [1.1e8]
│ │ └─ ← [Return] 110000001 [1.1e8]
│ ├─ [477] WToken::totalSupply() [staticcall]
│ │ └─ ← [Return] 110000000 [1.1e8]
│ ├─ [40665] 0x794a61358D6845594F94dc1DB02A252b5b4814aD::withdraw(0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359, 1, 0x0E6b8E34dC115a2848F585851AF23D99D09b8463)
│ │ ├─ [40088] 0x5DFb8c777C19d3cEdcDc7398d2EeF1FB0b9b05c9::withdraw(0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359, 1, 0x0E6b8E34dC115a2848F585851AF23D99D09b8463) [delegatecall]
│ │ │ ├─ [2402] 0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb::getPriceOracle() [staticcall]
│ │ │ │ └─ ← [Return] 0x000000000000000000000000b023e699f5a33916ea823a16485e259257ca8bd1
│ │ │ ├─ [31573] 0x2b22E425C1322fbA0DbF17bb1dA25d71811EE7ba::186dea44(00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003702d183c14bea6b53d1a60b293e9416ed749f2af0faddac5a251f02731f788fbe0000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c335900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000e6b8e34dc115a2848f585851af23d99d09b84630000000000000000000000000000000000000000000000000000000000000015000000000000000000000000b023e699f5a33916ea823a16485e259257ca8bd10000000000000000000000000000000000000000000000000000000000000000) [delegatecall]
│ │ │ │ ├─ [1024] 0xE701126012EC0290822eEA17B794454d1AF8b030::scaledTotalSupply() [staticcall]
│ │ │ │ │ ├─ [419] 0x79b5e91037AE441dE0d9e6fd3Fd85b96B83d4E93::scaledTotalSupply() [delegatecall]
│ │ │ │ │ │ └─ ← [Return] 0x0000000000000000000000000000000000000000000000000000223647f85ce8
│ │ │ │ │ └─ ← [Return] 0x0000000000000000000000000000000000000000000000000000223647f85ce8
│ │ │ │ ├─ [1299] 0xA4D94019934D8333Ef880ABFFbF2FDd611C762BD::scaledBalanceOf(AaveDIVAWrapper: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f]) [staticcall]
│ │ │ │ │ ├─ [691] 0xCf85FF1c37c594a10195F7A9Ab85CBb0a03f69dE::scaledBalanceOf(AaveDIVAWrapper: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f]) [delegatecall]
│ │ │ │ │ │ └─ ← [Return] 0x0000000000000000000000000000000000000000000000000000000005feaa23
│ │ │ │ │ └─ ← [Return] 0x0000000000000000000000000000000000000000000000000000000005feaa23
│ │ │ │ ├─ [3705] 0x56076f960980d453b5B749CB6A1c4D2E4e138B1A::b90db31b(0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000262bdb846d9d00000000000000000000000000000000000000000000000000000000000003e80000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c3359000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000b3af838ff17) [staticcall]
│ │ │ │ │ └─ ← [Return] 0x0000000000000000000000000000000000000000003b42f20426e5f05c8e57da0000000000000000000000000000000000000000005537f9258d124cfabb8eca
│ │ │ │ ├─ emit ReserveDataUpdated(param0: 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359, param1: 71642763956377601377720282 [7.164e25], param2: 0, param3: 103023020768914736968077002 [1.03e26], param4: 1093702697531922623236877552 [1.093e27], param5: 1115727771297863082559753035 [1.115e27])
│ │ │ │ ├─ [14339] 0xA4D94019934D8333Ef880ABFFbF2FDd611C762BD::burn(AaveDIVAWrapper: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f], 0x0E6b8E34dC115a2848F585851AF23D99D09b8463, 1, 1093702697531922623236877552 [1.093e27])
│ │ │ │ │ ├─ [13703] 0xCf85FF1c37c594a10195F7A9Ab85CBb0a03f69dE::burn(AaveDIVAWrapper: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f], 0x0E6b8E34dC115a2848F585851AF23D99D09b8463, 1, 1093702697531922623236877552 [1.093e27]) [delegatecall]
│ │ │ │ │ │ ├─ [1371] 0x929EC64c34a17401F460460D4B9390518E5B473e::handleAction(AaveDIVAWrapper: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f], 49663891005477 [4.966e13], 100575779 [1.005e8])
│ │ │ │ │ │ │ ├─ [717] 0x5f4d15d761528c57a5C30c43c1DAb26Fc5452731::handleAction(AaveDIVAWrapper: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f], 49663891005477 [4.966e13], 100575779 [1.005e8]) [delegatecall]
│ │ │ │ │ │ │ │ └─ ← [Stop]
│ │ │ │ │ │ │ └─ ← [Return]
│ │ │ │ │ │ ├─ emit Transfer(from: AaveDIVAWrapper: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f], to: 0x0000000000000000000000000000000000000000, value: 1)
│ │ │ │ │ │ ├─ emit Burn(param0: AaveDIVAWrapper: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f], param1: 0x0E6b8E34dC115a2848F585851AF23D99D09b8463, param2: 1, param3: 0, param4: 1093702697531922623236877552 [1.093e27])
│ │ │ │ │ │ ├─ [3777] 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359::transfer(0x0E6b8E34dC115a2848F585851AF23D99D09b8463, 1)
│ │ │ │ │ │ │ ├─ [3058] 0x235AE97b28466Db30469b89A9fe4cFf0659f82Cb::transfer(0x0E6b8E34dC115a2848F585851AF23D99D09b8463, 1) [delegatecall]
│ │ │ │ │ │ │ │ └─ ← [Revert] revert: Blacklistable: account is blacklisted
Tools Used
Recommendations