Files
explorer-monorepo/docs/WETH9_1_TO_1_RATIO_VERIFICATION.md

7.3 KiB

WETH9 1:1 Ratio Verification

Overview

WETH9 (Wrapped Ether) must maintain a strict 1:1 ratio with ETH. This means:

  • 1 ETH = 1 WETH9 (exactly)
  • No fees should be deducted during wrapping
  • No slippage should occur
  • The contract balance should always equal the total supply

The Issue

If you're experiencing a ratio that is NOT 1:1, this could indicate:

  1. Contract Implementation Issue: The WETH9 contract may have been modified
  2. Fee Deduction: Fees may be incorrectly deducted during deposit
  3. Display/Calculation Error: The issue may be in how amounts are displayed or calculated
  4. Gas Cost Confusion: Gas fees are separate from the wrap amount

Standard WETH9 Implementation

The standard WETH9 deposit() function should be:

function deposit() public payable {
    balanceOf[msg.sender] += msg.value;
    totalSupply += msg.value;
    Deposit(msg.sender, msg.value);
}

Key Points:

  • msg.value is added directly to balanceOf[msg.sender] (1:1)
  • msg.value is added directly to totalSupply (1:1)
  • No fees are deducted
  • No calculations or conversions are performed

Verification Process

Step 1: Test the Ratio

Use the verification script to test the actual ratio:

./scripts/verify-weth9-ratio.sh [private_key] [test_amount]

Example:

./scripts/verify-weth9-ratio.sh 0xYourPrivateKey 0.001

This script will:

  1. Check initial ETH and WETH9 balances
  2. Wrap a test amount (e.g., 0.001 ETH)
  3. Verify the exact amount of WETH9 received
  4. Calculate the ratio
  5. Report if the ratio is exactly 1:1

Step 2: Manual Verification

You can also verify manually:

# 1. Get initial balances
DEPLOYER=$(cast wallet address --private-key "0xYourPrivateKey")
INITIAL_ETH=$(cast balance "$DEPLOYER" --rpc-url "http://192.168.11.250:8545")
INITIAL_WETH9=$(cast call "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" \
  "balanceOf(address)" "$DEPLOYER" \
  --rpc-url "http://192.168.11.250:8545")

# 2. Wrap a test amount (0.001 ETH)
TEST_AMOUNT_WEI=$(cast --to-wei 0.001 ether)
cast send "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" "deposit()" \
  --value "$TEST_AMOUNT_WEI" \
  --rpc-url "http://192.168.11.250:8545" \
  --private-key "0xYourPrivateKey" \
  --gas-price 5000000000

# 3. Wait for confirmation
sleep 15

# 4. Get final balances
FINAL_ETH=$(cast balance "$DEPLOYER" --rpc-url "http://192.168.11.250:8545")
FINAL_WETH9=$(cast call "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" \
  "balanceOf(address)" "$DEPLOYER" \
  --rpc-url "http://192.168.11.250:8545")

# 5. Calculate differences
ETH_SPENT=$(echo "$INITIAL_ETH - $FINAL_ETH" | bc)
WETH9_RECEIVED=$(echo "$FINAL_WETH9 - $INITIAL_WETH9" | bc)

# 6. Verify ratio
echo "ETH Spent: $ETH_SPENT wei"
echo "WETH9 Received: $WETH9_RECEIVED wei"
echo "Expected: $TEST_AMOUNT_WEI wei"

# They should be equal (WETH9_RECEIVED == TEST_AMOUNT_WEI)
# ETH_SPENT will be higher due to gas fees

Step 3: Check Contract State

Verify the contract maintains proper backing:

# Check contract ETH balance
CONTRACT_ETH=$(cast balance "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" \
  --rpc-url "http://192.168.11.250:8545")

# Check total supply
TOTAL_SUPPLY=$(cast call "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" \
  "totalSupply()" \
  --rpc-url "http://192.168.11.250:8545")

# They should be equal
echo "Contract ETH: $CONTRACT_ETH wei"
echo "Total Supply: $TOTAL_SUPPLY wei"

Common Issues and Solutions

Issue 1: Gas Fees Confusion

Problem: Users think gas fees are part of the wrap ratio.

Reality:

  • Gas fees are separate from the wrap amount
  • If you wrap 1 ETH, you receive exactly 1 WETH9
  • But your ETH balance decreases by 1 ETH + gas fees

Example:

Initial: 10 ETH
Wrap: 1 ETH
Gas: 0.001 ETH
Result:
  - ETH Balance: 8.999 ETH (10 - 1 - 0.001)
  - WETH9 Balance: 1 WETH9 ✅
  - Ratio: 1:1 ✅ (gas is separate)

Issue 2: Display/Precision Issues

Problem: Display rounding makes it appear non-1:1.

Solution: Always check raw wei values, not displayed amounts.

# Use wei for exact comparison
cast call "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" \
  "balanceOf(address)" "$DEPLOYER" \
  --rpc-url "http://192.168.11.250:8545"
# Returns: 1000000000000000 (0.001 ETH in wei)

Issue 3: Contract Modification

Problem: The WETH9 contract may have been modified to include fees.

Solution: Inspect the contract bytecode or source code:

# Get contract bytecode
cast code "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" \
  --rpc-url "http://192.168.11.250:8545" > weth9_bytecode.bin

# Compare with standard WETH9 bytecode
# Or decompile and check the deposit() function

Issue 4: Incorrect Amount Calculation

Problem: Scripts may be calculating amounts incorrectly.

Solution: Verify amount calculations in scripts:

# Always use cast --to-wei for conversion
AMOUNT_WEI=$(cast --to-wei 1.0 ether)
# Result: 1000000000000000000 (exactly 1 ETH in wei)

# Verify before sending
echo "Sending: $AMOUNT_WEI wei"
cast --to-unit "$AMOUNT_WEI" ether
# Should output: 1.0

Expected Behavior

Correct 1:1 Ratio

Input: 1.0 ETH
Output: 1.0 WETH9
Ratio: 1.0 ✅

Input: 0.001 ETH
Output: 0.001 WETH9
Ratio: 1.0 ✅

Input: 100 ETH
Output: 100 WETH9
Ratio: 1.0 ✅

What to Check

  1. WETH9 Received = ETH Deposited (excluding gas)
  2. Contract Balance = Total Supply (always)
  3. No fees deducted from the wrap amount
  4. Exact wei match (no rounding errors)

Troubleshooting

If Ratio is NOT 1:1

  1. Run Verification Script

    ./scripts/verify-weth9-ratio.sh [private_key] 0.001
    
  2. Check Contract Implementation

    • Inspect the contract bytecode
    • Verify the deposit() function logic
    • Check for any fee mechanisms
  3. Review Transaction Details

    cast tx [transaction_hash] --rpc-url "http://192.168.11.250:8545"
    
    • Check the actual value sent
    • Verify the transaction succeeded
    • Check for any events emitted
  4. Compare with Standard WETH9

    • Standard WETH9 address on Ethereum: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
    • Verify the implementation matches

If Verification Fails

  1. Document the Issue

    • Record the exact amounts (in wei)
    • Note the transaction hash
    • Capture the ratio calculated
  2. Check Contract Source

    • Request contract source code if available
    • Compare with standard WETH9 implementation
    • Look for modifications
  3. Report the Issue

    • This is a critical bug if the ratio is not 1:1
    • WETH9 must maintain 1:1 parity for proper functionality

Script Updates

The wrap script (wrap-and-bridge-to-ethereum.sh) has been reviewed and should maintain 1:1 ratio:

  • Uses cast --to-wei for exact conversion
  • Sends exact amount via --value flag
  • No additional calculations or fees
  • Verifies balance after wrapping

If you find the ratio is not 1:1, please:

  1. Run the verification script
  2. Document the exact amounts
  3. Check the contract implementation
  4. Report the issue

Summary

  • WETH9 MUST maintain 1:1 ratio with ETH
  • No fees should be deducted during wrapping
  • Gas fees are separate and do not affect the ratio
  • Always verify using wei values, not displayed amounts
  • Use the verification script to test the actual ratio