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

The order of `_aaveV3Pool` address and `_diva` address received in AaveDIVAWrapperCore constructor is wrong.

Summary

The _aaveV3Pool address and _diva address received by the AaveDIVAWrapper contract and the AaveDIVAWrapperCore constructor are inconsistent, resulting in the _diva address and _aaveV3Pool address set in the AaveDIVAWrapperCore contract being reversed, and the contract cannot work properly.

Vulnerability Details

The constructor of the AaveDIVAWrapper contract is implemented as follows:

constructor(address _aaveV3Pool, address _diva, address _owner) AaveDIVAWrapperCore(_aaveV3Pool, _diva, _owner) {}

Here the AaveDIVAWrapper contract constructor receives the following parameters in order:

  1. _aaveV3Pool

  2. _diva

  3. _owner

And it is also passed to the constructor of the AaveDIVAWrapperCore contract in this order.

However, the AaveDIVAWrapperCore constructor code is as follows:

constructor(address diva_, address aaveV3Pool_, address owner_) Ownable(owner_) {
// Validate that none of the input addresses is zero to prevent unintended initialization with default addresses.
// Zero address check on `owner_` is performed in the OpenZeppelin's `Ownable` contract.
if (diva_ == address(0) || aaveV3Pool_ == address(0)) {
revert ZeroAddress();
}
// Store the addresses of DIVA Protocol and Aave V3 in storage.
_diva = diva_;
_aaveV3Pool = aaveV3Pool_;
}

However, the order of parameters received by the constructor of the AaveDIVAWrapperCore contract is:

  1. diva_

  2. aaveV3Pool_

  3. owner_

This will cause the diva_ address and aaveV3Pool_ address to be reversed in the AaveDIVAWrapper contract and AaveDIVAWrapperCore.

Impact

In this case, all function calls to the _diva address in the AaveDIVAWrapperCore contract actually call functions of aaveV3Pool_, and all function calls to the aaveV3Pool_ address actually call functions of _diva. This will revert and cause all related functions of the contract to be unable to work properly.

Tools Used

Foundry

POC

import "forge-std/Test.sol";
import "../src/AaveDIVAWrapper.sol";
import "forge-std/console2.sol";
contract AuditAaveDIVAWrapper is Test {
address aave_v3_pool_eth;
address diva_addr_eth;
address owner;
AaveDIVAWrapper public aave_diva_wrapper;
function setUp() public {
vm.createSelectFork("https://rpc.ankr.com/eth");
aave_v3_pool_eth = 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2;
diva_addr_eth = 0x2C9c47E7d254e493f02acfB410864b9a86c28e1D;
owner = makeAddr("owner");
console2.log("in setUp function, aave_v3_pool_eth: ", aave_v3_pool_eth);
console2.log("in setUp function, diva_addr_eth: ", diva_addr_eth);
console2.log("------");
aave_diva_wrapper = new AaveDIVAWrapper(aave_v3_pool_eth, diva_addr_eth, owner);
}
function test_poc1() public{
address diva;
address aaveV3Pool;
(diva, aaveV3Pool, ) = aave_diva_wrapper.getContractDetails();
console2.log("in getContractDetails function, diva_addr_eth: ",diva);
console2.log("in getContractDetails function, aave_v3_pool_eth: ",aaveV3Pool);
}
}
  • Execute the following command:

cd 2025-01-diva/contracts
forge init --force
forge install openzeppelin/openzeppelin-contracts --no-commit
forge install openzeppelin/openzeppelin-contracts-upgradeable --no-commit
cd test/
# Save the above solidity code to the Audit.t.sol file under test
forge test --mt "test_poc1" -vvv
  • result:

Ran 1 test for test/AuditAaveDIVAWrapper.t.sol:AuditAaveDIVAWrapper
[PASS] test_poc1() (gas: 11923)
Logs:
in setUp function, aave_v3_pool_eth: 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2
in setUp function, diva_addr_eth: 0x2C9c47E7d254e493f02acfB410864b9a86c28e1D
------
in getContractDetails function, diva_addr_eth: 0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2
in getContractDetails function, aave_v3_pool_eth: 0x2C9c47E7d254e493f02acfB410864b9a86c28e1D

Recommendations

In the constructor of the AaveDIVAWrapperCore contract, just change the order of _aaveV3Pool and _diva:

diff --git a/contracts/src/AaveDIVAWrapperCore.sol b/contracts/src/AaveDIVAWrapperCore.sol
index 46ddc5f..5d207c6 100644
--- a/contracts/src/AaveDIVAWrapperCore.sol
+++ b/contracts/src/AaveDIVAWrapperCore.sol
@@ -49,7 +49,7 @@ abstract contract AaveDIVAWrapperCore is IAaveDIVAWrapper, Ownable2Step {
* @param owner_ Address of the owner for the contract, who will be entitled to claim the yield.
* Retrievable via Ownable's `owner()` function or this contract's `getContractDetails` functions.
*/
- constructor(address diva_, address aaveV3Pool_, address owner_) Ownable(owner_) {
+ constructor(address aaveV3Pool_ , address diva_, address owner_) Ownable(owner_) {
// Validate that none of the input addresses is zero to prevent unintended initialization with default addresses.
// Zero address check on `owner_` is performed in the OpenZeppelin's `Ownable` contract.
if (diva_ == address(0) || aaveV3Pool_ == address(0)) {
Updates

Lead Judging Commences

bube Lead Judge 6 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Constructor arguments mismatch

Support

FAQs

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