Skip to content

Latest commit

 

History

History
122 lines (83 loc) · 4.4 KB

064.md

File metadata and controls

122 lines (83 loc) · 4.4 KB

Tiny Licorice Loris

Medium

Malicious actors can prevent executeMintUnbacked() from setting minted Atokens as collateral for first time supply users.

Summary

returned isFirstSupply bool relies on users Atoken balance. A malicious user can transfer a minuscule amount of Atokens to user who is just minting Atokens via BridgeLogic.executeMintUnbacked() for the first time... preventing the function from setting minted Atokens as collateral for the user.

https://github.com/sherlock-audit/2025-01-aave-v3-3/blob/main/aave-v3-origin/src/contracts/protocol/libraries/logic/BridgeLogic.sol#L85-L105

Root Cause

The root cause of this issue can be found in ScaledBalanceTokenBase._mintScaled() which is used by Atoken.mint(). In the function, the returned boolean value depends on the balance of the user whom the tokens are being minted for.

 function _mintScaled(
    address caller,
    address onBehalfOf,
    uint256 amount,
    uint256 index
  ) internal returns (bool) {
    uint256 amountScaled = amount.rayDiv(index);
    require(amountScaled != 0, Errors.INVALID_MINT_AMOUNT);

    uint256 scaledBalance = super.balanceOf(onBehalfOf);//@audit 
    uint256 balanceIncrease = scaledBalance.rayMul(index) -
      scaledBalance.rayMul(_userState[onBehalfOf].additionalData);

    _userState[onBehalfOf].additionalData = index.toUint128();

    _mint(onBehalfOf, amountScaled.toUint128());

    uint256 amountToMint = amount + balanceIncrease;
    emit Transfer(address(0), onBehalfOf, amountToMint);
    emit Mint(caller, onBehalfOf, amountToMint, balanceIncrease, index);

    return (scaledBalance == 0);
  }

so if scaledBalance != 0 for any reason, isFirstSupply will be false

 function mint(
    address caller,
    address onBehalfOf,
    uint256 amount,
    uint256 index
  ) external virtual override onlyPool returns (bool) {
    return _mintScaled(caller, onBehalfOf, amount, index);
  }

This will prevent BridgeLogic.executeMintUnbacked() from setting the minted Atokens as collateral for the user even though it is his first time minting.

    bool isFirstSupply = IAToken(reserveCache.aTokenAddress).mint(//@audit-issue `executeMintUnbacked()` can fail to `setUsingAsCollateral()` for first-time supply user. (A malicious user can prevent this by transferring a very minuscule amount to `onBehalfOf`)
      msg.sender,
      onBehalfOf,
      amount,
      reserveCache.nextLiquidityIndex
    );

    if (isFirstSupply) {
      if (
        ValidationLogic.validateAutomaticUseAsCollateral(
          reservesData,
          reservesList,
          userConfig,
          reserveCache.reserveConfiguration,
          reserveCache.aTokenAddress
        )
      ) {
        userConfig.setUsingAsCollateral(reserve.id, true);
        emit ReserveUsedAsCollateralEnabled(asset, onBehalfOf);
      }
    }

    emit MintUnbacked(asset, msg.sender, onBehalfOf, amount, referralCode);
  }

A malicious user can transfer a minuscule amount of Atokens to user who is just minting Atokens via BridgeLogic.executeMintUnbacked() for the first time... preventing the function from setting minted Atokens as collateral for the user.

Internal Pre-conditions

  1. Atokens need to be transferrable. Which they are https://aave.com/docs/developers/smart-contracts/tokenization#atoken

External Pre-conditions

  1. User is indeed minting Atokens for the first time
  2. Attacker needs to be able to monitor the user.. either via observing the mempool and frontrunning users tx or knowing user in person.

Attack Path

  1. A user Alice is minting Atokens for the first time via BridgeLogic.executeMintUnbacked()
  2. Attacker notices and sends Alice a minuscule amount of the Atoken(e.g 1 cent of the token)... so that Alice's balance will != 0
  3. BridgeLogic.executeMintUnbacked() will fail to set minted Atokens as collateral for Alice even though it is her first time of minting collaterals via the function

Impact

Attacker can prevent Atokens minted for users via BridgeLogic.executeMintUnbacked() for the first time from being used as collateral for the users.

The minted Atokens wont be used as collateral

PoC

No response

Mitigation

To determine if a user is minting Atokens for the first time don't depend on user's balance.

You can use the same method used for 'initialized'....where it is set on first call and recorded per user

External parties can influence the balance of tokens.