Skip to main content

Gas and Fees

OXN measures execution cost in gas, exactly like Ethereum. If you have shipped an Ethereum dApp, most of what you know still applies. But there are a few practical differences you must handle correctly, or your transactions will fail in confusing ways.

The short version

  • Gas is denominated in BLUAI. Standard gasPrice × gasUsed fee formula.
  • Always set gasLimit explicitly on every transaction rather than relying on client auto-estimation. See the recommended defaults below.
  • gasPrice: 0 is accepted on testnet. Useful for testing and for accounts that would otherwise be too poor to pay.
  • Refunds work like Ethereum. Unused gas is refunded — setting the limit generously is safe.
  • Encrypted calls cost more gas than plain calls because of the extra decryption and re-encryption work. Budget accordingly.

The fee model

Fees are computed the standard EVM way:

fee = gasUsed × gasPrice

Both gasPrice and gasLimit are set by the sender on each transaction. Unused gas is refunded (standard EVM behavior). The fee is paid from the sender's BLUAI balance.

OXN currently uses the legacy transaction fee model (as opposed to Ethereum's EIP-1559 with base fee + priority fee). All the fee logic you write should assume legacy semantics.

Setting gasLimit explicitly

On OXN, every transaction should set gasLimit explicitly rather than relying on client-side auto-estimation. Encrypted calldata means the gateway cannot cheaply preview an encrypted transaction's execution, so eth_estimateGas is not the recommended path — pin the value yourself instead. Unused gas is refunded (standard EVM behavior), so a generous limit is safe.

The pattern in ethers.js:

await contract.transfer(recipient, amount, { gasLimit: 500_000n });

And in Foundry:

forge create ... --gas-limit 3000000
cast send ... --gas-limit 500000
Call typeSuggested gasLimit
Native token transfer100_000n
ERC-20 transfer / approve500_000n
ERC-721 mint / transfer500_000n
Simple contract deploy (small ERC-20)3_000_000n
Large contract deploy5_000_000n+
Complex composed call1_000_000n

These are conservative upper bounds. Unused gas is refunded, so setting the limit high is safe. Setting it too low causes out of gas reverts.

gasPrice: 0 on testnet

The testnet chain layer accepts transactions with gasPrice: 0. This is useful in two scenarios:

Freshly funded accounts. A brand-new account with only the faucet's 10 TBLUAI cannot pay 100 wei × 3M gas for a contract deployment. Setting gasPrice: 0 bypasses this.

Testing. Deterministic tests are easier when you don't have to model fee dynamics.

Don't use gasPrice: 0 in production traffic. Mainnet will require positive fees.

Why encrypted calls cost more gas

An encrypted transaction goes through additional steps inside the enclave:

  1. Envelope parsing. The runtime parses the CBOR wrapper.
  2. X25519 key derivation. A symmetric key is derived from the caller's ephemeral pubkey and the enclave's private key.
  3. Deoxys-II decryption. The calldata is decrypted.
  4. Return-data encryption. The response is encrypted back to the caller.

Each step consumes some gas on top of the standard EVM execution. As a rule of thumb, an encrypted transaction uses roughly 20–50k more gas than the equivalent plain transaction on Ethereum, though the exact overhead depends on payload size.

out of gas on a call that used to work. Bump gasLimit. If the same call worked previously and stopped working, the runtime may have made small gas-cost adjustments in a recent upgrade. Reset your defaults to the upper bounds above.

insufficient balance to pay fees. Your account cannot afford gasLimit × gasPrice. Either faucet more TBLUAI, or set gasPrice: 0 on testnet. Note: the OXN Web Wallet UI currently mislabels this error as "Invalid address" in some versions — check the underlying error before assuming a bad address.

Deposit / withdraw operations require gas too. Moving value between address formats is a state-changing transaction. Budget the standard 500_000n for it.

Refunds are automatic. You do not need to reclaim unused gas manually. If you set gasLimit: 5_000_000n but the transaction uses 800_000, only 800_000 × gasPrice is billed.

What's not (yet) supported

  • EIP-1559 fee model — no maxFeePerGas / maxPriorityFeePerGas. Use legacy gasPrice.
  • Fee delegation / gas sponsorship — no meta-transaction relayer built into the protocol. Applications can build one on top.

Next steps