Skip to content

Latest commit

 

History

History
57 lines (34 loc) · 2.49 KB

010.md

File metadata and controls

57 lines (34 loc) · 2.49 KB

Obedient Lava Monkey

Medium

repayETH can result in loss of excess ETH during repayment.

Summary

The failure to refund the entire excess ETH when msg.value > paybackAmount will cause ETH loss for users as the contract may retain unclaimed dust ETH if the exact refund logic is not implemented correctly.

Root Cause

In WrappedTokenGatewayV3.sol, the contract refunds excess ETH after depositing paybackAmount to WETH, but does not account for edge cases where dust ETH (remaining small fractions) might remain in the contract due to rounding issues.

Contracts interacting with msg.value often deal with rounding issues or leftover ETH. This is particularly true when interacting with contracts like WETH or POOL, which may have rounding discrepancies or fixed-point arithmetic constraints. In repayETH:

if (msg.value > paybackAmount) _safeTransferETH(msg.sender, msg.value - paybackAmount);

The contract only refunds the explicit difference between msg.value and paybackAmount. However, dust ETH can remain in the contract due to:

  • Rounding discrepancies in WETH.deposit.
  • Small mismatches when converting ETH to WETH or handling fractional amounts.

Internal Pre-conditions

  1. User calls repayETH with msg.value greater than the debt being repaid (paybackAmount).

External Pre-conditions

  1. Rounding discrepancies arise in WETH’s deposit function or the pool’s internal handling of debt.

Attack Path

  1. User sends msg.value slightly greater than the actual repayment amount (e.g., to ensure full coverage).
  2. Contract performs repayment but refunds only the computed difference (msg.value - paybackAmount).
  3. Dust ETH remains in the contract, which the user cannot retrieve, resulting in ETH loss over multiple transactions.

Impact

The user suffers a loss of residual ETH (dust ETH) left in the contract after repayment. Over time, this could accumulate significantly for high-traffic contracts.

PoC

No response

Mitigation

Ensure all residual ETH is refunded to the user after the repayment is completed. Modify repayETH as follows:

if (address(this).balance > 0) {
  _safeTransferETH(msg.sender, address(this).balance);
}