| argument-hint | <chain-name> <recipient-address> |
| name | sweep-eth |
| description | Sweep the full native balance of the configured account to a recipient using a legacy (type-0) transaction so the remaining balance lands at exactly zero. Use when the user asks to "sweep ETH", "drain the account", "empty the wallet to zero", or "send everything minus gas". Loads ETH_PRIVATE_KEY plus ADDRESS from the repo-root dotenvx `.env`, resolves chain metadata through `$evm-chains`, and broadcasts with cast only after the user explicitly confirms emptying the account. The user must specify the chain name and the recipient address. |
Sweep ETH
Overview
Send the entire native balance of the configured account to a recipient, leaving exactly zero behind. A legacy transaction is mandatory: it debits exactly gasPrice * gasUsed, and a plain transfer to an EOA uses exactly 21000 gas, so the total cost is known before signing. Post-EIP-1559 transaction types make the realized fee depend on the inclusion-time base fee, which cannot be fixed in advance.
Use $evm-chains to resolve chain name, chain ID, native currency symbol, and RPC URL before any onchain step. Use cli-cast only for the cast commands.
Workflow
1. Load the signing environment
Load ETH_PRIVATE_KEY and ADDRESS from the repo-root dotenvx .env. Run secret-dependent commands through a dotenvx-run subshell, such as dotenvx run --quiet -- sh -c '...'; do not source .env directly because it is encrypted. If ADDRESS is missing, derive it from ETH_PRIVATE_KEY with cast wallet address.
2. Resolve chain and recipient
- Resolve the user-supplied chain through
$evm-chains to get RPC_URL, chain ID, and native symbol.
- Validate the recipient as a checksummed address with
cast to-check-sum-address.
- Require
cast code "$RECIPIENT" --rpc-url "$RPC_URL" to return 0x. A contract recipient may need more than 21000 gas, which breaks the exact-zero math. Stop and report if the recipient has code.
3. Compute the sweep amount
BALANCE=$(cast balance "$ADDRESS" --rpc-url "$RPC_URL")
GAS_PRICE=$(cast gas-price --rpc-url "$RPC_URL")
GAS_PRICE=$(echo "$GAS_PRICE * 13 / 10" | bc)
VALUE=$(echo "$BALANCE - 21000 * $GAS_PRICE" | bc)
- Use
bc for the arithmetic; wei amounts overflow 64-bit shell integers.
- The headroom only shifts wei from
VALUE into the fee — the end balance is exactly zero either way — but the gas price must stay above the base fee until inclusion or the transaction stalls.
- If
VALUE is zero or negative, stop and report that the balance does not cover gas.
4. Confirm with the user
This action empties the account. Before broadcasting, show the user:
- chain and chain ID
- sender and recipient addresses
- current balance, gas cost, and the exact
VALUE being sent
Then ask them to double-check that they truly want to drain the account to zero. Do not broadcast without an explicit yes; treat anything else as a no.
5. Broadcast
cast send "$RECIPIENT" \
--value "$VALUE" \
--legacy \
--gas-price "$GAS_PRICE" \
--gas-limit 21000 \
--rpc-url "$RPC_URL" \
--private-key "$ETH_PRIVATE_KEY"
6. Verify
- Confirm success with
cast receipt.
- Re-read the balance and confirm it is exactly
0.
Guardrails
- Never use EIP-1559 transaction types; only
--legacy keeps the fee deterministic.
- Never broadcast without the explicit confirmation in step 4.
- Stop if there are pending transactions from the account (compare
cast nonce with the pending nonce); a queued transaction changes the balance math.
- Do not infer chain IDs or RPC URLs locally; resolve them through
$evm-chains.
Minimum Inputs
- one chain name, resolved through
$evm-chains
- one recipient address (EOA)
- explicit user confirmation to empty the account