Skip to content

Latest commit

 

History

History
76 lines (52 loc) · 2.44 KB

095.md

File metadata and controls

76 lines (52 loc) · 2.44 KB

Upbeat Amethyst Salmon

Medium

makeWeb3safe - Insufficicient integer type precision in unbacked token minting

Summary

Forced uint256 to uint128 casting will cause an artificial supply cap and potential transaction failure for user and integrators as users attempting large mints will encounter reverts on legitimate minting operations above uint128max

Root Cause

https://github.com/sherlock-audit/2025-01-aave-v3-3/blob/main/aave-v3-origin/src/contracts/protocol/libraries/logic/BridgeLogic.sol#L76 The root cause lies in the forced downcasting of the unbacked amount. this create two issues:

  1. The storage variable reserve.unbacked is defined as uint128 instead uint256
  2. The amount parameters is forcefully downcast without proper validation or handling.

The limitation means that:

  1. Maximum single mint amount = 340,282,366,920,938,463,463,374,607,431,768,211,455 (uint128.max)
  2. For a token with 18 decimals, this equals approximately 340.28 tokens 3 Total unbacked supply cannot exceed uint128.max

Internal Pre-conditions

No response

External Pre-conditions

No response

Attack Path

  1. First amount starts as a uint256, which holdd value up to 2^256-1
// uint256 range: 0 to 115792089237316195423570985008687907853269984665640564039457584007913129639935
// uint128 range: 0 to 340282366920938463463374607431768211455

2 Then it forcefully cast to uint128 with .toUint128()

  • If amount > type(uint128).max (340282366920938463463374607431768211455), the transaction will revert
  • This means you can never mint more than 340,282,366,920 tokens even if you have 18 decimals
  • For a token with 18 decimals, this limits the actual token amount to approximately 340.28 tokens
  1. The risk amnifest in two ways
// Scenario 1: Direct Precision Loss
uint256 largeAmount = 340282366920938463463374607431768211456; // Just over uint128.max
uint128 converted = uint128(largeAmount); // This will revert

// Scenario 2: Accumulated Precision Loss
uint256 amount1 = 340282366920938463463374607431768211455; // uint128.max
uint256 amount2 = 1; 
uint128 result = uint128(amount1) + uint128(amount2); // This will overflow

Impact

Transaction failures for legitimate minting operations

PoC

No response

Mitigation

// Update storage variable to uint256
struct ReserveData {
+ uint256 unbacked;  // Changed from uint128
   
}

// Remove downcasting
+ uint256 unbacked = reserve.unbacked += amount;