maxPriorityFeePerGas is always 0, baseFee is denominated in USDT0, and the value field in a native transfer carries USDT0 (not ETH).
This guide shows how to construct transactions correctly on Stable and what to change when porting Ethereum code.
What changes vs. Ethereum
Because the transaction format is unchanged, existing ethers.js, viem, Hardhat, and Foundry code runs on Stable without changes. The differences are in how you compute gas fields, not how you encode them.
Construct a transaction
Fetch the base fee, setmaxPriorityFeePerGas to 0, and double the base fee as a safety margin.
1 gwei, a 21,000-gas native transfer costs approximately 0.000021 USDT0.
Estimate gas cost in USDT0
eth_estimateGas and eth_gasPrice behave identically to Ethereum. The result is already in USDT0 because that is the gas token.
Tooling configuration
- Hardhat / Foundry: no special configuration needed. Standard EVM settings work. If your config explicitly sets a priority fee, set it to
0. - Wallets: hide or disable the priority tip input field. Displaying it is misleading because the value has no effect on ordering or inclusion.
- Monitoring: fee analytics dashboards should not chart priority fees. They are always zero on Stable.
Common mistakes when porting from Ethereum
- Applying an ETH-denominated tip: copying a priority-fee constant from Ethereum doesn’t produce faster inclusion. Stable orders transactions by base fee only.
- Treating
valueas ETH: a native transfer’svalueis USDT0. Don’t convert it through ETH/USD prices. - Hard-coding a fee cap: set
maxFeePerGasfrom the livebaseFeePerGas(e.g.,baseFee * 2) rather than a fixed value, so transactions don’t stall when the base fee rises.
Next recommended
Gas pricing reference
Full base-fee model, EIP-1559 format, and
eth_* method behavior.Zero gas transactions
Let an application cover gas via the Gas Waiver.
USDT0 behavior on Stable
Balance reconciliation and contract design with USDT0’s dual role.

