Seaport Dutch Auction balance spoofing — MetaMask Signature Insights API

Working PoC for HackerOne report. Demonstrates the wallet UI rendering only startAmount while users actually approve up to endAmount.

Not connected.
Attack 1

Bid escalation — 100,000× understatement

Seaport bid on BAYC #1234. Offer is WETH with startAmount = 0.001 and endAmount = 100. Attacker fills near endTime.

What MetaMask will display

BIDDING 0.001 WETH
From signature-insights response — amount = 1e15 wei.

What you actually approve

up to 100 WETH (~$300,000)
Hidden endAmount = 100e18 wei never reaches the popup.
Attack 2

Listing drain — NFT sold for ~$0

Seaport listing of BAYC #5678. Consideration WETH with startAmount = 50 and endAmount = 1 wei. Attacker fills near endTime.

What MetaMask will display

RECEIVE 50 WETH
API returns amount = 50e18 in the RECEIVE state change.

What you actually receive

1 wei (~$0)
Hidden endAmount = 1.
Attack 3

USDC variant — 1 USDC shown, 1B USDC actual

Seaport bid on BAYC #9999. Offer is USDC with startAmount = 1 USDC and endAmount = 1,000,000,000 USDC.

What MetaMask will display

BIDDING 1 USDC
API returns amount = 1_000_000 (6-decimal USDC).

What you actually approve

up to 1,000,000,000 USDC
Hidden endAmount = 1e15.
Control

Non-Dutch order — startAmount === endAmount

Baseline. The API renders this correctly because there is no Dutch curve to ignore.

What MetaMask will display

BIDDING 5 WETH

What you actually approve

5 WETH
Matches — no spoofing possible without a price curve.

Reproduction notes for triage: