-
Notifications
You must be signed in to change notification settings - Fork 227
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge the develop branch to the master branch, preparation to v6.0.0-rc0
This set of changes includes the following improvements and fixes: * [Improvement] AMB Home-to-Foreign async calls (#570), closes #492 * [Improvement] Add GSN support for erc20-to-native bridge mode (#571) * [Fix] Fix issues with packages versions and linter (#600) * [Other] Bump package version before 6.0.0-rc0 (#598)
- Loading branch information
Showing
31 changed files
with
18,383 additions
and
47,919 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,4 @@ deploy/*.env* | |
!deploy/.env.example | ||
upgrade/*.env* | ||
!upgrade/.env.example | ||
.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// SPDX-License-Identifier:MIT | ||
pragma solidity 0.4.24; | ||
pragma experimental ABIEncoderV2; | ||
|
||
import "../upgradeable_contracts/Ownable.sol"; | ||
|
||
import "./interfaces/GsnTypes.sol"; | ||
import "./interfaces/IPaymaster.sol"; | ||
import "./interfaces/IRelayHub.sol"; | ||
import "./utils/GsnEip712Library.sol"; | ||
import "./forwarder/IForwarder.sol"; | ||
|
||
/** | ||
* Abstract base class to be inherited by a concrete Paymaster | ||
* A subclass must implement: | ||
* - preRelayedCall | ||
* - postRelayedCall | ||
*/ | ||
contract BasePaymaster is IPaymaster, Ownable { | ||
IRelayHub internal relayHub; | ||
IForwarder public trustedForwarder; | ||
|
||
function getHubAddr() public view returns (address) { | ||
return address(relayHub); | ||
} | ||
|
||
//overhead of forwarder verify+signature, plus hub overhead. | ||
uint256 public constant FORWARDER_HUB_OVERHEAD = 50000; | ||
|
||
//These parameters are documented in IPaymaster.GasLimits | ||
uint256 public constant PRE_RELAYED_CALL_GAS_LIMIT = 100000; | ||
uint256 public constant POST_RELAYED_CALL_GAS_LIMIT = 110000; | ||
uint256 public constant PAYMASTER_ACCEPTANCE_BUDGET = PRE_RELAYED_CALL_GAS_LIMIT + FORWARDER_HUB_OVERHEAD; | ||
|
||
function getGasLimits() external view returns (IPaymaster.GasLimits) { | ||
return | ||
IPaymaster.GasLimits(PAYMASTER_ACCEPTANCE_BUDGET, PRE_RELAYED_CALL_GAS_LIMIT, POST_RELAYED_CALL_GAS_LIMIT); | ||
} | ||
|
||
// this method must be called from preRelayedCall to validate that the forwarder | ||
// is approved by the paymaster as well as by the recipient contract. | ||
function _verifyForwarder(GsnTypes.RelayRequest relayRequest) public view { | ||
require(address(trustedForwarder) == relayRequest.relayData.forwarder, "Forwarder is not trusted"); | ||
GsnEip712Library.verifyForwarderTrusted(relayRequest); | ||
} | ||
|
||
/* | ||
* modifier to be used by recipients as access control protection for preRelayedCall & postRelayedCall | ||
*/ | ||
modifier relayHubOnly() { | ||
require(msg.sender == getHubAddr(), "Function can only be called by RelayHub"); | ||
_; | ||
} | ||
|
||
function setRelayHub(IRelayHub hub) public onlyOwner { | ||
relayHub = hub; | ||
} | ||
|
||
function setTrustedForwarder(IForwarder forwarder) public onlyOwner { | ||
trustedForwarder = forwarder; | ||
} | ||
|
||
// check current deposit on relay hub. | ||
function getRelayHubDeposit() public view returns (uint256) { | ||
return relayHub.balanceOf(address(this)); | ||
} | ||
|
||
// withdraw deposit from relayHub | ||
function withdrawRelayHubDepositTo(uint256 amount, address target) public onlyOwner { | ||
relayHub.withdraw(amount, target); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// SPDX-License-Identifier:MIT | ||
// solhint-disable no-inline-assembly | ||
pragma solidity 0.4.24; | ||
|
||
import "./interfaces/IRelayRecipient.sol"; | ||
|
||
/** | ||
* A base contract to be inherited by any contract that want to receive relayed transactions | ||
* A subclass must use "_msgSender()" instead of "msg.sender" | ||
*/ | ||
contract BaseRelayRecipient is IRelayRecipient { | ||
/** | ||
* return the sender of this call. | ||
* if the call came through our trusted forwarder, return the original sender. | ||
* otherwise, return `msg.sender`. | ||
* should be used in the contract anywhere instead of msg.sender | ||
*/ | ||
function _msgSender() internal view returns (address ret) { | ||
if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) { | ||
// At this point we know that the sender is a trusted forwarder, | ||
// so we trust that the last bytes of msg.data are the verified sender address. | ||
// extract sender address from the end of msg.data | ||
assembly { | ||
ret := shr(96, calldataload(sub(calldatasize, 20))) | ||
} | ||
} else { | ||
return msg.sender; | ||
} | ||
} | ||
|
||
/** | ||
* return the msg.data of this call. | ||
* if the call came through our trusted forwarder, then the real sender was appended as the last 20 bytes | ||
* of the msg.data - so this method will strip those 20 bytes off. | ||
* otherwise, return `msg.data` | ||
* should be used in the contract instead of msg.data, where the difference matters (e.g. when explicitly | ||
* signing or hashing the | ||
*/ | ||
function _msgData() internal view returns (bytes memory ret) { | ||
if (msg.data.length >= 24 && isTrustedForwarder(msg.sender)) { | ||
// At this point we know that the sender is a trusted forwarder, | ||
// we copy the msg.data , except the last 20 bytes (and update the total length) | ||
assembly { | ||
let ptr := mload(0x40) | ||
// copy only size-20 bytes | ||
let size := sub(calldatasize, 20) | ||
// structure RLP data as <offset> <length> <bytes> | ||
mstore(ptr, 0x20) | ||
mstore(add(ptr, 32), size) | ||
calldatacopy(add(ptr, 64), 0, size) | ||
return(ptr, add(size, 64)) | ||
} | ||
} else { | ||
return msg.data; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// SPDX-License-Identifier:MIT | ||
pragma solidity 0.4.24; | ||
pragma experimental ABIEncoderV2; | ||
|
||
contract IForwarder { | ||
struct ForwardRequest { | ||
address from; | ||
address to; | ||
uint256 value; | ||
uint256 gas; | ||
uint256 nonce; | ||
bytes data; | ||
} | ||
|
||
function getNonce(address from) external view returns (uint256); | ||
|
||
/** | ||
* verify the transaction would execute. | ||
* validate the signature and the nonce of the request. | ||
* revert if either signature or nonce are incorrect. | ||
*/ | ||
function verify( | ||
ForwardRequest forwardRequest, | ||
bytes32 domainSeparator, | ||
bytes32 requestTypeHash, | ||
bytes suffixData, | ||
bytes signature | ||
) external view; | ||
|
||
/** | ||
* execute a transaction | ||
* @param forwardRequest - all transaction parameters | ||
* @param domainSeparator - domain used when signing this request | ||
* @param requestTypeHash - request type used when signing this request. | ||
* @param suffixData - the extension data used when signing this request. | ||
* @param signature - signature to validate. | ||
* | ||
* the transaction is verified, and then executed. | ||
* the success and ret of "call" are returned. | ||
* This method would revert only verification errors. target errors | ||
* are reported using the returned "success" and ret string | ||
*/ | ||
function execute( | ||
ForwardRequest forwardRequest, | ||
bytes32 domainSeparator, | ||
bytes32 requestTypeHash, | ||
bytes suffixData, | ||
bytes signature | ||
) external payable returns (bool success, bytes memory ret); | ||
|
||
/** | ||
* Register a new Request typehash. | ||
* @param typeName - the name of the request type. | ||
* @param typeSuffix - anything after the generic params can be empty string (if no extra fields are needed) | ||
* if it does contain a value, then a comma is added first. | ||
*/ | ||
function registerRequestType(string typeName, string typeSuffix) external; | ||
|
||
/** | ||
* Register a new domain separator. | ||
* The domain separator must have the following fields: name,version,chainId, verifyingContract. | ||
* the chainId is the current network's chainId, and the verifyingContract is this forwarder. | ||
* This method is given the domain name and version to create and register the domain separator value. | ||
* @param name the domain's display name | ||
* @param version the domain/protocol version | ||
*/ | ||
function registerDomainSeparator(string name, string version) external; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// SPDX-License-Identifier:MIT | ||
pragma solidity 0.4.24; | ||
|
||
import "../forwarder/IForwarder.sol"; | ||
|
||
contract GsnTypes { | ||
struct RelayData { | ||
uint256 gasPrice; | ||
uint256 pctRelayFee; | ||
uint256 baseRelayFee; | ||
address relayWorker; | ||
address paymaster; | ||
bytes paymasterData; | ||
uint256 clientId; | ||
address forwarder; | ||
} | ||
|
||
//note: must start with the ForwardRequest to be an extension of the generic forwarder | ||
struct RelayRequest { | ||
IForwarder.ForwardRequest request; | ||
RelayData relayData; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// SPDX-License-Identifier:MIT | ||
pragma solidity 0.4.24; | ||
|
||
interface IKnowForwarderAddress { | ||
/** | ||
* return the forwarder we trust to forward relayed transactions to us. | ||
* the forwarder is required to verify the sender's signature, and verify | ||
* the call is not a replay. | ||
*/ | ||
function getTrustedForwarder() external view returns (address); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// SPDX-License-Identifier:MIT | ||
pragma solidity 0.4.24; | ||
pragma experimental ABIEncoderV2; | ||
|
||
import "./GsnTypes.sol"; | ||
|
||
contract IPaymaster { | ||
/** | ||
* @param acceptanceBudget - | ||
* Paymaster expected gas budget to accept (or reject) a request | ||
* This a gas required by any calculations that might need to reject the | ||
* transaction, by preRelayedCall, forwarder and recipient. | ||
* See value in BasePaymaster.PAYMASTER_ACCEPTANCE_BUDGET | ||
* Transaction that gets rejected above that gas usage is on the paymaster's expense. | ||
* As long this value is above preRelayedCallGasLimit (see defaults in BasePaymaster), the | ||
* Paymaster is guaranteed it will never pay for rejected transactions. | ||
* If this value is below preRelayedCallGasLimt, it might might make Paymaster open to a "griefing" attack. | ||
* | ||
* Specifying value too high might make the call rejected by some relayers. | ||
* | ||
* From a Relay's point of view, this is the highest gas value a paymaster might "grief" the relay, | ||
* since the paymaster will pay anything above that (regardless if the tx reverts) | ||
* | ||
* @param preRelayedCallGasLimit - the max gas usage of preRelayedCall. any revert (including OOG) | ||
* of preRelayedCall is a reject by the paymaster. | ||
* as long as acceptanceBudget is above preRelayedCallGasLimit, any such revert (including OOG) | ||
* is not payed by the paymaster. | ||
* @param postRelayedCallGasLimit - the max gas usage of postRelayedCall. | ||
* note that an OOG will revert the transaction, but the paymaster already committed to pay, | ||
* so the relay will get compensated, at the expense of the paymaster | ||
*/ | ||
struct GasLimits { | ||
uint256 acceptanceBudget; | ||
uint256 preRelayedCallGasLimit; | ||
uint256 postRelayedCallGasLimit; | ||
} | ||
|
||
/** | ||
* Return the GasLimits constants used by the Paymaster. | ||
*/ | ||
function getGasLimits() external view returns (GasLimits memory limits); | ||
|
||
/** | ||
* return the relayHub of this contract. | ||
*/ | ||
function getHubAddr() public view returns (address); | ||
|
||
/** | ||
* Can be used to determine if the contract can pay for incoming calls before making any. | ||
* @return the paymaster's deposit in the RelayHub. | ||
*/ | ||
function getRelayHubDeposit() public view returns (uint256); | ||
|
||
/** | ||
* Called by Relay (and RelayHub), to validate if the paymaster agrees to pay for this call. | ||
* | ||
* MUST be protected with relayHubOnly() in case it modifies state. | ||
* | ||
* The Paymaster rejects by the following "revert" operations | ||
* - preRelayedCall() method reverts | ||
* - the forwarder reverts because of nonce or signature error | ||
* - the paymaster returned "rejectOnRecipientRevert", and the recipient contract reverted. | ||
* In any of the above cases, all paymaster calls (and recipient call) are reverted. | ||
* In any other case, the paymaster agrees to pay for the gas cost of the transaction (note | ||
* that this includes also postRelayedCall revert) | ||
* | ||
* The rejectOnRecipientRevert flag means the Paymaster "delegate" the rejection to the recipient | ||
* code. It also means the Paymaster trust the recipient to reject fast: both preRelayedCall, | ||
* forwarder check and receipient checks must fit into the GasLimits.acceptanceBudget, | ||
* otherwise the TX is paid by the Paymaster. | ||
* | ||
* @param relayRequest - the full relay request structure | ||
* @param signature - user's EIP712-compatible signature of the {@link relayRequest}. | ||
* Note that in most cases the paymaster shouldn't try use it at all. It is always checked | ||
* by the forwarder immediately after preRelayedCall returns. | ||
* @param approvalData - extra dapp-specific data (e.g. signature from trusted party) | ||
* @param maxPossibleGas - based on values returned from {@link getGasLimits}, | ||
* the RelayHub will calculate the maximum possible amount of gas the user may be charged for. | ||
* In order to convert this value to wei, the Paymaster has to call "relayHub.calculateCharge()" | ||
* return: | ||
* a context to be passed to postRelayedCall | ||
* rejectOnRecipientRevert - TRUE if paymaster want to reject the TX if the recipient reverts. | ||
* FALSE means that rejects by the recipient will be completed on chain, and paid by the paymaster. | ||
* (note that in the latter case, the preRelayedCall and postRelayedCall are not reverted). | ||
*/ | ||
function preRelayedCall( | ||
GsnTypes.RelayRequest relayRequest, | ||
bytes signature, | ||
bytes approvalData, | ||
uint256 maxPossibleGas | ||
) public returns (bytes memory context, bool rejectOnRecipientRevert); | ||
|
||
/** | ||
* This method is called after the actual relayed function call. | ||
* It may be used to record the transaction (e.g. charge the caller by some contract logic) for this call. | ||
* | ||
* MUST be protected with relayHubOnly() in case it modifies state. | ||
* | ||
* @param context - the call context, as returned by the preRelayedCall | ||
* @param success - true if the relayed call succeeded, false if it reverted | ||
* @param gasUseWithoutPost - the actual amount of gas used by the entire transaction, EXCEPT | ||
* the gas used by the postRelayedCall itself. | ||
* @param relayData - the relay params of the request. can be used by relayHub.calculateCharge() | ||
* | ||
* Revert in this functions causes a revert of the client's relayed call (and preRelayedCall(), but the Paymaster | ||
* is still committed to pay the relay for the entire transaction. | ||
*/ | ||
function postRelayedCall(bytes context, bool success, uint256 gasUseWithoutPost, GsnTypes.RelayData relayData) | ||
public; | ||
|
||
function versionPaymaster() external view returns (string memory); | ||
} |
Oops, something went wrong.