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

Unrestricted Token Approval in `approveCollateralTokenForAave` Leading to Unauthorized Token Transfers

Summary

The function approveCollateralTokenForAave in AaveDIVAWrapper.sol lacks proper access control, allowing any user to call it and approve collateral tokens for the Aave V3 Pool. This oversight enables unauthorized approvals, increasing the risk of front-running attacks, token hijacking, and fund mismanagement. Given that _approveCollateralTokenForAave may set unlimited allowances, attackers can potentially manipulate this function to drain protocol-owned tokens or interfere with legitimate transactions.


Tech Analysis

Vulnerable Code

function approveCollateralTokenForAave(address _collateralToken) external override {
_approveCollateralTokenForAave(_collateralToken);
}
  • This function does not have any access control (onlyOwner or onlyAuthorized), meaning any external user can call it.

  • _approveCollateralTokenForAave likely uses safeApprove or safeIncreaseAllowance, granting unlimited approvals for the Aave V3 Pool.

  • Since approvals are set at the contract level, a malicious or unauthorized approval could lead to fund mismanagement or loss.


Attack Scenarios

Scenario 1: Frontrunning Legitimate Approvals to Drain Tokens

Condition: If _approveCollateralTokenForAave sets an unlimited token approval for Aave V3 without first setting it to zero, an attacker can exploit this to front-run legitimate transactions.

  1. User A initiates a deposit into the contract, requiring the contract to approve a collateral token for Aave V3.

  2. Attacker B monitors the mempool and quickly calls approveCollateralTokenForAave(_collateralToken) for the same token before the user’s transaction is mined.

  3. Since the function lacks an onlyOwner check, the attacker can modify the approval settings, potentially allowing another contract to withdraw tokens from the protocol.

  4. Once the approval is in place, the attacker’s contract immediately transfers out the approved tokens before the protocol or user can interact with them.

Outcome:

  • Protocol or user funds can be drained before legitimate deposits are processed.

  • The approval remains valid for future unauthorized transactions, allowing continuous exploitation.


Scenario 2: Malicious Contract Manipulation

Condition: If _approveCollateralTokenForAave does not restrict approvals to safe or whitelisted contracts, an attacker can approve a contract they control to receive collateral funds.

  1. Attacker C calls approveCollateralTokenForAave(_collateralToken), which grants approval for Aave V3.

  2. However, Aave does not immediately use the approved tokens—they remain under contract control until explicitly transferred.

  3. Instead of Aave, the attacker can deploy a contract that mimics Aave’s function calls.

  4. The attacker calls the malicious contract, which then triggers token transfers from the wrapper contract to an unauthorized address.

Outcome:

  • The protocol unknowingly allows malicious interactions by blindly approving all tokens.

  • Attackers withdraw protocol-held assets to their own accounts.

  • There is no way to revert lost funds once they have been transferred.


Impact

  • Loss of Funds: Attackers can exploit unrestricted approvals to drain protocol assets.

  • Manipulation of Token Approvals: Malicious actors can repeatedly set arbitrary approvals.

  • Breakdown of Trust: Users will lose confidence if approvals can be modified by anyone, exposing their funds to unauthorized access.


Proof of Concept (PoC)

This PoC demonstrates how an attacker can manipulate the approval system and front-run legitimate transactions to extract protocol funds.

Malicious Contract Exploiting Approval Loophole

// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IAaveDIVAWrapper {
function approveCollateralTokenForAave(address _collateralToken) external;
}
contract ApprovalExploit {
IAaveDIVAWrapper public wrapper;
IERC20 public collateralToken;
address public attacker;
constructor(address _wrapper, address _collateralToken) {
wrapper = IAaveDIVAWrapper(_wrapper);
collateralToken = IERC20(_collateralToken);
attacker = msg.sender;
}
function exploitApproval() external {
require(msg.sender == attacker, "Not attacker");
// Step 1: Call unrestricted function to approve tokens for Aave V3
wrapper.approveCollateralTokenForAave(address(collateralToken));
// Step 2: Immediately transfer approved tokens to attacker-controlled address
collateralToken.transferFrom(address(wrapper), attacker, collateralToken.balanceOf(address(wrapper)));
}
}

Exploit Flow

  1. The attacker deploys the malicious contract and calls exploitApproval().

  2. The wrapper contract approves tokens for Aave V3 without verifying the caller.

  3. The attacker immediately transfers the approved tokens to themselves.

  4. The protocol loses funds with no way to recover them.


Fixes

Fix 1: Restrict Access to Owner or Authorized Roles

Solution: Add onlyOwner Modifier

Restricting the function ensures only the contract owner or admin can modify collateral approvals.

function approveCollateralTokenForAave(address _collateralToken) external override onlyOwner {
_approveCollateralTokenForAave(_collateralToken);
}

Prevents unauthorized approvals
Eliminates the risk of arbitrary approvals
Ensures only trusted parties can modify token settings

Updates

Lead Judging Commences

bube Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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