Bläddra i källkod

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
Francisco Giordano 6 år sedan
förälder
incheckning
f1c7e63923

+ 13 - 0
contracts/GSN/GSNRecipient.sol

@@ -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);
     }

+ 5 - 1
contracts/GSN/README.adoc

@@ -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
 

+ 31 - 0
contracts/GSN/bouncers/GSNBouncerERC20Fee.sol

@@ -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));

+ 12 - 0
contracts/GSN/bouncers/GSNBouncerSignature.sol

@@ -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,

+ 1 - 0
docs/modules/ROOT/pages/gsn-advanced.adoc

@@ -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.

+ 1 - 1
docs/modules/ROOT/pages/gsn.adoc

@@ -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].