123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- pragma solidity ^0.5.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-registerd. 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 contracts'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 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.
- */
- 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);
- }
|