Architecture

Resonance is a general, two-sided fee market, matching sets of user transactions, TT, to sets of capable, executing nodes, NN. This is in contrast to fee mechanisms like EIP-1559 (Ethereum’s current default fee mechanism) that operate on the basis of assigning single transactions to execution by every node in a network.

User valuation

Transactions in Ethereum pay gas for inclusion into a block.

After EIP-1559, gas fees are split into two parameters: a baseFee and a priorityFee. The baseFee is a minimum inclusion fee that modulates based on blockspace demand and is burnt. The priorityFee is a user-specified tip to block proposers to prioritize inclusion of their transaction relative to others.

Resonance operates in a surplus-maximizing setting. Rather than transactions specifying baseFee or priorityFee, users instead assign a valuation to their transactions, which represents the maximum amount of money a user submitting a transaction is willing to pay for its execution.

Surplus maximization is the process of achieving the highest total surplus in a market, achieved by setting the right price and quantity for a product. By operating in a surplus-maximizing setting, Resonance ensures that its allocations are the most economically efficient; no matching besides the winning one will lead to better prices for users or more earnings for nodes.

Unlike priorityFee in EIP-1559, a valuation in Resonance must stay private to the network until a successful transaction ↔︎ node match is found. For this reason, valuation is encrypted to the Auctioneer (described below).

Node cost function

In Ethereum today, all nodes execute each and every transaction in a block. In return for their service, validators actively benefit from sum(priorityFee) of included transactions and an inflationary block reward (currently, 2 ETH) when they are the elected block proposer, and passively from ETH supply reduction via the baseFee burn.

Irrespective of whether a node is specialized to execute certain types of compute, it is rewarded congruently to any other, and forced to execute all transactions.

In Ritual, via Resonance and Symphony, we enable selective execution and node specialization, reducing redundant re-execution and enabling nodes to make explicit their unique execution costs.

Akin to users specifying a true valuation for their transactions, each node also specifies a cost function which dictates their true cost to executing a set of transactions.

Formally, this can be defined as each node, nNn \in N (nn is an element in the set of nodes, NN), specifies a cost function, cn(X):2TR0c_n(X):2^T\rightarrow\mathbb{R}_{\ge0}, denoting the amount of money the node, nn, must be paid to execute a bundle of transactions, XX, where XTX \subseteq T (XX is a subset of all valid transactions, TT).

A node cost function must stay private to the network at the risk of exposing true execution costs, and hence node margins, to informed participants. It is also encrypted to the Auctioneer (described below).

Brokers

Resonance introduces a new set of entities known as brokers. Brokers are sophisticated and profit-seeking agents that compute efficient allocations assigning transactions to set of nodes.

Think of brokers as a parallel to searchers or block builders in the MEV ecosystem: advanced participants that use their informed priors to efficiently match transactions, pocketing the spread between transaction valuation and node execution cost in the process.

Unlike in the Ethereum block building process, Resonance provides strong guarantees on the equilibrium behavior of brokers at pure Nash equilibrium.

Brokers primarily interface with the Auctioneer (described below). For each Auctioneer batch:

  1. Brokers collect the set of transactions, TT, that need to be matched via Auctioneer API
  2. Execute their internal logic to produce a valid allocation, α:T2N\alpha:T\rightarrow 2^N
  3. Submit their best routing, RbR_b, to the Auctioneer via API

A routing, Rb=(α,π,ϕ)R_b = (\alpha, \pi, \phi), where bBb \in B (bb is a single broker in the set of all brokers, BB), is made up of a valid allocation αV\alpha \in V (α\alpha is an allocation in the set of all valid allocations, VV) and payment rules π\pi (how much a user should pay for execution of a transaction, tt) and ϕ\phi (how much a node should be paid to execute a transaction, tt).

You can learn more about brokers via our canonical, open-source implementation, Echo (coming soon…).

Auctioneer

At the center of Resonance lies the Auctioneer, a new entity responsible for orchestrating brokers and executing the Resonance mechanism.

The Auctioneer has two components: an on-chain smart contract and an off-chain service:

On-chain smart contract

The Auctioneer smart contract, Auctioneer.sol, has four core functions:

  1. Exposing the auctioneer publicKey to which users and nodes encrypt data
  2. Managing node registration and periodic cost function updates
  3. Enshrining match transactions from the off-chain service into chain state
  4. Handling post-execution payments and disputes between users, nodes, and brokers

Off-chain service

The off-chain Auctioneer service has six core functions:

  1. Receiving an inbound stream of pending transactions, tt, from various nodes
  2. Reading the on-chain node registration and cost function updates
  3. Periodically initiating a new Auctioneer batch, exposing a set of to-match transactions, TT
  4. Receiving and validating broker routing, RbR_b, submissions, per batch
  5. Executing the Resonance mechanism to select the surplus-maximizing routing, RR^*
  6. Enshrining the best routing, RR^*, via match transaction to the on-chain smart contract

Desired properties

An Auctioneer must adhere to certain desired properties:

  1. Auctioneers must execute the Resonance mechanism correctly
  2. Auctioneers must not censor any broker routing, RbR_b, submissions
  3. Auctioneers must not censor any query valuation or node cost function submissions
  4. Auctioneers must not leak decrypted transaction valuation, decrypted node cost function, or broker routing submissions publicly

Keen observers will notice that part of the mechanism design detailed above, while purposefully inefficient from the standpoint of E2E transaction latency, ensures that these properties are upheld. For example, by handling node registration and cost function updates on-chain, we explicitly introduce a one block best-case E2E delay (of four total induced), but in doing so, ensure that node registration and cost function updates benefit from the same censorship-resistant guarantees of any other blockchain transaction.

For private testnet, Ritual operates a single, centralized Auctioneer that users, nodes, and brokers must trust to correctly execute and not censor. For public testnet and mainnet, we introduce a multi-Auctioneer design (not dissimilar to how the MEV-Boost sidecar operates today) that (1) enables anyone to run an Auctioneer, and (2) produce succinct proofs of valid Auctioneer execution and not censoring.

Today, the Auctioneer operates in a batch setting, with batches currently executed once-per-block. For public testnet and mainnet, we are working on dynamic, streaming implementations.

Account Abstraction

EIP-1559 is enforced as the default Ethereum fee mechanism and enshrined directly into the execution client codebase.

In contrast, Resonance is an opt-in upgrade for users that demand heterogeneous compute or those willing to trade increased transaction inclusion latency for potentially cheaper execution.

As a result of this optionality, Resonance transactions are implemented at a smart-contract layer rather than through the introduction of a custom transaction type (akin to Type-2 transactions which were introduced when Ethereum added EIP-1559 support).

This optionality presents a few problems:

  1. Without the addition of a new transaction type, we can’t introduce encrypted valuation as a transaction parameter
  2. Because valuation must remain private except to the Auctioneer, only the Auctioneer can validate and deduct balances for transaction execution
  3. Without using the transaction value parameter (publicly enforced), nodes cannot deduct any ETH balances at all
  4. Transactions must remain in-executable until after their match is enshrined
  5. But, once a match is enshrined, transactions must reflect a payment to matched nodes
  6. We must co-opt existing Ethereum wallet provider APIs for seamless integration with popular wallets
  7. We must enable 1-6 without forcing all developers to introduce modifications in their own smart contracts

We found our solution to these problems via account abstraction:

  1. Resonance users upgrade their wallets by setting their implementation to AuctioneerWallet.sol
  2. AuctioneerWallet.sol permissions the on-chain Auctioneer.sol contract to manage EOA ETH balances through an auctioneer-permissioned withdraw() function
  3. AuctioneerWallet.sol::execute() entrypoint conforms to similar parameters as a regular transaction
  4. Yet, the new, smart implementation reverts until an Auctioneer sets a match (and thus, executing node) for the transaction

In this way, users can continue to use regular EIP-1559 transactions and Resonance, in parallel, with the same wallets and tooling they are familiar with.

// Minimal example of AuctioneerWallet.sol implementation
struct Transaction {
  bytes32 id;
  address to;
  uint256 value;
  uint256 gasLimit;
  bytes data;
  bytes encryptedValuation;
}

contract AuctioneerWallet {
  function withdraw(uint256 value) onlyAuctioneer {}

  function execute(Transaction calldata trx) external returns (bytes memory) {
    // Execute transaction normally
    (...) = address(trx.to).call{value: trx.value, gas: trx.gasLimit}(trx.data);

    // Auctioneer callback to pay assigned transaction executor
    // (reverts if none assigned)
    AUCTIONEER.txExecuted(trx.id);
  }
}

Transaction lifecycle

Resonance is an opt-in upgrade that allows users to choose the fee mechanism they want to use, for each transaction they send. To that extent, Resonance was designed to be a simple drop-in addition to the transaction lifecycle users are already familiar with:

Standard EIP-1559 lifecycle

A simplified smart contract transaction lifecycle, without Resonance, looks like:

  1. Ethereum users authenticate with decentralized applications (dApps) via wallets
  2. dApps prepare transaction payloads that execute on-chain smart contracts
  3. dApps prompt wallets to send transaction payloads via the wallet provider API
  4. Wallets interface with execution clients via their JSON-RPC API to estimate gas fees
  5. Users select appropriate fees, usually deferring to wallet and RPC recommendations
  6. Users sign fee-included transaction payloads with their wallet and broadcast via RPC
  7. Nodes receive transactions via RPC and append to their local transaction pools
  8. Then, nodes gossip transactions to other nodes in the network
  9. Block-building nodes collect transactions with sufficient fees and propose blocks
  10. Blocks are gossiped and validated amongst validators, progressing the chain
  11. As blocks are included, users see executed state as a result of their transaction

New Resonance lifecycle

A simplified smart contract transaction lifecycle, with Resonance, looks like:

Steps that change under Resonance are highlighted by

Enable Resonance

To begin using Resonance, users must upgrade their wallet implementation, via account abstraction, to the AuctioneerWallet.sol reference implementation. This is an opt-in upgrade, and can be reversed by users at any time.

For most users, this step will be abstracted by their wallets or the decentralized applications (dApps) they interface with.

For power users, enabling Resonance is as simple as sending a SetCodeTx transaction. Example via Foundry’s Cast:

cast send <eoa_address> \
  --auth "<address of AuctioneerWallet deployment>" \
  --private-key <eoa_private_key>

Once upgraded, users can send both regular EIP-1559 and upgraded Resonance transactions with no additional interaction.

2

Authenticate with dApps

dApps prepare transaction payloads

Via our tooling, using Resonance is as simple as checking a Use Resonance box.

Behind the scenes, we plug into popular libraries like Viem, Web3.js, and ethers to handle any payload modifications.

Users select valuation

Rather than steps 4 & 5 where users collect estimated gas fees and select an appropriate priorityFee, with Resonance, users simply input their valuation.

5

Users sign transaction payloads

6

Nodes receive transactions via RPC

7

Nodes gossip transactions to other nodes

Auctioneer executes batch

When using Resonance, the Auctioneer is responsible for coordinating a match between transactions and executing nodes, via brokers.

Behind the scenes, each batch, the Auctioneer:

  1. Collects and decrypts node cost function submissions
  2. Collects and publishes user transactions
  3. Decrypts user valuation submissions
  4. Collects broker routing submissions
  5. Finalizes and publishes the surplus-maximizing routing

All of this happens transparently, yet abstracted, from a user.

Assigned nodes execute transaction

Once a routing has been posted on-chain, nodes execute their assigned transaction payloads, gossiping outputs and optional proofs to the rest of the network.

10

Block-building nodes collect transactions and propose blocks

11

Blocks are gossiped and validated

12

Users see executed state

Put together, using Resonance is simple and fully opt-in with few changes to the patterns users are already familiar with.


Looking forward

We expect to extend Resonance in a few ways:

  1. Support natively pricing scheduled transactions
  2. Decentralize the Auctioneer, enabling anyone to run the mechanism
  3. Support a streaming setting rather than fixed duration Auctioneer batches to reduce E2E transaction inclusion latency
  4. Explore posted price mechanisms to reduce user difficulty in inferring transaction valuation

More information

For more information on Resonance, see our blog posts and academic paper: