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
This commit is contained in:
Francisco Giordano
2019-08-16 20:30:37 +02:00
committed by GitHub
parent 79c30f96aa
commit f1c7e63923
6 changed files with 63 additions and 2 deletions

View File

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

View File

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