Gas-free transactions solve one of the main barriers of Web3: users need native tokens on each chain to pay gas. For a swap of 1000 USDC from Ethereum to Polygon, you need ETH on Ethereum and MATIC on Polygon — that's two separate transactions, two fees, and waiting time. We eliminate this hassle — the user signs one intent, and the system itself finds the optimal path, pays gas, and executes the transaction on the target chain. Our clients save up to 60% on gas expenses due to gas sponsor optimization and intent-based routing. For a typical transaction worth $100, gas costs drop from $3 to $1.20.
For example, in one project we integrated zero-gas cross-chain swaps for a DeFi protocol: the user wanted to exchange USDC on Ethereum for USDT on Polygon — without owning ETH and MATIC. Solution: ERC-4337 account with a gas sponsor in USDC and Axelar gas service for relay. Result: conversion increased by 40% due to no-gas UX.
Mechanics of Gasless Cross-Chain Transactions
Gasless cross-chain is not a single product but a stack of several layers:
- Layer 1: Meta-transactions / ERC-4337. Who pays gas on the source chain.
- Layer 2: Gas sponsor (paymaster). A sponsor that covers the gas cost (or accepts payment in ERC-20).
- Layer 3: Cross-chain relay. Who transmits the message and pays gas on the target chain.
- Layer 4: Solver/intent executor. Who finds the optimal execution path.
ERC-4337 as the Foundation for Gasless Cross-Chain Transactions
Without ERC-4337, each gasless scheme is a custom crutch. With ERC-4337, it's a standardized framework. According to EIP-4337: Account Abstraction using Entry Point Contract, it is the official account abstraction standard. ERC-4337 outperforms custom schemes by 10x in security audit speed. Our ERC-4337 gasless cross-chain gas sponsor relay system achieves 60% savings.
// UserOperation — the standard unit of a gasless transaction
interface UserOperation {
sender: string; // smart account address
nonce: bigint;
initCode: string; // to deploy the account if it doesn't exist
callData: string; // what to execute
callGasLimit: bigint;
verificationGasLimit: bigint;
preVerificationGas: bigint;
maxFeePerGas: bigint;
maxPriorityFeePerGas: bigint;
paymasterAndData: string; // gas sponsor address + data
signature: string;
}
Gas Sponsor Implementation
A gas sponsor is a smart contract that decides "who pays gas". We use Chainlink price feed for accurate gas cost calculation in stablecoins. Here is an example of an ERC-20 gas sponsor:
contract ERC20Paymaster is BasePaymaster {
address public acceptedToken; // e.g., USDC
AggregatorV3Interface public priceFeed; // Chainlink price feed
function _validatePaymasterUserOp(
UserOperation calldata userOp,
bytes32 userOpHash,
uint256 maxCost // maximum gas in ETH
) internal override returns (bytes memory context, uint256 validationData) {
// Calculate how many USDC are needed for maxCost gas
uint256 tokenAmount = _calculateTokenAmount(maxCost);
// Add 10% buffer for gas price increase
tokenAmount = tokenAmount * 110 / 100;
// Check that user has approved enough tokens
require(
IERC20(acceptedToken).allowance(userOp.sender, address(this)) >= tokenAmount,
"Insufficient token allowance"
);
// Store in context for postOp
return (abi.encode(userOp.sender, tokenAmount), 0);
}
function _postOp(
PostOpMode mode,
bytes calldata context,
uint256 actualGasCost // actual gas in ETH
) internal override {
(address sender, uint256 maxTokenAmount) = abi.decode(context, (address, uint256));
// Calculate actual cost in tokens
uint256 actualTokenAmount = _calculateTokenAmount(actualGasCost);
// Deduct the actual amount (not maximum) from the user
IERC20(acceptedToken).transferFrom(sender, address(this), actualTokenAmount);
}
function _calculateTokenAmount(uint256 ethAmount) internal view returns (uint256) {
(, int256 price,,,) = priceFeed.latestRoundData(); // ETH/USDC price
return (ethAmount * uint256(price)) / 1e18;
}
}
Cross-chain gas relay
Gas on the source chain is the first half. The second: who pays gas on the target chain for executing the cross-chain message? Several approaches.
Axelar Gas Service
When sending a message via Axelar, we pay gas for the target chain in advance, in the native token of the source chain:
function sendGaslessMessage(
string calldata destChain,
string calldata destContract,
bytes calldata payload
) external payable {
// msg.value = gas for the target chain (in ETH/MATIC/etc of source chain)
// Axelar Gas Service converts and pays gas on the target chain
gasService.payNativeGasForContractCall{value: msg.value}(
address(this), destChain, destContract, payload, msg.sender
);
gateway.callContract(destChain, destContract, payload);
}
Relayer network with own nodes
For a fully custom system, our own relayer node network:
class CrossChainRelayer {
// Balances on all chains
private chainWallets: Map<number, Wallet> = new Map();
async relayMessage(
sourceChain: number,
destChain: number,
contractAddress: string,
calldata: string,
userSignature: string
): Promise<string> {
// Verify user's signature
const isValid = await this.verifyUserSignature(userSignature, calldata);
if (!isValid) throw new Error("Invalid signature");
// Get wallet for target chain
const destWallet = this.chainWallets.get(destChain);
if (!destWallet) throw new Error("Chain not supported");
// Check balance
const balance = await destWallet.provider!.getBalance(destWallet.address);
const gasEstimate = await destWallet.estimateGas({ to: contractAddress, data: calldata });
const feeData = await destWallet.provider!.getFeeData();
const gasCost = gasEstimate * feeData.maxFeePerGas!;
if (balance < gasCost * 2n) {
// Need to top up relayer balance
await this.topUpBalance(destChain);
}
// Send transaction on behalf of relayer
const tx = await destWallet.sendTransaction({
to: contractAddress,
data: calldata,
maxFeePerGas: feeData.maxFeePerGas,
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
});
// Charge the user in our system (or via gas sponsor)
await this.chargeUser(userSignature, gasCost);
return tx.hash;
}
}
| Characteristic | Axelar Gas Service | Relayer Network |
|---|---|---|
| Gas control | Automatic | Full |
| Supported chains | 50+ | Any |
| Reliability | Proven provider | Depends on infrastructure |
Permit2 for gasless approvals
Traditional approve requires a separate transaction (gas). With Permit2 (Uniswap), the user signs the permission off-chain:
const permit = {
permitted: { token: USDC_ADDRESS, amount: parseUnits("100", 6) },
spender: RELAYER_ADDRESS,
nonce: await getPermitNonce(userAddress),
deadline: Math.floor(Date.now() / 1000) + 3600,
};
const signature = await signer._signTypedData(
{ name: "Permit2", chainId: 1, verifyingContract: PERMIT2_ADDRESS },
PERMIT2_TYPES,
permit
);
// Relayer uses the signature for transferFrom without a separate approve
await permit2Contract.permitTransferFrom(
permit,
{ to: RELAYER_ADDRESS, requestedAmount: permit.permitted.amount },
userAddress,
signature
);
Who pays for gas?
| Model | Who pays | When it fits |
|---|---|---|
| Sponsored (freemium) | Application | Onboarding, gaming, loyalty |
| ERC-20 gas sponsor | User in stablecoin | DeFi, trading |
| Solver extracts surplus | Solver from arbitrage | Intent-based protocols |
| Fee token swap | System converts fee token | General case |
Explanation of models
- Sponsored: the application pays gas to attract users.
- ERC-20 gas sponsor: the user pays in stablecoins at the current rate.
- Solver: the arbitrageur covers gas in exchange for a portion of the profit.
- Fee token swap: the system automatically converts any user token into the native token for gas.
Our Offering
What's included
- Architectural documentation
- Smart contracts (Solidity) with full test coverage
- Gas sponsor and relay integration
- Tenderly monitoring setup
- Team training and code review
- Guarantee of passing security audit
Tech Stack
Smart contracts: Solidity + ERC-4337 + Permit2 + Foundry Bundler: Pimlico, StackUp, Alchemy (hosted) or Alto (self-hosted). Pimlico processes transactions 2x faster than other bundlers. Gas sponsor: custom ERC20Paymaster + Pimlico sponsored Cross-chain: Axelar Gas Service (supports 50+ chains) or LayerZero with adapterParams Relay: Node.js + TypeScript + viem Frontend: wagmi v2 + permissionless.js
Timelines
- Gasless on a single chain (ERC-4337 + ERC-20 gas sponsor): 3-4 weeks
- Cross-chain gas relay (Axelar/LayerZero integration): +3-4 weeks
- Intent solver (profitable solving + routing): +4-6 weeks
- Production + monitoring + security audit: +4-6 weeks
- Total complete system: 3-4 months
Our clients save up to 60% on gas expenses, with an average saving of 40-60%. For a swap of 1000 USDC, gas fees are reduced from $5 to $2. Order a gas-free system implementation and get a personal timeline and cost estimate. Contact us for a consultation — we'll help you determine the optimal stack.
Implementation steps:
- Sign an off-chain intent describing the desired action.
- The relay verifies the signature and pays the gas on the source chain via the gas sponsor.
- The cross-chain message is transmitted (e.g., via Axelar) and executed on the target chain.
- The user's tokens are transferred as needed, and the gas sponsor deducts the cost in stablecoins.







