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

Potential Manipulation of `_collateralTokenContract.balanceOf(address(this))`

Summary

The AaveDIVAWrapperCore contract relies on the balanceOf function of collateral tokens to determine the contract's token balance during critical operations such as withdrawals and liquidity removal. However, this value can potentially be manipulated by malicious actors through techniques such as donation attacks. This manipulation could lead to incorrect calculations, resulting in financial losses or disruptions to the protocol.

Vulnerability Details

The contract calculates the amount of collateral to return during operations such as removeLiquidity and redeemPositionTokens by subtracting the initial balance from the current balance using the balanceOf function. A malicious actor could manipulate this balance by sending additional tokens to the contract, inflating the balance and causing the contract to overestimate the amount of collateral available for withdrawal.

removeLiquidity function

//...SNIP...
// Remove liquidity on DIVA Protocol to receive wTokens, and calculate the returned wToken amount (net of DIVA fees)
// as DIVA Protocol's removeLiquidity function does not return the amount of collateral token received.
>> uint256 _wTokenBalanceBeforeRemoveLiquidity = _collateralTokenContract.balanceOf(address(this));
IDIVA(_diva).removeLiquidity(_poolId, _positionTokenAmountToRemove);
>> uint256 _wTokenAmountReturned = _collateralTokenContract.balanceOf(address(this)) -
_wTokenBalanceBeforeRemoveLiquidity;
// Conscious decision to omit an early zero amount check here as it will either revert inside `removeLiquidity` due to
// zero DIVA fees (if DIVA fee pct != 0) or in the subsequent call to Aave's `withdraw` function inside `_redeemWTokenPrivate`.
// Withdraw collateral token from Aave, burn wTokens owned by this contract and transfer collateral token to `_recipient`.
uint256 _amountReturned = _redeemWTokenPrivate(
_pool.collateralToken, // wToken
_wTokenAmountReturned,
_recipient,
address(this)
);
return _amountReturned;
}

redeemPositionToken function

//...SNIP...
// Redeem position token on DIVA Protocol to receive wTokens, and calculate the returned wToken amount (net of DIVA fees)
// as DIVA Protocol's redeemPositionToken function does not return the amount of collateral token received.
>> uint256 _wTokenBalanceBeforeRedeem = _collateralTokenContract.balanceOf(address(this));
IDIVA(_diva).redeemPositionToken(_positionToken, _positionTokenAmountToRedeem);
>> uint256 _wTokenAmountReturned = _collateralTokenContract.balanceOf(address(this)) - _wTokenBalanceBeforeRedeem;
// Conscious decision to omit an early zero amount check here as it will either revert inside `redeemPositionToken` due to
// zero DIVA fees or in the subsequent call to Aave's `withdraw` function inside `_redeemWTokenPrivate`.
// Withdraw collateral token from Aave, burn wTokens owned by this contract and transfer collateral token to `_recipient`.
uint256 _amountReturned = _redeemWTokenPrivate(
_pool.collateralToken, // wToken
_wTokenAmountReturned,
_recipient,
address(this)
);
return _amountReturned;
}

Impact

  1. Incorrect balance calculations could result in users receiving more or fewer tokens than they are entitled to, leading to financial losses for either the protocol or its users.

  2. Malicious actors could exploit the vulnerability to drain funds from the contract or manipulate its state for personal gain.

Tools Used

Manual Review

Recommendation

Instead of relying on balanceOf, maintain an internal accounting system to track the contract's token balances. For example, use a mapping to store the expected balance of each collateral token and update it during deposits and withdrawals.

Updates

Lead Judging Commences

bube Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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