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

M1 : No Method to recover Tokens Stuck in the AaveDIVAWrappe

Summary

If an Aave update breaks compatibility with AaveDIVAWrapper, or if a user mistakenly sends a token (other than aTokens) directly to the contract, the tokens become locked and irretrievable.

Vulnerability Details

Any tokens sent directly to the contract are permanently lost, as there is no mechanism to withdraw or recover them from the AaveDIVAWrapper smart contract.

Additionally, if an Aave API update is incompatible with the wrapper, causing the withdraw function of Aave to stop working, the aTokens will be stuck in the contract with no way to retrieve them.

Impact

Users who accidentally send tokens to the contract will lose their tokens permanently.
If Aave updates break compatibility, aTokens could become locked in the contract, making them unrecoverable.

Tools Used

Manuel Review

POC

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {Test, console} from "forge-std/Test.sol";
import "../../contracts/src/AaveDIVAWrapper.sol";
import "../../contracts/src/mocks/MockERC20.sol";
import "../../contracts/src/WToken.sol";
import "../../contracts/src/interfaces/IAave.sol";
import "../../contracts/src/interfaces/IDIVA.sol";
import "../../contracts/src/interfaces/IAaveDIVAWrapper.sol";
contract TokenLockTest is Test {
address public collateralToken;
address public collateralToken2;
address public divaAddress = 0x2C9c47E7d254e493f02acfB410864b9a86c28e1D;
address public aaveAddress = 0x794a61358D6845594F94dc1DB02A252b5b4814aD;
address public dataProvider = address(0xabc123);
address public USDC = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831;
address public USDT = 0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9;
address public owner = address(0x1);
address public bob = address(0x2);
address public alice = address(0x3);
address public attacker = address(0x4);
// Contrats
AaveDIVAWrapper public aaveDIVAWrapper;
WToken public wToken;
IAave public aave;
IDIVA public diva;
MockERC20 public collateralTokenContract;
ERC20 usdt;
ERC20 usdc;
ERC20 mockERC;
IAaveDIVAWrapper.PoolParams createContingentPoolParams;
function setUp() public {
uint256 avaxChainid =
vm.createFork("https://virtual.arbitrum.rpc.tenderly.co/xxxxxxxxxxx");
vm.selectFork(avaxChainid);
console.log("active fork: ", avaxChainid);
usdc = ERC20(address(USDC));
usdt = ERC20(USDT);
diva = IDIVA(divaAddress);
aave = IAave(aaveAddress);
mockERC = new MockERC20("MockERC", "MERC", 100e18, attacker, 18, 0);
aaveDIVAWrapper = new AaveDIVAWrapper(divaAddress, aaveAddress, owner);
deal(address(usdc), alice, 100 * 1e6);
deal(address(usdt), alice, 100 * 1e6);
vm.label(alice, "Alice");
vm.label(bob, "Bob");
vm.label(owner, "Owner");
vm.label(attacker, "Attacker");
vm.label(address(usdc), "USDC");
vm.label(address(usdt), "USDT");
vm.label(address(aaveDIVAWrapper), "AaveDIVAWrapper");
vm.label(divaAddress, "DIVA");
vm.label(aaveAddress, "Aave");
}
function test_tokenlock() public {
//check balance attacker before --> 100 token
uint256 balanceAttacker = mockERC.balanceOf(attacker);
assertEq(balanceAttacker, 100e18);
//check balance aaveDIVAWrapper ---> 0 token
uint256 balanceAaveDIVAWrapper = mockERC.balanceOf(address(aaveDIVAWrapper));
assertEq(balanceAaveDIVAWrapper, 0);
//attacker send 100 token to aaveDIVAWrapper
vm.prank(attacker);
mockERC.transfer(address(aaveDIVAWrapper), 100e18);
//check balance attacker and aaveDIVAWrapper after transfer
balanceAttacker = mockERC.balanceOf(attacker);
balanceAaveDIVAWrapper = mockERC.balanceOf(address(aaveDIVAWrapper));
// 100 mockERC are stuck in aaveDIVAWrapper
assertEq(balanceAttacker, 0);
assertEq(balanceAaveDIVAWrapper, 100e18);
}
}

Add a new method in the smart contract AaveDIVAWrapper , so the admin counld withdraw token stuck in the smart contract ( except collateral and atoken )

Recommendations

Add a methode to withdraw tokens in the smart contract ( execpt Atoken and Collateral)

Updates

Lead Judging Commences

bube Lead Judge 5 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.