# Theft of funds under relaying the transaction

SmartAccount.execTransaction refunds gas per calldata byte at 8 gas but zero bytes cost 4, letting a frontrunner pad calldata with zeros to drain the wallet via inflated relayer refunds.

- Payout: Contest reward
- Severity: high
- Program: Biconomy
- Credited: V\_B
- Disclosed: 2023-03-03
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-01-biconomy-findings/issues/489
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-biconomy%3AH-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:accounting-error vuln:business-logic

**Target:** SmartAccount.execTransaction relayer gas refund logic
**Root cause:** Refund is computed from msg.data.length * 8 gas per byte, but zero bytes only cost 4 gas, so appended zero padding yields refund exceeding actual gas spent.
**Steps:**
1. Observe execTransaction computes startGas including msg.data.length * 8 and refunds gasleft()-startGas to relayer.
2. Craft original calldata `abi.encodeWithSignature(RelayerManager.execute.selector, ...)` for a signed user tx.
3. Frontrun relayer tx with same calldata plus `0x00[]` zero bytes appended (e.g. 100000 zeros).
4. Solidity ABI decoder accepts trailing zero bytes; refund inflated by 100000*4 = 400000 gas.
5. Repeat/scale padding to drain wallet ETH via refund.
**How found:** Code reading of execTransaction's gas accounting: noticed refund uses msg.data.length * 8 while zero calldata bytes cost only 4 gas, and that Solidity tolerates trailing zero bytes in ABI-encoded input.
**Exploitation:** Attacker frontruns a relayer's execTransaction, appending arbitrary zero bytes to calldata; the contract accepts it and pays an inflated gas refund to the attacker-controlled relayer, extracting ETH from the smart wallet.
**Escalation:** Padding length is unbounded, so refund can be made arbitrarily large relative to actual gas cost, draining wallet balance.
**Insight:** When a contract reimburses gas based on msg.data.length, compare per-byte refund rate against actual calldata gas cost (4 for zero, 16 for non-zero) and check whether the ABI decoder accepts trailing/padded bytes to inflate length cheaply.
