# RelayHub

The RelayHub Implementation

This contract implements the IRelayHub interface for the EVM-compatible networks.

# Functions

# versionHub()

→ string (public)

# Return values

SemVer-compliant version of the RelayHub contract.

# getConfiguration()

→ struct IRelayHub.RelayHubConfig (public)

# Return values

The configuration of the RelayHub.

# setConfiguration(struct IRelayHub.RelayHubConfig _config)


Sets or changes the configuration of this RelayHub.

_config: The new configuration.

# setMinimumStakes(contract IERC20[] token, uint256[] minimumStake)


Sets or changes the minimum amount of a given token that needs to be staked so that the Relay Manager is considered to be 'staked' by this RelayHub. Zero value means this token is not allowed for staking.

token: An array of addresses of ERC-20 compatible tokens.

minimumStake: An array of minimal amounts necessary for a corresponding token, in wei.

# constructor(contract IStakeManager _stakeManager, address _penalizer, address _batchGateway, address _relayRegistrar, struct IRelayHub.RelayHubConfig _config)


# getCreationBlock()

→ uint256 (external)

# Return values

block number in which the contract has been deployed.

# getDeprecationTime()

→ uint256 (external)

# Return values

timestamp from which the hub no longer allows relaying calls.

# getStakeManager()

→ contract IStakeManager (external)

# Return values

StakeManager address for this RelayHub.

# getPenalizer()

→ address (external)

# Return values

Penalizer address for this RelayHub.

# getBatchGateway()

→ address (external)

# Return values

BatchGateway address for this RelayHub.

# getRelayRegistrar()

→ address (external)

# Return values

RelayRegistrar address for this RelayHub.

# getMinimumStakePerToken(contract IERC20 token)

→ uint256 (external)

token: An address of an ERC-20 compatible tokens.

# Return values

minimum amount of a given token that needs to be staked so that the Relay Manager is considered to be 'staked' by this RelayHub. Zero value means this token is not allowed for staking.

# getWorkerManager(address worker)

→ address (external)

worker: An address of the Relay Worker.

# Return values

address of its Relay Manager.

# getWorkerCount(address manager)

→ uint256 (external)

manager: An address of the Relay Manager.

# Return values

count of Relay Workers associated with this Relay Manager.

# supportsInterface(bytes4 interfaceId)

→ bool (public)

Returns true if this contract implements the interface defined by interfaceId. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

# onRelayServerRegistered(address relayManager)


The RelayRegistrar callback to notify the RelayHub that this relayManager has updated registration.

# addRelayWorkers(address[] newRelayWorkers)


Add new worker addresses controlled by the sender who must be a staked Relay Manager address. Emits a RelayWorkersAdded event. This function can be called multiple times, emitting new events.

# depositFor(address target)


Deposits ether for a Paymaster, so that it can and pay for relayed transactions. ⚠️ Warning ⚠️ Unused balance can only be withdrawn by the holder itself, by calling withdraw. Emits a Deposited event.

# balanceOf(address target)

→ uint256 (external)

# Return values

account's balance. It can be either a deposit of a Paymaster, or a revenue of a Relay Manager.

# withdraw(address payable dest, uint256 amount)


Withdraws from an account's balance, sending it back to the caller. Relay Managers call this to retrieve their revenue, and Paymasters can also use it to reduce their funding. Emits a Withdrawn event.

# withdrawMultiple(address payable[] dest, uint256[] amount)


Withdraws from an account's balance, sending funds to multiple provided addresses. Relay Managers call this to retrieve their revenue, and Paymasters can also use it to reduce their funding. Emits a Withdrawn event for each destination.

# relayCall(string domainSeparatorName, uint256 maxAcceptanceBudget, struct GsnTypes.RelayRequest relayRequest, bytes signature, bytes approvalData)

→ bool paymasterAccepted, uint256 charge, enum IRelayHub.RelayCallStatus status, bytes returnValue (external)

Relays a transaction. For this to succeed, multiple conditions must be met:

  • Paymaster's preRelayCall method must succeed and not revert.
  • the msg.sender must be a registered Relay Worker that the user signed to use.
  • the transaction's gas fees must be equal or larger than the ones that were signed by the sender.
  • the transaction must have enough gas to run all internal transactions if they use all gas available to them.
  • the Paymaster must have enough balance to pay the Relay Worker if all gas is spent.

If all conditions are met, the call will be relayed and the Paymaster charged.

domainSeparatorName: The name of the Domain Separator used to verify the EIP-712 signature

maxAcceptanceBudget: The maximum valid value for paymaster.getGasLimits().acceptanceBudget to return.

relayRequest: All details of the requested relayed call.

signature: The client's EIP-712 signature over the relayRequest struct.

approvalData: The dapp-specific data forwarded to the Paymaster's preRelayedCall method. This value is not verified by the RelayHub in any way. As an example, it can be used to pass some kind of a third-party signature to the Paymaster for verification.

Emits a TransactionRelayed event regardless of whether the transaction succeeded or failed.

# innerRelayCall(string domainSeparatorName, struct GsnTypes.RelayRequest relayRequest, bytes signature, bytes approvalData, struct IPaymaster.GasAndDataLimits gasAndDataLimits, uint256 totalInitialGas, uint256 maxPossibleGas)

→ enum IRelayHub.RelayCallStatus, bytes (external)

This method can only by called by this RelayHub. It wraps the execution of the RelayRequest in a revertable frame context.

# calculateDevCharge(uint256 charge)

→ uint256 (public)

The fee is expressed as a percentage of the actual charge. For example, a value '40' stands for a 40% fee, so the Relay Manager will only get 60% of the charge.

charge: The amount of Ether in wei the Paymaster will be charged for this transaction.

# Return values

calculated devFee, in wei.

# calculateCharge(uint256 gasUsed, struct GsnTypes.RelayData relayData)

→ uint256 (public)

The fee is expressed as a base fee in wei plus percentage of the actual charge. For example, a value '40' stands for a 40% fee, so the recipient will be charged for 1.4 times the spent amount.

gasUsed: An amount of gas used by the transaction.

relayData: The details of a transaction signed by the sender.

# Return values

calculated charge, in wei.

# verifyRelayManagerStaked(address relayManager)


Uses StakeManager to decide if the Relay Manager can be considered staked or not. Returns if the stake's token, amount and delay satisfy all requirements, reverts otherwise.

# deprecateHub(uint256 _deprecationTime)


Deprecate hub by reverting all incoming relayCall() calls starting from a given timestamp

_deprecationTime: The timestamp in seconds after which the RelayHub stops serving transactions.

# isDeprecated()

→ bool (public)

# Return values

the RelayHub is deprecated, false it it is not deprecated and can serve transactions.

# penalize(address relayWorker, address payable beneficiary)


In case the Relay Worker has been found to be in violation of some rules by the Penalizer contract, the Penalizer will call this method to execute a penalization. The RelayHub will look up the Relay Manager of the given Relay Worker and will forward the call to the StakeManager contract. The RelayHub does not perform the actual penalization either.

relayWorker: The address of the Relay Worker that committed a penalizable offense.

beneficiary: The address that called the Penalizer and will receive a reward for it.

# isRelayEscheatable(address relayManager)

→ bool (public)

Uses StakeManager to check if the Relay Manager can be considered abandoned or not. Returns true if the stake's abandonment time is in the past including the escheatment delay, false otherwise.

# escheatAbandonedRelayBalance(address relayManager)



# aggregateGasleft()

→ uint256 (public)

# Return values

total measurable amount of gas left to current execution. Same as 'gasleft()' for pure EVMs.

# Structs

# RelayCallData

bool success

bytes4 functionSelector

uint256 initialGasLeft

bytes recipientContext

bytes relayedCallReturnValue

struct IPaymaster.GasAndDataLimits gasAndDataLimits

enum IRelayHub.RelayCallStatus status

uint256 innerGasUsed

uint256 maxPossibleGas

uint256 innerGasLimit

uint256 gasBeforeInner

uint256 gasUsed

uint256 devCharge

bytes retData

address relayManager

bytes32 relayRequestId

uint256 tmpInitialGas

bytes relayCallStatus

# InnerRelayCallData

uint256 initialGasLeft

uint256 gasUsedToCallInner

uint256 balanceBefore

bytes32 preReturnValue

bool relayedCallSuccess

bytes relayedCallReturnValue

bytes recipientContext

bytes data

bool rejectOnRecipientRevert

# Modifiers

# penalizerOnly()

Prevents any address other than the Penalizer from calling this method.