Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial GSN support (beta) #1844

Merged
merged 79 commits into from
Aug 12, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
2e28b70
Add base Context contract
nventuro Jul 19, 2019
f12245b
Add GSNContext and tests
nventuro Jul 22, 2019
50d596a
Add RelayHub deployment to tests
nventuro Jul 23, 2019
2b1cc85
Add RelayProvider integration, complete GSNContext tests
nventuro Jul 24, 2019
07e37ef
Switch dependency to openzeppelin-gsn-provider
nventuro Jul 25, 2019
df4f2c2
Add default txfee to provider
nventuro Jul 26, 2019
167510a
Add basic signing recipient
nventuro Jul 26, 2019
dc35dff
Sign more values
nventuro Jul 26, 2019
e52ec1a
Add comment clarifying RelayHub's msg.data
nventuro Jul 29, 2019
7363e46
Make context constructors internal
nventuro Jul 29, 2019
67e534f
Rename SigningRecipient to GSNRecipientSignedData
nventuro Jul 29, 2019
f8b97c2
Add ERC20Charge recipients
nventuro Jul 30, 2019
544a56f
Harcode RelayHub address into GSNContext
nventuro Jul 31, 2019
8b3377e
Fix Solidity linter errors
nventuro Jul 31, 2019
8a5d21b
Run server from binary, use gsn-helpers to fund it
nventuro Jul 31, 2019
dc8adcd
Migrate to published @openzeppelin/gsn-helpers
nventuro Aug 1, 2019
82ca6ab
Silence false-positive compiler warning
nventuro Aug 1, 2019
e5ca467
Use GSN helper assertions
nventuro Aug 1, 2019
6871bb7
Rename meta-tx to gsn, take out of drafts
nventuro Aug 1, 2019
108c998
Merge ERC20 charge recipients into a single one
nventuro Aug 1, 2019
5c0e49b
Rename GSNRecipients to Bouncers
nventuro Aug 1, 2019
9847c98
Add GSNBouncerUtils to decouple the bouncers from GSNRecipient
nventuro Aug 1, 2019
af81255
Add _upgradeRelayHub
nventuro Aug 1, 2019
02c8e13
Store RelayHub address using unstructored storage
nventuro Aug 1, 2019
dc9139a
Add IRelayHub
nventuro Aug 2, 2019
081ddc6
Add _withdrawDeposits to GSNRecipient
nventuro Aug 2, 2019
d5af791
Add relayHub version to recipient
nventuro Aug 2, 2019
0302cf1
Make _acceptRelayedCall and _declineRelayedCall easier to use
nventuro Aug 2, 2019
988b6f0
Rename GSNBouncerUtils to GSNBouncerBase, make it IRelayRecipient
nventuro Aug 2, 2019
ca59d08
Improve GSNBouncerBase, make pre and post sender-protected and optional
nventuro Aug 2, 2019
d10109f
Fix GSNBouncerERC20Fee, add tests
nventuro Aug 2, 2019
0ef0023
Add missing GSNBouncerSignature test
nventuro Aug 2, 2019
e3034b0
Override transferFrom in __unstable__ERC20PrimaryAdmin
nventuro Aug 2, 2019
0b3cf83
Fix gsn dependencies in package.json
spalladino Aug 2, 2019
d7d4ff1
Rhub address slot reduced by 1
spalladino Aug 2, 2019
e42d51f
Rename relay hub changed event
spalladino Aug 2, 2019
de0d458
Use released gsn-provider
spalladino Aug 2, 2019
af92387
Run relayer with short sleep of 1s instead of 100ms
spalladino Aug 2, 2019
eebd131
Merge branch 'master' of github.com:OpenZeppelin/openzeppelin-contrac…
frangio Aug 7, 2019
c57bbe6
update package-lock.json
frangio Aug 7, 2019
bcb6b6d
clear circle cache
frangio Aug 7, 2019
25f3ed7
Merge remote-tracking branch 'upstream/master' into gsn-beta
frangio Aug 7, 2019
339250e
Merge branch 'master' of github.com:OpenZeppelin/openzeppelin-contrac…
frangio Aug 8, 2019
98d422e
Merge branch 'master' of github.com:OpenZeppelin/openzeppelin-contrac…
frangio Aug 8, 2019
1108426
use optimized gsn-provider
frangio Aug 8, 2019
c493683
update to latest @openzeppelin/gsn-provider
frangio Aug 9, 2019
68de4a3
replace with gsn dev provider
frangio Aug 9, 2019
00b2818
remove relay server
frangio Aug 9, 2019
1bee370
rename arguments in approveFunction
frangio Aug 9, 2019
e69599e
fix GSNBouncerSignature test
frangio Aug 9, 2019
83eb525
change gsn txfee
frangio Aug 9, 2019
9e25a2c
initialize development provider only once
frangio Aug 9, 2019
f18f937
update RelayHub interface
frangio Aug 9, 2019
9b52cda
adapt to new IRelayHub.withdraw
frangio Aug 9, 2019
b7d3c38
Merge branch 'master' into gsn-beta
frangio Aug 9, 2019
3b9e5af
update @openzeppelin/gsn-helpers
frangio Aug 9, 2019
dc32422
update relayhub singleton address
frangio Aug 9, 2019
73798a8
fix helper name
frangio Aug 9, 2019
8a7b5be
set up gsn provider for coverage too
frangio Aug 9, 2019
944cadb
lint
frangio Aug 9, 2019
0805666
Revert "set up gsn provider for coverage too"
frangio Aug 9, 2019
5921789
remove unused code
frangio Aug 9, 2019
56c8522
add gsn provider to coverage
frangio Aug 12, 2019
79f5db1
move truffle contract options back out
frangio Aug 12, 2019
5af42ff
increase gas limit for coverage
frangio Aug 12, 2019
6bc7622
remove unreachable code
frangio Aug 12, 2019
515d40d
add more gas for GSNContext test
frangio Aug 12, 2019
0ecb521
fix test suite name
frangio Aug 12, 2019
d9cc437
rename GSNBouncerBase internal API
frangio Aug 12, 2019
768b17d
remove onlyRelayHub modifier
frangio Aug 12, 2019
4312948
add explicit inheritance
frangio Aug 12, 2019
f1716b2
remove redundant event
frangio Aug 12, 2019
f02fa1d
update name of bouncers error codes enums
frangio Aug 12, 2019
018065b
add basic docs page for gsn contracts
frangio Aug 12, 2019
2d0b43b
make gsn directory all caps
frangio Aug 12, 2019
76f03d1
Merge branch 'master' into gsn-beta
frangio Aug 12, 2019
74cbca9
add changelog entry
frangio Aug 12, 2019
f73dbb9
lint
frangio Aug 12, 2019
eaed1c4
enable test run to fail in coverage
frangio Aug 12, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add ERC20Charge recipients
  • Loading branch information
nventuro authored and spalladino committed Aug 2, 2019
commit f8b97c24bd87e78d1251b8d545478b37bf2105aa
57 changes: 57 additions & 0 deletions contracts/drafts/meta-tx/GSNRecipientERC20BuiltInCharge.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
pragma solidity ^0.5.0;

import "./GSNRecipientERC20Charge.sol";
import "../../token/ERC20/ERC20.sol";
import "../../token/ERC20/ERC20Detailed.sol";
import "../../ownership/Secondary.sol";

contract GSNRecipientERC20BuiltInCharge is GSNRecipientERC20Charge {
constructor(string memory name, string memory symbol, uint8 decimals) public {
_setToken(new __unstable__ERC20PrimaryAdmin(name, symbol, decimals));
}

function _getEquivalentTokens(uint256 weiAmount) internal view returns (uint256) {
return weiAmount;
}

function _mintBuiltIn(address account, uint256 amount) internal {
// Solidity doesn't allow converting contract types, so we need to go through the intermediate address type
__unstable__ERC20PrimaryAdmin(address(token())).mint(account, amount);
}
}

/**
* @title __unstable__ERC20PrimaryAdmin
* @dev An ERC20 token owned by another contract, which has minting permissions and can use transferFrom to receive
* anyone's tokens. This contract is an internal helper for GSNRecipientERC20BuiltInCharge, and should not be used
* outside of this context.
*/
// solhint-disable-next-line contract-name-camelcase
contract __unstable__ERC20PrimaryAdmin is ERC20, ERC20Detailed, Secondary {
uint256 private constant UINT256_MAX = 2**256 - 1;

constructor(string memory name, string memory symbol, uint8 decimals) ERC20Detailed(name, symbol, decimals) public { }

// The primary account (GSNRecipientERC20BuiltInCharge) can mint tokens
function mint(address account, uint256 amount) public onlyPrimary {
_mint(account, amount);
}

// The primary account has 'infinite' allowance for all token holders
function allowance(address owner, address spender) public view returns (uint256) {
if (spender == primary()) {
return UINT256_MAX;
} else {
return super.allowance(owner, spender);
}
}

// Allowance for the primary account cannot be changed (it is always 'infinite')
function _approve(address owner, address spender, uint256 value) internal {
if (spender == primary()) {
return;
} else {
super._approve(owner, spender, value);
}
}
}
77 changes: 77 additions & 0 deletions contracts/drafts/meta-tx/GSNRecipientERC20Charge.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
pragma solidity ^0.5.0;

import "./GSNRecipient.sol";
import "../../math/SafeMath.sol";
import "../../token/ERC20/IERC20.sol";
import "../../token/ERC20/SafeERC20.sol";

contract GSNRecipientERC20Charge is GSNRecipient {
using SafeERC20 for IERC20;
using SafeMath for uint256;

IERC20 private _token;

enum GSNRecipientERC20ChargeErrorCodes {
INSUFFICIENT_BALANCE,
INSUFFICIENT_ALLOWANCE
}

function token() public view returns (IERC20) {
return _token;
}

// We provide this as a function instead of a constructor to give more flexibility to derived contracts, which may
// not receive the token address as an argument, or even deploy it themselves.
function _setToken(IERC20 token_) internal {
require(address(_token) == address(0), "ERC20Migrator: token already set");
require(address(token_) != address(0), "ERC20Migrator: token is the zero address");

_token = token_;
}

function acceptRelayedCall(
address,
address from,
bytes calldata,
uint256,
uint256,
uint256,
uint256,
bytes calldata,
uint256 maxPossibleCharge
)
external
view
returns (uint256, bytes memory)
{
uint256 maxTokenCharge = _getEquivalentTokens(maxPossibleCharge);

if (_token.balanceOf(from) < maxTokenCharge) {
return (_declineRelayedCall(uint256(GSNRecipientERC20ChargeErrorCodes.INSUFFICIENT_BALANCE)), "");
} else if (_token.allowance(from, address(this)) < maxTokenCharge) {
return (_declineRelayedCall(uint256(GSNRecipientERC20ChargeErrorCodes.INSUFFICIENT_ALLOWANCE)), "");
}

return (_acceptRelayedCall(), abi.encode(from, maxTokenCharge));
}

function preRelayedCall(bytes calldata context) external returns (bytes32) {
(address from, uint256 maxTokenCharge) = abi.decode(context, (address, uint256));

// The maximum token charge is pre-charged from the user
_token.safeTransferFrom(from, address(this), maxTokenCharge);
}

function postRelayedCall(bytes calldata context, bool, uint256 actualCharge, bytes32) external {
(address from, uint256 maxTokenCharge) = abi.decode(context, (address, uint256));

// After the relayed call has been executed and the actual charge estimated, the excess pre-charge is returned
_token.safeTransfer(from, maxTokenCharge.sub(actualCharge));
}

/**
* @dev Converts an amount in wei to the equivalent number of tokens. This fucntion must be implemented by derived
* contracts by specifying an exchange rate, which may e.g. be consulted from an oracle.
*/
function _getEquivalentTokens(uint256 weiAmount) internal view returns (uint256);
}