|
@@ -1,269 +0,0 @@
|
|
|
-// SPDX-License-Identifier: MIT
|
|
|
-
|
|
|
-pragma solidity ^0.8.0;
|
|
|
-
|
|
|
-/**
|
|
|
- * @dev Interface for `RelayHub`, the core contract of the GSN. Users should not need to interact with this contract
|
|
|
- * directly.
|
|
|
- *
|
|
|
- * See the https://github.com/OpenZeppelin/openzeppelin-gsn-helpers[OpenZeppelin GSN helpers] for more information on
|
|
|
- * how to deploy an instance of `RelayHub` on your local test network.
|
|
|
- */
|
|
|
-interface IRelayHub {
|
|
|
- // Relay management
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev 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.
|
|
|
- */
|
|
|
- function stake(address relayaddr, uint256 unstakeDelay) external payable;
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Emitted when a relay's stake or unstakeDelay are increased
|
|
|
- */
|
|
|
- event Staked(address indexed relay, uint256 stake, uint256 unstakeDelay);
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev 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.
|
|
|
- */
|
|
|
- function registerRelay(uint256 transactionFee, string calldata url) external;
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Emitted when a relay is registered or re-registered. Looking at these events (and filtering out
|
|
|
- * {RelayRemoved} events) lets a client discover the list of available relays.
|
|
|
- */
|
|
|
- event RelayAdded(address indexed relay, address indexed owner, uint256 transactionFee, uint256 stake, uint256 unstakeDelay, string url);
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev 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.
|
|
|
- */
|
|
|
- function removeRelayByOwner(address relay) external;
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Emitted when a relay is removed (deregistered). `unstakeTime` is the time when unstake will be callable.
|
|
|
- */
|
|
|
- event RelayRemoved(address indexed relay, uint256 unstakeTime);
|
|
|
-
|
|
|
- /** Deletes the relay from the system, and gives back its stake to the owner.
|
|
|
- *
|
|
|
- * Can only be called by the relay owner, after `unstakeDelay` has elapsed since {removeRelayByOwner} was called.
|
|
|
- *
|
|
|
- * Emits an {Unstaked} event.
|
|
|
- */
|
|
|
- function unstake(address relay) external;
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Emitted when a relay is unstaked for, including the returned stake.
|
|
|
- */
|
|
|
- event Unstaked(address indexed relay, uint256 stake);
|
|
|
-
|
|
|
- // States a relay can be in
|
|
|
- enum RelayState {
|
|
|
- Unknown, // The relay is unknown to the system: it has never been staked for
|
|
|
- Staked, // The relay has been staked for, but it is not yet active
|
|
|
- Registered, // The relay has registered itself, and is active (can relay calls)
|
|
|
- Removed // The relay has been removed by its owner and can no longer relay calls. It must wait for its unstakeDelay to elapse before it can unstake
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Returns a relay's status. Note that relays can be deleted when unstaked or penalized, causing this function
|
|
|
- * to return an empty entry.
|
|
|
- */
|
|
|
- function getRelay(address relay) external view returns (uint256 totalStake, uint256 unstakeDelay, uint256 unstakeTime, address payable owner, RelayState state);
|
|
|
-
|
|
|
- // Balance management
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev 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.
|
|
|
- */
|
|
|
- function depositFor(address target) external payable;
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Emitted when {depositFor} is called, including the amount and account that was funded.
|
|
|
- */
|
|
|
- event Deposited(address indexed recipient, address indexed from, uint256 amount);
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Returns an account's deposits. These can be either a contract's funds, or a relay owner's revenue.
|
|
|
- */
|
|
|
- function balanceOf(address target) external view returns (uint256);
|
|
|
-
|
|
|
- /**
|
|
|
- * Withdraws from an account's balance, sending it back to it. Relay owners call this to retrieve their revenue, and
|
|
|
- * contracts can use it to reduce their funding.
|
|
|
- *
|
|
|
- * Emits a {Withdrawn} event.
|
|
|
- */
|
|
|
- function withdraw(uint256 amount, address payable dest) external;
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Emitted when an account withdraws funds from `RelayHub`.
|
|
|
- */
|
|
|
- event Withdrawn(address indexed account, address indexed dest, uint256 amount);
|
|
|
-
|
|
|
- // Relaying
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev 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}.
|
|
|
- */
|
|
|
- function canRelay(
|
|
|
- address relay,
|
|
|
- address from,
|
|
|
- address to,
|
|
|
- bytes calldata encodedFunction,
|
|
|
- uint256 transactionFee,
|
|
|
- uint256 gasPrice,
|
|
|
- uint256 gasLimit,
|
|
|
- uint256 nonce,
|
|
|
- bytes calldata signature,
|
|
|
- bytes calldata approvalData
|
|
|
- ) external view returns (uint256 status, bytes memory recipientContext);
|
|
|
-
|
|
|
- // Preconditions for relaying, checked by canRelay and returned as the corresponding numeric values.
|
|
|
- enum PreconditionCheck {
|
|
|
- OK, // All checks passed, the call can be relayed
|
|
|
- WrongSignature, // The transaction to relay is not signed by requested sender
|
|
|
- WrongNonce, // The provided nonce has already been used by the sender
|
|
|
- AcceptRelayedCallReverted, // The recipient rejected this call via acceptRelayedCall
|
|
|
- InvalidRecipientStatusCode // The recipient returned an invalid (reserved) status code
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev 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 forwarded 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.
|
|
|
- */
|
|
|
- function relayCall(
|
|
|
- address from,
|
|
|
- address to,
|
|
|
- bytes calldata encodedFunction,
|
|
|
- uint256 transactionFee,
|
|
|
- uint256 gasPrice,
|
|
|
- uint256 gasLimit,
|
|
|
- uint256 nonce,
|
|
|
- bytes calldata signature,
|
|
|
- bytes calldata approvalData
|
|
|
- ) external;
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev 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}.
|
|
|
- */
|
|
|
- event CanRelayFailed(address indexed relay, address indexed from, address indexed to, bytes4 selector, uint256 reason);
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev 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.
|
|
|
- */
|
|
|
- event TransactionRelayed(address indexed relay, address indexed from, address indexed to, bytes4 selector, RelayCallStatus status, uint256 charge);
|
|
|
-
|
|
|
- // Reason error codes for the TransactionRelayed event
|
|
|
- enum RelayCallStatus {
|
|
|
- OK, // The transaction was successfully relayed and execution successful - never included in the event
|
|
|
- RelayedCallFailed, // The transaction was relayed, but the relayed call failed
|
|
|
- PreRelayedFailed, // The transaction was not relayed due to preRelatedCall reverting
|
|
|
- PostRelayedFailed, // The transaction was relayed and reverted due to postRelatedCall reverting
|
|
|
- RecipientBalanceChanged // The transaction was relayed and reverted due to the recipient's balance changing
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev 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.
|
|
|
- */
|
|
|
- function requiredGas(uint256 relayedCallStipend) external view returns (uint256);
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Returns the maximum recipient charge, given the amount of gas forwarded, gas price and relay fee.
|
|
|
- */
|
|
|
- function maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) external view returns (uint256);
|
|
|
-
|
|
|
- // Relay penalization.
|
|
|
- // Any account can penalize relays, removing them from the system immediately, and rewarding the
|
|
|
- // reporter with half of the relay's stake. The other half is burned so that, even if the relay penalizes itself, it
|
|
|
- // still loses half of its stake.
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev 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.
|
|
|
- */
|
|
|
- function penalizeRepeatedNonce(bytes calldata unsignedTx1, bytes calldata signature1, bytes calldata unsignedTx2, bytes calldata signature2) external;
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Penalize a relay that sent a transaction that didn't target ``RelayHub``'s {registerRelay} or {relayCall}.
|
|
|
- */
|
|
|
- function penalizeIllegalTransaction(bytes calldata unsignedTx, bytes calldata signature) external;
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Emitted when a relay is penalized.
|
|
|
- */
|
|
|
- event Penalized(address indexed relay, address sender, uint256 amount);
|
|
|
-
|
|
|
- /**
|
|
|
- * @dev Returns an account's nonce in `RelayHub`.
|
|
|
- */
|
|
|
- function getNonce(address from) external view returns (uint256);
|
|
|
-}
|
|
|
-
|