V 1

Contracts

ECDSA

recover(bytes32 hash, bytes signature) → addressinternal

Returns the address that signed a hashed message (hash) with signature. This address can then be used for verification purposes.

The ecrecover EVM opcode allows for malleable (non-unique) signatures: this function rejects them by requiring the s value to be in the lower half order, and the v value to be either 27 or 28.

(.note) This call does not revert if the signature is invalid, or if the signer is otherwise unable to be retrieved. In those scenarios, the zero address is returned.

(.warning) hash must be the result of a hash operation for the verification to be secure: it is possible to craft signatures that recover to arbitrary addresses for non-hashed data. A safe way to ensure this is by receiving a hash of the original message (which may otherwise) be too long), and then calling toEthSignedMessageHash on it.

toEthSignedMessageHash(bytes32 hash) → bytes32internal

Returns an Ethereum Signed Message, created from a hash. This replicates the behavior of the eth_sign JSON-RPC method.

See recover.

GsnUtils

getMethodSig(bytes msgData) → bytes4internal

getParam(bytes msgData, uint256 index) → uint256internal

getBytesParam(bytes msgData, uint256 index) → bytesinternal

getStringParam(bytes msgData, uint256 index) → stringinternal

checkSig(address signer, bytes32 hash, bytes sig) → boolinternal

IRelayHub

FunctionsEvents

stake(address relayaddr, uint256 unstakeDelay)external

Adds stake to a relay and sets its unstakeDelay. If the relay does not exist, it is created, and the caller of this function becomes its owner. If the relay already exists, only the owner can call this function. A relay cannot be its own owner.

All Ether in this function call will be added to the relay's stake. Its unstake delay will be assigned to unstakeDelay, but the new value must be greater or equal to the current one.

Emits a {Staked} event.

registerRelay(uint256 transactionFee, string url)external

Registers the caller as a relay. The relay must be staked for, and not be a contract (i.e. this function must be called directly from an EOA).

This function can be called multiple times, emitting new {RelayAdded} events. Note that the received transactionFee is not enforced by {relayCall}.

Emits a {RelayAdded} event.

removeRelayByOwner(address relay)external

Removes (deregisters) a relay. Unregistered (but staked for) relays can also be removed.

Can only be called by the owner of the relay. After the relay's unstakeDelay has elapsed, {unstake} will be callable.

Emits a {RelayRemoved} event.

unstake(address relay)external

getRelay(address relay) → uint256,uint256,uint256,address payable,enum IRelayHub.RelayStateexternal

Returns a relay's status. Note that relays can be deleted when unstaked or penalized, causing this function to return an empty entry.

depositFor(address target)external

Deposits Ether for a contract, so that it can receive (and pay for) relayed transactions.

Unused balance can only be withdrawn by the contract itself, by calling {withdraw}.

Emits a {Deposited} event.

balanceOf(address target) → uint256external

Returns an account's deposits. These can be either a contracts's funds, or a relay owner's revenue.

withdraw(uint256 amount, address payable dest)external

canRelay(address relay, address from, address to, bytes encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes signature, bytes approvalData) → uint256,bytesexternal

Checks if the RelayHub will accept a relayed operation. Multiple things must be true for this to happen:

  • all arguments must be signed for by the sender (from)
  • the sender's nonce must be the current one
  • the recipient must accept this transaction (via {acceptRelayedCall})

Returns a PreconditionCheck value (OK when the transaction can be relayed), or a recipient-specific error code if it returns one in {acceptRelayedCall}.

relayCall(address from, address to, bytes encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes signature, bytes approvalData)external

Relays a transaction.

For this to succeed, multiple conditions must be met:

  • {canRelay} must return PreconditionCheck.OK
  • the sender must be a registered relay
  • the transaction's gas price must be larger or equal to the one that was requested by the sender
  • the transaction must have enough gas to not run out of gas if all internal transactions (calls to the recipient) use all gas available to them
  • the recipient must have enough balance to pay the relay for the worst-case scenario (i.e. when all gas is spent)

If all conditions are met, the call will be relayed and the recipient charged. {preRelayedCall}, the encoded function and {postRelayedCall} will be called in that order.

Parameters:

  • from: the client originating the request
  • to: the target {IRelayRecipient} contract
  • encodedFunction: the function call to relay, including data
  • transactionFee: fee (%) the relay takes over actual gas cost
  • gasPrice: gas price the client is willing to pay
  • gasLimit: gas to forward when calling the encoded function
  • nonce: client's nonce
  • signature: client's signature over all previous params, plus the relay and RelayHub addresses
  • approvalData: dapp-specific data forwared to {acceptRelayedCall}. This value is not verified by the RelayHub, but it still can be used for e.g. a signature.

Emits a {TransactionRelayed} event.

requiredGas(uint256 relayedCallStipend) → uint256external

Returns how much gas should be forwarded to a call to {relayCall}, in order to relay a transaction that will spend up to relayedCallStipend gas.

maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) → uint256external

Returns the maximum recipient charge, given the amount of gas forwarded, gas price and relay fee.

penalizeRepeatedNonce(bytes unsignedTx1, bytes signature1, bytes unsignedTx2, bytes signature2)external

Penalize a relay that signed two transactions using the same nonce (making only the first one valid) and different data (gas price, gas limit, etc. may be different).

The (unsigned) transaction data and signature for both transactions must be provided.

penalizeIllegalTransaction(bytes unsignedTx, bytes signature)external

Penalize a relay that sent a transaction that didn't target RelayHub's {registerRelay} or {relayCall}.

getNonce(address from) → uint256external

Returns an account's nonce in RelayHub.

Staked(address relay, uint256 stake, uint256 unstakeDelay)

Emitted when a relay's stake or unstakeDelay are increased

RelayAdded(address relay, address owner, uint256 transactionFee, uint256 stake, uint256 unstakeDelay, string url)

Emitted when a relay is registered or re-registerd. Looking at these events (and filtering out {RelayRemoved} events) lets a client discover the list of available relays.

RelayRemoved(address relay, uint256 unstakeTime)

Emitted when a relay is removed (deregistered). unstakeTime is the time when unstake will be callable.

Unstaked(address relay, uint256 stake)

Emitted when a relay is unstaked for, including the returned stake.

Deposited(address recipient, address from, uint256 amount)

Emitted when {depositFor} is called, including the amount and account that was funded.

Withdrawn(address account, address dest, uint256 amount)

Emitted when an account withdraws funds from RelayHub.

CanRelayFailed(address relay, address from, address to, bytes4 selector, uint256 reason)

Emitted when an attempt to relay a call failed.

This can happen due to incorrect {relayCall} arguments, or the recipient not accepting the relayed call. The actual relayed call was not executed, and the recipient not charged.

The reason parameter contains an error code: values 1-10 correspond to PreconditionCheck entries, and values over 10 are custom recipient error codes returned from {acceptRelayedCall}.

TransactionRelayed(address relay, address from, address to, bytes4 selector, enum IRelayHub.RelayCallStatus status, uint256 charge)

Emitted when a transaction is relayed. Useful when monitoring a relay's operation and relayed calls to a contract

Note that the actual encoded function might be reverted: this is indicated in the status parameter.

charge is the Ether value deducted from the recipient's balance, paid to the relay's owner.

Penalized(address relay, address sender, uint256 amount)

Emitted when a relay is penalized.

IRelayRecipient

getHubAddr() → addressexternal

Returns the address of the {IRelayHub} instance this recipient interacts with.

acceptRelayedCall(address relay, address from, bytes encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes approvalData, uint256 maxPossibleCharge) → uint256,bytesexternal

Called by {IRelayHub} to validate if this recipient accepts being charged for a relayed call. Note that the recipient will be charged regardless of the execution result of the relayed call (i.e. if it reverts or not).

The relay request was originated by from and will be served by relay. encodedFunction is the relayed call calldata, so its first four bytes are the function selector. The relayed call will be forwarded gasLimit gas, and the transaction executed with a gas price of at least gasPrice. relay's fee is transactionFee, and the recipient will be charged at most maxPossibleCharge (in wei). nonce is the sender's (from) nonce for replay attack protection in {IRelayHub}, and approvalData is a optional parameter that can be used to hold a signature over all or some of the previous values.

Returns a tuple, where the first value is used to indicate approval (0) or rejection (custom non-zero error code, values 1 to 10 are reserved) and the second one is data to be passed to the other {IRelayRecipient} functions.

{acceptRelayedCall} is called with 50k gas: if it runs out during execution, the request will be considered rejected. A regular revert will also trigger a rejection.

preRelayedCall(bytes context) → bytes32external

Called by {IRelayHub} on approved relay call requests, before the relayed call is executed. This allows to e.g. pre-charge the sender of the transaction.

context is the second value returned in the tuple by {acceptRelayedCall}.

Returns a value to be passed to {postRelayedCall}.

{preRelayedCall} is called with 100k gas: if it runs out during exection or otherwise reverts, the relayed call will not be executed, but the recipient will still be charged for the transaction's cost.

postRelayedCall(bytes context, bool success, uint256 actualCharge, bytes32 preRetVal)external

Called by {IRelayHub} on approved relay call requests, after the relayed call is executed. This allows to e.g. charge the user for the relayed call costs, return any overcharges from {preRelayedCall}, or perform contract-specific bookkeeping.

context is the second value returned in the tuple by {acceptRelayedCall}. success is the execution status of the relayed call. actualCharge is an estimate of how much the recipient will be charged for the transaction, not including any gas used by {postRelayedCall} itself. preRetVal is {preRelayedCall}'s return value.

{postRelayedCall} is called with 100k gas: if it runs out during execution or otherwise reverts, the relayed call and the call to {preRelayedCall} will be reverted retroactively, but the recipient will still be charged for the transaction's cost.

LibBytes

rawAddress(bytes input) → uint256internal

Gets the memory address for a byte array. @param input Byte array to lookup. @return memoryAddress Memory address of byte array. This points to the header of the byte array which contains the length.

contentAddress(bytes input) → uint256internal

Gets the memory address for the contents of a byte array. @param input Byte array to lookup. @return memoryAddress Memory address of the contents of the byte array.

memCopy(uint256 dest, uint256 source, uint256 length)internal

Copies length bytes from memory location source to dest. @param dest memory address to copy bytes to. @param source memory address to copy bytes from. @param length number of bytes to copy.

slice(bytes b, uint256 from, uint256 to) → bytesinternal

Returns a slices from a byte array. @param b The byte array to take a slice from. @param from The starting index for the slice (inclusive). @param to The final index for the slice (exclusive). @return result The slice containing bytes at indices [from, to)

sliceDestructive(bytes b, uint256 from, uint256 to) → bytesinternal

Returns a slice from a byte array without preserving the input. @param b The byte array to take a slice from. Will be destroyed in the process. @param from The starting index for the slice (inclusive). @param to The final index for the slice (exclusive). @return result The slice containing bytes at indices [from, to) @dev When from == 0, the original array will match the slice. In other cases its state will be corrupted.

popLastByte(bytes b) → bytes1internal

Pops the last byte off of a byte array by modifying its length. @param b Byte array that will be modified. @return The byte that was popped off.

equals(bytes lhs, bytes rhs) → boolinternal

Tests equality of two byte arrays. @param lhs First byte array to compare. @param rhs Second byte array to compare. @return True if arrays are the same. False otherwise.

readAddress(bytes b, uint256 index) → addressinternal

Reads an address from a position in a byte array. @param b Byte array containing an address. @param index Index in byte array of address. @return address from byte array.

writeAddress(bytes b, uint256 index, address input)internal

Writes an address into a specific position in a byte array. @param b Byte array to insert address into. @param index Index in byte array of address. @param input Address to put into byte array.

readBytes32(bytes b, uint256 index) → bytes32internal

Reads a bytes32 value from a position in a byte array. @param b Byte array containing a bytes32 value. @param index Index in byte array of bytes32 value. @return bytes32 value from byte array.

writeBytes32(bytes b, uint256 index, bytes32 input)internal

Writes a bytes32 into a specific position in a byte array. @param b Byte array to insert <input> into. @param index Index in byte array of <input>. @param input bytes32 to put into byte array.

readUint256(bytes b, uint256 index) → uint256internal

Reads a uint256 value from a position in a byte array. @param b Byte array containing a uint256 value. @param index Index in byte array of uint256 value. @return uint256 value from byte array.

writeUint256(bytes b, uint256 index, uint256 input)internal

Writes a uint256 into a specific position in a byte array. @param b Byte array to insert <input> into. @param index Index in byte array of <input>. @param input uint256 to put into byte array.

readBytes4(bytes b, uint256 index) → bytes4internal

Reads an unpadded bytes4 value from a position in a byte array. @param b Byte array containing a bytes4 value. @param index Index in byte array of bytes4 value. @return bytes4 value from byte array.

writeLength(bytes b, uint256 length)internal

Writes a new length to a byte array. Decreasing length will lead to removing the corresponding lower order bytes from the byte array. Increasing length may lead to appending adjacent in-memory bytes to the end of the byte array. @param b Bytes array to write new length to. @param length New length of byte array.

RLPReader

decodeTransaction(bytes rawTransaction) → uint256,uint256,uint256,address,uint256,bytesinternal

toRlpItem(bytes item) → struct RLPReader.RLPIteminternal

toList(struct RLPReader.RLPItem item) → struct RLPReader.RLPItem[]internal

isList(struct RLPReader.RLPItem item) → boolinternal

numItems(struct RLPReader.RLPItem item) → uint256internal

_itemLength(uint256 memPtr) → uint256internal

_payloadOffset(uint256 memPtr) → uint256internal

toRlpBytes(struct RLPReader.RLPItem item) → bytesinternal

toBoolean(struct RLPReader.RLPItem item) → boolinternal

toAddress(struct RLPReader.RLPItem item) → addressinternal

toUint(struct RLPReader.RLPItem item) → uint256internal

toBytes(struct RLPReader.RLPItem item) → bytesinternal

copy(uint256 src, uint256 dest, uint256 len)internal

RelayHub

FunctionsEvents

stake(address relay, uint256 unstakeDelay)external

registerRelay(uint256 transactionFee, string url)public

removeRelayByOwner(address relay)public

unstake(address relay)public

getRelay(address relay) → uint256,uint256,uint256,address payable,enum IRelayHub.RelayStateexternal

depositFor(address target)public

balanceOf(address target) → uint256external

withdraw(uint256 amount, address payable dest)public

getNonce(address from) → uint256external

canUnstake(address relay) → boolpublic

canRelay(address relay, address from, address to, bytes encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes signature, bytes approvalData) → uint256,bytespublic

relayCall(address from, address recipient, bytes encodedFunction, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 nonce, bytes signature, bytes approvalData)public

recipientCallsAtomic(address recipient, bytes encodedFunctionWithFrom, uint256 transactionFee, uint256 gasPrice, uint256 gasLimit, uint256 preChecksGas, bytes recipientContext) → enum IRelayHub.RelayCallStatusexternal

requiredGas(uint256 relayedCallStipend) → uint256public

maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) → uint256public

penalizeRepeatedNonce(bytes unsignedTx1, bytes signature1, bytes unsignedTx2, bytes signature2)public

penalizeIllegalTransaction(bytes unsignedTx, bytes signature)public

SafeMath

add(uint256 a, uint256 b) → uint256internal

Returns the addition of two unsigned integers, reverting on overflow.

Counterpart to Solidity's + operator.

Requirements:

  • Addition cannot overflow.

sub(uint256 a, uint256 b) → uint256internal

Returns the subtraction of two unsigned integers, reverting on overflow (when the result is negative).

Counterpart to Solidity's - operator.

Requirements:

  • Subtraction cannot overflow.

mul(uint256 a, uint256 b) → uint256internal

Returns the multiplication of two unsigned integers, reverting on overflow.

Counterpart to Solidity's * operator.

Requirements:

  • Multiplication cannot overflow.

div(uint256 a, uint256 b) → uint256internal

Returns the integer division of two unsigned integers. Reverts on division by zero. The result is rounded towards zero.

Counterpart to Solidity's / operator. Note: this function uses a revert opcode (which leaves remaining gas untouched) while Solidity uses an invalid opcode to revert (consuming all remaining gas).

Requirements:

  • The divisor cannot be zero.

mod(uint256 a, uint256 b) → uint256internal

Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), Reverts when dividing by zero.

Counterpart to Solidity's % operator. This function uses a revert opcode (which leaves remaining gas untouched) while Solidity uses an invalid opcode to revert (consuming all remaining gas).

Requirements:

  • The divisor cannot be zero.