fix: count the network fee in the confirm-screen balance check (closes #154)
Some checks failed
check / check (push) Has been cancelled
Some checks failed
check / check (push) Has been cancelled
The Send button was enabled whenever the amount alone fit the balance, so a max-value ETH send passed the confirmation screen and failed at broadcast, after the user had committed to it. The arithmetic moves into src/shared/txValidation.js as a pure function over 18-decimal fixed point: native ETH now requires amount + fee <= balance, and an ERC-20 transfer requires the ETH balance to cover the fee on top of the token check, reported as its own error. Validation re-runs when the async estimate resolves; Send stays disabled while the estimate is pending and when it fails, so an unknown fee is never treated as zero. The fee messages are static elements that already reserve their space, so nothing moves when the estimate lands. The fee reserved is the one the node will actually require. The send pins no fee fields, so ethers broadcasts a type-2 transaction and the node validates it against value + gasLimit * maxFeePerGas; gating on gasPrice would under-reserve by roughly gasLimit * baseFee and let through exactly the broadcast failure this change exists to prevent. feeReserveWei() derives that reserve, falling back to gasPrice only where no type-2 pricing exists. The reserve is read when the screen opens and the broadcast derives its own, so a base fee that roughly doubles while the user is at the password field can still outrun it: this turns a deterministic failure on every max-value send into a rare one, not into none. The fee line shows both numbers rather than one - what the transfer is expected to cost, and below it the larger amount reserved until it confirms. Quoting only the reserve overstates the typical mainnet cost by roughly double on every send; quoting only the estimate contradicts the gate. The second line holds its space from the first paint. validateTransfer() fails closed: a feeWei that is not a non-negative bigint under FEE_KNOWN, any unrecognised feeStatus, and a negative amount all block, rather than counting as a fee of zero or as an amount that passes every comparison trivially.
This commit is contained in:
18
README.md
18
README.md
@@ -575,16 +575,26 @@ screen, including ExportPrivKey, falls back to Home.
|
||||
- To: blockie + color dot + full address + etherscan link + ENS name
|
||||
- Amount: value + symbol (USD in parentheses)
|
||||
- Your balance: value + symbol (USD in parentheses)
|
||||
- Estimated network fee: "Estimating..." then the ETH amount (USD in
|
||||
parentheses) or "Unable to estimate", fetched async
|
||||
- Network fee: "Estimating..." then two lines, or "Unable to estimate",
|
||||
fetched async. The first line is what the transfer is expected to cost,
|
||||
`gasLimit * gasPrice` (USD in parentheses); the second is the
|
||||
`gasLimit * maxFeePerGas` reserve the node requires, which is what the
|
||||
balance check gates on. The second line is omitted on a network with no
|
||||
type-2 pricing, where the two are the same number, but its space is
|
||||
reserved either way
|
||||
- Warnings: inline warnings from the local checks (scam address, self-send)
|
||||
plus four reserved warning boxes made visible by the async checks —
|
||||
recipient with no transaction history, recipient is a contract, burn
|
||||
address, and an Etherscan phishing/scam label
|
||||
- Errors (insufficient balance)
|
||||
- Errors (insufficient balance), plus three reserved error boxes — the
|
||||
amount plus the fee exceeds the balance (ETH transfers), not enough ETH to
|
||||
pay the fee for the transfer (ERC-20 transfers), and the fee could not be
|
||||
estimated. The first two are mutually exclusive per transfer type, so only
|
||||
the applicable one holds space
|
||||
- Password: an inline field on this screen, not a modal, with its own error
|
||||
line
|
||||
- "Sign & Send" button (disabled if errors)
|
||||
- "Sign & Send" button (disabled if errors, and while the network fee
|
||||
estimate is pending or unavailable)
|
||||
- **Transitions**:
|
||||
- "Sign & Send" (correct password) → broadcast tx → **WaitTx**
|
||||
- "Sign & Send" (correct password) → broadcast fails → **ErrorTx**
|
||||
|
||||
Reference in New Issue
Block a user