ADR-004: Relayer Economy and Security
| Status | Proposed |
| Date | 2026-03-11 |
Context
This ADR is complementary to ADR-002 — it addresses the economic and security model of the relayer at a higher level, and both can be implemented together.
In the current implementation, the relayer accepts transaction requests from any user, permissionlessly. The relayer bears the full gas cost and is never refunded. This makes the relayer vulnerable to a griefing attack: an adversary floods it with transaction requests until it runs out of gas funds.
This problem cannot be ignored:
- Extortion risk. A blackhat will eventually discover this attack surface and use it to drain the relayer, demanding payment to stop.
- Non-negligible gas costs. Privacy transactions (ZK proof verification, encrypted balance updates) are significantly more expensive than simple transfers. Even on the cheapest chains, subsidizing them indefinitely is not sustainable.
Why per-transaction refund doesn't work
In typical relayer systems (ERC-4337 paymasters, Tornado Cash, Railgun), the relayer pays for gas but is refunded within the same transaction — usually via an ERC-20 transfer from the user. This class of solutions requires the user to already hold assets that can cover the refund.
In our system, this assumption does not hold. When a new user sets up an account, they have no on-chain assets at all — yet the relayer still needs to submit a transaction on their behalf (e.g., registering an encryption key). This rules out in-transaction refund as a general solution.
Beyond our specific constraints, per-transaction refund mechanisms are notoriously complex. They require handling a large number of edge cases (gas estimation, refund token pricing, failed-but-gas-consuming transactions, etc.), which is one of the reasons ERC-4337 adoption remains limited despite years of development.
Proposal
Partner model
We operate in a model where the privacy system (encrypted balances, and potentially "L3") does not serve end users directly. Instead, partners integrate the system and serve their own end users. Users always interact with the system through a partner's application.
This partner model provides a natural trust and billing boundary for the relayer.
Partner authentication
Each partner registers a public key PK_partner with the relayer. Every request sent to the relayer must include a signature produced with the corresponding secret key SK_partner. The relayer verifies this signature before processing any request.
Unsigned or incorrectly signed requests are rejected — this eliminates the griefing attack surface entirely, since only registered partners can cause the relayer to spend gas.
Usage tracking and billing
The relayer maintains a per-partner usage table, aggregating metrics such as:
- Number of transactions submitted
- Aggregate gas costs
- Transaction counts by type (shield, transfer, unshield, stake, etc.)
Partners are billed based on this table. The specific billing and payment mechanism (invoicing, prepaid credits, on-chain settlement, etc.) is out of scope for this ADR and is fully independent of the authentication scheme described here.
Request flow
The authentication requirement means that user requests cannot go directly to the relayer. Instead, each partner operates a backend service that holds SK_partner and acts as a gateway:
User (client app) → Partner backend → Relayer
(holds SK_partner,
signs requests)
- The user's client app sends a transaction request to the partner's backend.
- The partner backend can apply its own logic: per-user quotas, rate limiting, fraud checks, request validation, etc.
- The backend signs the request with
SK_partnerand forwards it to the relayer. - The relayer verifies the signature, records the usage against the partner, and submits the transaction.
Privacy note: There are variants of this design where user requests are encrypted so that only the relayer can decrypt the contents. In such a setup, the partner backend signs the request envelope without learning the transaction details — limiting partner visibility into what its users are submitting.
Hosted backend option
Requiring each partner to run a backend server raises the barrier to integration. To address this, we can offer a hosted backend as a service:
- We deploy and operate the backend on the partner's behalf (this could even be the default setup).
- The hosted backend comes preconfigured with sensible defaults: per-user rate limits, basic anti-abuse rules, and spending caps that limit the partner's relayer costs.
- Partners who need custom logic can run their own backend, or extend the hosted one.
This keeps the integration path simple for partners who just want to get started, while preserving the flexibility for those who need more control.
Consequences
What becomes easier:
- Relayer is protected from griefing — only authenticated partners can trigger gas-spending operations
- Clear accountability: every transaction is attributable to a specific partner
- Partners get visibility and control over their users' relayer usage via their own backend
- Billing is straightforward — usage is tracked per partner with no complex on-chain refund logic
- New partners can integrate quickly via the hosted backend option
What becomes harder:
- Partners must either run a backend or use the hosted service — direct user-to-relayer requests are no longer possible
- Partner key management:
SK_partnermust be stored securely; compromise allows an attacker to submit requests (and costs) on the partner's behalf - Additional latency from the extra hop (user → partner backend → relayer), though this should be negligible in practice
What stays the same:
- On-chain contract logic: no changes required
- User-facing flow from the client app perspective: users still submit transaction requests and receive results
- Privacy properties of the underlying encrypted balance system