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

Precision Errors and Protocol Instability Incomplete Decimals Handling in WToken Contract

Summary

The WToken contract within the AaveDIVAWrapper protocol allows for manual setting of decimals during deployment, which can result in mismatched decimals between WToken and the underlying collateral token. This misalignment introduces precision errors during liquidity operations, yield distributions, and collateral conversions. These errors are not the result of malicious actions but can stem from developer oversight during the deployment of WToken. This vulnerability can lead to incorrect yield calculations, liquidity pool imbalances, and user dissatisfaction.


Detailed Analysis

Root Cause

The root issue lies in the design of the WToken contract, which allows decimals to be manually set during deployment. This opens the possibility of decimals misalignment between WToken and the underlying collateral token.

Vulnerable Code:

uint8 private _decimals;
constructor(string memory symbol_, uint8 decimals_, address owner_) ERC20(symbol_, symbol_) {
_owner = owner_;
_decimals = decimals_; // Decimals manually set here
}
function decimals() public view override(ERC20, IWToken) returns (uint8) {
return _decimals; // Returns manually set decimals
}
  • Manual Decimals Management: Developers deploying WToken can inadvertently assign decimals that do not match the collateral token’s decimals.

  • Lack of Decimals Validation: The protocol does not validate the decimals of WToken against the underlying collateral token during the registration process.


Developer Oversight Leading to Precision Errors

  1. Deployment of WToken with Misconfigured Decimals

    • A developer deploys a WToken with 18 decimals, while the underlying collateral token (e.g., USDC) has 6 decimals. This could occur due to a lack of clear documentation or oversight during deployment.

  2. Registration of WToken

    • The misconfigured WToken is registered as collateral in the protocol via registerCollateralToken. The protocol does not validate the decimals during this process.

  3. Operational Errors

    • During liquidity operations or yield distributions, the protocol performs calculations assuming consistent decimals between WToken and the collateral token. Due to the mismatch:

      • Over-Calculation: Users receive more WToken than intended during collateral conversions.

      • Under-Calculation: Users receive less yield than they are entitled to during distributions.

  4. Financial and Operational Impact

    • Imbalanced Liquidity Pools: The protocol’s liquidity pools are destabilized, increasing the risk of liquidation.

    • User Dissatisfaction: Users experience financial losses due to inaccurate conversions and distributions.


Impact

  1. Financial Discrepancies:

    • Incorrect calculations result in over or under-distribution of funds, directly affecting user balances and the protocol’s reserves.

  2. Protocol Instability:

    • Liquidity pool imbalances lead to operational disruptions and increased risk of insolvency.

  3. Eroded User Trust:

    • Users lose confidence in the protocol’s reliability due to perceived inaccuracies in token handling.


Proof of Concept (PoC)

Deploy a WToken with Mismatched Decimals

Simulate the deployment of a WToken with 18 decimals for a 6-decimal collateral token (e.g., USDC):

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MisconfiguredWToken is ERC20 {
uint8 private _decimals;
constructor() ERC20("MisconfiguredWToken", "MWT") {
_decimals = 18; // Mismatched decimals
}
function decimals() public view override returns (uint8) {
return _decimals;
}
}

Register the Misconfigured WToken

Register the WToken as collateral using the protocol’s registerCollateralToken function.

IAaveDIVAWrapper(wrapperAddress).registerCollateralToken(address(misconfiguredWToken));

Simulate Precision Errors

Perform liquidity operations with the misconfigured WToken:

IAaveDIVAWrapper(wrapperAddress).addLiquidity(
poolId,
1000 * 10**18, // Assumes 18 decimals
longRecipient,
shortRecipient
);

Behavior:

  • The protocol over-mints WToken due to the assumption of 6 decimals for USDC.

  • This results in users receiving excessive yields or liquidity imbalances within the pool.


Recommendations

1. Enforce Standardized Decimals for WToken

Set a fixed decimals value (e.g., 18) for all WToken deployments to ensure consistency:

uint8 private constant DECIMALS = 18;
constructor(string memory symbol_, address owner_) ERC20(symbol_, symbol_) {
_owner = owner_;
_decimals = DECIMALS;
}

2. Validate Decimals During Collateral Registration

Ensure that the decimals of WToken match the underlying collateral token during the registration process:

function _registerCollateralToken(address _collateralToken) internal returns (address) {
uint8 collateralDecimals = IERC20Metadata(_collateralToken).decimals();
require(collateralDecimals == EXPECTED_DECIMALS, "Collateral decimals mismatch");
// Continue registration
}
Updates

Lead Judging Commences

bube Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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