Compare commits
22 Commits
v2.5.0-rc.
...
v3.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
| 9188faa2fa | |||
| e4d2830f1d | |||
| 19417c7cd5 | |||
| 5dfe7215a9 | |||
| 04a1b21874 | |||
| f905a14f5f | |||
| 4a531fe588 | |||
| 25dec297bf | |||
| 8e58cda8c3 | |||
| e7bded655b | |||
| 5f357d85de | |||
| 58a3368215 | |||
| 941d305044 | |||
| 1b938e39a8 | |||
| 7988c044e0 | |||
| 0ac83ce289 | |||
| 8975289c6b | |||
| 6102ddf675 | |||
| 5a67a69f80 | |||
| f2512a4f7b | |||
| 06be0ab39a | |||
| d775e315cc |
@ -1,14 +1,9 @@
|
||||
{
|
||||
"extends": "solhint:recommended",
|
||||
"rules": {
|
||||
"indent": ["error", 4],
|
||||
"func-order": "off",
|
||||
"bracket-align": "off",
|
||||
"compiler-fixed": "off",
|
||||
"no-simple-event-func-name": "off",
|
||||
"separate-by-one-line-in-contract": "off",
|
||||
"two-lines-top-level-separator": "off",
|
||||
"mark-callable-contracts": "off",
|
||||
"compiler-version": ["error", "^0.5.0"]
|
||||
"no-empty-blocks": "off",
|
||||
"compiler-version": ["error", "^0.6.0"]
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Changelog
|
||||
|
||||
## 2.5.0 (unreleased)
|
||||
## 2.5.0 (2020-02-04)
|
||||
|
||||
### New features
|
||||
* `SafeCast.toUintXX`: new library for integer downcasting, which allows for safe operation on smaller types (e.g. `uint32`) when combined with `SafeMath`. ([#1926](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1926))
|
||||
|
||||
@ -38,9 +38,9 @@ contract MyNFT is ERC721Full, ERC721Mintable {
|
||||
}
|
||||
```
|
||||
|
||||
_If you're new to smart contract development, head to [Developing Smart Contracts](https://docs.openzeppelin.com/contracts/learn::developing-smart-contracts) to learn about creating a new project and compiling your contracts._
|
||||
_If you're new to smart contract development, head to [Developing Smart Contracts](https://docs.openzeppelin.com/learn/developing-smart-contracts) to learn about creating a new project and compiling your contracts._
|
||||
|
||||
To keep your system secure, you should **always** use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself.
|
||||
To keep your system secure, you should **always** use the installed code as-is, and neither copy-paste it from online sources, nor modify it yourself. The library is designed so that only the contracts and functions you use are deployed, so you don't need to worry about it needlessly increasing gas costs.
|
||||
|
||||
## Learn More
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/*
|
||||
* @dev Provides information about the current execution context, including the
|
||||
@ -14,13 +14,12 @@ contract Context {
|
||||
// Empty internal constructor, to prevent people from mistakenly deploying
|
||||
// an instance of this contract, which should be used via inheritance.
|
||||
constructor () internal { }
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
|
||||
function _msgSender() internal view returns (address payable) {
|
||||
function _msgSender() internal view virtual returns (address payable) {
|
||||
return msg.sender;
|
||||
}
|
||||
|
||||
function _msgData() internal view returns (bytes memory) {
|
||||
function _msgData() internal view virtual returns (bytes memory) {
|
||||
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
|
||||
return msg.data;
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "./IRelayRecipient.sol";
|
||||
import "./IRelayHub.sol";
|
||||
@ -15,7 +15,7 @@ import "./Context.sol";
|
||||
* information on how to use the pre-built {GSNRecipientSignature} and
|
||||
* {GSNRecipientERC20Fee}, or how to write your own.
|
||||
*/
|
||||
contract GSNRecipient is IRelayRecipient, Context {
|
||||
abstract contract GSNRecipient is IRelayRecipient, Context {
|
||||
// Default RelayHub address, deployed on mainnet and all testnets at the same address
|
||||
address private _relayHub = 0xD216153c06E857cD7f72665E0aF1d7D82172F494;
|
||||
|
||||
@ -33,7 +33,7 @@ contract GSNRecipient is IRelayRecipient, Context {
|
||||
/**
|
||||
* @dev Returns the address of the {IRelayHub} contract for this recipient.
|
||||
*/
|
||||
function getHubAddr() public view returns (address) {
|
||||
function getHubAddr() public view override returns (address) {
|
||||
return _relayHub;
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ contract GSNRecipient is IRelayRecipient, Context {
|
||||
* IMPORTANT: After upgrading, the {GSNRecipient} will no longer be able to receive relayed calls from the old
|
||||
* {IRelayHub} instance. Additionally, all funds should be previously withdrawn via {_withdrawDeposits}.
|
||||
*/
|
||||
function _upgradeRelayHub(address newRelayHub) internal {
|
||||
function _upgradeRelayHub(address newRelayHub) internal virtual {
|
||||
address currentRelayHub = _relayHub;
|
||||
require(newRelayHub != address(0), "GSNRecipient: new RelayHub is the zero address");
|
||||
require(newRelayHub != currentRelayHub, "GSNRecipient: new RelayHub is the current one");
|
||||
@ -70,7 +70,7 @@ contract GSNRecipient is IRelayRecipient, Context {
|
||||
*
|
||||
* Derived contracts should expose this in an external interface with proper access control.
|
||||
*/
|
||||
function _withdrawDeposits(uint256 amount, address payable payee) internal {
|
||||
function _withdrawDeposits(uint256 amount, address payable payee) internal virtual {
|
||||
IRelayHub(_relayHub).withdraw(amount, payee);
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ contract GSNRecipient is IRelayRecipient, Context {
|
||||
*
|
||||
* IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.sender`, and use {_msgSender} instead.
|
||||
*/
|
||||
function _msgSender() internal view returns (address payable) {
|
||||
function _msgSender() internal view virtual override returns (address payable) {
|
||||
if (msg.sender != _relayHub) {
|
||||
return msg.sender;
|
||||
} else {
|
||||
@ -99,7 +99,7 @@ contract GSNRecipient is IRelayRecipient, Context {
|
||||
*
|
||||
* IMPORTANT: Contracts derived from {GSNRecipient} should never use `msg.data`, and use {_msgData} instead.
|
||||
*/
|
||||
function _msgData() internal view returns (bytes memory) {
|
||||
function _msgData() internal view virtual override returns (bytes memory) {
|
||||
if (msg.sender != _relayHub) {
|
||||
return msg.data;
|
||||
} else {
|
||||
@ -119,7 +119,7 @@ contract GSNRecipient is IRelayRecipient, Context {
|
||||
*
|
||||
* - the caller must be the `RelayHub` contract.
|
||||
*/
|
||||
function preRelayedCall(bytes calldata context) external returns (bytes32) {
|
||||
function preRelayedCall(bytes calldata context) external virtual override returns (bytes32) {
|
||||
require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub");
|
||||
return _preRelayedCall(context);
|
||||
}
|
||||
@ -131,7 +131,7 @@ contract GSNRecipient is IRelayRecipient, Context {
|
||||
* must implement this function with any relayed-call preprocessing they may wish to do.
|
||||
*
|
||||
*/
|
||||
function _preRelayedCall(bytes memory context) internal returns (bytes32);
|
||||
function _preRelayedCall(bytes memory context) internal virtual returns (bytes32);
|
||||
|
||||
/**
|
||||
* @dev See `IRelayRecipient.postRelayedCall`.
|
||||
@ -142,7 +142,7 @@ contract GSNRecipient is IRelayRecipient, Context {
|
||||
*
|
||||
* - the caller must be the `RelayHub` contract.
|
||||
*/
|
||||
function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external {
|
||||
function postRelayedCall(bytes calldata context, bool success, uint256 actualCharge, bytes32 preRetVal) external virtual override {
|
||||
require(msg.sender == getHubAddr(), "GSNRecipient: caller is not RelayHub");
|
||||
_postRelayedCall(context, success, actualCharge, preRetVal);
|
||||
}
|
||||
@ -154,7 +154,7 @@ contract GSNRecipient is IRelayRecipient, Context {
|
||||
* must implement this function with any relayed-call postprocessing they may wish to do.
|
||||
*
|
||||
*/
|
||||
function _postRelayedCall(bytes memory context, bool success, uint256 actualCharge, bytes32 preRetVal) internal;
|
||||
function _postRelayedCall(bytes memory context, bool success, uint256 actualCharge, bytes32 preRetVal) internal virtual;
|
||||
|
||||
/**
|
||||
* @dev Return this in acceptRelayedCall to proceed with the execution of a relayed call. Note that this contract
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "./GSNRecipient.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
@ -43,7 +43,7 @@ contract GSNRecipientERC20Fee is GSNRecipient {
|
||||
/**
|
||||
* @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 {
|
||||
function _mint(address account, uint256 amount) internal virtual {
|
||||
_token.mint(account, amount);
|
||||
}
|
||||
|
||||
@ -63,6 +63,8 @@ contract GSNRecipientERC20Fee is GSNRecipient {
|
||||
)
|
||||
external
|
||||
view
|
||||
virtual
|
||||
override
|
||||
returns (uint256, bytes memory)
|
||||
{
|
||||
if (_token.balanceOf(from) < maxPossibleCharge) {
|
||||
@ -78,7 +80,7 @@ contract GSNRecipientERC20Fee is GSNRecipient {
|
||||
* 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) {
|
||||
function _preRelayedCall(bytes memory context) internal virtual override returns (bytes32) {
|
||||
(address from, uint256 maxPossibleCharge) = abi.decode(context, (address, uint256));
|
||||
|
||||
// The maximum token charge is pre-charged from the user
|
||||
@ -88,7 +90,7 @@ contract GSNRecipientERC20Fee is GSNRecipient {
|
||||
/**
|
||||
* @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 {
|
||||
function _postRelayedCall(bytes memory context, bool, uint256 actualCharge, bytes32) internal virtual override {
|
||||
(address from, uint256 maxPossibleCharge, uint256 transactionFee, uint256 gasPrice) =
|
||||
abi.decode(context, (address, uint256, uint256, uint256));
|
||||
|
||||
@ -113,9 +115,7 @@ contract GSNRecipientERC20Fee is GSNRecipient {
|
||||
contract __unstable__ERC20PrimaryAdmin is ERC20, ERC20Detailed, Secondary {
|
||||
uint256 private constant UINT256_MAX = 2**256 - 1;
|
||||
|
||||
constructor(string memory name, string memory symbol, uint8 decimals) public ERC20Detailed(name, symbol, decimals) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
constructor(string memory name, string memory symbol, uint8 decimals) public ERC20Detailed(name, symbol, decimals) { }
|
||||
|
||||
// The primary account (GSNRecipientERC20Fee) can mint tokens
|
||||
function mint(address account, uint256 amount) public onlyPrimary {
|
||||
@ -123,7 +123,7 @@ contract __unstable__ERC20PrimaryAdmin is ERC20, ERC20Detailed, Secondary {
|
||||
}
|
||||
|
||||
// The primary account has 'infinite' allowance for all token holders
|
||||
function allowance(address owner, address spender) public view returns (uint256) {
|
||||
function allowance(address owner, address spender) public view override(ERC20, IERC20) returns (uint256) {
|
||||
if (spender == primary()) {
|
||||
return UINT256_MAX;
|
||||
} else {
|
||||
@ -132,7 +132,7 @@ contract __unstable__ERC20PrimaryAdmin is ERC20, ERC20Detailed, Secondary {
|
||||
}
|
||||
|
||||
// Allowance for the primary account cannot be changed (it is always 'infinite')
|
||||
function _approve(address owner, address spender, uint256 value) internal {
|
||||
function _approve(address owner, address spender, uint256 value) internal override {
|
||||
if (spender == primary()) {
|
||||
return;
|
||||
} else {
|
||||
@ -140,7 +140,7 @@ contract __unstable__ERC20PrimaryAdmin is ERC20, ERC20Detailed, Secondary {
|
||||
}
|
||||
}
|
||||
|
||||
function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
|
||||
function transferFrom(address sender, address recipient, uint256 amount) public override(ERC20, IERC20) returns (bool) {
|
||||
if (recipient == primary()) {
|
||||
_transfer(sender, recipient, amount);
|
||||
return true;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "./GSNRecipient.sol";
|
||||
import "../cryptography/ECDSA.sol";
|
||||
@ -42,6 +42,8 @@ contract GSNRecipientSignature is GSNRecipient {
|
||||
)
|
||||
external
|
||||
view
|
||||
virtual
|
||||
override
|
||||
returns (uint256, bytes memory)
|
||||
{
|
||||
bytes memory blob = abi.encodePacked(
|
||||
@ -62,11 +64,7 @@ contract GSNRecipientSignature is GSNRecipient {
|
||||
}
|
||||
}
|
||||
|
||||
function _preRelayedCall(bytes memory) internal returns (bytes32) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
function _preRelayedCall(bytes memory) internal virtual override returns (bytes32) { }
|
||||
|
||||
function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal virtual override { }
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @dev Interface for `RelayHub`, the core contract of the GSN. Users should not need to interact with this contract
|
||||
@ -207,7 +207,7 @@ interface IRelayHub {
|
||||
event CanRelayFailed(address indexed relay, address indexed from, address indexed to, bytes4 selector, uint256 reason);
|
||||
|
||||
/**
|
||||
* @dev Emitted when a transaction is relayed.
|
||||
* @dev Emitted when a transaction is relayed.
|
||||
* Useful when monitoring a relay's operation and relayed calls to a contract
|
||||
*
|
||||
* Note that the actual encoded function might be reverted: this is indicated in the `status` parameter.
|
||||
@ -236,7 +236,7 @@ interface IRelayHub {
|
||||
*/
|
||||
function maxPossibleCharge(uint256 relayedCallStipend, uint256 gasPrice, uint256 transactionFee) external view returns (uint256);
|
||||
|
||||
// Relay penalization.
|
||||
// Relay penalization.
|
||||
// Any account can penalize relays, removing them from the system immediately, and rewarding the
|
||||
// reporter with half of the relay's stake. The other half is burned so that, even if the relay penalizes itself, it
|
||||
// still loses half of its stake.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @dev Base interface for a contract that will be called via the GSN from {IRelayHub}.
|
||||
|
||||
@ -5,17 +5,3 @@ NOTE: This page is incomplete. We're working to improve it for the next release.
|
||||
== Library
|
||||
|
||||
{{Roles}}
|
||||
|
||||
== Roles
|
||||
|
||||
{{CapperRole}}
|
||||
|
||||
{{MinterRole}}
|
||||
|
||||
{{PauserRole}}
|
||||
|
||||
{{SignerRole}}
|
||||
|
||||
{{WhitelistAdminRole}}
|
||||
|
||||
{{WhitelistedRole}}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @title Roles
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../GSN/Context.sol";
|
||||
import "../Roles.sol";
|
||||
|
||||
contract CapperRole is Context {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event CapperAdded(address indexed account);
|
||||
event CapperRemoved(address indexed account);
|
||||
|
||||
Roles.Role private _cappers;
|
||||
|
||||
constructor () internal {
|
||||
_addCapper(_msgSender());
|
||||
}
|
||||
|
||||
modifier onlyCapper() {
|
||||
require(isCapper(_msgSender()), "CapperRole: caller does not have the Capper role");
|
||||
_;
|
||||
}
|
||||
|
||||
function isCapper(address account) public view returns (bool) {
|
||||
return _cappers.has(account);
|
||||
}
|
||||
|
||||
function addCapper(address account) public onlyCapper {
|
||||
_addCapper(account);
|
||||
}
|
||||
|
||||
function renounceCapper() public {
|
||||
_removeCapper(_msgSender());
|
||||
}
|
||||
|
||||
function _addCapper(address account) internal {
|
||||
_cappers.add(account);
|
||||
emit CapperAdded(account);
|
||||
}
|
||||
|
||||
function _removeCapper(address account) internal {
|
||||
_cappers.remove(account);
|
||||
emit CapperRemoved(account);
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../GSN/Context.sol";
|
||||
import "../Roles.sol";
|
||||
|
||||
contract MinterRole is Context {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event MinterAdded(address indexed account);
|
||||
event MinterRemoved(address indexed account);
|
||||
|
||||
Roles.Role private _minters;
|
||||
|
||||
constructor () internal {
|
||||
_addMinter(_msgSender());
|
||||
}
|
||||
|
||||
modifier onlyMinter() {
|
||||
require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role");
|
||||
_;
|
||||
}
|
||||
|
||||
function isMinter(address account) public view returns (bool) {
|
||||
return _minters.has(account);
|
||||
}
|
||||
|
||||
function addMinter(address account) public onlyMinter {
|
||||
_addMinter(account);
|
||||
}
|
||||
|
||||
function renounceMinter() public {
|
||||
_removeMinter(_msgSender());
|
||||
}
|
||||
|
||||
function _addMinter(address account) internal {
|
||||
_minters.add(account);
|
||||
emit MinterAdded(account);
|
||||
}
|
||||
|
||||
function _removeMinter(address account) internal {
|
||||
_minters.remove(account);
|
||||
emit MinterRemoved(account);
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../GSN/Context.sol";
|
||||
import "../Roles.sol";
|
||||
|
||||
contract PauserRole is Context {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event PauserAdded(address indexed account);
|
||||
event PauserRemoved(address indexed account);
|
||||
|
||||
Roles.Role private _pausers;
|
||||
|
||||
constructor () internal {
|
||||
_addPauser(_msgSender());
|
||||
}
|
||||
|
||||
modifier onlyPauser() {
|
||||
require(isPauser(_msgSender()), "PauserRole: caller does not have the Pauser role");
|
||||
_;
|
||||
}
|
||||
|
||||
function isPauser(address account) public view returns (bool) {
|
||||
return _pausers.has(account);
|
||||
}
|
||||
|
||||
function addPauser(address account) public onlyPauser {
|
||||
_addPauser(account);
|
||||
}
|
||||
|
||||
function renouncePauser() public {
|
||||
_removePauser(_msgSender());
|
||||
}
|
||||
|
||||
function _addPauser(address account) internal {
|
||||
_pausers.add(account);
|
||||
emit PauserAdded(account);
|
||||
}
|
||||
|
||||
function _removePauser(address account) internal {
|
||||
_pausers.remove(account);
|
||||
emit PauserRemoved(account);
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../GSN/Context.sol";
|
||||
import "../Roles.sol";
|
||||
|
||||
contract SignerRole is Context {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event SignerAdded(address indexed account);
|
||||
event SignerRemoved(address indexed account);
|
||||
|
||||
Roles.Role private _signers;
|
||||
|
||||
constructor () internal {
|
||||
_addSigner(_msgSender());
|
||||
}
|
||||
|
||||
modifier onlySigner() {
|
||||
require(isSigner(_msgSender()), "SignerRole: caller does not have the Signer role");
|
||||
_;
|
||||
}
|
||||
|
||||
function isSigner(address account) public view returns (bool) {
|
||||
return _signers.has(account);
|
||||
}
|
||||
|
||||
function addSigner(address account) public onlySigner {
|
||||
_addSigner(account);
|
||||
}
|
||||
|
||||
function renounceSigner() public {
|
||||
_removeSigner(_msgSender());
|
||||
}
|
||||
|
||||
function _addSigner(address account) internal {
|
||||
_signers.add(account);
|
||||
emit SignerAdded(account);
|
||||
}
|
||||
|
||||
function _removeSigner(address account) internal {
|
||||
_signers.remove(account);
|
||||
emit SignerRemoved(account);
|
||||
}
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../GSN/Context.sol";
|
||||
import "../Roles.sol";
|
||||
|
||||
/**
|
||||
* @title WhitelistAdminRole
|
||||
* @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts.
|
||||
*/
|
||||
contract WhitelistAdminRole is Context {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event WhitelistAdminAdded(address indexed account);
|
||||
event WhitelistAdminRemoved(address indexed account);
|
||||
|
||||
Roles.Role private _whitelistAdmins;
|
||||
|
||||
constructor () internal {
|
||||
_addWhitelistAdmin(_msgSender());
|
||||
}
|
||||
|
||||
modifier onlyWhitelistAdmin() {
|
||||
require(isWhitelistAdmin(_msgSender()), "WhitelistAdminRole: caller does not have the WhitelistAdmin role");
|
||||
_;
|
||||
}
|
||||
|
||||
function isWhitelistAdmin(address account) public view returns (bool) {
|
||||
return _whitelistAdmins.has(account);
|
||||
}
|
||||
|
||||
function addWhitelistAdmin(address account) public onlyWhitelistAdmin {
|
||||
_addWhitelistAdmin(account);
|
||||
}
|
||||
|
||||
function renounceWhitelistAdmin() public {
|
||||
_removeWhitelistAdmin(_msgSender());
|
||||
}
|
||||
|
||||
function _addWhitelistAdmin(address account) internal {
|
||||
_whitelistAdmins.add(account);
|
||||
emit WhitelistAdminAdded(account);
|
||||
}
|
||||
|
||||
function _removeWhitelistAdmin(address account) internal {
|
||||
_whitelistAdmins.remove(account);
|
||||
emit WhitelistAdminRemoved(account);
|
||||
}
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../GSN/Context.sol";
|
||||
import "../Roles.sol";
|
||||
import "./WhitelistAdminRole.sol";
|
||||
|
||||
/**
|
||||
* @title WhitelistedRole
|
||||
* @dev Whitelisted accounts have been approved by a WhitelistAdmin to perform certain actions (e.g. participate in a
|
||||
* 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.
|
||||
*/
|
||||
contract WhitelistedRole is Context, WhitelistAdminRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event WhitelistedAdded(address indexed account);
|
||||
event WhitelistedRemoved(address indexed account);
|
||||
|
||||
Roles.Role private _whitelisteds;
|
||||
|
||||
modifier onlyWhitelisted() {
|
||||
require(isWhitelisted(_msgSender()), "WhitelistedRole: caller does not have the Whitelisted role");
|
||||
_;
|
||||
}
|
||||
|
||||
function isWhitelisted(address account) public view returns (bool) {
|
||||
return _whitelisteds.has(account);
|
||||
}
|
||||
|
||||
function addWhitelisted(address account) public onlyWhitelistAdmin {
|
||||
_addWhitelisted(account);
|
||||
}
|
||||
|
||||
function removeWhitelisted(address account) public onlyWhitelistAdmin {
|
||||
_removeWhitelisted(account);
|
||||
}
|
||||
|
||||
function renounceWhitelisted() public {
|
||||
_removeWhitelisted(_msgSender());
|
||||
}
|
||||
|
||||
function _addWhitelisted(address account) internal {
|
||||
_whitelisteds.add(account);
|
||||
emit WhitelistedAdded(account);
|
||||
}
|
||||
|
||||
function _removeWhitelisted(address account) internal {
|
||||
_whitelisteds.remove(account);
|
||||
emit WhitelistedRemoved(account);
|
||||
}
|
||||
}
|
||||
@ -1,200 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../GSN/Context.sol";
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
import "../utils/ReentrancyGuard.sol";
|
||||
|
||||
/**
|
||||
* @title Crowdsale
|
||||
* @dev Crowdsale is a base contract for managing a token crowdsale,
|
||||
* allowing investors to purchase tokens with ether. This contract implements
|
||||
* such functionality in its most fundamental form and can be extended to provide additional
|
||||
* functionality and/or custom behavior.
|
||||
* The external interface represents the basic interface for purchasing tokens, and conforms
|
||||
* the base architecture for crowdsales. It is *not* intended to be modified / overridden.
|
||||
* The internal interface conforms the extensible and modifiable surface of crowdsales. Override
|
||||
* the methods to add functionality. Consider using 'super' where appropriate to concatenate
|
||||
* behavior.
|
||||
*/
|
||||
contract Crowdsale is Context, ReentrancyGuard {
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
// The token being sold
|
||||
IERC20 private _token;
|
||||
|
||||
// Address where funds are collected
|
||||
address payable private _wallet;
|
||||
|
||||
// How many token units a buyer gets per wei.
|
||||
// The rate is the conversion between wei and the smallest and indivisible token unit.
|
||||
// So, if you are using a rate of 1 with a ERC20Detailed token with 3 decimals called TOK
|
||||
// 1 wei will give you 1 unit, or 0.001 TOK.
|
||||
uint256 private _rate;
|
||||
|
||||
// Amount of wei raised
|
||||
uint256 private _weiRaised;
|
||||
|
||||
/**
|
||||
* Event for token purchase logging
|
||||
* @param purchaser who paid for the tokens
|
||||
* @param beneficiary who got the tokens
|
||||
* @param value weis paid for purchase
|
||||
* @param amount amount of tokens purchased
|
||||
*/
|
||||
event TokensPurchased(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
|
||||
|
||||
/**
|
||||
* @param rate Number of token units a buyer gets per wei
|
||||
* @dev The rate is the conversion between wei and the smallest and indivisible
|
||||
* token unit. So, if you are using a rate of 1 with a ERC20Detailed token
|
||||
* with 3 decimals called TOK, 1 wei will give you 1 unit, or 0.001 TOK.
|
||||
* @param wallet Address where collected funds will be forwarded to
|
||||
* @param token Address of the token being sold
|
||||
*/
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token) public {
|
||||
require(rate > 0, "Crowdsale: rate is 0");
|
||||
require(wallet != address(0), "Crowdsale: wallet is the zero address");
|
||||
require(address(token) != address(0), "Crowdsale: token is the zero address");
|
||||
|
||||
_rate = rate;
|
||||
_wallet = wallet;
|
||||
_token = token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev fallback function ***DO NOT OVERRIDE***
|
||||
* Note that other contracts will transfer funds with a base gas stipend
|
||||
* of 2300, which is not enough to call buyTokens. Consider calling
|
||||
* buyTokens directly when purchasing tokens from a contract.
|
||||
*/
|
||||
function () external payable {
|
||||
buyTokens(_msgSender());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the token being sold.
|
||||
*/
|
||||
function token() public view returns (IERC20) {
|
||||
return _token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the address where funds are collected.
|
||||
*/
|
||||
function wallet() public view returns (address payable) {
|
||||
return _wallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of token units a buyer gets per wei.
|
||||
*/
|
||||
function rate() public view returns (uint256) {
|
||||
return _rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the amount of wei raised.
|
||||
*/
|
||||
function weiRaised() public view returns (uint256) {
|
||||
return _weiRaised;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev low level token purchase ***DO NOT OVERRIDE***
|
||||
* This function has a non-reentrancy guard, so it shouldn't be called by
|
||||
* another `nonReentrant` function.
|
||||
* @param beneficiary Recipient of the token purchase
|
||||
*/
|
||||
function buyTokens(address beneficiary) public nonReentrant payable {
|
||||
uint256 weiAmount = msg.value;
|
||||
_preValidatePurchase(beneficiary, weiAmount);
|
||||
|
||||
// calculate token amount to be created
|
||||
uint256 tokens = _getTokenAmount(weiAmount);
|
||||
|
||||
// update state
|
||||
_weiRaised = _weiRaised.add(weiAmount);
|
||||
|
||||
_processPurchase(beneficiary, tokens);
|
||||
emit TokensPurchased(_msgSender(), beneficiary, weiAmount, tokens);
|
||||
|
||||
_updatePurchasingState(beneficiary, weiAmount);
|
||||
|
||||
_forwardFunds();
|
||||
_postValidatePurchase(beneficiary, weiAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met.
|
||||
* Use `super` in contracts that inherit from Crowdsale to extend their validations.
|
||||
* Example from CappedCrowdsale.sol's _preValidatePurchase method:
|
||||
* super._preValidatePurchase(beneficiary, weiAmount);
|
||||
* require(weiRaised().add(weiAmount) <= cap);
|
||||
* @param beneficiary Address performing the token purchase
|
||||
* @param weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
|
||||
require(beneficiary != address(0), "Crowdsale: beneficiary is the zero address");
|
||||
require(weiAmount != 0, "Crowdsale: weiAmount is 0");
|
||||
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid
|
||||
* conditions are not met.
|
||||
* @param beneficiary Address performing the token purchase
|
||||
* @param weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _postValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends
|
||||
* its tokens.
|
||||
* @param beneficiary Address performing the token purchase
|
||||
* @param tokenAmount Number of tokens to be emitted
|
||||
*/
|
||||
function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
|
||||
_token.safeTransfer(beneficiary, tokenAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Executed when a purchase has been validated and is ready to be executed. Doesn't necessarily emit/send
|
||||
* tokens.
|
||||
* @param beneficiary Address receiving the tokens
|
||||
* @param tokenAmount Number of tokens to be purchased
|
||||
*/
|
||||
function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
|
||||
_deliverTokens(beneficiary, tokenAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Override for extensions that require an internal state to check for validity (current user contributions,
|
||||
* etc.)
|
||||
* @param beneficiary Address receiving the tokens
|
||||
* @param weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Override to extend the way in which ether is converted to tokens.
|
||||
* @param weiAmount Value in wei to be converted into tokens
|
||||
* @return Number of tokens that can be purchased with the specified _weiAmount
|
||||
*/
|
||||
function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
|
||||
return weiAmount.mul(_rate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Determines how ETH is stored/forwarded on purchases.
|
||||
*/
|
||||
function _forwardFunds() internal {
|
||||
_wallet.transfer(msg.value);
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
= Crowdsales
|
||||
|
||||
NOTE: This page is incomplete. We're working to improve it for the next release. Stay tuned!
|
||||
|
||||
== Core
|
||||
|
||||
{{Crowdsale}}
|
||||
|
||||
== Emission
|
||||
|
||||
{{AllowanceCrowdsale}}
|
||||
|
||||
{{MintedCrowdsale}}
|
||||
|
||||
== Validation
|
||||
|
||||
{{CappedCrowdsale}}
|
||||
|
||||
{{IndividuallyCappedCrowdsale}}
|
||||
|
||||
{{PausableCrowdsale}}
|
||||
|
||||
{{TimedCrowdsale}}
|
||||
|
||||
{{WhitelistCrowdsale}}
|
||||
|
||||
== Distribution
|
||||
|
||||
{{FinalizableCrowdsale}}
|
||||
|
||||
{{PostDeliveryCrowdsale}}
|
||||
|
||||
{{RefundableCrowdsale}}
|
||||
|
||||
{{RefundablePostDeliveryCrowdsale}}
|
||||
@ -1,51 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
|
||||
/**
|
||||
* @title FinalizableCrowdsale
|
||||
* @dev Extension of TimedCrowdsale with a one-off finalization action, where one
|
||||
* can do extra work after finishing.
|
||||
*/
|
||||
contract FinalizableCrowdsale is TimedCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
bool private _finalized;
|
||||
|
||||
event CrowdsaleFinalized();
|
||||
|
||||
constructor () internal {
|
||||
_finalized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the crowdsale is finalized, false otherwise.
|
||||
*/
|
||||
function finalized() public view returns (bool) {
|
||||
return _finalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Must be called after crowdsale ends, to do some extra finalization
|
||||
* work. Calls the contract's finalization function.
|
||||
*/
|
||||
function finalize() public {
|
||||
require(!_finalized, "FinalizableCrowdsale: already finalized");
|
||||
require(hasClosed(), "FinalizableCrowdsale: not closed");
|
||||
|
||||
_finalized = true;
|
||||
|
||||
_finalization();
|
||||
emit CrowdsaleFinalized();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Can be overridden to add finalization logic. The overriding function
|
||||
* should call super._finalization() to ensure the chain of finalization is
|
||||
* executed entirely.
|
||||
*/
|
||||
function _finalization() internal {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../../ownership/Secondary.sol";
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
|
||||
/**
|
||||
* @title PostDeliveryCrowdsale
|
||||
* @dev Crowdsale that locks tokens from withdrawal until it ends.
|
||||
*/
|
||||
contract PostDeliveryCrowdsale is TimedCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
mapping(address => uint256) private _balances;
|
||||
__unstable__TokenVault private _vault;
|
||||
|
||||
constructor() public {
|
||||
_vault = new __unstable__TokenVault();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Withdraw tokens only after crowdsale ends.
|
||||
* @param beneficiary Whose tokens will be withdrawn.
|
||||
*/
|
||||
function withdrawTokens(address beneficiary) public {
|
||||
require(hasClosed(), "PostDeliveryCrowdsale: not closed");
|
||||
uint256 amount = _balances[beneficiary];
|
||||
require(amount > 0, "PostDeliveryCrowdsale: beneficiary is not due any tokens");
|
||||
|
||||
_balances[beneficiary] = 0;
|
||||
_vault.transfer(token(), beneficiary, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the balance of an account.
|
||||
*/
|
||||
function balanceOf(address account) public view returns (uint256) {
|
||||
return _balances[account];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides parent by storing due balances, and delivering tokens to the vault instead of the end user. This
|
||||
* ensures that the tokens will be available by the time they are withdrawn (which may not be the case if
|
||||
* `_deliverTokens` was called later).
|
||||
* @param beneficiary Token purchaser
|
||||
* @param tokenAmount Amount of tokens purchased
|
||||
*/
|
||||
function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
|
||||
_balances[beneficiary] = _balances[beneficiary].add(tokenAmount);
|
||||
_deliverTokens(address(_vault), tokenAmount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @title __unstable__TokenVault
|
||||
* @dev Similar to an Escrow for tokens, this contract allows its primary account to spend its tokens as it sees fit.
|
||||
* This contract is an internal helper for PostDeliveryCrowdsale, and should not be used outside of this context.
|
||||
*/
|
||||
// solhint-disable-next-line contract-name-camelcase
|
||||
contract __unstable__TokenVault is Secondary {
|
||||
function transfer(IERC20 token, address to, uint256 amount) public onlyPrimary {
|
||||
token.transfer(to, amount);
|
||||
}
|
||||
}
|
||||
@ -1,83 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../GSN/Context.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
import "./FinalizableCrowdsale.sol";
|
||||
import "../../payment/escrow/RefundEscrow.sol";
|
||||
|
||||
/**
|
||||
* @title RefundableCrowdsale
|
||||
* @dev Extension of `FinalizableCrowdsale` contract that adds a funding goal, and the possibility of users
|
||||
* getting a refund if goal is not met.
|
||||
*
|
||||
* Deprecated, use `RefundablePostDeliveryCrowdsale` instead. Note that if you allow tokens to be traded before the goal
|
||||
* is met, then an attack is possible in which the attacker purchases tokens from the crowdsale and when they sees that
|
||||
* 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.
|
||||
*/
|
||||
contract RefundableCrowdsale is Context, FinalizableCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
// minimum amount of funds to be raised in weis
|
||||
uint256 private _goal;
|
||||
|
||||
// refund escrow used to hold funds while crowdsale is running
|
||||
RefundEscrow private _escrow;
|
||||
|
||||
/**
|
||||
* @dev Constructor, creates RefundEscrow.
|
||||
* @param goal Funding goal
|
||||
*/
|
||||
constructor (uint256 goal) public {
|
||||
require(goal > 0, "RefundableCrowdsale: goal is 0");
|
||||
_escrow = new RefundEscrow(wallet());
|
||||
_goal = goal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return minimum amount of funds to be raised in wei.
|
||||
*/
|
||||
function goal() public view returns (uint256) {
|
||||
return _goal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Investors can claim refunds here if crowdsale is unsuccessful.
|
||||
* @param refundee Whose refund will be claimed.
|
||||
*/
|
||||
function claimRefund(address payable refundee) public {
|
||||
require(finalized(), "RefundableCrowdsale: not finalized");
|
||||
require(!goalReached(), "RefundableCrowdsale: goal reached");
|
||||
|
||||
_escrow.withdraw(refundee);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks whether funding goal was reached.
|
||||
* @return Whether funding goal was reached
|
||||
*/
|
||||
function goalReached() public view returns (bool) {
|
||||
return weiRaised() >= _goal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Escrow finalization task, called when finalize() is called.
|
||||
*/
|
||||
function _finalization() internal {
|
||||
if (goalReached()) {
|
||||
_escrow.close();
|
||||
_escrow.beneficiaryWithdraw();
|
||||
} else {
|
||||
_escrow.enableRefunds();
|
||||
}
|
||||
|
||||
super._finalization();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides Crowdsale fund forwarding, sending funds to escrow.
|
||||
*/
|
||||
function _forwardFunds() internal {
|
||||
_escrow.deposit.value(msg.value)(_msgSender());
|
||||
}
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "./RefundableCrowdsale.sol";
|
||||
import "./PostDeliveryCrowdsale.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title RefundablePostDeliveryCrowdsale
|
||||
* @dev Extension of RefundableCrowdsale contract that only delivers the tokens
|
||||
* once the crowdsale has closed and the goal met, preventing refunds to be issued
|
||||
* to token holders.
|
||||
*/
|
||||
contract RefundablePostDeliveryCrowdsale is RefundableCrowdsale, PostDeliveryCrowdsale {
|
||||
function withdrawTokens(address beneficiary) public {
|
||||
require(finalized(), "RefundablePostDeliveryCrowdsale: not finalized");
|
||||
require(goalReached(), "RefundablePostDeliveryCrowdsale: goal not reached");
|
||||
|
||||
super.withdrawTokens(beneficiary);
|
||||
}
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Crowdsale.sol";
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
import "../../token/ERC20/SafeERC20.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../../math/Math.sol";
|
||||
|
||||
/**
|
||||
* @title AllowanceCrowdsale
|
||||
* @dev Extension of Crowdsale where tokens are held by a wallet, which approves an allowance to the crowdsale.
|
||||
*/
|
||||
contract AllowanceCrowdsale is Crowdsale {
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
address private _tokenWallet;
|
||||
|
||||
/**
|
||||
* @dev Constructor, takes token wallet address.
|
||||
* @param tokenWallet Address holding the tokens, which has approved allowance to the crowdsale.
|
||||
*/
|
||||
constructor (address tokenWallet) public {
|
||||
require(tokenWallet != address(0), "AllowanceCrowdsale: token wallet is the zero address");
|
||||
_tokenWallet = tokenWallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the address of the wallet that will hold the tokens.
|
||||
*/
|
||||
function tokenWallet() public view returns (address) {
|
||||
return _tokenWallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks the amount of tokens left in the allowance.
|
||||
* @return Amount of tokens left in the allowance
|
||||
*/
|
||||
function remainingTokens() public view returns (uint256) {
|
||||
return Math.min(token().balanceOf(_tokenWallet), token().allowance(_tokenWallet, address(this)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides parent behavior by transferring tokens from wallet.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param tokenAmount Amount of tokens purchased
|
||||
*/
|
||||
function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
|
||||
token().safeTransferFrom(_tokenWallet, beneficiary, tokenAmount);
|
||||
}
|
||||
}
|
||||
@ -1,24 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Crowdsale.sol";
|
||||
import "../../token/ERC20/ERC20Mintable.sol";
|
||||
|
||||
/**
|
||||
* @title MintedCrowdsale
|
||||
* @dev Extension of Crowdsale contract whose tokens are minted in each purchase.
|
||||
* Token ownership should be transferred to MintedCrowdsale for minting.
|
||||
*/
|
||||
contract MintedCrowdsale is Crowdsale {
|
||||
/**
|
||||
* @dev Overrides delivery by minting tokens upon purchase.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param tokenAmount Number of tokens to be minted
|
||||
*/
|
||||
function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
|
||||
// Potentially dangerous assumption about the type of the token.
|
||||
require(
|
||||
ERC20Mintable(address(token())).mint(beneficiary, tokenAmount),
|
||||
"MintedCrowdsale: minting failed"
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,79 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
|
||||
/**
|
||||
* @title IncreasingPriceCrowdsale
|
||||
* @dev Extension of Crowdsale contract that increases the price of tokens linearly in time.
|
||||
* Note that what should be provided to the constructor is the initial and final _rates_, that is,
|
||||
* the amount of tokens per wei contributed. Thus, the initial rate must be greater than the final rate.
|
||||
*/
|
||||
contract IncreasingPriceCrowdsale is TimedCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
uint256 private _initialRate;
|
||||
uint256 private _finalRate;
|
||||
|
||||
/**
|
||||
* @dev Constructor, takes initial and final rates of tokens received per wei contributed.
|
||||
* @param initialRate Number of tokens a buyer gets per wei at the start of the crowdsale
|
||||
* @param finalRate Number of tokens a buyer gets per wei at the end of the crowdsale
|
||||
*/
|
||||
constructor (uint256 initialRate, uint256 finalRate) public {
|
||||
require(finalRate > 0, "IncreasingPriceCrowdsale: final rate is 0");
|
||||
// solhint-disable-next-line max-line-length
|
||||
require(initialRate > finalRate, "IncreasingPriceCrowdsale: initial rate is not greater than final rate");
|
||||
_initialRate = initialRate;
|
||||
_finalRate = finalRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base rate function is overridden to revert, since this crowdsale doesn't use it, and
|
||||
* all calls to it are a mistake.
|
||||
*/
|
||||
function rate() public view returns (uint256) {
|
||||
revert("IncreasingPriceCrowdsale: rate() called");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the initial rate of the crowdsale.
|
||||
*/
|
||||
function initialRate() public view returns (uint256) {
|
||||
return _initialRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the final rate of the crowdsale.
|
||||
*/
|
||||
function finalRate() public view returns (uint256) {
|
||||
return _finalRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the rate of tokens per wei at the present time.
|
||||
* Note that, as price _increases_ with time, the rate _decreases_.
|
||||
* @return The number of tokens a buyer gets per wei at a given time
|
||||
*/
|
||||
function getCurrentRate() public view returns (uint256) {
|
||||
if (!isOpen()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
uint256 elapsedTime = block.timestamp.sub(openingTime());
|
||||
uint256 timeRange = closingTime().sub(openingTime());
|
||||
uint256 rateRange = _initialRate.sub(_finalRate);
|
||||
return _initialRate.sub(elapsedTime.mul(rateRange).div(timeRange));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides parent method taking into account variable rate.
|
||||
* @param weiAmount The value in wei to be converted into tokens
|
||||
* @return The number of tokens _weiAmount wei will buy at present time
|
||||
*/
|
||||
function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
|
||||
uint256 currentRate = getCurrentRate();
|
||||
return currentRate.mul(weiAmount);
|
||||
}
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
|
||||
/**
|
||||
* @title CappedCrowdsale
|
||||
* @dev Crowdsale with a limit for total contributions.
|
||||
*/
|
||||
contract CappedCrowdsale is Crowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
uint256 private _cap;
|
||||
|
||||
/**
|
||||
* @dev Constructor, takes maximum amount of wei accepted in the crowdsale.
|
||||
* @param cap Max amount of wei to be contributed
|
||||
*/
|
||||
constructor (uint256 cap) public {
|
||||
require(cap > 0, "CappedCrowdsale: cap is 0");
|
||||
_cap = cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cap of the crowdsale.
|
||||
*/
|
||||
function cap() public view returns (uint256) {
|
||||
return _cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks whether the cap has been reached.
|
||||
* @return Whether the cap was reached
|
||||
*/
|
||||
function capReached() public view returns (bool) {
|
||||
return weiRaised() >= _cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior requiring purchase to respect the funding cap.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
require(weiRaised().add(weiAmount) <= _cap, "CappedCrowdsale: cap exceeded");
|
||||
}
|
||||
}
|
||||
@ -1,64 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
import "../../access/roles/CapperRole.sol";
|
||||
|
||||
/**
|
||||
* @title IndividuallyCappedCrowdsale
|
||||
* @dev Crowdsale with per-beneficiary caps.
|
||||
*/
|
||||
contract IndividuallyCappedCrowdsale is Crowdsale, CapperRole {
|
||||
using SafeMath for uint256;
|
||||
|
||||
mapping(address => uint256) private _contributions;
|
||||
mapping(address => uint256) private _caps;
|
||||
|
||||
/**
|
||||
* @dev Sets a specific beneficiary's maximum contribution.
|
||||
* @param beneficiary Address to be capped
|
||||
* @param cap Wei limit for individual contribution
|
||||
*/
|
||||
function setCap(address beneficiary, uint256 cap) external onlyCapper {
|
||||
_caps[beneficiary] = cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the cap of a specific beneficiary.
|
||||
* @param beneficiary Address whose cap is to be checked
|
||||
* @return Current cap for individual beneficiary
|
||||
*/
|
||||
function getCap(address beneficiary) public view returns (uint256) {
|
||||
return _caps[beneficiary];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the amount contributed so far by a specific beneficiary.
|
||||
* @param beneficiary Address of contributor
|
||||
* @return Beneficiary contribution so far
|
||||
*/
|
||||
function getContribution(address beneficiary) public view returns (uint256) {
|
||||
return _contributions[beneficiary];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior requiring purchase to respect the beneficiary's funding cap.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
// solhint-disable-next-line max-line-length
|
||||
require(_contributions[beneficiary].add(weiAmount) <= _caps[beneficiary], "IndividuallyCappedCrowdsale: beneficiary's cap exceeded");
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior to update beneficiary contributions.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal {
|
||||
super._updatePurchasingState(beneficiary, weiAmount);
|
||||
_contributions[beneficiary] = _contributions[beneficiary].add(weiAmount);
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Crowdsale.sol";
|
||||
import "../../lifecycle/Pausable.sol";
|
||||
|
||||
/**
|
||||
* @title PausableCrowdsale
|
||||
* @dev Extension of Crowdsale contract where purchases can be paused and unpaused by the pauser role.
|
||||
*/
|
||||
contract PausableCrowdsale is Crowdsale, Pausable {
|
||||
/**
|
||||
* @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met.
|
||||
* Use super to concatenate validations.
|
||||
* Adds the validation that the crowdsale must not be paused.
|
||||
* @param _beneficiary Address performing the token purchase
|
||||
* @param _weiAmount Value in wei involved in the purchase
|
||||
*/
|
||||
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal view whenNotPaused {
|
||||
return super._preValidatePurchase(_beneficiary, _weiAmount);
|
||||
}
|
||||
}
|
||||
@ -1,98 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
|
||||
/**
|
||||
* @title TimedCrowdsale
|
||||
* @dev Crowdsale accepting contributions only within a time frame.
|
||||
*/
|
||||
contract TimedCrowdsale is Crowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
uint256 private _openingTime;
|
||||
uint256 private _closingTime;
|
||||
|
||||
/**
|
||||
* Event for crowdsale extending
|
||||
* @param newClosingTime new closing time
|
||||
* @param prevClosingTime old closing time
|
||||
*/
|
||||
event TimedCrowdsaleExtended(uint256 prevClosingTime, uint256 newClosingTime);
|
||||
|
||||
/**
|
||||
* @dev Reverts if not in crowdsale time range.
|
||||
*/
|
||||
modifier onlyWhileOpen {
|
||||
require(isOpen(), "TimedCrowdsale: not open");
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Constructor, takes crowdsale opening and closing times.
|
||||
* @param openingTime Crowdsale opening time
|
||||
* @param closingTime Crowdsale closing time
|
||||
*/
|
||||
constructor (uint256 openingTime, uint256 closingTime) public {
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
require(openingTime >= block.timestamp, "TimedCrowdsale: opening time is before current time");
|
||||
// solhint-disable-next-line max-line-length
|
||||
require(closingTime > openingTime, "TimedCrowdsale: opening time is not before closing time");
|
||||
|
||||
_openingTime = openingTime;
|
||||
_closingTime = closingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the crowdsale opening time.
|
||||
*/
|
||||
function openingTime() public view returns (uint256) {
|
||||
return _openingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the crowdsale closing time.
|
||||
*/
|
||||
function closingTime() public view returns (uint256) {
|
||||
return _closingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the crowdsale is open, false otherwise.
|
||||
*/
|
||||
function isOpen() public view returns (bool) {
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
return block.timestamp >= _openingTime && block.timestamp <= _closingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks whether the period in which the crowdsale is open has already elapsed.
|
||||
* @return Whether crowdsale period has elapsed
|
||||
*/
|
||||
function hasClosed() public view returns (bool) {
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
return block.timestamp > _closingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend parent behavior requiring to be within contributing period.
|
||||
* @param beneficiary Token purchaser
|
||||
* @param weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal onlyWhileOpen view {
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Extend crowdsale.
|
||||
* @param newClosingTime Crowdsale closing time
|
||||
*/
|
||||
function _extendTime(uint256 newClosingTime) internal {
|
||||
require(!hasClosed(), "TimedCrowdsale: already closed");
|
||||
// solhint-disable-next-line max-line-length
|
||||
require(newClosingTime > _closingTime, "TimedCrowdsale: new closing time is before current closing time");
|
||||
|
||||
emit TimedCrowdsaleExtended(_closingTime, newClosingTime);
|
||||
_closingTime = newClosingTime;
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
import "../Crowdsale.sol";
|
||||
import "../../access/roles/WhitelistedRole.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title WhitelistCrowdsale
|
||||
* @dev Crowdsale in which only whitelisted users can contribute.
|
||||
*/
|
||||
contract WhitelistCrowdsale is WhitelistedRole, Crowdsale {
|
||||
/**
|
||||
* @dev Extend parent behavior requiring beneficiary to be whitelisted. Note that no
|
||||
* restriction is imposed on the account sending the transaction.
|
||||
* @param _beneficiary Token beneficiary
|
||||
* @param _weiAmount Amount of wei contributed
|
||||
*/
|
||||
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal view {
|
||||
require(isWhitelisted(_beneficiary), "WhitelistCrowdsale: beneficiary doesn't have the Whitelisted role");
|
||||
super._preValidatePurchase(_beneficiary, _weiAmount);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @dev These functions deal with verification of Merkle trees (hash trees),
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
|
||||
@ -18,7 +18,7 @@ contract ERC20Metadata {
|
||||
return _tokenURI;
|
||||
}
|
||||
|
||||
function _setTokenURI(string memory tokenURI_) internal {
|
||||
function _setTokenURI(string memory tokenURI_) internal virtual {
|
||||
_tokenURI = tokenURI_;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,103 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
import "../math/Math.sol";
|
||||
|
||||
/**
|
||||
* @title ERC20Migrator
|
||||
* @dev This contract can be used to migrate an ERC20 token from one
|
||||
* contract to another, where each token holder has to opt-in to the migration.
|
||||
* To opt-in, users must approve for this contract the number of tokens they
|
||||
* want to migrate. Once the allowance is set up, anyone can trigger the
|
||||
* migration to the new token contract. In this way, token holders "turn in"
|
||||
* their old balance and will be minted an equal amount in the new token.
|
||||
* The new token contract must be mintable. For the precise interface refer to
|
||||
* OpenZeppelin's {ERC20Mintable}, but the only functions that are needed are
|
||||
* {MinterRole-isMinter} and {ERC20Mintable-mint}. The migrator will check
|
||||
* that it is a minter for the token.
|
||||
* The balance from the legacy token will be transferred to the migrator, as it
|
||||
* is migrated, and remain there forever.
|
||||
* Although this contract can be used in many different scenarios, the main
|
||||
* motivation was to provide a way to migrate ERC20 tokens into an upgradeable
|
||||
* version of it using ZeppelinOS. To read more about how this can be done
|
||||
* using this implementation, please follow the official documentation site of
|
||||
* ZeppelinOS: https://docs.zeppelinos.org/docs/erc20_onboarding.html
|
||||
*
|
||||
* Example of usage:
|
||||
* ```
|
||||
* const migrator = await ERC20Migrator.new(legacyToken.address);
|
||||
* await newToken.addMinter(migrator.address);
|
||||
* await migrator.beginMigration(newToken.address);
|
||||
* ```
|
||||
*/
|
||||
contract ERC20Migrator {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/// Address of the old token contract
|
||||
IERC20 private _legacyToken;
|
||||
|
||||
/// Address of the new token contract
|
||||
ERC20Mintable private _newToken;
|
||||
|
||||
/**
|
||||
* @param legacyToken address of the old token contract
|
||||
*/
|
||||
constructor (IERC20 legacyToken) public {
|
||||
require(address(legacyToken) != address(0), "ERC20Migrator: legacy token is the zero address");
|
||||
_legacyToken = legacyToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the legacy token that is being migrated.
|
||||
*/
|
||||
function legacyToken() public view returns (IERC20) {
|
||||
return _legacyToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the new token to which we are migrating.
|
||||
*/
|
||||
function newToken() public view returns (IERC20) {
|
||||
return _newToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Begins the migration by setting which is the new token that will be
|
||||
* minted. This contract must be a minter for the new token.
|
||||
* @param newToken_ the token that will be minted
|
||||
*/
|
||||
function beginMigration(ERC20Mintable newToken_) public {
|
||||
require(address(_newToken) == address(0), "ERC20Migrator: migration already started");
|
||||
require(address(newToken_) != address(0), "ERC20Migrator: new token is the zero address");
|
||||
//solhint-disable-next-line max-line-length
|
||||
require(newToken_.isMinter(address(this)), "ERC20Migrator: not a minter for new token");
|
||||
|
||||
_newToken = newToken_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers part of an account's balance in the old token to this
|
||||
* contract, and mints the same amount of new tokens for that account.
|
||||
* @param account whose tokens will be migrated
|
||||
* @param amount amount of tokens to be migrated
|
||||
*/
|
||||
function migrate(address account, uint256 amount) public {
|
||||
require(address(_newToken) != address(0), "ERC20Migrator: migration not started");
|
||||
_legacyToken.safeTransferFrom(account, address(this), amount);
|
||||
_newToken.mint(account, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers all of an account's allowed balance in the old token to
|
||||
* this contract, and mints the same amount of new tokens for that account.
|
||||
* @param account whose tokens will be migrated
|
||||
*/
|
||||
function migrateAll(address account) public {
|
||||
uint256 balance = _legacyToken.balanceOf(account);
|
||||
uint256 allowance = _legacyToken.allowance(account, address(this));
|
||||
uint256 amount = Math.min(balance, allowance);
|
||||
migrate(account, amount);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../math/SafeMath.sol";
|
||||
import "../utils/Arrays.sol";
|
||||
@ -43,7 +43,7 @@ contract ERC20Snapshot is ERC20 {
|
||||
// Creates a new snapshot id. Balances are only stored in snapshots on demand: unless a snapshot was taken, a
|
||||
// balance change will not be recorded. This means the extra added cost of storing snapshotted balances is only paid
|
||||
// when required, but is also flexible enough that it allows for e.g. daily snapshots.
|
||||
function snapshot() public returns (uint256) {
|
||||
function snapshot() public virtual returns (uint256) {
|
||||
_currentSnapshotId.increment();
|
||||
|
||||
uint256 currentId = _currentSnapshotId.current();
|
||||
@ -66,21 +66,21 @@ contract ERC20Snapshot is ERC20 {
|
||||
// _transfer, _mint and _burn are the only functions where the balances are modified, so it is there that the
|
||||
// snapshots are updated. Note that the update happens _before_ the balance change, with the pre-modified value.
|
||||
// The same is true for the total supply and _mint and _burn.
|
||||
function _transfer(address from, address to, uint256 value) internal {
|
||||
function _transfer(address from, address to, uint256 value) internal virtual override {
|
||||
_updateAccountSnapshot(from);
|
||||
_updateAccountSnapshot(to);
|
||||
|
||||
super._transfer(from, to, value);
|
||||
}
|
||||
|
||||
function _mint(address account, uint256 value) internal {
|
||||
function _mint(address account, uint256 value) internal virtual override {
|
||||
_updateAccountSnapshot(account);
|
||||
_updateTotalSupplySnapshot();
|
||||
|
||||
super._mint(account, value);
|
||||
}
|
||||
|
||||
function _burn(address account, uint256 value) internal {
|
||||
function _burn(address account, uint256 value) internal virtual override {
|
||||
_updateAccountSnapshot(account);
|
||||
_updateTotalSupplySnapshot();
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @title SignedSafeMath
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @title Strings
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
import "../ownership/Ownable.sol";
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../crowdsale/validation/CappedCrowdsale.sol";
|
||||
import "../crowdsale/distribution/RefundableCrowdsale.sol";
|
||||
import "../crowdsale/emission/MintedCrowdsale.sol";
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
import "../token/ERC20/ERC20Detailed.sol";
|
||||
|
||||
/**
|
||||
* @title SampleCrowdsaleToken
|
||||
* @dev Very simple ERC20 Token that can be minted.
|
||||
* It is meant to be used in a crowdsale contract.
|
||||
*/
|
||||
contract SampleCrowdsaleToken is ERC20Mintable, ERC20Detailed {
|
||||
constructor () public ERC20Detailed("Sample Crowdsale Token", "SCT", 18) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @title SampleCrowdsale
|
||||
* @dev This is an example of a fully fledged crowdsale.
|
||||
* The way to add new features to a base crowdsale is by multiple inheritance.
|
||||
* In this example we are providing following extensions:
|
||||
* CappedCrowdsale - sets a max boundary for raised funds
|
||||
* RefundableCrowdsale - set a min goal to be reached and returns funds if it's not met
|
||||
* MintedCrowdsale - assumes the token can be minted by the crowdsale, which does so
|
||||
* when receiving purchases.
|
||||
*
|
||||
* After adding multiple features it's good practice to run integration tests
|
||||
* to ensure that subcontracts works together as intended.
|
||||
*/
|
||||
contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale, MintedCrowdsale {
|
||||
constructor (
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
uint256 rate,
|
||||
address payable wallet,
|
||||
uint256 cap,
|
||||
ERC20Mintable token,
|
||||
uint256 goal
|
||||
)
|
||||
public
|
||||
Crowdsale(rate, wallet, token)
|
||||
CappedCrowdsale(cap)
|
||||
TimedCrowdsale(openingTime, closingTime)
|
||||
RefundableCrowdsale(goal)
|
||||
{
|
||||
//As goal needs to be met for a successful crowdsale
|
||||
//the value needs to less or equal than a cap which is limit for accepted funds
|
||||
require(goal <= cap, "SampleCrowdSale: goal is greater than cap");
|
||||
}
|
||||
}
|
||||
@ -1,21 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../GSN/Context.sol";
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../token/ERC20/ERC20Detailed.sol";
|
||||
|
||||
/**
|
||||
* @title SimpleToken
|
||||
* @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
|
||||
* Note they can later distribute these tokens as they wish using `transfer` and other
|
||||
* `ERC20` functions.
|
||||
*/
|
||||
contract SimpleToken is Context, ERC20, ERC20Detailed {
|
||||
|
||||
/**
|
||||
* @dev Constructor that gives _msgSender() all of existing tokens.
|
||||
*/
|
||||
constructor () public ERC20Detailed("SimpleToken", "SIM", 18) {
|
||||
_mint(_msgSender(), 10000 * (10 ** uint256(decimals())));
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "./IERC165.sol";
|
||||
|
||||
@ -30,7 +30,7 @@ contract ERC165 is IERC165 {
|
||||
*
|
||||
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
|
||||
function supportsInterface(bytes4 interfaceId) external view override returns (bool) {
|
||||
return _supportedInterfaces[interfaceId];
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ contract ERC165 is IERC165 {
|
||||
*
|
||||
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
|
||||
*/
|
||||
function _registerInterface(bytes4 interfaceId) internal {
|
||||
function _registerInterface(bytes4 interfaceId) internal virtual {
|
||||
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
|
||||
_supportedInterfaces[interfaceId] = true;
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.10;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @dev Library used to query support of an interface declared via {IERC165}.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "./IERC1820Implementer.sol";
|
||||
|
||||
@ -18,7 +18,7 @@ contract ERC1820Implementer is IERC1820Implementer {
|
||||
/**
|
||||
* See {IERC1820Implementer-canImplementInterfaceForAddress}.
|
||||
*/
|
||||
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view returns (bytes32) {
|
||||
function canImplementInterfaceForAddress(bytes32 interfaceHash, address account) external view override returns (bytes32) {
|
||||
return _supportedInterfaces[interfaceHash][account] ? ERC1820_ACCEPT_MAGIC : bytes32(0x00);
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ contract ERC1820Implementer is IERC1820Implementer {
|
||||
* See {IERC1820Registry-setInterfaceImplementer} and
|
||||
* {IERC1820Registry-interfaceHash}.
|
||||
*/
|
||||
function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal {
|
||||
function _registerInterfaceForAddress(bytes32 interfaceHash, address account) internal virtual {
|
||||
_supportedInterfaces[interfaceHash][account] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @dev Interface of the ERC165 standard, as defined in the
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @dev Interface for an ERC1820 implementer, as defined in the
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @dev Interface of the global ERC1820 Registry, as defined in the
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
= Introspection
|
||||
|
||||
This set of interfaces and contracts deal with [type introspection](https://en.wikipedia.org/wiki/Type_introspection) of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_.
|
||||
This set of interfaces and contracts deal with https://en.wikipedia.org/wiki/Type_introspection[type introspection] of contracts, that is, examining which functions can be called on them. This is usually referred to as a contract's _interface_.
|
||||
|
||||
Ethereum contracts have no native concept of an interface, so applications must usually simply trust they are not making an incorrect call. For trusted setups this is a non-issue, but often unknown and untrusted third-party addresses need to be interacted with. There may even not be any direct calls to them! (e.g. `ERC20` tokens may be sent to a contract that lacks a way to transfer them out of it, locking them forever). In these cases, a contract _declaring_ its interface can be very helpful in preventing errors.
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../GSN/Context.sol";
|
||||
import "../access/roles/PauserRole.sol";
|
||||
|
||||
/**
|
||||
* @dev Contract module which allows children to implement an emergency stop
|
||||
@ -12,7 +11,7 @@ import "../access/roles/PauserRole.sol";
|
||||
* the functions of your contract. Note that they will not be pausable by
|
||||
* simply including this module, only once the modifiers are put in place.
|
||||
*/
|
||||
contract Pausable is Context, PauserRole {
|
||||
contract Pausable is Context {
|
||||
/**
|
||||
* @dev Emitted when the pause is triggered by a pauser (`account`).
|
||||
*/
|
||||
@ -59,7 +58,7 @@ contract Pausable is Context, PauserRole {
|
||||
/**
|
||||
* @dev Called by a pauser to pause, triggers stopped state.
|
||||
*/
|
||||
function pause() public onlyPauser whenNotPaused {
|
||||
function _pause() internal virtual whenNotPaused {
|
||||
_paused = true;
|
||||
emit Paused(_msgSender());
|
||||
}
|
||||
@ -67,7 +66,7 @@ contract Pausable is Context, PauserRole {
|
||||
/**
|
||||
* @dev Called by a pauser to unpause, returns to normal state.
|
||||
*/
|
||||
function unpause() public onlyPauser whenPaused {
|
||||
function _unpause() internal virtual whenPaused {
|
||||
_paused = false;
|
||||
emit Unpaused(_msgSender());
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @dev Standard math utilities missing in the Solidity language.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
/**
|
||||
* @dev Wrappers over Solidity's arithmetic operations with added overflow
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../utils/Address.sol";
|
||||
|
||||
@ -15,5 +15,6 @@ contract AddressImpl {
|
||||
Address.sendValue(receiver, amount);
|
||||
}
|
||||
|
||||
function () external payable { } // sendValue's tests require the contract to hold Ether
|
||||
// sendValue's tests require the contract to hold Ether
|
||||
receive () external payable { }
|
||||
}
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/emission/AllowanceCrowdsale.sol";
|
||||
|
||||
contract AllowanceCrowdsaleImpl is AllowanceCrowdsale {
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token, address tokenWallet)
|
||||
public
|
||||
Crowdsale(rate, wallet, token)
|
||||
AllowanceCrowdsale(tokenWallet)
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../utils/Arrays.sol";
|
||||
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/validation/CappedCrowdsale.sol";
|
||||
|
||||
contract CappedCrowdsaleImpl is CappedCrowdsale {
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token, uint256 cap)
|
||||
public
|
||||
Crowdsale(rate, wallet, token)
|
||||
CappedCrowdsale(cap)
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/roles/CapperRole.sol";
|
||||
|
||||
contract CapperRoleMock is CapperRole {
|
||||
function removeCapper(address account) public {
|
||||
_removeCapper(account);
|
||||
}
|
||||
|
||||
function onlyCapperMock() public view onlyCapper {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
// Causes a compilation error if super._removeCapper is not internal
|
||||
function _removeCapper(address account) internal {
|
||||
super._removeCapper(account);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../payment/escrow/ConditionalEscrow.sol";
|
||||
|
||||
@ -10,7 +10,7 @@ contract ConditionalEscrowMock is ConditionalEscrow {
|
||||
_allowed[payee] = allowed;
|
||||
}
|
||||
|
||||
function withdrawalAllowed(address payee) public view returns (bool) {
|
||||
function withdrawalAllowed(address payee) public view override returns (bool) {
|
||||
return _allowed[payee];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../GSN/Context.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../drafts/Counters.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../utils/Create2.sol";
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
@ -20,4 +20,8 @@ contract Create2Impl {
|
||||
function computeAddress(bytes32 salt, bytes memory code, address deployer) public pure returns (address) {
|
||||
return Create2.computeAddress(salt, code, deployer);
|
||||
}
|
||||
|
||||
function computeAddress(bytes32 salt, bytes32 codeHash, address deployer) public pure returns (address) {
|
||||
return Create2.computeAddress(salt, codeHash, deployer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../crowdsale/Crowdsale.sol";
|
||||
|
||||
contract CrowdsaleMock is Crowdsale {
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token) public Crowdsale(rate, wallet, token) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../cryptography/ECDSA.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../../introspection/IERC165.sol";
|
||||
|
||||
@ -34,7 +34,7 @@ contract SupportsInterfaceWithLookupMock is IERC165 {
|
||||
/**
|
||||
* @dev Implement supportsInterface(bytes4) using a lookup table.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceId) external view returns (bool) {
|
||||
function supportsInterface(bytes4 interfaceId) external view override returns (bool) {
|
||||
return _supportedInterfaces[interfaceId];
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
contract ERC165NotSupported {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
contract ERC165NotSupported { }
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../introspection/ERC165Checker.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../introspection/ERC165.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../introspection/ERC1820Implementer.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC20/ERC20Burnable.sol";
|
||||
|
||||
|
||||
11
contracts/mocks/ERC20CappedMock.sol
Normal file
11
contracts/mocks/ERC20CappedMock.sol
Normal file
@ -0,0 +1,11 @@
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC20/ERC20Capped.sol";
|
||||
|
||||
contract ERC20CappedMock is ERC20Capped {
|
||||
constructor (uint256 cap) public ERC20Capped(cap) { }
|
||||
|
||||
function mint(address to, uint256 tokenId) public {
|
||||
_mint(to, tokenId);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../token/ERC20/ERC20Detailed.sol";
|
||||
@ -8,6 +8,6 @@ contract ERC20DetailedMock is ERC20, ERC20Detailed {
|
||||
public
|
||||
ERC20Detailed(name, symbol, decimals)
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../drafts/ERC1046/ERC20Metadata.sol";
|
||||
|
||||
contract ERC20MetadataMock is ERC20, ERC20Metadata {
|
||||
constructor (string memory tokenURI) public ERC20Metadata(tokenURI) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
constructor (string memory tokenURI) public ERC20Metadata(tokenURI) { }
|
||||
|
||||
function setTokenURI(string memory tokenURI) public {
|
||||
_setTokenURI(tokenURI);
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
import "./MinterRoleMock.sol";
|
||||
|
||||
contract ERC20MintableMock is ERC20Mintable, MinterRoleMock {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
|
||||
|
||||
@ -1,11 +1,18 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC20/ERC20Pausable.sol";
|
||||
import "./PauserRoleMock.sol";
|
||||
|
||||
// mock class using ERC20Pausable
|
||||
contract ERC20PausableMock is ERC20Pausable, PauserRoleMock {
|
||||
contract ERC20PausableMock is ERC20Pausable {
|
||||
constructor (address initialAccount, uint256 initialBalance) public {
|
||||
_mint(initialAccount, initialBalance);
|
||||
}
|
||||
|
||||
function pause() external {
|
||||
_pause();
|
||||
}
|
||||
|
||||
function unpause() external {
|
||||
_unpause();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../drafts/ERC20Snapshot.sol";
|
||||
|
||||
|
||||
9
contracts/mocks/ERC721BurnableMock.sol
Normal file
9
contracts/mocks/ERC721BurnableMock.sol
Normal file
@ -0,0 +1,9 @@
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC721/ERC721Burnable.sol";
|
||||
|
||||
contract ERC721BurnableMock is ERC721Burnable {
|
||||
function mint(address to, uint256 tokenId) public {
|
||||
_mint(to, tokenId);
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,6 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC721/ERC721Full.sol";
|
||||
import "../token/ERC721/ERC721Mintable.sol";
|
||||
import "../token/ERC721/ERC721MetadataMintable.sol";
|
||||
import "../token/ERC721/ERC721Burnable.sol";
|
||||
|
||||
/**
|
||||
@ -10,10 +8,8 @@ import "../token/ERC721/ERC721Burnable.sol";
|
||||
* This mock just provides public functions for setting metadata URI, getting all tokens of an owner,
|
||||
* checking token existence, removal of a token from an address
|
||||
*/
|
||||
contract ERC721FullMock is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
|
||||
constructor (string memory name, string memory symbol) public ERC721Mintable() ERC721Full(name, symbol) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
contract ERC721FullMock is ERC721Full, ERC721Burnable {
|
||||
constructor (string memory name, string memory symbol) public ERC721Full(name, symbol) { }
|
||||
|
||||
function exists(uint256 tokenId) public view returns (bool) {
|
||||
return _exists(tokenId);
|
||||
@ -30,4 +26,12 @@ contract ERC721FullMock is ERC721Full, ERC721Mintable, ERC721MetadataMintable, E
|
||||
function setBaseURI(string memory baseURI) public {
|
||||
_setBaseURI(baseURI);
|
||||
}
|
||||
|
||||
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override(ERC721, ERC721Full) {
|
||||
super._beforeTokenTransfer(from, to, tokenId);
|
||||
}
|
||||
|
||||
function mint(address to, uint256 tokenId) public {
|
||||
_mint(to, tokenId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC721/ERC721.sol";
|
||||
import "../GSN/GSNRecipient.sol";
|
||||
@ -10,9 +10,16 @@ import "../GSN/GSNRecipientSignature.sol";
|
||||
*/
|
||||
contract ERC721GSNRecipientMock is ERC721, GSNRecipient, GSNRecipientSignature {
|
||||
constructor(address trustedSigner) public GSNRecipientSignature(trustedSigner) { }
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
|
||||
function mint(uint256 tokenId) public {
|
||||
_mint(_msgSender(), tokenId);
|
||||
}
|
||||
|
||||
function _msgSender() internal view override(Context, GSNRecipient) returns (address payable) {
|
||||
return GSNRecipient._msgSender();
|
||||
}
|
||||
|
||||
function _msgData() internal view override(Context, GSNRecipient) returns (bytes memory) {
|
||||
return GSNRecipient._msgData();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC721/ERC721Full.sol";
|
||||
import "../token/ERC721/ERC721Mintable.sol";
|
||||
import "../token/ERC721/ERC721MetadataMintable.sol";
|
||||
import "../token/ERC721/ERC721Burnable.sol";
|
||||
|
||||
/**
|
||||
* @title ERC721MintableBurnableImpl
|
||||
*/
|
||||
contract ERC721MintableBurnableImpl is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
|
||||
constructor () public ERC721Mintable() ERC721Full("Test", "TEST") {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC721/ERC721.sol";
|
||||
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC721/ERC721Pausable.sol";
|
||||
import "./PauserRoleMock.sol";
|
||||
|
||||
/**
|
||||
* @title ERC721PausableMock
|
||||
* This mock just provides a public mint, burn and exists functions for testing purposes
|
||||
*/
|
||||
contract ERC721PausableMock is ERC721Pausable, PauserRoleMock {
|
||||
contract ERC721PausableMock is ERC721Pausable {
|
||||
function mint(address to, uint256 tokenId) public {
|
||||
super._mint(to, tokenId);
|
||||
}
|
||||
@ -19,4 +18,12 @@ contract ERC721PausableMock is ERC721Pausable, PauserRoleMock {
|
||||
function exists(uint256 tokenId) public view returns (bool) {
|
||||
return super._exists(tokenId);
|
||||
}
|
||||
|
||||
function pause() external {
|
||||
_pause();
|
||||
}
|
||||
|
||||
function unpause() external {
|
||||
_unpause();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../token/ERC721/IERC721Receiver.sol";
|
||||
|
||||
@ -14,7 +14,7 @@ contract ERC721ReceiverMock is IERC721Receiver {
|
||||
}
|
||||
|
||||
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
|
||||
public returns (bytes4)
|
||||
public override returns (bytes4)
|
||||
{
|
||||
require(!_reverts, "ERC721ReceiverMock: reverting");
|
||||
emit Received(operator, from, tokenId, data, gasleft());
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../GSN/Context.sol";
|
||||
import "../token/ERC777/ERC777.sol";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../GSN/Context.sol";
|
||||
import "../token/ERC777/IERC777.sol";
|
||||
@ -47,7 +47,7 @@ contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient,
|
||||
uint256 amount,
|
||||
bytes calldata userData,
|
||||
bytes calldata operatorData
|
||||
) external {
|
||||
) external override {
|
||||
if (_shouldRevertSend) {
|
||||
revert();
|
||||
}
|
||||
@ -78,7 +78,7 @@ contract ERC777SenderRecipientMock is Context, IERC777Sender, IERC777Recipient,
|
||||
uint256 amount,
|
||||
bytes calldata userData,
|
||||
bytes calldata operatorData
|
||||
) external{
|
||||
) external override {
|
||||
if (_shouldRevertReceive) {
|
||||
revert();
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../utils/EnumerableSet.sol";
|
||||
|
||||
@ -9,25 +9,29 @@ contract EnumerableSetMock{
|
||||
|
||||
EnumerableSet.AddressSet private set;
|
||||
|
||||
constructor() public {
|
||||
set = EnumerableSet.newAddressSet();
|
||||
}
|
||||
|
||||
function contains(address value) public view returns (bool) {
|
||||
return EnumerableSet.contains(set, value);
|
||||
return set.contains(value);
|
||||
}
|
||||
|
||||
function add(address value) public {
|
||||
bool result = EnumerableSet.add(set, value);
|
||||
bool result = set.add(value);
|
||||
emit TransactionResult(result);
|
||||
}
|
||||
|
||||
function remove(address value) public {
|
||||
bool result = EnumerableSet.remove(set, value);
|
||||
bool result = set.remove(value);
|
||||
emit TransactionResult(result);
|
||||
}
|
||||
|
||||
function enumerate() public view returns (address[] memory) {
|
||||
return EnumerableSet.enumerate(set);
|
||||
return set.enumerate();
|
||||
}
|
||||
|
||||
function length() public view returns (uint256) {
|
||||
return set.length();
|
||||
}
|
||||
|
||||
function get(uint256 index) public view returns (address) {
|
||||
return set.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
contract EtherReceiverMock {
|
||||
bool private _acceptEther;
|
||||
@ -7,7 +7,7 @@ contract EtherReceiverMock {
|
||||
_acceptEther = acceptEther;
|
||||
}
|
||||
|
||||
function () external payable {
|
||||
receive () external payable {
|
||||
if (!_acceptEther) {
|
||||
revert();
|
||||
}
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/distribution/FinalizableCrowdsale.sol";
|
||||
|
||||
contract FinalizableCrowdsaleImpl is FinalizableCrowdsale {
|
||||
constructor (uint256 openingTime, uint256 closingTime, uint256 rate, address payable wallet, IERC20 token)
|
||||
public
|
||||
Crowdsale(rate, wallet, token)
|
||||
TimedCrowdsale(openingTime, closingTime)
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,10 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../GSN/GSNRecipient.sol";
|
||||
import "../GSN/GSNRecipientERC20Fee.sol";
|
||||
|
||||
contract GSNRecipientERC20FeeMock is GSNRecipient, GSNRecipientERC20Fee {
|
||||
constructor(string memory name, string memory symbol) public GSNRecipientERC20Fee(name, symbol) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
constructor(string memory name, string memory symbol) public GSNRecipientERC20Fee(name, symbol) { }
|
||||
|
||||
function mint(address account, uint256 amount) public {
|
||||
_mint(account, amount);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "./ContextMock.sol";
|
||||
import "../GSN/GSNRecipient.sol";
|
||||
@ -12,20 +12,25 @@ contract GSNRecipientMock is ContextMock, GSNRecipient {
|
||||
function acceptRelayedCall(address, address, bytes calldata, uint256, uint256, uint256, uint256, bytes calldata, uint256)
|
||||
external
|
||||
view
|
||||
override
|
||||
returns (uint256, bytes memory)
|
||||
{
|
||||
return (0, "");
|
||||
}
|
||||
|
||||
function _preRelayedCall(bytes memory) internal returns (bytes32) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
function _preRelayedCall(bytes memory) internal override returns (bytes32) { }
|
||||
|
||||
function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
function _postRelayedCall(bytes memory, bool, uint256, bytes32) internal override { }
|
||||
|
||||
function upgradeRelayHub(address newRelayHub) public {
|
||||
return _upgradeRelayHub(newRelayHub);
|
||||
}
|
||||
|
||||
function _msgSender() internal override(Context, GSNRecipient) view virtual returns (address payable) {
|
||||
return GSNRecipient._msgSender();
|
||||
}
|
||||
|
||||
function _msgData() internal override(Context, GSNRecipient) view virtual returns (bytes memory) {
|
||||
return GSNRecipient._msgData();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../GSN/GSNRecipient.sol";
|
||||
import "../GSN/GSNRecipientSignature.sol";
|
||||
|
||||
contract GSNRecipientSignatureMock is GSNRecipient, GSNRecipientSignature {
|
||||
constructor(address trustedSigner) public GSNRecipientSignature(trustedSigner) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
constructor(address trustedSigner) public GSNRecipientSignature(trustedSigner) { }
|
||||
|
||||
event MockFunctionCalled();
|
||||
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../crowdsale/price/IncreasingPriceCrowdsale.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale {
|
||||
constructor (
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
address payable wallet,
|
||||
IERC20 token,
|
||||
uint256 initialRate,
|
||||
uint256 finalRate
|
||||
)
|
||||
public
|
||||
Crowdsale(initialRate, wallet, token)
|
||||
TimedCrowdsale(openingTime, closingTime)
|
||||
IncreasingPriceCrowdsale(initialRate, finalRate)
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol";
|
||||
import "./CapperRoleMock.sol";
|
||||
|
||||
contract IndividuallyCappedCrowdsaleImpl is IndividuallyCappedCrowdsale, CapperRoleMock {
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token) public Crowdsale(rate, wallet, token) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../math/Math.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import { MerkleProof } from "../cryptography/MerkleProof.sol";
|
||||
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
import "../crowdsale/emission/MintedCrowdsale.sol";
|
||||
|
||||
contract MintedCrowdsaleImpl is MintedCrowdsale {
|
||||
constructor (uint256 rate, address payable wallet, ERC20Mintable token) public Crowdsale(rate, wallet, token) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/roles/MinterRole.sol";
|
||||
|
||||
contract MinterRoleMock is MinterRole {
|
||||
function removeMinter(address account) public {
|
||||
_removeMinter(account);
|
||||
}
|
||||
|
||||
function onlyMinterMock() public view onlyMinter {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
// Causes a compilation error if super._removeMinter is not internal
|
||||
function _removeMinter(address account) internal {
|
||||
super._removeMinter(account);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../ownership/Ownable.sol";
|
||||
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
pragma solidity ^0.5.0;
|
||||
pragma solidity ^0.6.0;
|
||||
|
||||
import "../ownership/Ownable.sol";
|
||||
|
||||
contract OwnableMock is Ownable {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
contract OwnableMock is Ownable { }
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../crowdsale/validation/PausableCrowdsale.sol";
|
||||
|
||||
contract PausableCrowdsaleImpl is PausableCrowdsale {
|
||||
constructor (uint256 _rate, address payable _wallet, ERC20 _token) public Crowdsale(_rate, _wallet, _token) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user