Add docs to GSN API (#1887)

* move gsn link

* change underscore to dash

* add content to gsn api ref

* change link of GSN announcement

* Update contracts/GSN/bouncers/GSNBouncerERC20Fee.sol

Co-Authored-By: Nicolás Venturo <nicolas.venturo@gmail.com>

* fix crossreference to gsn guide
pull/1888/head
Francisco Giordano 6 years ago committed by GitHub
parent 79c30f96aa
commit f1c7e63923
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      contracts/GSN/GSNRecipient.sol
  2. 6
      contracts/GSN/README.adoc
  3. 31
      contracts/GSN/bouncers/GSNBouncerERC20Fee.sol
  4. 12
      contracts/GSN/bouncers/GSNBouncerSignature.sol
  5. 1
      docs/modules/ROOT/pages/gsn-advanced.adoc
  6. 2
      docs/modules/ROOT/pages/gsn.adoc

@ -11,10 +11,18 @@ import "./IRelayHub.sol";
* must do so themselves.
*/
contract GSNRecipient is IRelayRecipient, GSNContext, GSNBouncerBase {
/**
* @dev Returns the RelayHub address for this recipient contract.
*/
function getHubAddr() public view returns (address) {
return _relayHub;
}
/**
* @dev This function returns the version string of the RelayHub for which
* this recipient implementation was built. It's not currently used, but
* may be used by tooling.
*/
// This function is view for future-proofing, it may require reading from
// storage in the future.
function relayHubVersion() public view returns (string memory) {
@ -22,6 +30,11 @@ contract GSNRecipient is IRelayRecipient, GSNContext, GSNBouncerBase {
return "1.0.0";
}
/**
* @dev Triggers a withdraw of the recipient's deposits in RelayHub. Can
* be used by derived contracts to expose the functionality in an external
* interface.
*/
function _withdrawDeposits(uint256 amount, address payable payee) internal {
IRelayHub(_relayHub).withdraw(amount, payee);
}

@ -1,4 +1,8 @@
= GSN
= Gas Station Network
NOTE: This feature is being released in the next version of OpenZeppelin Contracts, available right now through `npm install @openzeppelin/contracts@next`.
TIP: Check out our guide on the xref:ROOT:gsn.adoc[basics of the GSN] as well as the xref:ROOT:gsn-advanced.adoc[more advanced topics].
== Recipient

@ -7,6 +7,15 @@ import "../../token/ERC20/SafeERC20.sol";
import "../../token/ERC20/ERC20.sol";
import "../../token/ERC20/ERC20Detailed.sol";
/**
* @dev A xref:ROOT:gsn-advanced.adoc#gsn-bouncers[GSN Bouncer] that charges transaction fees in a special purpose ERC20
* token, which we refer to as the gas payment token. The amount charged is exactly the amount of Ether charged to the
* recipient. This means that the token is essentially pegged to the value of Ether.
*
* The distribution strategy of the gas payment token to users is not defined by this contract. It's a mintable token
* whose only minter is the recipient, so the strategy must be implemented in a derived contract, making use of the
* internal {_mint} function.
*/
contract GSNBouncerERC20Fee is GSNBouncerBase {
using SafeERC20 for __unstable__ERC20PrimaryAdmin;
using SafeMath for uint256;
@ -17,18 +26,31 @@ contract GSNBouncerERC20Fee is GSNBouncerBase {
__unstable__ERC20PrimaryAdmin private _token;
/**
* @dev The arguments to the constructor are the details that the gas payment token will have: `name`, `symbol`, and
* `decimals`.
*/
constructor(string memory name, string memory symbol, uint8 decimals) public {
_token = new __unstable__ERC20PrimaryAdmin(name, symbol, decimals);
}
/**
* @dev Returns the gas payment token.
*/
function token() public view returns (IERC20) {
return IERC20(_token);
}
/**
* @dev Internal function that mints the gas payment token. Derived contracts should expose this function in their public API, with proper access control mechanisms.
*/
function _mint(address account, uint256 amount) internal {
_token.mint(account, amount);
}
/**
* @dev Ensures that only users with enough gas payment token balance can have transactions relayed through the GSN.
*/
function acceptRelayedCall(
address,
address from,
@ -51,6 +73,12 @@ contract GSNBouncerERC20Fee is GSNBouncerBase {
return _approveRelayedCall(abi.encode(from, maxPossibleCharge, transactionFee, gasPrice));
}
/**
* @dev Implements the precharge to the user. The maximum possible charge (depending on gas limit, gas price, and
* fee) will be deducted from the user balance of gas payment token. Note that this is an overestimation of the
* actual charge, necessary because we cannot predict how much gas the execution will actually need. The remainder
* is returned to the user in {_postRelayedCall}.
*/
function _preRelayedCall(bytes memory context) internal returns (bytes32) {
(address from, uint256 maxPossibleCharge) = abi.decode(context, (address, uint256));
@ -58,6 +86,9 @@ contract GSNBouncerERC20Fee is GSNBouncerBase {
_token.safeTransferFrom(from, address(this), maxPossibleCharge);
}
/**
* @dev Returns to the user the extra amount that was previously charged, once the actual execution cost is known.
*/
function _postRelayedCall(bytes memory context, bool, uint256 actualCharge, bytes32) internal {
(address from, uint256 maxPossibleCharge, uint256 transactionFee, uint256 gasPrice) =
abi.decode(context, (address, uint256, uint256, uint256));

@ -3,6 +3,12 @@ pragma solidity ^0.5.0;
import "./GSNBouncerBase.sol";
import "../../cryptography/ECDSA.sol";
/**
* @dev A xref:ROOT:gsn-advanced.adoc#gsn-bouncers[GSN Bouncer] that allows relayed transactions through when they are
* accompanied by the signature of a trusted signer. The intent is for this signature to be generated by a server that
* performs validations off-chain. Note that nothing is charged to the user in this scheme. Thus, the server should make
* sure to account for this in their economic and threat model.
*/
contract GSNBouncerSignature is GSNBouncerBase {
using ECDSA for bytes32;
@ -12,10 +18,16 @@ contract GSNBouncerSignature is GSNBouncerBase {
INVALID_SIGNER
}
/**
* @dev Sets the trusted signer that is going to be producing signatures to approve relayed calls.
*/
constructor(address trustedSigner) public {
_trustedSigner = trustedSigner;
}
/**
* @dev Ensures that only transactions with a trusted signature can be relayed through the GSN.
*/
function acceptRelayedCall(
address relay,
address from,

@ -8,6 +8,7 @@ Finally, we will cover how to create your own custom Bouncer.
If you're still learning about the basics of the Gas Station Network, you should head over to our xref:api:gsn.adoc[GSN Guide], which will help you get started from scratch.
[[gsn-bouncers]]
== GSN Bouncers
A *GSN Bouncer* decides which transaction gets approved and which transaction gets rejected. Bouncers are a key concept within GSN. Dapps need Bouncers to prevent malicious users from spending the subsidies for the transactions.

@ -87,4 +87,4 @@ These functions allow you to implement, for instance, a flow where you charge yo
== Further reading
Read our xref:gsn-advanced.adoc[guide on the payment strategies] (called _bouncers_) pre-built and shipped in OpenZeppelin Contracts, or check out xref:api:gsn.adoc[the API reference of the GSN base contracts].
Read our xref:gsn-advanced.adoc[guide on the payment strategies] (called _bouncers_) pre-built and shipped in OpenZeppelin Contracts, or check out xref:api:GSN.adoc[the API reference of the GSN base contracts].

Loading…
Cancel
Save