Commit 89835152 by Nicolás Venturo Committed by Francisco Giordano

GSN compatibility (#1880)

* switch to using Context internally

* add context import

* Add smoke test to make sure enabling GSN support works

* Update test/GSN/ERC721GSNRecipientMock.test.js

Co-Authored-By: Francisco Giordano <frangio.1@gmail.com>

* Upgrade truffle

* add missing awaits

* Revert "Upgrade truffle"

This reverts commit f9b0ba9019650fdbf8919a33e6fba834689e6b04.
parent 4070719f
...@@ -6,7 +6,12 @@ root = true ...@@ -6,7 +6,12 @@ root = true
[*] [*]
charset = utf-8 charset = utf-8
end_of_line = lf end_of_line = lf
indent_size = 2
indent_style = space indent_style = space
insert_final_newline = true insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true
[*.sol]
indent_size = 4
[*.js]
indent_size = 2
...@@ -20,7 +20,7 @@ contract GSNBouncerERC20Fee is Initializable, GSNBouncerBase { ...@@ -20,7 +20,7 @@ contract GSNBouncerERC20Fee is Initializable, GSNBouncerBase {
// storage layout. This value is calculated as: keccak256('gsn.bouncer.signature.token'), minus 1. // storage layout. This value is calculated as: keccak256('gsn.bouncer.signature.token'), minus 1.
bytes32 constant private TOKEN_STORAGE_SLOT = 0xd918b70a5a5c95a8c0cac8acbdd59e1b4acd0645f53c0461d64b41f8825c8828; bytes32 constant private TOKEN_STORAGE_SLOT = 0xd918b70a5a5c95a8c0cac8acbdd59e1b4acd0645f53c0461d64b41f8825c8828;
function initialize(string memory name, string memory symbol, uint8 decimals) initializer public { function initialize(string memory name, string memory symbol, uint8 decimals) public initializer {
// TODO: Should we inject this token, instead of creating it, in order to make it upgradeable? // TODO: Should we inject this token, instead of creating it, in order to make it upgradeable?
// However, that would mean removing it from unstable and making in an official contract // However, that would mean removing it from unstable and making in an official contract
_setToken(new __unstable__ERC20PrimaryAdmin(name, symbol, decimals)); _setToken(new __unstable__ERC20PrimaryAdmin(name, symbol, decimals));
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../Roles.sol";
import "../../GSN/Context.sol";
import "../Roles.sol";
contract CapperRole is Initializable { contract CapperRole is Initializable, Context {
using Roles for Roles.Role; using Roles for Roles.Role;
event CapperAdded(address indexed account); event CapperAdded(address indexed account);
...@@ -19,7 +20,7 @@ contract CapperRole is Initializable { ...@@ -19,7 +20,7 @@ contract CapperRole is Initializable {
} }
modifier onlyCapper() { modifier onlyCapper() {
require(isCapper(msg.sender)); require(isCapper(_msgSender()), "CapperRole: caller does not have the Capper role");
_; _;
} }
...@@ -32,7 +33,7 @@ contract CapperRole is Initializable { ...@@ -32,7 +33,7 @@ contract CapperRole is Initializable {
} }
function renounceCapper() public { function renounceCapper() public {
_removeCapper(msg.sender); _removeCapper(_msgSender());
} }
function _addCapper(address account) internal { function _addCapper(address account) internal {
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../Roles.sol";
import "../../GSN/Context.sol";
import "../Roles.sol";
contract MinterRole is Initializable { contract MinterRole is Initializable, Context {
using Roles for Roles.Role; using Roles for Roles.Role;
event MinterAdded(address indexed account); event MinterAdded(address indexed account);
...@@ -19,7 +20,7 @@ contract MinterRole is Initializable { ...@@ -19,7 +20,7 @@ contract MinterRole is Initializable {
} }
modifier onlyMinter() { modifier onlyMinter() {
require(isMinter(msg.sender)); require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role");
_; _;
} }
...@@ -32,7 +33,7 @@ contract MinterRole is Initializable { ...@@ -32,7 +33,7 @@ contract MinterRole is Initializable {
} }
function renounceMinter() public { function renounceMinter() public {
_removeMinter(msg.sender); _removeMinter(_msgSender());
} }
function _addMinter(address account) internal { function _addMinter(address account) internal {
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../Roles.sol";
import "../../GSN/Context.sol";
import "../Roles.sol";
contract PauserRole is Initializable { contract PauserRole is Initializable, Context {
using Roles for Roles.Role; using Roles for Roles.Role;
event PauserAdded(address indexed account); event PauserAdded(address indexed account);
...@@ -19,7 +20,7 @@ contract PauserRole is Initializable { ...@@ -19,7 +20,7 @@ contract PauserRole is Initializable {
} }
modifier onlyPauser() { modifier onlyPauser() {
require(isPauser(msg.sender)); require(isPauser(_msgSender()), "PauserRole: caller does not have the Pauser role");
_; _;
} }
...@@ -32,7 +33,7 @@ contract PauserRole is Initializable { ...@@ -32,7 +33,7 @@ contract PauserRole is Initializable {
} }
function renouncePauser() public { function renouncePauser() public {
_removePauser(msg.sender); _removePauser(_msgSender());
} }
function _addPauser(address account) internal { function _addPauser(address account) internal {
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../Roles.sol";
import "../../GSN/Context.sol";
import "../Roles.sol";
contract SignerRole is Initializable { contract SignerRole is Initializable, Context {
using Roles for Roles.Role; using Roles for Roles.Role;
event SignerAdded(address indexed account); event SignerAdded(address indexed account);
...@@ -19,7 +20,7 @@ contract SignerRole is Initializable { ...@@ -19,7 +20,7 @@ contract SignerRole is Initializable {
} }
modifier onlySigner() { modifier onlySigner() {
require(isSigner(msg.sender)); require(isSigner(_msgSender()), "SignerRole: caller does not have the Signer role");
_; _;
} }
...@@ -32,7 +33,7 @@ contract SignerRole is Initializable { ...@@ -32,7 +33,7 @@ contract SignerRole is Initializable {
} }
function renounceSigner() public { function renounceSigner() public {
_removeSigner(msg.sender); _removeSigner(_msgSender());
} }
function _addSigner(address account) internal { function _addSigner(address account) internal {
......
...@@ -2,13 +2,14 @@ pragma solidity ^0.5.2; ...@@ -2,13 +2,14 @@ pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../../GSN/Context.sol";
import "../Roles.sol"; import "../Roles.sol";
/** /**
* @title WhitelistAdminRole * @title WhitelistAdminRole
* @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts. * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts.
*/ */
contract WhitelistAdminRole is Initializable { contract WhitelistAdminRole is Initializable, Context {
using Roles for Roles.Role; using Roles for Roles.Role;
event WhitelistAdminAdded(address indexed account); event WhitelistAdminAdded(address indexed account);
...@@ -23,7 +24,7 @@ contract WhitelistAdminRole is Initializable { ...@@ -23,7 +24,7 @@ contract WhitelistAdminRole is Initializable {
} }
modifier onlyWhitelistAdmin() { modifier onlyWhitelistAdmin() {
require(isWhitelistAdmin(msg.sender)); require(isWhitelistAdmin(_msgSender()), "WhitelistAdminRole: caller does not have the WhitelistAdmin role");
_; _;
} }
...@@ -36,7 +37,7 @@ contract WhitelistAdminRole is Initializable { ...@@ -36,7 +37,7 @@ contract WhitelistAdminRole is Initializable {
} }
function renounceWhitelistAdmin() public { function renounceWhitelistAdmin() public {
_removeWhitelistAdmin(msg.sender); _removeWhitelistAdmin(_msgSender());
} }
function _addWhitelistAdmin(address account) internal { function _addWhitelistAdmin(address account) internal {
......
...@@ -2,6 +2,7 @@ pragma solidity ^0.5.2; ...@@ -2,6 +2,7 @@ pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../../GSN/Context.sol";
import "../Roles.sol"; import "../Roles.sol";
import "./WhitelistAdminRole.sol"; import "./WhitelistAdminRole.sol";
...@@ -11,7 +12,7 @@ import "./WhitelistAdminRole.sol"; ...@@ -11,7 +12,7 @@ import "./WhitelistAdminRole.sol";
* crowdsale). This role is special in that the only accounts that can add it are WhitelistAdmins (who can also remove * crowdsale). This role is special in that the only accounts that can add it are WhitelistAdmins (who can also remove
* it), and not Whitelisteds themselves. * it), and not Whitelisteds themselves.
*/ */
contract WhitelistedRole is Initializable, WhitelistAdminRole { contract WhitelistedRole is Initializable, Context, WhitelistAdminRole {
using Roles for Roles.Role; using Roles for Roles.Role;
event WhitelistedAdded(address indexed account); event WhitelistedAdded(address indexed account);
...@@ -20,7 +21,7 @@ contract WhitelistedRole is Initializable, WhitelistAdminRole { ...@@ -20,7 +21,7 @@ contract WhitelistedRole is Initializable, WhitelistAdminRole {
Roles.Role private _whitelisteds; Roles.Role private _whitelisteds;
modifier onlyWhitelisted() { modifier onlyWhitelisted() {
require(isWhitelisted(msg.sender)); require(isWhitelisted(_msgSender()), "WhitelistedRole: caller does not have the Whitelisted role");
_; _;
} }
...@@ -41,7 +42,7 @@ contract WhitelistedRole is Initializable, WhitelistAdminRole { ...@@ -41,7 +42,7 @@ contract WhitelistedRole is Initializable, WhitelistAdminRole {
} }
function renounceWhitelisted() public { function renounceWhitelisted() public {
_removeWhitelisted(msg.sender); _removeWhitelisted(_msgSender());
} }
function _addWhitelisted(address account) internal { function _addWhitelisted(address account) internal {
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../GSN/Context.sol";
import "../token/ERC20/IERC20.sol"; import "../token/ERC20/IERC20.sol";
import "../math/SafeMath.sol"; import "../math/SafeMath.sol";
import "../token/ERC20/SafeERC20.sol"; import "../token/ERC20/SafeERC20.sol";
...@@ -18,7 +20,7 @@ import "../utils/ReentrancyGuard.sol"; ...@@ -18,7 +20,7 @@ import "../utils/ReentrancyGuard.sol";
* the methods to add functionality. Consider using 'super' where appropriate to concatenate * the methods to add functionality. Consider using 'super' where appropriate to concatenate
* behavior. * behavior.
*/ */
contract Crowdsale is Initializable, ReentrancyGuard { contract Crowdsale is Initializable, Context, ReentrancyGuard {
using SafeMath for uint256; using SafeMath for uint256;
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
...@@ -71,7 +73,7 @@ contract Crowdsale is Initializable, ReentrancyGuard { ...@@ -71,7 +73,7 @@ contract Crowdsale is Initializable, ReentrancyGuard {
* buyTokens directly when purchasing tokens from a contract. * buyTokens directly when purchasing tokens from a contract.
*/ */
function () external payable { function () external payable {
buyTokens(msg.sender); buyTokens(_msgSender());
} }
/** /**
...@@ -119,7 +121,7 @@ contract Crowdsale is Initializable, ReentrancyGuard { ...@@ -119,7 +121,7 @@ contract Crowdsale is Initializable, ReentrancyGuard {
_weiRaised = _weiRaised.add(weiAmount); _weiRaised = _weiRaised.add(weiAmount);
_processPurchase(beneficiary, tokens); _processPurchase(beneficiary, tokens);
emit TokensPurchased(msg.sender, beneficiary, weiAmount, tokens); emit TokensPurchased(_msgSender(), beneficiary, weiAmount, tokens);
_updatePurchasingState(beneficiary, weiAmount); _updatePurchasingState(beneficiary, weiAmount);
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../../GSN/Context.sol";
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
import "./FinalizableCrowdsale.sol"; import "./FinalizableCrowdsale.sol";
import "../../payment/escrow/RefundEscrow.sol"; import "../../payment/escrow/RefundEscrow.sol";
...@@ -15,7 +17,7 @@ import "../../payment/escrow/RefundEscrow.sol"; ...@@ -15,7 +17,7 @@ import "../../payment/escrow/RefundEscrow.sol";
* the goal is unlikely to be met, they sell their tokens (possibly at a discount). The attacker will be refunded when * the goal is unlikely to be met, they sell their tokens (possibly at a discount). The attacker will be refunded when
* the crowdsale is finalized, and the users that purchased from them will be left with worthless tokens. * the crowdsale is finalized, and the users that purchased from them will be left with worthless tokens.
*/ */
contract RefundableCrowdsale is Initializable, FinalizableCrowdsale { contract RefundableCrowdsale is Initializable, Context, FinalizableCrowdsale {
using SafeMath for uint256; using SafeMath for uint256;
// minimum amount of funds to be raised in weis // minimum amount of funds to be raised in weis
...@@ -85,7 +87,7 @@ contract RefundableCrowdsale is Initializable, FinalizableCrowdsale { ...@@ -85,7 +87,7 @@ contract RefundableCrowdsale is Initializable, FinalizableCrowdsale {
* @dev Overrides Crowdsale fund forwarding, sending funds to escrow. * @dev Overrides Crowdsale fund forwarding, sending funds to escrow.
*/ */
function _forwardFunds() internal { function _forwardFunds() internal {
_escrow.deposit.value(msg.value)(msg.sender); _escrow.deposit.value(msg.value)(_msgSender());
} }
uint256[50] private ______gap; uint256[50] private ______gap;
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../GSN/Context.sol";
import "../access/roles/SignerRole.sol"; import "../access/roles/SignerRole.sol";
import "../cryptography/ECDSA.sol"; import "../cryptography/ECDSA.sol";
...@@ -35,7 +37,7 @@ import "../cryptography/ECDSA.sol"; ...@@ -35,7 +37,7 @@ import "../cryptography/ECDSA.sol";
* the data in the signature much more complex. * the data in the signature much more complex.
* See https://ethereum.stackexchange.com/a/50616 for more details. * See https://ethereum.stackexchange.com/a/50616 for more details.
*/ */
contract SignatureBouncer is Initializable, SignerRole { contract SignatureBouncer is Initializable, Context, SignerRole {
using ECDSA for bytes32; using ECDSA for bytes32;
// Function selectors are 4 bytes long, as documented in // Function selectors are 4 bytes long, as documented in
...@@ -52,7 +54,7 @@ contract SignatureBouncer is Initializable, SignerRole { ...@@ -52,7 +54,7 @@ contract SignatureBouncer is Initializable, SignerRole {
* @dev requires that a valid signature of a signer was provided * @dev requires that a valid signature of a signer was provided
*/ */
modifier onlyValidSignature(bytes memory signature) { modifier onlyValidSignature(bytes memory signature) {
require(_isValidSignature(msg.sender, signature)); require(_isValidSignature(_msgSender(), signature), "SignatureBouncer: invalid signature for caller");
_; _;
} }
...@@ -60,7 +62,8 @@ contract SignatureBouncer is Initializable, SignerRole { ...@@ -60,7 +62,8 @@ contract SignatureBouncer is Initializable, SignerRole {
* @dev requires that a valid signature with a specified method of a signer was provided * @dev requires that a valid signature with a specified method of a signer was provided
*/ */
modifier onlyValidSignatureAndMethod(bytes memory signature) { modifier onlyValidSignatureAndMethod(bytes memory signature) {
require(_isValidSignatureAndMethod(msg.sender, signature)); // solhint-disable-next-line max-line-length
require(_isValidSignatureAndMethod(_msgSender(), signature), "SignatureBouncer: invalid signature for caller and method");
_; _;
} }
...@@ -68,7 +71,8 @@ contract SignatureBouncer is Initializable, SignerRole { ...@@ -68,7 +71,8 @@ contract SignatureBouncer is Initializable, SignerRole {
* @dev requires that a valid signature with a specified method and params of a signer was provided * @dev requires that a valid signature with a specified method and params of a signer was provided
*/ */
modifier onlyValidSignatureAndData(bytes memory signature) { modifier onlyValidSignatureAndData(bytes memory signature) {
require(_isValidSignatureAndData(msg.sender, signature)); // solhint-disable-next-line max-line-length
require(_isValidSignatureAndData(_msgSender(), signature), "SignatureBouncer: invalid signature for caller and data");
_; _;
} }
...@@ -85,9 +89,10 @@ contract SignatureBouncer is Initializable, SignerRole { ...@@ -85,9 +89,10 @@ contract SignatureBouncer is Initializable, SignerRole {
* @return bool * @return bool
*/ */
function _isValidSignatureAndMethod(address account, bytes memory signature) internal view returns (bool) { function _isValidSignatureAndMethod(address account, bytes memory signature) internal view returns (bool) {
bytes memory msgData = _msgData();
bytes memory data = new bytes(_METHOD_ID_SIZE); bytes memory data = new bytes(_METHOD_ID_SIZE);
for (uint i = 0; i < data.length; i++) { for (uint256 i = 0; i < data.length; i++) {
data[i] = msg.data[i]; data[i] = msgData[i];
} }
return _isValidDataHash(keccak256(abi.encodePacked(address(this), account, data)), signature); return _isValidDataHash(keccak256(abi.encodePacked(address(this), account, data)), signature);
} }
...@@ -98,11 +103,12 @@ contract SignatureBouncer is Initializable, SignerRole { ...@@ -98,11 +103,12 @@ contract SignatureBouncer is Initializable, SignerRole {
* @return bool * @return bool
*/ */
function _isValidSignatureAndData(address account, bytes memory signature) internal view returns (bool) { function _isValidSignatureAndData(address account, bytes memory signature) internal view returns (bool) {
require(msg.data.length > _SIGNATURE_SIZE); bytes memory msgData = _msgData();
require(msgData.length > _SIGNATURE_SIZE, "SignatureBouncer: data is too short");
bytes memory data = new bytes(msg.data.length - _SIGNATURE_SIZE); bytes memory data = new bytes(msgData.length - _SIGNATURE_SIZE);
for (uint i = 0; i < data.length; i++) { for (uint256 i = 0; i < data.length; i++) {
data[i] = msg.data[i]; data[i] = msgData[i];
} }
return _isValidDataHash(keccak256(abi.encodePacked(address(this), account, data)), signature); return _isValidDataHash(keccak256(abi.encodePacked(address(this), account, data)), signature);
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../GSN/Context.sol";
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
import "../token/ERC20/ERC20Detailed.sol"; import "../token/ERC20/ERC20Detailed.sol";
...@@ -10,16 +12,14 @@ import "../token/ERC20/ERC20Detailed.sol"; ...@@ -10,16 +12,14 @@ import "../token/ERC20/ERC20Detailed.sol";
* Note they can later distribute these tokens as they wish using `transfer` and other * Note they can later distribute these tokens as they wish using `transfer` and other
* `ERC20` functions. * `ERC20` functions.
*/ */
contract SimpleToken is Initializable, ERC20, ERC20Detailed { contract SimpleToken is Initializable, Context, ERC20, ERC20Detailed {
uint8 public constant DECIMALS = 18;
uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(DECIMALS));
/** /**
* @dev Constructor that gives msg.sender all of existing tokens. * @dev Constructor that gives _msgSender() all of existing tokens.
*/ */
function initialize(address sender) public initializer { function initialize(address sender) public initializer {
ERC20Detailed.initialize("SimpleToken", "SIM", DECIMALS); ERC20Detailed.initialize("SimpleToken", "SIM", 18);
_mint(sender, INITIAL_SUPPLY); _mint(sender, 10000 * (10 ** uint256(decimals())));
} }
uint256[50] private ______gap; uint256[50] private ______gap;
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../GSN/Context.sol";
import "../access/roles/PauserRole.sol"; import "../access/roles/PauserRole.sol";
/** /**
* @title Pausable * @title Pausable
* @dev Base contract which allows children to implement an emergency stop mechanism. * @dev Base contract which allows children to implement an emergency stop mechanism.
*/ */
contract Pausable is Initializable, PauserRole { contract Pausable is Initializable, Context, PauserRole {
event Paused(address account); event Paused(address account);
event Unpaused(address account); event Unpaused(address account);
...@@ -47,7 +49,7 @@ contract Pausable is Initializable, PauserRole { ...@@ -47,7 +49,7 @@ contract Pausable is Initializable, PauserRole {
*/ */
function pause() public onlyPauser whenNotPaused { function pause() public onlyPauser whenNotPaused {
_paused = true; _paused = true;
emit Paused(msg.sender); emit Paused(_msgSender());
} }
/** /**
...@@ -55,7 +57,7 @@ contract Pausable is Initializable, PauserRole { ...@@ -55,7 +57,7 @@ contract Pausable is Initializable, PauserRole {
*/ */
function unpause() public onlyPauser whenPaused { function unpause() public onlyPauser whenPaused {
_paused = false; _paused = false;
emit Unpaused(msg.sender); emit Unpaused(_msgSender());
} }
uint256[50] private ______gap; uint256[50] private ______gap;
......
...@@ -4,7 +4,7 @@ import "../access/roles/CapperRole.sol"; ...@@ -4,7 +4,7 @@ import "../access/roles/CapperRole.sol";
contract CapperRoleMock is CapperRole { contract CapperRoleMock is CapperRole {
constructor() public { constructor() public {
CapperRole.initialize(msg.sender); CapperRole.initialize(_msgSender());
} }
function removeCapper(address account) public { function removeCapper(address account) public {
......
...@@ -7,7 +7,7 @@ contract ConditionalEscrowMock is ConditionalEscrow { ...@@ -7,7 +7,7 @@ contract ConditionalEscrowMock is ConditionalEscrow {
mapping(address => bool) private _allowed; mapping(address => bool) private _allowed;
constructor() public { constructor() public {
ConditionalEscrow.initialize(msg.sender); ConditionalEscrow.initialize(_msgSender());
} }
function setAllowed(address payee, bool allowed) public { function setAllowed(address payee, bool allowed) public {
......
...@@ -7,7 +7,7 @@ import "./MinterRoleMock.sol"; ...@@ -7,7 +7,7 @@ import "./MinterRoleMock.sol";
contract ERC20CappedMock is ERC20Capped, MinterRoleMock { contract ERC20CappedMock is ERC20Capped, MinterRoleMock {
constructor(uint256 cap) public { constructor(uint256 cap) public {
ERC20Capped.initialize(cap, msg.sender); ERC20Capped.initialize(cap, _msgSender());
} }
} }
...@@ -5,6 +5,6 @@ import "./MinterRoleMock.sol"; ...@@ -5,6 +5,6 @@ import "./MinterRoleMock.sol";
contract ERC20MintableMock is ERC20Mintable, MinterRoleMock { contract ERC20MintableMock is ERC20Mintable, MinterRoleMock {
constructor() public { constructor() public {
ERC20Mintable.initialize(msg.sender); ERC20Mintable.initialize(_msgSender());
} }
} }
...@@ -6,7 +6,7 @@ import "./PauserRoleMock.sol"; ...@@ -6,7 +6,7 @@ import "./PauserRoleMock.sol";
// mock class using ERC20Pausable // mock class using ERC20Pausable
contract ERC20PausableMock is ERC20Pausable, PauserRoleMock { contract ERC20PausableMock is ERC20Pausable, PauserRoleMock {
constructor (address initialAccount, uint initialBalance) public { constructor (address initialAccount, uint initialBalance) public {
ERC20Pausable.initialize(msg.sender); ERC20Pausable.initialize(_msgSender());
_mint(initialAccount, initialBalance); _mint(initialAccount, initialBalance);
} }
} }
...@@ -15,8 +15,8 @@ contract ERC721FullMock is ERC721Full, ERC721Mintable, ERC721MetadataMintable, E ...@@ -15,8 +15,8 @@ contract ERC721FullMock is ERC721Full, ERC721Mintable, ERC721MetadataMintable, E
ERC721.initialize(); ERC721.initialize();
ERC721Metadata.initialize(name, symbol); ERC721Metadata.initialize(name, symbol);
ERC721Enumerable.initialize(); ERC721Enumerable.initialize();
ERC721Mintable.initialize(msg.sender); ERC721Mintable.initialize(_msgSender());
ERC721MetadataMintable.initialize(msg.sender); ERC721MetadataMintable.initialize(_msgSender());
} }
function exists(uint256 tokenId) public view returns (bool) { function exists(uint256 tokenId) public view returns (bool) {
......
pragma solidity ^0.5.2;
import "../token/ERC721/ERC721.sol";
import "../GSN/GSNRecipient.sol";
import "../GSN/bouncers/GSNBouncerSignature.sol";
/**
* @title ERC721GSNRecipientMock
* A simple ERC721 mock that has GSN support enabled
*/
contract ERC721GSNRecipientMock is ERC721, GSNRecipient, GSNBouncerSignature {
constructor(address trustedSigner) public {
ERC721.initialize();
GSNRecipient.initialize();
GSNBouncerSignature.initialize(trustedSigner);
}
function mint(uint256 tokenId) public {
_mint(_msgSender(), tokenId);
}
}
...@@ -13,7 +13,7 @@ contract ERC721MintableBurnableImpl is ERC721Full, ERC721Mintable, ERC721Metadat ...@@ -13,7 +13,7 @@ contract ERC721MintableBurnableImpl is ERC721Full, ERC721Mintable, ERC721Metadat
ERC721.initialize(); ERC721.initialize();
ERC721Metadata.initialize("Test", "TEST"); ERC721Metadata.initialize("Test", "TEST");
ERC721Enumerable.initialize(); ERC721Enumerable.initialize();
ERC721Mintable.initialize(msg.sender); ERC721Mintable.initialize(_msgSender());
ERC721MetadataMintable.initialize(msg.sender); ERC721MetadataMintable.initialize(_msgSender());
} }
} }
...@@ -10,7 +10,7 @@ import "./PauserRoleMock.sol"; ...@@ -10,7 +10,7 @@ import "./PauserRoleMock.sol";
contract ERC721PausableMock is ERC721Pausable, PauserRoleMock { contract ERC721PausableMock is ERC721Pausable, PauserRoleMock {
constructor() public { constructor() public {
ERC721.initialize(); ERC721.initialize();
ERC721Pausable.initialize(msg.sender); ERC721Pausable.initialize(_msgSender());
} }
function mint(address to, uint256 tokenId) public { function mint(address to, uint256 tokenId) public {
......
...@@ -4,6 +4,6 @@ import "../payment/escrow/Escrow.sol"; ...@@ -4,6 +4,6 @@ import "../payment/escrow/Escrow.sol";
contract EscrowMock is Escrow { contract EscrowMock is Escrow {
constructor() public { constructor() public {
Escrow.initialize(msg.sender); Escrow.initialize(_msgSender());
} }
} }
...@@ -6,8 +6,8 @@ import "../GSN/bouncers/GSNBouncerERC20Fee.sol"; ...@@ -6,8 +6,8 @@ import "../GSN/bouncers/GSNBouncerERC20Fee.sol";
contract GSNBouncerERC20FeeMock is GSNRecipient, GSNBouncerERC20Fee { contract GSNBouncerERC20FeeMock is GSNRecipient, GSNBouncerERC20Fee {
constructor(string memory name, string memory symbol, uint8 decimals) public { constructor(string memory name, string memory symbol, uint8 decimals) public {
GSNBouncerERC20Fee.initialize(name, symbol, decimals);
GSNRecipient.initialize(); GSNRecipient.initialize();
GSNBouncerERC20Fee.initialize(name, symbol, decimals);
} }
function mint(address account, uint256 amount) public { function mint(address account, uint256 amount) public {
......
...@@ -6,8 +6,8 @@ import "../GSN/bouncers/GSNBouncerSignature.sol"; ...@@ -6,8 +6,8 @@ import "../GSN/bouncers/GSNBouncerSignature.sol";
contract GSNBouncerSignatureMock is GSNRecipient, GSNBouncerSignature { contract GSNBouncerSignatureMock is GSNRecipient, GSNBouncerSignature {
constructor(address trustedSigner) public { constructor(address trustedSigner) public {
GSNBouncerSignature.initialize(trustedSigner);
GSNRecipient.initialize(); GSNRecipient.initialize();
GSNBouncerSignature.initialize(trustedSigner);
} }
event MockFunctionCalled(); event MockFunctionCalled();
......
...@@ -7,6 +7,6 @@ import "./CapperRoleMock.sol"; ...@@ -7,6 +7,6 @@ import "./CapperRoleMock.sol";
contract IndividuallyCappedCrowdsaleImpl is IndividuallyCappedCrowdsale, CapperRoleMock { contract IndividuallyCappedCrowdsaleImpl is IndividuallyCappedCrowdsale, CapperRoleMock {
constructor (uint256 rate, address payable wallet, IERC20 token) public { constructor (uint256 rate, address payable wallet, IERC20 token) public {
Crowdsale.initialize(rate, wallet, token); Crowdsale.initialize(rate, wallet, token);
IndividuallyCappedCrowdsale.initialize(msg.sender); IndividuallyCappedCrowdsale.initialize(_msgSender());
} }
} }
...@@ -4,7 +4,7 @@ import "../access/roles/MinterRole.sol"; ...@@ -4,7 +4,7 @@ import "../access/roles/MinterRole.sol";
contract MinterRoleMock is MinterRole { contract MinterRoleMock is MinterRole {
constructor() public { constructor() public {
MinterRole.initialize(msg.sender); MinterRole.initialize(_msgSender());
} }
function removeMinter(address account) public { function removeMinter(address account) public {
......
...@@ -4,6 +4,6 @@ import "../ownership/Ownable.sol"; ...@@ -4,6 +4,6 @@ import "../ownership/Ownable.sol";
contract OwnableMock is Ownable { contract OwnableMock is Ownable {
constructor() public { constructor() public {
Ownable.initialize(msg.sender); Ownable.initialize(_msgSender());
} }
} }
...@@ -6,6 +6,6 @@ import "../crowdsale/validation/PausableCrowdsale.sol"; ...@@ -6,6 +6,6 @@ import "../crowdsale/validation/PausableCrowdsale.sol";
contract PausableCrowdsaleImpl is PausableCrowdsale { contract PausableCrowdsaleImpl is PausableCrowdsale {
constructor (uint256 _rate, address payable _wallet, ERC20 _token) public { constructor (uint256 _rate, address payable _wallet, ERC20 _token) public {
Crowdsale.initialize(_rate, _wallet, _token); Crowdsale.initialize(_rate, _wallet, _token);
PausableCrowdsale.initialize(msg.sender); PausableCrowdsale.initialize(_msgSender());
} }
} }
...@@ -9,7 +9,7 @@ contract PausableMock is Pausable, PauserRoleMock { ...@@ -9,7 +9,7 @@ contract PausableMock is Pausable, PauserRoleMock {
uint256 public count; uint256 public count;
constructor () public { constructor () public {
Pausable.initialize(msg.sender); Pausable.initialize(_msgSender());
drasticMeasureTaken = false; drasticMeasureTaken = false;
count = 0; count = 0;
......
...@@ -4,7 +4,7 @@ import "../access/roles/PauserRole.sol"; ...@@ -4,7 +4,7 @@ import "../access/roles/PauserRole.sol";
contract PauserRoleMock is PauserRole { contract PauserRoleMock is PauserRole {
constructor () public { constructor () public {
PauserRole.initialize(msg.sender); PauserRole.initialize(_msgSender());
} }
function removePauser(address account) public { function removePauser(address account) public {
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
contract ReentrancyAttack { import "../GSN/Context.sol";
contract ReentrancyAttack is Context {
function callSender(bytes4 data) public { function callSender(bytes4 data) public {
// solhint-disable-next-line avoid-low-level-calls // solhint-disable-next-line avoid-low-level-calls
(bool success,) = msg.sender.call(abi.encodeWithSelector(data)); (bool success,) = _msgSender().call(abi.encodeWithSelector(data));
require(success); require(success, "ReentrancyAttack: failed call");
} }
} }
...@@ -4,6 +4,6 @@ import "../payment/escrow/RefundEscrow.sol"; ...@@ -4,6 +4,6 @@ import "../payment/escrow/RefundEscrow.sol";
contract RefundEscrowMock is RefundEscrow { contract RefundEscrowMock is RefundEscrow {
constructor(address payable beneficiary) public { constructor(address payable beneficiary) public {
RefundEscrow.initialize(beneficiary, msg.sender); RefundEscrow.initialize(beneficiary, _msgSender());
} }
} }
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "../GSN/Context.sol";
import "../token/ERC20/IERC20.sol"; import "../token/ERC20/IERC20.sol";
import "../token/ERC20/SafeERC20.sol"; import "../token/ERC20/SafeERC20.sol";
contract ERC20ReturnFalseMock { contract ERC20ReturnFalseMock is Context {
uint256 private _allowance; uint256 private _allowance;
// IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings, // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
...@@ -31,7 +32,7 @@ contract ERC20ReturnFalseMock { ...@@ -31,7 +32,7 @@ contract ERC20ReturnFalseMock {
} }
} }
contract ERC20ReturnTrueMock { contract ERC20ReturnTrueMock is Context {
mapping (address => uint256) private _allowances; mapping (address => uint256) private _allowances;
// IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings, // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
...@@ -54,7 +55,7 @@ contract ERC20ReturnTrueMock { ...@@ -54,7 +55,7 @@ contract ERC20ReturnTrueMock {
} }
function setAllowance(uint256 allowance_) public { function setAllowance(uint256 allowance_) public {
_allowances[msg.sender] = allowance_; _allowances[_msgSender()] = allowance_;
} }
function allowance(address owner, address) public view returns (uint256) { function allowance(address owner, address) public view returns (uint256) {
...@@ -62,7 +63,7 @@ contract ERC20ReturnTrueMock { ...@@ -62,7 +63,7 @@ contract ERC20ReturnTrueMock {
} }
} }
contract ERC20NoReturnMock { contract ERC20NoReturnMock is Context {
mapping (address => uint256) private _allowances; mapping (address => uint256) private _allowances;
// IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings, // IERC20's functions are not pure, but these mock implementations are: to prevent Solidity from issuing warnings,
...@@ -82,7 +83,7 @@ contract ERC20NoReturnMock { ...@@ -82,7 +83,7 @@ contract ERC20NoReturnMock {
} }
function setAllowance(uint256 allowance_) public { function setAllowance(uint256 allowance_) public {
_allowances[msg.sender] = allowance_; _allowances[_msgSender()] = allowance_;
} }
function allowance(address owner, address) public view returns (uint256) { function allowance(address owner, address) public view returns (uint256) {
...@@ -90,7 +91,7 @@ contract ERC20NoReturnMock { ...@@ -90,7 +91,7 @@ contract ERC20NoReturnMock {
} }
} }
contract SafeERC20Wrapper { contract SafeERC20Wrapper is Context {
using SafeERC20 for IERC20; using SafeERC20 for IERC20;
IERC20 private _token; IERC20 private _token;
......
...@@ -5,7 +5,7 @@ import "../examples/SampleCrowdsale.sol"; ...@@ -5,7 +5,7 @@ import "../examples/SampleCrowdsale.sol";
contract SampleCrowdsaleTokenMock is SampleCrowdsaleToken { contract SampleCrowdsaleTokenMock is SampleCrowdsaleToken {
constructor() public { constructor() public {
SampleCrowdsaleToken.initialize(msg.sender); SampleCrowdsaleToken.initialize(_msgSender());
} }
} }
......
...@@ -4,7 +4,7 @@ import "../ownership/Secondary.sol"; ...@@ -4,7 +4,7 @@ import "../ownership/Secondary.sol";
contract SecondaryMock is Secondary { contract SecondaryMock is Secondary {
constructor() public { constructor() public {
Secondary.initialize(msg.sender); Secondary.initialize(_msgSender());
} }
function onlyPrimaryMock() public view onlyPrimary { function onlyPrimaryMock() public view onlyPrimary {
......
...@@ -5,7 +5,7 @@ import "./SignerRoleMock.sol"; ...@@ -5,7 +5,7 @@ import "./SignerRoleMock.sol";
contract SignatureBouncerMock is SignatureBouncer, SignerRoleMock { contract SignatureBouncerMock is SignatureBouncer, SignerRoleMock {
constructor() public { constructor() public {
SignatureBouncer.initialize(msg.sender); SignatureBouncer.initialize(_msgSender());
} }
function checkValidSignature(address account, bytes memory signature) function checkValidSignature(address account, bytes memory signature)
......
...@@ -4,7 +4,7 @@ import "../access/roles/SignerRole.sol"; ...@@ -4,7 +4,7 @@ import "../access/roles/SignerRole.sol";
contract SignerRoleMock is SignerRole { contract SignerRoleMock is SignerRole {
constructor() public { constructor() public {
SignerRole.initialize(msg.sender); SignerRole.initialize(_msgSender());
} }
function removeSigner(address account) public { function removeSigner(address account) public {
......
...@@ -4,6 +4,6 @@ import "../examples/SimpleToken.sol"; ...@@ -4,6 +4,6 @@ import "../examples/SimpleToken.sol";
contract SimpleTokenMock is SimpleToken { contract SimpleTokenMock is SimpleToken {
constructor() public { constructor() public {
SimpleToken.initialize(msg.sender); SimpleToken.initialize(_msgSender());
} }
} }
...@@ -16,7 +16,7 @@ contract TokenVestingMock is TokenVesting { ...@@ -16,7 +16,7 @@ contract TokenVestingMock is TokenVesting {
cliffDuration, cliffDuration,
duration, duration,
revocable, revocable,
msg.sender _msgSender()
); );
} }
} }
...@@ -4,7 +4,7 @@ import "../access/roles/WhitelistAdminRole.sol"; ...@@ -4,7 +4,7 @@ import "../access/roles/WhitelistAdminRole.sol";
contract WhitelistAdminRoleMock is WhitelistAdminRole { contract WhitelistAdminRoleMock is WhitelistAdminRole {
constructor () public { constructor () public {
WhitelistAdminRole.initialize(msg.sender); WhitelistAdminRole.initialize(_msgSender());
} }
function removeWhitelistAdmin(address account) public { function removeWhitelistAdmin(address account) public {
......
...@@ -4,10 +4,9 @@ import "../token/ERC20/IERC20.sol"; ...@@ -4,10 +4,9 @@ import "../token/ERC20/IERC20.sol";
import "../crowdsale/validation/WhitelistCrowdsale.sol"; import "../crowdsale/validation/WhitelistCrowdsale.sol";
import "../crowdsale/Crowdsale.sol"; import "../crowdsale/Crowdsale.sol";
contract WhitelistCrowdsaleImpl is Crowdsale, WhitelistCrowdsale { contract WhitelistCrowdsaleImpl is Crowdsale, WhitelistCrowdsale {
constructor (uint256 _rate, address payable _wallet, IERC20 _token) public { constructor (uint256 _rate, address payable _wallet, IERC20 _token) public {
Crowdsale.initialize(_rate, _wallet, _token); Crowdsale.initialize(_rate, _wallet, _token);
WhitelistCrowdsale.initialize(msg.sender); WhitelistCrowdsale.initialize(_msgSender());
} }
} }
...@@ -4,7 +4,7 @@ import "../access/roles/WhitelistedRole.sol"; ...@@ -4,7 +4,7 @@ import "../access/roles/WhitelistedRole.sol";
contract WhitelistedRoleMock is WhitelistedRole { contract WhitelistedRoleMock is WhitelistedRole {
constructor() public { constructor() public {
WhitelistedRole.initialize(msg.sender); WhitelistedRole.initialize(_msgSender());
} }
function onlyWhitelistedMock() public view onlyWhitelisted { function onlyWhitelistedMock() public view onlyWhitelisted {
......
...@@ -2,12 +2,14 @@ pragma solidity ^0.5.2; ...@@ -2,12 +2,14 @@ pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../GSN/Context.sol";
/** /**
* @title Ownable * @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control * @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions". * functions, this simplifies the implementation of "user permissions".
*/ */
contract Ownable is Initializable { contract Ownable is Initializable, Context {
address private _owner; address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
...@@ -40,7 +42,7 @@ contract Ownable is Initializable { ...@@ -40,7 +42,7 @@ contract Ownable is Initializable {
* @return true if `msg.sender` is the owner of the contract. * @return true if `msg.sender` is the owner of the contract.
*/ */
function isOwner() public view returns (bool) { function isOwner() public view returns (bool) {
return msg.sender == _owner; return _msgSender() == _owner;
} }
/** /**
......
...@@ -2,11 +2,13 @@ pragma solidity ^0.5.2; ...@@ -2,11 +2,13 @@ pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../GSN/Context.sol";
/** /**
* @title Secondary * @title Secondary
* @dev A Secondary contract can only be used by its primary account (the one that created it) * @dev A Secondary contract can only be used by its primary account (the one that created it)
*/ */
contract Secondary is Initializable { contract Secondary is Initializable, Context {
address private _primary; address private _primary;
event PrimaryTransferred( event PrimaryTransferred(
...@@ -25,7 +27,7 @@ contract Secondary is Initializable { ...@@ -25,7 +27,7 @@ contract Secondary is Initializable {
* @dev Reverts if called from any account other than the primary. * @dev Reverts if called from any account other than the primary.
*/ */
modifier onlyPrimary() { modifier onlyPrimary() {
require(msg.sender == _primary); require(_msgSender() == _primary, "Secondary: caller is not the primary account");
_; _;
} }
......
...@@ -2,6 +2,7 @@ pragma solidity ^0.5.2; ...@@ -2,6 +2,7 @@ pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../GSN/Context.sol";
import "../math/SafeMath.sol"; import "../math/SafeMath.sol";
/** /**
...@@ -9,7 +10,7 @@ import "../math/SafeMath.sol"; ...@@ -9,7 +10,7 @@ import "../math/SafeMath.sol";
* @dev This contract can be used when payments need to be received by a group * @dev This contract can be used when payments need to be received by a group
* of people and split proportionately to some number of shares they own. * of people and split proportionately to some number of shares they own.
*/ */
contract PaymentSplitter is Initializable { contract PaymentSplitter is Initializable, Context {
using SafeMath for uint256; using SafeMath for uint256;
event PayeeAdded(address account, uint256 shares); event PayeeAdded(address account, uint256 shares);
...@@ -39,7 +40,7 @@ contract PaymentSplitter is Initializable { ...@@ -39,7 +40,7 @@ contract PaymentSplitter is Initializable {
* @dev payable fallback * @dev payable fallback
*/ */
function () external payable { function () external payable {
emit PaymentReceived(msg.sender, msg.value); emit PaymentReceived(_msgSender(), msg.value);
} }
/** /**
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../../GSN/Context.sol";
import "./IERC20.sol"; import "./IERC20.sol";
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
...@@ -16,12 +18,12 @@ import "../../math/SafeMath.sol"; ...@@ -16,12 +18,12 @@ import "../../math/SafeMath.sol";
* all accounts just by listening to said events. Note that this isn't required by the specification, and other * all accounts just by listening to said events. Note that this isn't required by the specification, and other
* compliant implementations may not do it. * compliant implementations may not do it.
*/ */
contract ERC20 is Initializable, IERC20 { contract ERC20 is Initializable, Context, IERC20 {
using SafeMath for uint256; using SafeMath for uint256;
mapping (address => uint256) private _balances; mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowed; mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply; uint256 private _totalSupply;
...@@ -48,7 +50,7 @@ contract ERC20 is Initializable, IERC20 { ...@@ -48,7 +50,7 @@ contract ERC20 is Initializable, IERC20 {
* @return A uint256 specifying the amount of tokens still available for the spender. * @return A uint256 specifying the amount of tokens still available for the spender.
*/ */
function allowance(address owner, address spender) public view returns (uint256) { function allowance(address owner, address spender) public view returns (uint256) {
return _allowed[owner][spender]; return _allowances[owner][spender];
} }
/** /**
...@@ -57,7 +59,7 @@ contract ERC20 is Initializable, IERC20 { ...@@ -57,7 +59,7 @@ contract ERC20 is Initializable, IERC20 {
* @param value The amount to be transferred. * @param value The amount to be transferred.
*/ */
function transfer(address to, uint256 value) public returns (bool) { function transfer(address to, uint256 value) public returns (bool) {
_transfer(msg.sender, to, value); _transfer(_msgSender(), to, value);
return true; return true;
} }
...@@ -71,7 +73,7 @@ contract ERC20 is Initializable, IERC20 { ...@@ -71,7 +73,7 @@ contract ERC20 is Initializable, IERC20 {
* @param value The amount of tokens to be spent. * @param value The amount of tokens to be spent.
*/ */
function approve(address spender, uint256 value) public returns (bool) { function approve(address spender, uint256 value) public returns (bool) {
_approve(msg.sender, spender, value); _approve(_msgSender(), spender, value);
return true; return true;
} }
...@@ -85,13 +87,13 @@ contract ERC20 is Initializable, IERC20 { ...@@ -85,13 +87,13 @@ contract ERC20 is Initializable, IERC20 {
*/ */
function transferFrom(address from, address to, uint256 value) public returns (bool) { function transferFrom(address from, address to, uint256 value) public returns (bool) {
_transfer(from, to, value); _transfer(from, to, value);
_approve(from, msg.sender, _allowed[from][msg.sender].sub(value)); _approve(from, _msgSender(), _allowances[from][_msgSender()].sub(value));
return true; return true;
} }
/** /**
* @dev Increase the amount of tokens that an owner allowed to a spender. * @dev Increase the amount of tokens that an owner allowed to a spender.
* approve should be called when _allowed[msg.sender][spender] == 0. To increment * approve should be called when _allowances[msg.sender][spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until * allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined) * the first transaction is mined)
* From MonolithDAO Token.sol * From MonolithDAO Token.sol
...@@ -100,13 +102,13 @@ contract ERC20 is Initializable, IERC20 { ...@@ -100,13 +102,13 @@ contract ERC20 is Initializable, IERC20 {
* @param addedValue The amount of tokens to increase the allowance by. * @param addedValue The amount of tokens to increase the allowance by.
*/ */
function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
_approve(msg.sender, spender, _allowed[msg.sender][spender].add(addedValue)); _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true; return true;
} }
/** /**
* @dev Decrease the amount of tokens that an owner allowed to a spender. * @dev Decrease the amount of tokens that an owner allowed to a spender.
* approve should be called when _allowed[msg.sender][spender] == 0. To decrement * approve should be called when _allowances[msg.sender][spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until * allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined) * the first transaction is mined)
* From MonolithDAO Token.sol * From MonolithDAO Token.sol
...@@ -115,7 +117,7 @@ contract ERC20 is Initializable, IERC20 { ...@@ -115,7 +117,7 @@ contract ERC20 is Initializable, IERC20 {
* @param subtractedValue The amount of tokens to decrease the allowance by. * @param subtractedValue The amount of tokens to decrease the allowance by.
*/ */
function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
_approve(msg.sender, spender, _allowed[msg.sender][spender].sub(subtractedValue)); _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue));
return true; return true;
} }
...@@ -172,7 +174,7 @@ contract ERC20 is Initializable, IERC20 { ...@@ -172,7 +174,7 @@ contract ERC20 is Initializable, IERC20 {
require(spender != address(0)); require(spender != address(0));
require(owner != address(0)); require(owner != address(0));
_allowed[owner][spender] = value; _allowances[owner][spender] = value;
emit Approval(owner, spender, value); emit Approval(owner, spender, value);
} }
...@@ -182,11 +184,11 @@ contract ERC20 is Initializable, IERC20 { ...@@ -182,11 +184,11 @@ contract ERC20 is Initializable, IERC20 {
* internal burn function. * internal burn function.
* Emits an Approval event (reflecting the reduced allowance). * Emits an Approval event (reflecting the reduced allowance).
* @param account The account whose tokens will be burnt. * @param account The account whose tokens will be burnt.
* @param value The amount that will be burnt. * @param amount The amount that will be burnt.
*/ */
function _burnFrom(address account, uint256 value) internal { function _burnFrom(address account, uint256 amount) internal {
_burn(account, value); _burn(account, amount);
_approve(account, msg.sender, _allowed[account][msg.sender].sub(value)); _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount));
} }
uint256[50] private ______gap; uint256[50] private ______gap;
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../../GSN/Context.sol";
import "./ERC20.sol"; import "./ERC20.sol";
/** /**
* @title Burnable Token * @title Burnable Token
* @dev Token that can be irreversibly burned (destroyed). * @dev Token that can be irreversibly burned (destroyed).
*/ */
contract ERC20Burnable is Initializable, ERC20 { contract ERC20Burnable is Initializable, Context, ERC20 {
/** /**
* @dev Burns a specific amount of tokens. * @dev Burns a specific amount of tokens.
* @param value The amount of token to be burned. * @param amount The amount of token to be burned.
*/ */
function burn(uint256 value) public { function burn(uint256 amount) public {
_burn(msg.sender, value); _burn(_msgSender(), amount);
} }
/** /**
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../../GSN/Context.sol";
import "./IERC721.sol"; import "./IERC721.sol";
import "./IERC721Receiver.sol"; import "./IERC721Receiver.sol";
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
...@@ -12,7 +14,7 @@ import "../../introspection/ERC165.sol"; ...@@ -12,7 +14,7 @@ import "../../introspection/ERC165.sol";
* @title ERC721 Non-Fungible Token Standard basic implementation * @title ERC721 Non-Fungible Token Standard basic implementation
* @dev see https://eips.ethereum.org/EIPS/eip-721 * @dev see https://eips.ethereum.org/EIPS/eip-721
*/ */
contract ERC721 is Initializable, ERC165, IERC721 { contract ERC721 is Initializable, Context, ERC165, IERC721 {
using SafeMath for uint256; using SafeMath for uint256;
using Address for address; using Address for address;
using Counters for Counters.Counter; using Counters for Counters.Counter;
...@@ -89,8 +91,11 @@ contract ERC721 is Initializable, ERC165, IERC721 { ...@@ -89,8 +91,11 @@ contract ERC721 is Initializable, ERC165, IERC721 {
*/ */
function approve(address to, uint256 tokenId) public { function approve(address to, uint256 tokenId) public {
address owner = ownerOf(tokenId); address owner = ownerOf(tokenId);
require(to != owner); require(to != owner, "ERC721: approval to current owner");
require(msg.sender == owner || isApprovedForAll(owner, msg.sender));
require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_tokenApprovals[tokenId] = to; _tokenApprovals[tokenId] = to;
emit Approval(owner, to, tokenId); emit Approval(owner, to, tokenId);
...@@ -114,9 +119,10 @@ contract ERC721 is Initializable, ERC165, IERC721 { ...@@ -114,9 +119,10 @@ contract ERC721 is Initializable, ERC165, IERC721 {
* @param approved representing the status of the approval to be set * @param approved representing the status of the approval to be set
*/ */
function setApprovalForAll(address to, bool approved) public { function setApprovalForAll(address to, bool approved) public {
require(to != msg.sender); require(to != _msgSender(), "ERC721: approve to caller");
_operatorApprovals[msg.sender][to] = approved;
emit ApprovalForAll(msg.sender, to, approved); _operatorApprovals[_msgSender()][to] = approved;
emit ApprovalForAll(_msgSender(), to, approved);
} }
/** /**
...@@ -138,7 +144,8 @@ contract ERC721 is Initializable, ERC165, IERC721 { ...@@ -138,7 +144,8 @@ contract ERC721 is Initializable, ERC165, IERC721 {
* @param tokenId uint256 ID of the token to be transferred * @param tokenId uint256 ID of the token to be transferred
*/ */
function transferFrom(address from, address to, uint256 tokenId) public { function transferFrom(address from, address to, uint256 tokenId) public {
require(_isApprovedOrOwner(msg.sender, tokenId)); //solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transferFrom(from, to, tokenId); _transferFrom(from, to, tokenId);
} }
...@@ -164,7 +171,7 @@ contract ERC721 is Initializable, ERC165, IERC721 { ...@@ -164,7 +171,7 @@ contract ERC721 is Initializable, ERC165, IERC721 {
* which is called upon a safe transfer, and return the magic value * which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted. * the transfer is reverted.
* Requires the msg.sender to be the owner, approved, or operator * Requires the _msgSender() to be the owner, approved, or operator
* @param from current owner of the token * @param from current owner of the token
* @param to address to receive the ownership of the given token ID * @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred * @param tokenId uint256 ID of the token to be transferred
...@@ -277,7 +284,7 @@ contract ERC721 is Initializable, ERC165, IERC721 { ...@@ -277,7 +284,7 @@ contract ERC721 is Initializable, ERC165, IERC721 {
return true; return true;
} }
bytes4 retval = IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data); bytes4 retval = IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data);
return (retval == _ERC721_RECEIVED); return (retval == _ERC721_RECEIVED);
} }
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../../GSN/Context.sol";
import "./ERC721.sol"; import "./ERC721.sol";
/** /**
* @title ERC721 Burnable Token * @title ERC721 Burnable Token
* @dev ERC721 Token that can be irreversibly burned (destroyed). * @dev ERC721 Token that can be irreversibly burned (destroyed).
*/ */
contract ERC721Burnable is Initializable, ERC721 { contract ERC721Burnable is Initializable, Context, ERC721 {
/** /**
* @dev Burns a specific ERC721 token. * @dev Burns a specific ERC721 token.
* @param tokenId uint256 id of the ERC721 token to be burned. * @param tokenId uint256 id of the ERC721 token to be burned.
*/ */
function burn(uint256 tokenId) public { function burn(uint256 tokenId) public {
require(_isApprovedOrOwner(msg.sender, tokenId)); //solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
_burn(tokenId); _burn(tokenId);
} }
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../../GSN/Context.sol";
import "./IERC721Enumerable.sol"; import "./IERC721Enumerable.sol";
import "./ERC721.sol"; import "./ERC721.sol";
import "../../introspection/ERC165.sol"; import "../../introspection/ERC165.sol";
...@@ -9,7 +11,7 @@ import "../../introspection/ERC165.sol"; ...@@ -9,7 +11,7 @@ import "../../introspection/ERC165.sol";
* @title ERC-721 Non-Fungible Token with optional enumeration extension logic * @title ERC-721 Non-Fungible Token with optional enumeration extension logic
* @dev See https://eips.ethereum.org/EIPS/eip-721 * @dev See https://eips.ethereum.org/EIPS/eip-721
*/ */
contract ERC721Enumerable is Initializable, ERC165, ERC721, IERC721Enumerable { contract ERC721Enumerable is Initializable, Context, ERC165, ERC721, IERC721Enumerable {
// Mapping from owner to list of owned token IDs // Mapping from owner to list of owned token IDs
mapping(address => uint256[]) private _ownedTokens; mapping(address => uint256[]) private _ownedTokens;
......
pragma solidity ^0.5.2; pragma solidity ^0.5.2;
import "@openzeppelin/upgrades/contracts/Initializable.sol"; import "@openzeppelin/upgrades/contracts/Initializable.sol";
import "../../GSN/Context.sol";
import "./ERC721.sol"; import "./ERC721.sol";
import "./IERC721Metadata.sol"; import "./IERC721Metadata.sol";
import "../../introspection/ERC165.sol"; import "../../introspection/ERC165.sol";
contract ERC721Metadata is Initializable, ERC165, ERC721, IERC721Metadata { contract ERC721Metadata is Initializable, Context, ERC165, ERC721, IERC721Metadata {
// Token name // Token name
string private _name; string private _name;
......
...@@ -482,13 +482,15 @@ ...@@ -482,13 +482,15 @@
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
"dev": true "dev": true
}, },
"debug": { "eth-lib": {
"version": "3.1.0", "version": "0.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
"dev": true, "dev": true,
"requires": { "requires": {
"ms": "2.0.0" "bn.js": "^4.11.6",
"elliptic": "^6.4.0",
"xhr-request-promise": "^0.1.2"
} }
}, },
"ethers": { "ethers": {
...@@ -520,12 +522,6 @@ ...@@ -520,12 +522,6 @@
"hash.js": "^1.0.0", "hash.js": "^1.0.0",
"inherits": "^2.0.1" "inherits": "^2.0.1"
} }
},
"setimmediate": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz",
"integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=",
"dev": true
} }
} }
}, },
...@@ -535,15 +531,6 @@ ...@@ -535,15 +531,6 @@
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==",
"dev": true "dev": true
}, },
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"dev": true,
"requires": {
"debug": "=3.1.0"
}
},
"fs-extra": { "fs-extra": {
"version": "8.1.0", "version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
...@@ -575,6 +562,12 @@ ...@@ -575,6 +562,12 @@
"integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==",
"dev": true "dev": true
}, },
"js-sha3": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz",
"integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=",
"dev": true
},
"jsonfile": { "jsonfile": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
...@@ -644,12 +637,6 @@ ...@@ -644,12 +637,6 @@
"integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==", "integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==",
"dev": true "dev": true
}, },
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
"dev": true
},
"swarm-js": { "swarm-js": {
"version": "0.1.39", "version": "0.1.39",
"resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.39.tgz", "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.39.tgz",
...@@ -670,6 +657,21 @@ ...@@ -670,6 +657,21 @@
"xhr-request-promise": "^0.1.2" "xhr-request-promise": "^0.1.2"
}, },
"dependencies": { "dependencies": {
"eth-lib": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz",
"integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==",
"dev": true,
"requires": {
"bn.js": "^4.11.6",
"elliptic": "^6.4.0",
"keccakjs": "^0.2.1",
"nano-json-stream-parser": "^0.1.2",
"servify": "^0.1.12",
"ws": "^3.0.0",
"xhr-request-promise": "^0.1.2"
}
},
"fs-extra": { "fs-extra": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
...@@ -702,6 +704,12 @@ ...@@ -702,6 +704,12 @@
"url-parse-lax": "^1.0.0", "url-parse-lax": "^1.0.0",
"url-to-options": "^1.0.1" "url-to-options": "^1.0.1"
} }
},
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
"dev": true
} }
} }
}, },
...@@ -888,17 +896,6 @@ ...@@ -888,17 +896,6 @@
"web3-utils": "1.2.1" "web3-utils": "1.2.1"
}, },
"dependencies": { "dependencies": {
"eth-lib": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
"integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
"dev": true,
"requires": {
"bn.js": "^4.11.6",
"elliptic": "^6.4.0",
"xhr-request-promise": "^0.1.2"
}
},
"uuid": { "uuid": {
"version": "3.3.2", "version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
...@@ -1030,19 +1027,6 @@ ...@@ -1030,19 +1027,6 @@
"randomhex": "0.1.5", "randomhex": "0.1.5",
"underscore": "1.9.1", "underscore": "1.9.1",
"utf8": "3.0.0" "utf8": "3.0.0"
},
"dependencies": {
"eth-lib": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
"integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
"dev": true,
"requires": {
"bn.js": "^4.11.6",
"elliptic": "^6.4.0",
"xhr-request-promise": "^0.1.2"
}
}
} }
}, },
"websocket": { "websocket": {
...@@ -1056,17 +1040,6 @@ ...@@ -1056,17 +1040,6 @@
"nan": "^2.14.0", "nan": "^2.14.0",
"typedarray-to-buffer": "^3.1.5", "typedarray-to-buffer": "^3.1.5",
"yaeti": "^0.0.6" "yaeti": "^0.0.6"
},
"dependencies": {
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
}
} }
} }
} }
...@@ -3897,12 +3870,12 @@ ...@@ -3897,12 +3870,12 @@
} }
}, },
"color-convert": { "color-convert": {
"version": "1.9.1", "version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true, "dev": true,
"requires": { "requires": {
"color-name": "^1.1.1" "color-name": "1.1.3"
} }
}, },
"color-name": { "color-name": {
...@@ -4076,28 +4049,6 @@ ...@@ -4076,28 +4049,6 @@
"vary": "^1" "vary": "^1"
} }
}, },
"coveralls": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.6.tgz",
"integrity": "sha512-Pgh4v3gCI4T/9VijVrm8Ym5v0OgjvGLKj3zTUwkvsCiwqae/p6VLzpsFNjQS2i6ewV7ef+DjFJ5TSKxYt/mCrA==",
"dev": true,
"requires": {
"growl": "~> 1.10.0",
"js-yaml": "^3.13.1",
"lcov-parse": "^0.0.10",
"log-driver": "^1.2.7",
"minimist": "^1.2.0",
"request": "^2.86.0"
},
"dependencies": {
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
}
}
},
"create-ecdh": { "create-ecdh": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
...@@ -6328,6 +6279,26 @@ ...@@ -6328,6 +6279,26 @@
} }
} }
}, },
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"dev": true,
"requires": {
"debug": "=3.1.0"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
}
}
},
"for-each": { "for-each": {
"version": "0.3.3", "version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
...@@ -9708,12 +9679,6 @@ ...@@ -9708,12 +9679,6 @@
"invert-kv": "^1.0.0" "invert-kv": "^1.0.0"
} }
}, },
"lcov-parse": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz",
"integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=",
"dev": true
},
"lead": { "lead": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
...@@ -10129,12 +10094,6 @@ ...@@ -10129,12 +10094,6 @@
"integrity": "sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=", "integrity": "sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=",
"dev": true "dev": true
}, },
"log-driver": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz",
"integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==",
"dev": true
},
"lowercase-keys": { "lowercase-keys": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
......
...@@ -44,9 +44,8 @@ ...@@ -44,9 +44,8 @@
"@openzeppelin/gsn-helpers": "^0.1.5", "@openzeppelin/gsn-helpers": "^0.1.5",
"@openzeppelin/gsn-provider": "^0.1.5", "@openzeppelin/gsn-provider": "^0.1.5",
"@openzeppelin/upgrades": "2.5.0", "@openzeppelin/upgrades": "2.5.0",
"chai": "^4.1.2", "chai": "^4.2.0",
"chai-bn": "^0.1.1", "chai-bn": "^0.1.1",
"coveralls": "^3.0.1",
"eslint": "^4.19.1", "eslint": "^4.19.1",
"eslint-config-standard": "^10.2.1", "eslint-config-standard": "^10.2.1",
"eslint-plugin-import": "^2.13.0", "eslint-plugin-import": "^2.13.0",
......
const { constants, expectEvent } = require('openzeppelin-test-helpers');
const { ZERO_ADDRESS } = constants;
const gsn = require('@openzeppelin/gsn-helpers');
const { fixSignature } = require('../helpers/sign');
const { utils: { toBN } } = require('web3');
const ERC721GSNRecipientMock = artifacts.require('ERC721GSNRecipientMock');
contract('ERC721GSNRecipient (integration)', function ([_, signer, sender]) {
const tokenId = '42';
beforeEach(async function () {
this.token = await ERC721GSNRecipientMock.new(signer);
});
async function testMintToken (token, from, tokenId, options = {}) {
const { tx } = await token.mint(tokenId, { from, ...options });
await expectEvent.inTransaction(tx, ERC721GSNRecipientMock, 'Transfer', { from: ZERO_ADDRESS, to: from, tokenId });
}
context('when called directly', function () {
it('sender can mint tokens', async function () {
await testMintToken(this.token, sender, tokenId);
});
});
context('when relay-called', function () {
beforeEach(async function () {
await gsn.fundRecipient(web3, { recipient: this.token.address });
});
it('sender can mint tokens', async function () {
const approveFunction = async (data) =>
fixSignature(
await web3.eth.sign(
web3.utils.soliditySha3(
// eslint-disable-next-line max-len
data.relayerAddress, data.from, data.encodedFunctionCall, toBN(data.txFee), toBN(data.gasPrice), toBN(data.gas), toBN(data.nonce), data.relayHubAddress, this.token.address
), signer
)
);
await testMintToken(this.token, sender, tokenId, { useGSN: true, approveFunction });
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment