← Protocols
ERC-1077 — Gas Relay for Contract Calls
Standard / EIP·EVM

ERC-1077 — Gas Relay for Contract Calls

01Description

Stagnant ERC (precursor to ERC-4337) defining how a smart contract wallet accepts off-chain signed `executeGasRelay` messages so a third-party relayer can submit them on-chain and be reimbursed in ETH or ERC-20. Pioneered meta-transactions, gas abstraction, and ERC-1271 signature validation.

02Best for
  • 01historical context for AA / 4337 design decisions
  • 02legacy contract-wallet codebases (Universal Login, Status, Argent v1)
  • 03minimal meta-tx relayers where 4337 infra is overkill
  • 04pre-Pectra smart wallets without bundlers
  • 05teaching gas-abstraction primitives
03Install
  • # Reference implementations (legacy):
  • # - Status Network: https://github.com/status-im/account-contracts
  • # - Universal Login: https://github.com/UniversalLogin/UniversalLoginSDK
  • pnpm add @openzeppelin/contracts
05Prompt snippet
Implement an ERC-1077 wallet by exposing `function executeGasRelay(bytes calldata _execData, uint256 _nonce, uint256 _gasPrice, uint256 _gasLimit, address _gasToken, bytes calldata _messageSignatures) external returns (bool success)`. The signed message digest is `keccak256(0x1900 ++ address(this) ++ chainId ++ nonce ++ execData ++ gasPrice ++ gasLimit ++ gasToken ++ signatures)` (per EIP-191 v0). Verify owner signatures via ECDSA recovery for EOAs and ERC-1271 `isValidSignature(hash, sig)` for contract owners; multi-sig variants concatenate ordered signatures. After execution, reimburse the relayer (`tx.origin` or `msg.sender`) `gasUsed * gasPrice` in `_gasToken` (zero address ⇒ ETH). Increment a per-wallet nonce to prevent replay. Note: ERC-1077 has been superseded by ERC-4337 (UserOperation + EntryPoint + bundlers + paymasters); use 1077 only for legacy wallet maintenance — for new builds choose 4337 or ERC-7702.
06Gotchas
  • Signature replay across chains: early ERC-1077 implementations omitted `chainId` from the digest. Always include `block.chainid` in the hash and reject signatures whose chainId ≠ current — Status, Argent, and others patched this post-deploy.
  • Reimbursement re-entrancy: paying the relayer in an ERC-20 with a transfer hook (ERC-777, fee-on-transfer) re-enters the wallet's `executeGasRelay`. Use checks-effects-interactions, increment the nonce BEFORE the inner call, and prefer plain ERC-20 gas tokens or wrapped ETH.
  • Gas-price griefing: a malicious relayer can pick `_gasPrice` after seeing the signed message and inflate the reimbursement. Cap `_gasPrice` in the signed message and refuse calls where `tx.gasprice > _gasPrice`.
  • ERC-1271 + delegate signers: when the wallet's owner is itself a contract (multisig), use `isValidSignature` and gate validation on a known interfaceId — naive `ecrecover` will silently accept zero address for malformed sigs. Never trust a recovered address of `0x0`.
  • ERC-1077 is Stagnant and tooling (paymasters, bundlers, indexers) has migrated to ERC-4337. New deployments should pick ERC-4337 (UserOperation v0.7) or ERC-7702 delegation; treat 1077 as read-only legacy.
07Alternatives