Compare commits
27 Commits
v2.1.0-rc.
...
v2.1.3
| Author | SHA1 | Date | |
|---|---|---|---|
| 77d569d8fa | |||
| 634883ce8e | |||
| de90f4458a | |||
| 8617c4b4c8 | |||
| 96432bf28e | |||
| 1a9cb0786d | |||
| fd808b3ff8 | |||
| 6a658f2ac8 | |||
| d9a8cd2bef | |||
| 79145fa53a | |||
| 3e82db2f6f | |||
| 089f14aa06 | |||
| ae02103e47 | |||
| ba83239dd8 | |||
| 4f5715bbd7 | |||
| 312a2584e8 | |||
| 6aa88e2b7d | |||
| 76abd1a41e | |||
| 35d70397b6 | |||
| a5b14f262e | |||
| 40f08a8c0b | |||
| 8c20d53789 | |||
| 576b020384 | |||
| 13eff70112 | |||
| daa301fef0 | |||
| 4b8fcbcee1 | |||
| be5ed7364b |
11
.solhint.json
Normal file
11
.solhint.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "default",
|
||||
"rules": {
|
||||
"indent": ["error", 4],
|
||||
|
||||
"bracket-align": false,
|
||||
"compiler-fixed": false,
|
||||
"no-simple-event-func-name": false,
|
||||
"two-lines-top-level-separator": false
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
node_modules
|
||||
@ -1,22 +0,0 @@
|
||||
{
|
||||
"extends": "solium:all",
|
||||
"plugins": ["security"],
|
||||
"rules": {
|
||||
"arg-overflow": "off",
|
||||
"blank-lines": "off",
|
||||
"error-reason": "off",
|
||||
"indentation": ["error", 4],
|
||||
"lbrace": "off",
|
||||
"linebreak-style": ["error", "unix"],
|
||||
"max-len": ["error", 120],
|
||||
"no-constant": ["error"],
|
||||
"no-empty-blocks": "off",
|
||||
"quotes": ["error", "double"],
|
||||
"uppercase": "off",
|
||||
"visibility-first": "error",
|
||||
|
||||
"security/enforce-explicit-visibility": ["error"],
|
||||
"security/no-block-members": ["warning"],
|
||||
"security/no-inline-assembly": ["warning"]
|
||||
}
|
||||
}
|
||||
@ -25,10 +25,11 @@ jobs:
|
||||
name: "Unit tests"
|
||||
script: npm run test
|
||||
|
||||
- stage: tests
|
||||
name: "Unit tests with coverage report"
|
||||
script: npm run test
|
||||
env: SOLIDITY_COVERAGE=true
|
||||
# solidity-coverage fails at parsing 0.5.x code
|
||||
# - stage: tests
|
||||
# name: "Unit tests with coverage report"
|
||||
# script: npm run test
|
||||
# env: SOLIDITY_COVERAGE=true
|
||||
|
||||
- stage: tests
|
||||
name: "Unit tests using solc nightly"
|
||||
|
||||
18
CHANGELOG.md
18
CHANGELOG.md
@ -1,16 +1,28 @@
|
||||
# Changelog
|
||||
|
||||
## 2.1.0 (unreleased)
|
||||
## 2.2.0 (unreleased)
|
||||
|
||||
## 2.1.3 (2019-26-02)
|
||||
* Backported `SafeERC20.safeApprove` bugfix. ([#1647](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1647))
|
||||
|
||||
## 2.1.2 (2019-17-01)
|
||||
* Removed most of the test suite from the npm package, except `PublicRole.behavior.js`, which may be useful to users testing their own `Roles`.
|
||||
|
||||
## 2.1.1 (2019-04-01)
|
||||
* Version bump to avoid conflict in the npm registry.
|
||||
|
||||
## 2.1.0 (2019-04-01)
|
||||
|
||||
### New features:
|
||||
* `WhitelistCrowdsale`: a crowdsale where only whitelisted accounts (`WhitelistedRole`) can purchase tokens. Adding or removing accounts from the whitelist is done by whitelisters (`WhitelisterRole`). Similar to the pre-2.0 `WhitelistedCrowdsale`. ([#1525](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1525))
|
||||
* Now targeting the 0.5.x line of Solidity compilers. For 0.4.24 support, use version 2.0 of OpenZeppelin.
|
||||
* `WhitelistCrowdsale`: a crowdsale where only whitelisted accounts (`WhitelistedRole`) can purchase tokens. Adding or removing accounts from the whitelist is done by whitelist admins (`WhitelistAdminRole`). Similar to the pre-2.0 `WhitelistedCrowdsale`. ([#1525](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1525), [#1589](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1589))
|
||||
* `RefundablePostDeliveryCrowdsale`: replacement for `RefundableCrowdsale` (deprecated, see below) where tokens are only granted once the crowdsale ends (if it meets its goal). ([#1543](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1543))
|
||||
* `PausableCrowdsale`: allows for pausers (`PauserRole`) to pause token purchases. Other crowdsale operations (e.g. withdrawals and refunds, if applicable) are not affected. ([#832](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/832))
|
||||
* `ERC20`: `transferFrom` and `_burnFrom ` now emit `Approval` events, to represent the token's state comprehensively through events. ([#1524](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1524))
|
||||
* `ERC721`: added `_burn(uint256 tokenId)`, replacing the similar deprecated function (see below). ([#1550](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1550))
|
||||
* `ERC721`: added `_tokensOfOwner(address owner)`, allowing to internally retrieve the array of an account's owned tokens. ([#1522](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1522))
|
||||
* Crowdsales: all constructors are now `public`, meaning it is not necessary to extend these contracts in order to deploy them. The exception is `FinalizableCrowdsale`, since it is meaningless unless extended. ([#1564](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1564))
|
||||
* `SafeMath`: added overflow-safe operations for signed integers (`int256`). ([#1559](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1559))
|
||||
* `SignedSafeMath`: added overflow-safe operations for signed integers (`int256`). ([#1559](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1559), [#1588](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1588))
|
||||
|
||||
### Improvements:
|
||||
* The compiler version required by `Array` was behind the rest of the libray so it was updated to `v0.4.24`. ([#1553](https://github.com/OpenZeppelin/openzeppelin-solidity/pull/1553))
|
||||
|
||||
@ -12,8 +12,6 @@
|
||||
npm install openzeppelin-solidity
|
||||
```
|
||||
|
||||
If you're interested in trying out a preview of OpenZeppelin 2.0, install `openzeppelin-solidity@next`, check out the [release notes](https://github.com/OpenZeppelin/openzeppelin-solidity/releases/tag/v2.0.0-rc.1), and let us know what you think!
|
||||
|
||||
## Usage
|
||||
|
||||
To write your custom contracts, import ours and extend them through inheritance.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @title Roles
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
|
||||
47
contracts/access/roles/WhitelistAdminRole.sol
Normal file
47
contracts/access/roles/WhitelistAdminRole.sol
Normal file
@ -0,0 +1,47 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
/**
|
||||
* @title WhitelistAdminRole
|
||||
* @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts.
|
||||
*/
|
||||
contract WhitelistAdminRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event WhitelistAdminAdded(address indexed account);
|
||||
event WhitelistAdminRemoved(address indexed account);
|
||||
|
||||
Roles.Role private _whitelistAdmins;
|
||||
|
||||
constructor () internal {
|
||||
_addWhitelistAdmin(msg.sender);
|
||||
}
|
||||
|
||||
modifier onlyWhitelistAdmin() {
|
||||
require(isWhitelistAdmin(msg.sender));
|
||||
_;
|
||||
}
|
||||
|
||||
function isWhitelistAdmin(address account) public view returns (bool) {
|
||||
return _whitelistAdmins.has(account);
|
||||
}
|
||||
|
||||
function addWhitelistAdmin(address account) public onlyWhitelistAdmin {
|
||||
_addWhitelistAdmin(account);
|
||||
}
|
||||
|
||||
function renounceWhitelistAdmin() public {
|
||||
_removeWhitelistAdmin(msg.sender);
|
||||
}
|
||||
|
||||
function _addWhitelistAdmin(address account) internal {
|
||||
_whitelistAdmins.add(account);
|
||||
emit WhitelistAdminAdded(account);
|
||||
}
|
||||
|
||||
function _removeWhitelistAdmin(address account) internal {
|
||||
_whitelistAdmins.remove(account);
|
||||
emit WhitelistAdminRemoved(account);
|
||||
}
|
||||
}
|
||||
@ -1,15 +1,15 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Roles.sol";
|
||||
import "./WhitelisterRole.sol";
|
||||
import "./WhitelistAdminRole.sol";
|
||||
|
||||
/**
|
||||
* @title WhitelistedRole
|
||||
* @dev Whitelisted accounts have been approved by a Whitelister to perform certain actions (e.g. participate in a
|
||||
* crowdsale). This role is special in that the only accounts that can add it are Whitelisters (who can also remove it),
|
||||
* and not Whitelisteds themselves.
|
||||
* @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 WhitelisterRole {
|
||||
contract WhitelistedRole is WhitelistAdminRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event WhitelistedAdded(address indexed account);
|
||||
@ -26,11 +26,11 @@ contract WhitelistedRole is WhitelisterRole {
|
||||
return _whitelisteds.has(account);
|
||||
}
|
||||
|
||||
function addWhitelisted(address account) public onlyWhitelister {
|
||||
function addWhitelisted(address account) public onlyWhitelistAdmin {
|
||||
_addWhitelisted(account);
|
||||
}
|
||||
|
||||
function removeWhitelisted(address account) public onlyWhitelister {
|
||||
function removeWhitelisted(address account) public onlyWhitelistAdmin {
|
||||
_removeWhitelisted(account);
|
||||
}
|
||||
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
/**
|
||||
* @title WhitelisterRole
|
||||
* @dev Whitelisters are responsible for assigning and removing Whitelisted accounts.
|
||||
*/
|
||||
contract WhitelisterRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
event WhitelisterAdded(address indexed account);
|
||||
event WhitelisterRemoved(address indexed account);
|
||||
|
||||
Roles.Role private _whitelisters;
|
||||
|
||||
constructor () internal {
|
||||
_addWhitelister(msg.sender);
|
||||
}
|
||||
|
||||
modifier onlyWhitelister() {
|
||||
require(isWhitelister(msg.sender));
|
||||
_;
|
||||
}
|
||||
|
||||
function isWhitelister(address account) public view returns (bool) {
|
||||
return _whitelisters.has(account);
|
||||
}
|
||||
|
||||
function addWhitelister(address account) public onlyWhitelister {
|
||||
_addWhitelister(account);
|
||||
}
|
||||
|
||||
function renounceWhitelister() public {
|
||||
_removeWhitelister(msg.sender);
|
||||
}
|
||||
|
||||
function _addWhitelister(address account) internal {
|
||||
_whitelisters.add(account);
|
||||
emit WhitelisterAdded(account);
|
||||
}
|
||||
|
||||
function _removeWhitelister(address account) internal {
|
||||
_whitelisters.remove(account);
|
||||
emit WhitelisterRemoved(account);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
@ -25,7 +25,7 @@ contract Crowdsale is ReentrancyGuard {
|
||||
IERC20 private _token;
|
||||
|
||||
// Address where funds are collected
|
||||
address private _wallet;
|
||||
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.
|
||||
@ -53,20 +53,16 @@ contract Crowdsale is ReentrancyGuard {
|
||||
* @param wallet Address where collected funds will be forwarded to
|
||||
* @param token Address of the token being sold
|
||||
*/
|
||||
constructor (uint256 rate, address wallet, IERC20 token) public {
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token) public {
|
||||
require(rate > 0);
|
||||
require(wallet != address(0));
|
||||
require(token != address(0));
|
||||
require(address(token) != address(0));
|
||||
|
||||
_rate = rate;
|
||||
_wallet = wallet;
|
||||
_token = token;
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
// Crowdsale external interface
|
||||
// -----------------------------------------
|
||||
|
||||
/**
|
||||
* @dev fallback function ***DO NOT OVERRIDE***
|
||||
* Note that other contracts will transfer fund with a base gas stipend
|
||||
@ -87,7 +83,7 @@ contract Crowdsale is ReentrancyGuard {
|
||||
/**
|
||||
* @return the address where funds are collected.
|
||||
*/
|
||||
function wallet() public view returns (address) {
|
||||
function wallet() public view returns (address payable) {
|
||||
return _wallet;
|
||||
}
|
||||
|
||||
@ -130,12 +126,9 @@ contract Crowdsale is ReentrancyGuard {
|
||||
_postValidatePurchase(beneficiary, weiAmount);
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
// Internal interface (extensible)
|
||||
// -----------------------------------------
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @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);
|
||||
@ -148,16 +141,18 @@ contract Crowdsale is ReentrancyGuard {
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid conditions are not met.
|
||||
* @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 {
|
||||
// optional override
|
||||
// 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.
|
||||
* @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
|
||||
*/
|
||||
@ -166,7 +161,8 @@ contract Crowdsale is ReentrancyGuard {
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Executed when a purchase has been validated and is ready to be executed. Doesn't necessarily emit/send tokens.
|
||||
* @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
|
||||
*/
|
||||
@ -175,12 +171,13 @@ contract Crowdsale is ReentrancyGuard {
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Override for extensions that require an internal state to check for validity (current user contributions, etc.)
|
||||
* @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 {
|
||||
// optional override
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
@ -45,5 +45,7 @@ contract FinalizableCrowdsale is TimedCrowdsale {
|
||||
* should call super._finalization() to ensure the chain of finalization is
|
||||
* executed entirely.
|
||||
*/
|
||||
function _finalization() internal {}
|
||||
function _finalization() internal {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../math/SafeMath.sol";
|
||||
import "./FinalizableCrowdsale.sol";
|
||||
@ -44,7 +44,7 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
|
||||
* @dev Investors can claim refunds here if crowdsale is unsuccessful
|
||||
* @param refundee Whose refund will be claimed.
|
||||
*/
|
||||
function claimRefund(address refundee) public {
|
||||
function claimRefund(address payable refundee) public {
|
||||
require(finalized());
|
||||
require(!goalReached());
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "./RefundableCrowdsale.sol";
|
||||
import "./PostDeliveryCrowdsale.sol";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Crowdsale.sol";
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
@ -37,7 +37,7 @@ contract AllowanceCrowdsale is Crowdsale {
|
||||
* @return Amount of tokens left in the allowance
|
||||
*/
|
||||
function remainingTokens() public view returns (uint256) {
|
||||
return Math.min(token().balanceOf(_tokenWallet), token().allowance(_tokenWallet, this));
|
||||
return Math.min(token().balanceOf(_tokenWallet), token().allowance(_tokenWallet, address(this)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../Crowdsale.sol";
|
||||
import "../../token/ERC20/ERC20Mintable.sol";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
@ -59,7 +59,7 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// solium-disable-next-line security/no-block-members
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
uint256 elapsedTime = block.timestamp.sub(openingTime());
|
||||
uint256 timeRange = closingTime().sub(openingTime());
|
||||
uint256 rateRange = _initialRate.sub(_finalRate);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
|
||||
@ -1,17 +1,16 @@
|
||||
pragma solidity ^0.4.18;
|
||||
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.
|
||||
* @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
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
@ -27,7 +27,7 @@ contract TimedCrowdsale is Crowdsale {
|
||||
* @param closingTime Crowdsale closing time
|
||||
*/
|
||||
constructor (uint256 openingTime, uint256 closingTime) public {
|
||||
// solium-disable-next-line security/no-block-members
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
require(openingTime >= block.timestamp);
|
||||
require(closingTime > openingTime);
|
||||
|
||||
@ -53,7 +53,7 @@ contract TimedCrowdsale is Crowdsale {
|
||||
* @return true if the crowdsale is open, false otherwise.
|
||||
*/
|
||||
function isOpen() public view returns (bool) {
|
||||
// solium-disable-next-line security/no-block-members
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
return block.timestamp >= _openingTime && block.timestamp <= _closingTime;
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ contract TimedCrowdsale is Crowdsale {
|
||||
* @return Whether crowdsale period has elapsed
|
||||
*/
|
||||
function hasClosed() public view returns (bool) {
|
||||
// solium-disable-next-line security/no-block-members
|
||||
// solhint-disable-next-line not-rely-on-time
|
||||
return block.timestamp > _closingTime;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
import "../Crowdsale.sol";
|
||||
import "../../access/roles/WhitelistedRole.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @title Elliptic curve signature operations
|
||||
@ -13,7 +13,7 @@ library ECDSA {
|
||||
* @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address.
|
||||
* @param signature bytes signature, the signature is generated using web3.eth.sign()
|
||||
*/
|
||||
function recover(bytes32 hash, bytes signature) internal pure returns (address) {
|
||||
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
|
||||
bytes32 r;
|
||||
bytes32 s;
|
||||
uint8 v;
|
||||
@ -26,7 +26,7 @@ library ECDSA {
|
||||
// Divide the signature in r, s and v variables
|
||||
// ecrecover takes the signature parameters, and the only way to get them
|
||||
// currently is to use assembly.
|
||||
// solium-disable-next-line security/no-inline-assembly
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
r := mload(add(signature, 0x20))
|
||||
s := mload(add(signature, 0x40))
|
||||
@ -42,7 +42,6 @@ library ECDSA {
|
||||
if (v != 27 && v != 28) {
|
||||
return (address(0));
|
||||
} else {
|
||||
// solium-disable-next-line arg-overflow
|
||||
return ecrecover(hash, v, r, s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @title MerkleProof
|
||||
@ -13,7 +13,7 @@ library MerkleProof {
|
||||
* @param root Merkle root
|
||||
* @param leaf Leaf of Merkle tree
|
||||
*/
|
||||
function verify(bytes32[] proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
|
||||
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
|
||||
bytes32 computedHash = leaf;
|
||||
|
||||
for (uint256 i = 0; i < proof.length; i++) {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @title Counter
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
|
||||
@ -6,20 +6,19 @@ import "../../token/ERC20/IERC20.sol";
|
||||
* @title ERC-1047 Token Metadata
|
||||
* @dev See https://eips.ethereum.org/EIPS/eip-1046
|
||||
* @dev tokenURI must respond with a URI that implements https://eips.ethereum.org/EIPS/eip-1047
|
||||
* @dev TODO - update https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/IERC721.sol#L17 when 1046 is finalized
|
||||
*/
|
||||
contract ERC20TokenMetadata is IERC20 {
|
||||
function tokenURI() external view returns (string);
|
||||
function tokenURI() external view returns (string memory);
|
||||
}
|
||||
|
||||
contract ERC20WithMetadata is ERC20TokenMetadata {
|
||||
string private _tokenURI;
|
||||
|
||||
constructor (string tokenURI) public {
|
||||
constructor (string memory tokenURI) public {
|
||||
_tokenURI = tokenURI;
|
||||
}
|
||||
|
||||
function tokenURI() external view returns (string) {
|
||||
function tokenURI() external view returns (string memory) {
|
||||
return _tokenURI;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
@ -44,7 +44,7 @@ contract ERC20Migrator {
|
||||
* @param legacyToken address of the old token contract
|
||||
*/
|
||||
constructor (IERC20 legacyToken) public {
|
||||
require(legacyToken != address(0));
|
||||
require(address(legacyToken) != address(0));
|
||||
_legacyToken = legacyToken;
|
||||
}
|
||||
|
||||
@ -68,9 +68,9 @@ contract ERC20Migrator {
|
||||
* @param newToken the token that will be minted
|
||||
*/
|
||||
function beginMigration(ERC20Mintable newToken) public {
|
||||
require(_newToken == address(0));
|
||||
require(newToken != address(0));
|
||||
require(newToken.isMinter(this));
|
||||
require(address(_newToken) == address(0));
|
||||
require(address(newToken) != address(0));
|
||||
require(newToken.isMinter(address(this)));
|
||||
|
||||
_newToken = newToken;
|
||||
}
|
||||
@ -82,7 +82,7 @@ contract ERC20Migrator {
|
||||
* @param amount amount of tokens to be migrated
|
||||
*/
|
||||
function migrate(address account, uint256 amount) public {
|
||||
_legacyToken.safeTransferFrom(account, this, amount);
|
||||
_legacyToken.safeTransferFrom(account, address(this), amount);
|
||||
_newToken.mint(account, amount);
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ contract ERC20Migrator {
|
||||
*/
|
||||
function migrateAll(address account) public {
|
||||
uint256 balance = _legacyToken.balanceOf(account);
|
||||
uint256 allowance = _legacyToken.allowance(account, this);
|
||||
uint256 allowance = _legacyToken.allowance(account, address(this));
|
||||
uint256 amount = Math.min(balance, allowance);
|
||||
migrate(account, amount);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/roles/SignerRole.sol";
|
||||
import "../cryptography/ECDSA.sol";
|
||||
@ -43,12 +43,14 @@ contract SignatureBouncer is SignerRole {
|
||||
// Signature size is 65 bytes (tightly packed v + r + s), but gets padded to 96 bytes
|
||||
uint256 private constant _SIGNATURE_SIZE = 96;
|
||||
|
||||
constructor () internal {}
|
||||
constructor () internal {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev requires that a valid signature of a signer was provided
|
||||
*/
|
||||
modifier onlyValidSignature(bytes signature) {
|
||||
modifier onlyValidSignature(bytes memory signature) {
|
||||
require(_isValidSignature(msg.sender, signature));
|
||||
_;
|
||||
}
|
||||
@ -56,7 +58,7 @@ contract SignatureBouncer is SignerRole {
|
||||
/**
|
||||
* @dev requires that a valid signature with a specifed method of a signer was provided
|
||||
*/
|
||||
modifier onlyValidSignatureAndMethod(bytes signature) {
|
||||
modifier onlyValidSignatureAndMethod(bytes memory signature) {
|
||||
require(_isValidSignatureAndMethod(msg.sender, signature));
|
||||
_;
|
||||
}
|
||||
@ -64,7 +66,7 @@ contract SignatureBouncer is SignerRole {
|
||||
/**
|
||||
* @dev requires that a valid signature with a specifed method and params of a signer was provided
|
||||
*/
|
||||
modifier onlyValidSignatureAndData(bytes signature) {
|
||||
modifier onlyValidSignatureAndData(bytes memory signature) {
|
||||
require(_isValidSignatureAndData(msg.sender, signature));
|
||||
_;
|
||||
}
|
||||
@ -73,7 +75,7 @@ contract SignatureBouncer is SignerRole {
|
||||
* @dev is the signature of `this + sender` from a signer?
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidSignature(address account, bytes signature) internal view returns (bool) {
|
||||
function _isValidSignature(address account, bytes memory signature) internal view returns (bool) {
|
||||
return _isValidDataHash(keccak256(abi.encodePacked(address(this), account)), signature);
|
||||
}
|
||||
|
||||
@ -81,7 +83,7 @@ contract SignatureBouncer is SignerRole {
|
||||
* @dev is the signature of `this + sender + methodId` from a signer?
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidSignatureAndMethod(address account, bytes signature) internal view returns (bool) {
|
||||
function _isValidSignatureAndMethod(address account, bytes memory signature) internal view returns (bool) {
|
||||
bytes memory data = new bytes(_METHOD_ID_SIZE);
|
||||
for (uint i = 0; i < data.length; i++) {
|
||||
data[i] = msg.data[i];
|
||||
@ -94,7 +96,7 @@ contract SignatureBouncer is SignerRole {
|
||||
* @notice the signature parameter of the method being validated must be the "last" parameter
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidSignatureAndData(address account, bytes signature) internal view returns (bool) {
|
||||
function _isValidSignatureAndData(address account, bytes memory signature) internal view returns (bool) {
|
||||
require(msg.data.length > _SIGNATURE_SIZE);
|
||||
|
||||
bytes memory data = new bytes(msg.data.length - _SIGNATURE_SIZE);
|
||||
@ -110,7 +112,7 @@ contract SignatureBouncer is SignerRole {
|
||||
* and then recover the signature and check it against the signer role
|
||||
* @return bool
|
||||
*/
|
||||
function _isValidDataHash(bytes32 hash, bytes signature) internal view returns (bool) {
|
||||
function _isValidDataHash(bytes32 hash, bytes memory signature) internal view returns (bool) {
|
||||
address signer = hash.toEthSignedMessageHash().recover(signature);
|
||||
|
||||
return signer != address(0) && isSigner(signer);
|
||||
|
||||
60
contracts/drafts/SignedSafeMath.sol
Normal file
60
contracts/drafts/SignedSafeMath.sol
Normal file
@ -0,0 +1,60 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @title SignedSafeMath
|
||||
* @dev Signed math operations with safety checks that revert on error
|
||||
*/
|
||||
library SignedSafeMath {
|
||||
int256 constant private INT256_MIN = -2**255;
|
||||
|
||||
/**
|
||||
* @dev Multiplies two signed integers, reverts on overflow.
|
||||
*/
|
||||
function mul(int256 a, int256 b) internal pure returns (int256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below
|
||||
|
||||
int256 c = a * b;
|
||||
require(c / a == b);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
|
||||
*/
|
||||
function div(int256 a, int256 b) internal pure returns (int256) {
|
||||
require(b != 0); // Solidity only automatically asserts when dividing by 0
|
||||
require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow
|
||||
|
||||
int256 c = a / b;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Subtracts two signed integers, reverts on overflow.
|
||||
*/
|
||||
function sub(int256 a, int256 b) internal pure returns (int256) {
|
||||
int256 c = a - b;
|
||||
require((b >= 0 && c <= a) || (b < 0 && c > a));
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds two signed integers, reverts on overflow.
|
||||
*/
|
||||
function add(int256 a, int256 b) internal pure returns (int256) {
|
||||
int256 c = a + b;
|
||||
require((b >= 0 && c >= a) || (b < 0 && c < a));
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,4 @@
|
||||
/* solium-disable security/no-block-members */
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
import "../ownership/Ownable.sol";
|
||||
@ -13,6 +11,12 @@ import "../math/SafeMath.sol";
|
||||
* owner.
|
||||
*/
|
||||
contract TokenVesting is Ownable {
|
||||
// The vesting schedule is time-based (i.e. using block timestamps as opposed to e.g. block numbers), and is
|
||||
// therefore sensitive to timestamp manipulation (which is something miners can do, to a certain degree). Therefore,
|
||||
// it is recommended to avoid using short time durations (less than a minute). Typical vesting schemes, with a cliff
|
||||
// period of a year and a duration of four years, are safe to use.
|
||||
// solhint-disable not-rely-on-time
|
||||
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
@ -22,6 +26,7 @@ contract TokenVesting is Ownable {
|
||||
// beneficiary of tokens after they are released
|
||||
address private _beneficiary;
|
||||
|
||||
// Durations and timestamps are expressed in UNIX time, the same units as block.timestamp.
|
||||
uint256 private _cliff;
|
||||
uint256 private _start;
|
||||
uint256 private _duration;
|
||||
@ -112,11 +117,11 @@ contract TokenVesting is Ownable {
|
||||
|
||||
require(unreleased > 0);
|
||||
|
||||
_released[token] = _released[token].add(unreleased);
|
||||
_released[address(token)] = _released[address(token)].add(unreleased);
|
||||
|
||||
token.safeTransfer(_beneficiary, unreleased);
|
||||
|
||||
emit TokensReleased(token, unreleased);
|
||||
emit TokensReleased(address(token), unreleased);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,18 +131,18 @@ contract TokenVesting is Ownable {
|
||||
*/
|
||||
function revoke(IERC20 token) public onlyOwner {
|
||||
require(_revocable);
|
||||
require(!_revoked[token]);
|
||||
require(!_revoked[address(token)]);
|
||||
|
||||
uint256 balance = token.balanceOf(address(this));
|
||||
|
||||
uint256 unreleased = _releasableAmount(token);
|
||||
uint256 refund = balance.sub(unreleased);
|
||||
|
||||
_revoked[token] = true;
|
||||
_revoked[address(token)] = true;
|
||||
|
||||
token.safeTransfer(owner(), refund);
|
||||
|
||||
emit TokenVestingRevoked(token);
|
||||
emit TokenVestingRevoked(address(token));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,7 +150,7 @@ contract TokenVesting is Ownable {
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function _releasableAmount(IERC20 token) private view returns (uint256) {
|
||||
return _vestedAmount(token).sub(_released[token]);
|
||||
return _vestedAmount(token).sub(_released[address(token)]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,11 +159,11 @@ contract TokenVesting is Ownable {
|
||||
*/
|
||||
function _vestedAmount(IERC20 token) private view returns (uint256) {
|
||||
uint256 currentBalance = token.balanceOf(address(this));
|
||||
uint256 totalBalance = currentBalance.add(_released[token]);
|
||||
uint256 totalBalance = currentBalance.add(_released[address(token)]);
|
||||
|
||||
if (block.timestamp < _cliff) {
|
||||
return 0;
|
||||
} else if (block.timestamp >= _start.add(_duration) || _revoked[token]) {
|
||||
} else if (block.timestamp >= _start.add(_duration) || _revoked[address(token)]) {
|
||||
return totalBalance;
|
||||
} else {
|
||||
return totalBalance.mul(block.timestamp.sub(_start)).div(_duration);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../crowdsale/validation/CappedCrowdsale.sol";
|
||||
import "../crowdsale/distribution/RefundableCrowdsale.sol";
|
||||
@ -12,7 +12,9 @@ import "../token/ERC20/ERC20Detailed.sol";
|
||||
* It is meant to be used in a crowdsale contract.
|
||||
*/
|
||||
contract SampleCrowdsaleToken is ERC20Mintable, ERC20Detailed {
|
||||
constructor () public ERC20Detailed("Sample Crowdsale Token", "SCT", 18) {}
|
||||
constructor () public ERC20Detailed("Sample Crowdsale Token", "SCT", 18) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -28,17 +30,12 @@ contract SampleCrowdsaleToken is ERC20Mintable, ERC20Detailed {
|
||||
* After adding multiple features it's good practice to run integration tests
|
||||
* to ensure that subcontracts works together as intended.
|
||||
*/
|
||||
// XXX There doesn't seem to be a way to split this line that keeps solium
|
||||
// happy. See:
|
||||
// https://github.com/duaraghav8/Solium/issues/205
|
||||
// --elopio - 2018-05-10
|
||||
// solium-disable-next-line max-len
|
||||
contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale, MintedCrowdsale {
|
||||
constructor (
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
uint256 rate,
|
||||
address wallet,
|
||||
address payable wallet,
|
||||
uint256 cap,
|
||||
ERC20Mintable token,
|
||||
uint256 goal
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../token/ERC20/ERC20Detailed.sol";
|
||||
@ -10,12 +10,13 @@ import "../token/ERC20/ERC20Detailed.sol";
|
||||
* `ERC20` functions.
|
||||
*/
|
||||
contract SimpleToken is ERC20, ERC20Detailed {
|
||||
uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(decimals()));
|
||||
uint8 public constant DECIMALS = 18;
|
||||
uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(DECIMALS));
|
||||
|
||||
/**
|
||||
* @dev Constructor that gives msg.sender all of existing tokens.
|
||||
*/
|
||||
constructor () public ERC20Detailed("SimpleToken", "SIM", 18) {
|
||||
constructor () public ERC20Detailed("SimpleToken", "SIM", DECIMALS) {
|
||||
_mint(msg.sender, INITIAL_SUPPLY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "./IERC165.sol";
|
||||
|
||||
@ -8,7 +8,7 @@ import "./IERC165.sol";
|
||||
* @dev Implements ERC165 using a lookup table.
|
||||
*/
|
||||
contract ERC165 is IERC165 {
|
||||
bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7;
|
||||
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
|
||||
/**
|
||||
* 0x01ffc9a7 ===
|
||||
* bytes4(keccak256('supportsInterface(bytes4)'))
|
||||
@ -24,7 +24,7 @@ contract ERC165 is IERC165 {
|
||||
* implement ERC165 itself
|
||||
*/
|
||||
constructor () internal {
|
||||
_registerInterface(_InterfaceId_ERC165);
|
||||
_registerInterface(_INTERFACE_ID_ERC165);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @title ERC165Checker
|
||||
@ -7,9 +7,9 @@ pragma solidity ^0.4.24;
|
||||
*/
|
||||
library ERC165Checker {
|
||||
// As per the EIP-165 spec, no interface should ever match 0xffffffff
|
||||
bytes4 private constant _InterfaceId_Invalid = 0xffffffff;
|
||||
bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
|
||||
|
||||
bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7;
|
||||
bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
|
||||
/**
|
||||
* 0x01ffc9a7 ===
|
||||
* bytes4(keccak256('supportsInterface(bytes4)'))
|
||||
@ -23,8 +23,8 @@ library ERC165Checker {
|
||||
function _supportsERC165(address account) internal view returns (bool) {
|
||||
// Any contract that implements ERC165 must explicitly indicate support of
|
||||
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
|
||||
return _supportsERC165Interface(account, _InterfaceId_ERC165) &&
|
||||
!_supportsERC165Interface(account, _InterfaceId_Invalid);
|
||||
return _supportsERC165Interface(account, _INTERFACE_ID_ERC165) &&
|
||||
!_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,7 +49,7 @@ library ERC165Checker {
|
||||
* interfaceIds list, false otherwise
|
||||
* @dev Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function _supportsAllInterfaces(address account, bytes4[] interfaceIds) internal view returns (bool) {
|
||||
function _supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
|
||||
// query support of ERC165 itself
|
||||
if (!_supportsERC165(account)) {
|
||||
return false;
|
||||
@ -94,13 +94,13 @@ library ERC165Checker {
|
||||
* indicates support of the interface with identifier interfaceId, false otherwise
|
||||
*/
|
||||
function _callERC165SupportsInterface(address account, bytes4 interfaceId)
|
||||
private
|
||||
view
|
||||
returns (bool success, bool result)
|
||||
private
|
||||
view
|
||||
returns (bool success, bool result)
|
||||
{
|
||||
bytes memory encodedParams = abi.encodeWithSelector(_InterfaceId_ERC165,interfaceId);
|
||||
bytes memory encodedParams = abi.encodeWithSelector(_INTERFACE_ID_ERC165, interfaceId);
|
||||
|
||||
// solium-disable-next-line security/no-inline-assembly
|
||||
// solhint-disable-next-line no-inline-assembly
|
||||
assembly {
|
||||
let encodedParams_data := add(0x20, encodedParams)
|
||||
let encodedParams_size := mload(encodedParams)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @title IERC165
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/roles/PauserRole.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @title Math
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
/**
|
||||
* @title SafeMath
|
||||
* @dev Math operations with safety checks that revert on error
|
||||
* @dev Unsigned math operations with safety checks that revert on error
|
||||
*/
|
||||
library SafeMath {
|
||||
int256 constant private INT256_MIN = -2**255;
|
||||
|
||||
/**
|
||||
* @dev Multiplies two unsigned integers, reverts on overflow.
|
||||
*/
|
||||
@ -24,25 +22,6 @@ library SafeMath {
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Multiplies two signed integers, reverts on overflow.
|
||||
*/
|
||||
function mul(int256 a, int256 b) internal pure returns (int256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below
|
||||
|
||||
int256 c = a * b;
|
||||
require(c / a == b);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
|
||||
*/
|
||||
@ -55,18 +34,6 @@ library SafeMath {
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
|
||||
*/
|
||||
function div(int256 a, int256 b) internal pure returns (int256) {
|
||||
require(b != 0); // Solidity only automatically asserts when dividing by 0
|
||||
require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow
|
||||
|
||||
int256 c = a / b;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
|
||||
*/
|
||||
@ -77,16 +44,6 @@ library SafeMath {
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Subtracts two signed integers, reverts on overflow.
|
||||
*/
|
||||
function sub(int256 a, int256 b) internal pure returns (int256) {
|
||||
int256 c = a - b;
|
||||
require((b >= 0 && c <= a) || (b < 0 && c > a));
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds two unsigned integers, reverts on overflow.
|
||||
*/
|
||||
@ -97,16 +54,6 @@ library SafeMath {
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds two signed integers, reverts on overflow.
|
||||
*/
|
||||
function add(int256 a, int256 b) internal pure returns (int256) {
|
||||
int256 c = a + b;
|
||||
require((b >= 0 && c >= a) || (b < 0 && c < a));
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
|
||||
* reverts when dividing by zero.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
contract Acknowledger {
|
||||
event AcknowledgeFoo(uint256 a);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../utils/Address.sol";
|
||||
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/emission/AllowanceCrowdsale.sol";
|
||||
|
||||
contract AllowanceCrowdsaleImpl is AllowanceCrowdsale {
|
||||
constructor (uint256 rate, address wallet, IERC20 token, address tokenWallet)
|
||||
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.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../utils/Arrays.sol";
|
||||
|
||||
@ -7,7 +7,7 @@ contract ArraysImpl {
|
||||
|
||||
uint256[] private array;
|
||||
|
||||
constructor (uint256[] _array) public {
|
||||
constructor (uint256[] memory _array) public {
|
||||
array = _array;
|
||||
}
|
||||
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/validation/CappedCrowdsale.sol";
|
||||
|
||||
contract CappedCrowdsaleImpl is CappedCrowdsale {
|
||||
constructor (uint256 rate, address wallet, IERC20 token, uint256 cap)
|
||||
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,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/roles/CapperRole.sol";
|
||||
|
||||
@ -8,6 +8,7 @@ contract CapperRoleMock is CapperRole {
|
||||
}
|
||||
|
||||
function onlyCapperMock() public view onlyCapper {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
// Causes a compilation error if super._removeCapper is not internal
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../payment/escrow/ConditionalEscrow.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../drafts/Counter.sol";
|
||||
|
||||
@ -10,7 +10,7 @@ contract CounterImpl {
|
||||
// use whatever key you want to track your counters
|
||||
mapping(string => Counter.Counter) private _counters;
|
||||
|
||||
function doThing(string key) public returns (uint256) {
|
||||
function doThing(string memory key) public returns (uint256) {
|
||||
theId = _counters[key].next();
|
||||
return theId;
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../crowdsale/Crowdsale.sol";
|
||||
|
||||
contract CrowdsaleMock is Crowdsale {
|
||||
constructor (uint256 rate, address wallet, IERC20 token) public Crowdsale(rate, wallet, token) {}
|
||||
constructor (uint256 rate, address payable wallet, IERC20 token) public Crowdsale(rate, wallet, token) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,13 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../token/ERC20/ERC20Detailed.sol";
|
||||
|
||||
contract ERC20DetailedMock is ERC20, ERC20Detailed {
|
||||
constructor (string name, string symbol, uint8 decimals) ERC20Detailed(name, symbol, decimals) public {}
|
||||
constructor (string memory name, string memory symbol, uint8 decimals)
|
||||
public
|
||||
ERC20Detailed(name, symbol, decimals)
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../cryptography/ECDSA.sol";
|
||||
|
||||
contract ECDSAMock {
|
||||
using ECDSA for bytes32;
|
||||
|
||||
function recover(bytes32 hash, bytes signature) public pure returns (address) {
|
||||
function recover(bytes32 hash, bytes memory signature) public pure returns (address) {
|
||||
return hash.recover(signature);
|
||||
}
|
||||
|
||||
|
||||
@ -1,17 +1,18 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../../introspection/IERC165.sol";
|
||||
|
||||
/**
|
||||
* https://github.com/ethereum/EIPs/blob/master/EIPS/eip-214.md#specification
|
||||
* > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead throw an exception.
|
||||
* > Any attempts to make state-changing operations inside an execution instance with STATIC set to true will instead
|
||||
* throw an exception.
|
||||
* > These operations include [...], LOG0, LOG1, LOG2, [...]
|
||||
*
|
||||
* therefore, because this contract is staticcall'd we need to not emit events (which is how solidity-coverage works)
|
||||
* solidity-coverage ignores the /mocks folder, so we duplicate its implementation here to avoid instrumenting it
|
||||
*/
|
||||
contract SupportsInterfaceWithLookupMock is IERC165 {
|
||||
bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7;
|
||||
bytes4 public constant INTERFACE_ID_ERC165 = 0x01ffc9a7;
|
||||
/**
|
||||
* 0x01ffc9a7 ===
|
||||
* bytes4(keccak256('supportsInterface(bytes4)'))
|
||||
@ -27,7 +28,7 @@ contract SupportsInterfaceWithLookupMock is IERC165 {
|
||||
* implement ERC165 itself
|
||||
*/
|
||||
constructor () public {
|
||||
_registerInterface(InterfaceId_ERC165);
|
||||
_registerInterface(INTERFACE_ID_ERC165);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,7 +48,7 @@ contract SupportsInterfaceWithLookupMock is IERC165 {
|
||||
}
|
||||
|
||||
contract ERC165InterfacesSupported is SupportsInterfaceWithLookupMock {
|
||||
constructor (bytes4[] interfaceIds) public {
|
||||
constructor (bytes4[] memory interfaceIds) public {
|
||||
for (uint256 i = 0; i < interfaceIds.length; i++) {
|
||||
_registerInterface(interfaceIds[i]);
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
contract ERC165NotSupported {}
|
||||
contract ERC165NotSupported {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../introspection/ERC165Checker.sol";
|
||||
|
||||
@ -13,7 +13,7 @@ contract ERC165CheckerMock {
|
||||
return account._supportsInterface(interfaceId);
|
||||
}
|
||||
|
||||
function supportsAllInterfaces(address account, bytes4[] interfaceIds) public view returns (bool) {
|
||||
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) public view returns (bool) {
|
||||
return account._supportsAllInterfaces(interfaceIds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../introspection/ERC165.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20Burnable.sol";
|
||||
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
pragma solidity ^0.4.24;
|
||||
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.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20Pausable.sol";
|
||||
import "./PauserRoleMock.sol";
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../drafts/ERC1046/TokenMetadata.sol";
|
||||
|
||||
contract ERC20WithMetadataMock is ERC20, ERC20WithMetadata {
|
||||
constructor (string tokenURI) public ERC20WithMetadata(tokenURI) {}
|
||||
constructor (string memory tokenURI) public ERC20WithMetadata(tokenURI) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC721/ERC721Full.sol";
|
||||
import "../token/ERC721/ERC721Mintable.sol";
|
||||
@ -11,7 +11,9 @@ import "../token/ERC721/ERC721Burnable.sol";
|
||||
* checking token existence, removal of a token from an address
|
||||
*/
|
||||
contract ERC721FullMock is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
|
||||
constructor (string name, string symbol) public ERC721Mintable() ERC721Full(name, symbol) {}
|
||||
constructor (string memory name, string memory symbol) public ERC721Mintable() ERC721Full(name, symbol) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
function exists(uint256 tokenId) public view returns (bool) {
|
||||
return _exists(tokenId);
|
||||
@ -21,7 +23,7 @@ contract ERC721FullMock is ERC721Full, ERC721Mintable, ERC721MetadataMintable, E
|
||||
return _tokensOfOwner(owner);
|
||||
}
|
||||
|
||||
function setTokenURI(uint256 tokenId, string uri) public {
|
||||
function setTokenURI(uint256 tokenId, string memory uri) public {
|
||||
_setTokenURI(tokenId, uri);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC721/ERC721Full.sol";
|
||||
import "../token/ERC721/ERC721Mintable.sol";
|
||||
@ -9,5 +9,7 @@ import "../token/ERC721/ERC721Burnable.sol";
|
||||
* @title ERC721MintableBurnableImpl
|
||||
*/
|
||||
contract ERC721MintableBurnableImpl is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
|
||||
constructor () ERC721Mintable() ERC721Full("Test", "TEST") public {}
|
||||
constructor () public ERC721Mintable() ERC721Full("Test", "TEST") {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC721/ERC721.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC721/ERC721Pausable.sol";
|
||||
import "./PauserRoleMock.sol";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC721/IERC721Receiver.sol";
|
||||
|
||||
@ -13,7 +13,9 @@ contract ERC721ReceiverMock is IERC721Receiver {
|
||||
_reverts = reverts;
|
||||
}
|
||||
|
||||
function onERC721Received(address operator, address from, uint256 tokenId, bytes data) public returns (bytes4) {
|
||||
function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
|
||||
public returns (bytes4)
|
||||
{
|
||||
require(!_reverts);
|
||||
emit Received(operator, from, tokenId, data, gasleft());
|
||||
return _retval;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
contract EventEmitter {
|
||||
event Argumentless();
|
||||
@ -11,7 +11,7 @@ contract EventEmitter {
|
||||
event String(string value);
|
||||
event LongUintBooleanString(uint256 uintValue, bool booleanValue, string stringValue);
|
||||
|
||||
constructor (uint8 uintValue, bool booleanValue, string stringValue) public {
|
||||
constructor (uint8 uintValue, bool booleanValue, string memory stringValue) public {
|
||||
emit ShortUint(uintValue);
|
||||
emit Boolean(booleanValue);
|
||||
emit String(stringValue);
|
||||
@ -45,11 +45,11 @@ contract EventEmitter {
|
||||
emit Boolean(value);
|
||||
}
|
||||
|
||||
function emitString(string value) public {
|
||||
function emitString(string memory value) public {
|
||||
emit String(value);
|
||||
}
|
||||
|
||||
function emitLongUintBooleanString(uint256 uintValue, bool booleanValue, string stringValue) public {
|
||||
function emitLongUintBooleanString(uint256 uintValue, bool booleanValue, string memory stringValue) public {
|
||||
emit LongUintBooleanString(uintValue, booleanValue, stringValue);
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ contract EventEmitter {
|
||||
emit Boolean(boolValue);
|
||||
}
|
||||
|
||||
function emitStringAndEmitIndirectly(string value, IndirectEventEmitter emitter) public {
|
||||
function emitStringAndEmitIndirectly(string memory value, IndirectEventEmitter emitter) public {
|
||||
emit String(value);
|
||||
emitter.emitStringIndirectly(value);
|
||||
}
|
||||
@ -67,7 +67,7 @@ contract EventEmitter {
|
||||
contract IndirectEventEmitter {
|
||||
event IndirectString(string value);
|
||||
|
||||
function emitStringIndirectly(string value) public {
|
||||
function emitStringIndirectly(string memory value) public {
|
||||
emit IndirectString(value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
contract Failer {
|
||||
uint256[] private array;
|
||||
|
||||
function dontFail() public pure {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
function failWithRevert() public pure {
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
pragma solidity ^0.4.24;
|
||||
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 wallet, IERC20 token)
|
||||
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,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../crowdsale/price/IncreasingPriceCrowdsale.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
@ -7,7 +7,7 @@ contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale {
|
||||
constructor (
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
address wallet,
|
||||
address payable wallet,
|
||||
IERC20 token,
|
||||
uint256 initialRate,
|
||||
uint256 finalRate
|
||||
@ -16,5 +16,7 @@ contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale {
|
||||
Crowdsale(initialRate, wallet, token)
|
||||
TimedCrowdsale(openingTime, closingTime)
|
||||
IncreasingPriceCrowdsale(initialRate, finalRate)
|
||||
{}
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
pragma solidity ^0.4.24;
|
||||
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 wallet, IERC20 token) public Crowdsale(rate, wallet, token)
|
||||
{}
|
||||
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.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../math/Math.sol";
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import { MerkleProof } from "../cryptography/MerkleProof.sol";
|
||||
|
||||
contract MerkleProofWrapper {
|
||||
function verify(bytes32[] proof, bytes32 root, bytes32 leaf) public pure returns (bool) {
|
||||
function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) public pure returns (bool) {
|
||||
return MerkleProof.verify(proof, root, leaf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
import "../crowdsale/emission/MintedCrowdsale.sol";
|
||||
|
||||
contract MintedCrowdsaleImpl is MintedCrowdsale {
|
||||
constructor (uint256 rate, address wallet, ERC20Mintable token) public Crowdsale(rate, wallet, token) {}
|
||||
constructor (uint256 rate, address payable wallet, ERC20Mintable token) public Crowdsale(rate, wallet, token) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/roles/MinterRole.sol";
|
||||
|
||||
@ -8,6 +8,7 @@ contract MinterRoleMock is MinterRole {
|
||||
}
|
||||
|
||||
function onlyMinterMock() public view onlyMinter {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
// Causes a compilation error if super._removeMinter is not internal
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../ownership/Ownable.sol";
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../ownership/Ownable.sol";
|
||||
|
||||
contract OwnableMock is Ownable {}
|
||||
contract OwnableMock is Ownable {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
pragma solidity ^0.4.18;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../crowdsale/validation/PausableCrowdsale.sol";
|
||||
|
||||
contract PausableCrowdsaleImpl is PausableCrowdsale {
|
||||
constructor (uint256 _rate, address _wallet, ERC20 _token) public Crowdsale(_rate, _wallet, _token) {
|
||||
constructor (uint256 _rate, address payable _wallet, ERC20 _token) public Crowdsale(_rate, _wallet, _token) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../lifecycle/Pausable.sol";
|
||||
import "./PauserRoleMock.sol";
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/roles/PauserRole.sol";
|
||||
|
||||
@ -8,6 +8,7 @@ contract PauserRoleMock is PauserRole {
|
||||
}
|
||||
|
||||
function onlyPauserMock() public view onlyPauser {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
// Causes a compilation error if super._removePauser is not internal
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/distribution/PostDeliveryCrowdsale.sol";
|
||||
|
||||
contract PostDeliveryCrowdsaleImpl is PostDeliveryCrowdsale {
|
||||
constructor (uint256 openingTime, uint256 closingTime, uint256 rate, address wallet, IERC20 token)
|
||||
constructor (uint256 openingTime, uint256 closingTime, uint256 rate, address payable wallet, IERC20 token)
|
||||
public
|
||||
TimedCrowdsale(openingTime, closingTime)
|
||||
Crowdsale(rate, wallet, token)
|
||||
{}
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../payment/PullPayment.sol";
|
||||
|
||||
// mock class using PullPayment
|
||||
contract PullPaymentMock is PullPayment {
|
||||
constructor () public payable { }
|
||||
constructor () public payable {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
// test helper function to call asyncTransfer
|
||||
function callTransfer(address dest, uint256 amount) public {
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
contract ReentrancyAttack {
|
||||
|
||||
function callSender(bytes4 data) public {
|
||||
// solium-disable-next-line security/no-low-level-calls
|
||||
require(msg.sender.call(abi.encodeWithSelector(data)));
|
||||
// solhint-disable-next-line avoid-low-level-calls
|
||||
(bool success,) = msg.sender.call(abi.encodeWithSelector(data));
|
||||
require(success);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../utils/ReentrancyGuard.sol";
|
||||
import "./ReentrancyAttack.sol";
|
||||
@ -24,9 +24,9 @@ contract ReentrancyMock is ReentrancyGuard {
|
||||
function countThisRecursive(uint256 n) public nonReentrant {
|
||||
if (n > 0) {
|
||||
count();
|
||||
// solium-disable-next-line security/no-low-level-calls
|
||||
bool result = address(this).call(abi.encodeWithSignature("countThisRecursive(uint256)", n - 1));
|
||||
require(result == true);
|
||||
// solhint-disable-next-line avoid-low-level-calls
|
||||
(bool success,) = address(this).call(abi.encodeWithSignature("countThisRecursive(uint256)", n - 1));
|
||||
require(success);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/distribution/RefundableCrowdsale.sol";
|
||||
@ -8,7 +8,7 @@ contract RefundableCrowdsaleImpl is RefundableCrowdsale {
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
uint256 rate,
|
||||
address wallet,
|
||||
address payable wallet,
|
||||
IERC20 token,
|
||||
uint256 goal
|
||||
)
|
||||
@ -16,5 +16,7 @@ contract RefundableCrowdsaleImpl is RefundableCrowdsale {
|
||||
Crowdsale(rate, wallet, token)
|
||||
TimedCrowdsale(openingTime, closingTime)
|
||||
RefundableCrowdsale(goal)
|
||||
{}
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/distribution/RefundablePostDeliveryCrowdsale.sol";
|
||||
@ -8,7 +8,7 @@ contract RefundablePostDeliveryCrowdsaleImpl is RefundablePostDeliveryCrowdsale
|
||||
uint256 openingTime,
|
||||
uint256 closingTime,
|
||||
uint256 rate,
|
||||
address wallet,
|
||||
address payable wallet,
|
||||
IERC20 token,
|
||||
uint256 goal
|
||||
)
|
||||
@ -16,5 +16,7 @@ contract RefundablePostDeliveryCrowdsaleImpl is RefundablePostDeliveryCrowdsale
|
||||
Crowdsale(rate, wallet, token)
|
||||
TimedCrowdsale(openingTime, closingTime)
|
||||
RefundableCrowdsale(goal)
|
||||
{}
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/Roles.sol";
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
@ -24,7 +24,7 @@ contract ERC20FailingMock {
|
||||
}
|
||||
|
||||
contract ERC20SucceedingMock {
|
||||
uint256 private _allowance;
|
||||
mapping (address => uint256) private _allowances;
|
||||
|
||||
function transfer(address, uint256) public returns (bool) {
|
||||
return true;
|
||||
@ -39,11 +39,11 @@ contract ERC20SucceedingMock {
|
||||
}
|
||||
|
||||
function setAllowance(uint256 allowance_) public {
|
||||
_allowance = allowance_;
|
||||
_allowances[msg.sender] = allowance_;
|
||||
}
|
||||
|
||||
function allowance(address, address) public view returns (uint256) {
|
||||
return _allowance;
|
||||
function allowance(address owner, address) public view returns (uint256) {
|
||||
return _allowances[owner];
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,12 +54,10 @@ contract SafeERC20Helper {
|
||||
IERC20 private _succeeding;
|
||||
|
||||
constructor () public {
|
||||
_failing = IERC20(new ERC20FailingMock());
|
||||
_succeeding = IERC20(new ERC20SucceedingMock());
|
||||
_failing = IERC20(address(new ERC20FailingMock()));
|
||||
_succeeding = IERC20(address(new ERC20SucceedingMock()));
|
||||
}
|
||||
|
||||
// Using _failing
|
||||
|
||||
function doFailingTransfer() public {
|
||||
_failing.safeTransfer(address(0), 0);
|
||||
}
|
||||
@ -80,8 +78,6 @@ contract SafeERC20Helper {
|
||||
_failing.safeDecreaseAllowance(address(0), 0);
|
||||
}
|
||||
|
||||
// Using _succeeding
|
||||
|
||||
function doSucceedingTransfer() public {
|
||||
_succeeding.safeTransfer(address(0), 0);
|
||||
}
|
||||
@ -103,7 +99,7 @@ contract SafeERC20Helper {
|
||||
}
|
||||
|
||||
function setAllowance(uint256 allowance_) public {
|
||||
ERC20SucceedingMock(_succeeding).setAllowance(allowance_);
|
||||
ERC20SucceedingMock(address(_succeeding)).setAllowance(allowance_);
|
||||
}
|
||||
|
||||
function allowance() public view returns (uint256) {
|
||||
|
||||
@ -1,43 +1,25 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
|
||||
contract SafeMathMock {
|
||||
function mulUints(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
function mul(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return SafeMath.mul(a, b);
|
||||
}
|
||||
|
||||
function mulInts(int256 a, int256 b) public pure returns (int256) {
|
||||
return SafeMath.mul(a, b);
|
||||
}
|
||||
|
||||
function divUints(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
function div(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return SafeMath.div(a, b);
|
||||
}
|
||||
|
||||
function divInts(int256 a, int256 b) public pure returns (int256) {
|
||||
return SafeMath.div(a, b);
|
||||
}
|
||||
|
||||
function subUints(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
function sub(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return SafeMath.sub(a, b);
|
||||
}
|
||||
|
||||
function subInts(int256 a, int256 b) public pure returns (int256) {
|
||||
return SafeMath.sub(a, b);
|
||||
}
|
||||
|
||||
function addUints(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
function add(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return SafeMath.add(a, b);
|
||||
}
|
||||
|
||||
function addInts(int256 a, int256 b) public pure returns (int256) {
|
||||
return SafeMath.add(a, b);
|
||||
}
|
||||
|
||||
function modUints(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
function mod(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return SafeMath.mod(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../ownership/Secondary.sol";
|
||||
|
||||
contract SecondaryMock is Secondary {
|
||||
function onlyPrimaryMock() public view onlyPrimary {}
|
||||
function onlyPrimaryMock() public view onlyPrimary {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,28 +1,50 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../drafts/SignatureBouncer.sol";
|
||||
import "./SignerRoleMock.sol";
|
||||
|
||||
contract SignatureBouncerMock is SignatureBouncer, SignerRoleMock {
|
||||
function checkValidSignature(address account, bytes signature) public view returns (bool) {
|
||||
function checkValidSignature(address account, bytes memory signature)
|
||||
public view returns (bool)
|
||||
{
|
||||
return _isValidSignature(account, signature);
|
||||
}
|
||||
|
||||
function onlyWithValidSignature(bytes signature) public onlyValidSignature(signature) view {}
|
||||
function onlyWithValidSignature(bytes memory signature)
|
||||
public onlyValidSignature(signature) view
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
function checkValidSignatureAndMethod(address account, bytes signature) public view returns (bool) {
|
||||
function checkValidSignatureAndMethod(address account, bytes memory signature)
|
||||
public view returns (bool)
|
||||
{
|
||||
return _isValidSignatureAndMethod(account, signature);
|
||||
}
|
||||
|
||||
function onlyWithValidSignatureAndMethod(bytes signature) public onlyValidSignatureAndMethod(signature) view {}
|
||||
function onlyWithValidSignatureAndMethod(bytes memory signature)
|
||||
public onlyValidSignatureAndMethod(signature) view
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
function checkValidSignatureAndData(address account, bytes, uint, bytes signature) public view returns (bool) {
|
||||
function checkValidSignatureAndData(address account, bytes memory, uint, bytes memory signature)
|
||||
public view returns (bool)
|
||||
{
|
||||
return _isValidSignatureAndData(account, signature);
|
||||
}
|
||||
|
||||
function onlyWithValidSignatureAndData(uint, bytes signature) public onlyValidSignatureAndData(signature) view {}
|
||||
function onlyWithValidSignatureAndData(uint, bytes memory signature)
|
||||
public onlyValidSignatureAndData(signature) view
|
||||
{
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
function theWrongMethod(bytes) public pure {}
|
||||
function theWrongMethod(bytes memory) public pure {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
function tooShortMsgData() public onlyValidSignatureAndData("") view {}
|
||||
function tooShortMsgData() public onlyValidSignatureAndData("") view {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
21
contracts/mocks/SignedSafeMathMock.sol
Normal file
21
contracts/mocks/SignedSafeMathMock.sol
Normal file
@ -0,0 +1,21 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../drafts/SignedSafeMath.sol";
|
||||
|
||||
contract SignedSafeMathMock {
|
||||
function mul(int256 a, int256 b) public pure returns (int256) {
|
||||
return SignedSafeMath.mul(a, b);
|
||||
}
|
||||
|
||||
function div(int256 a, int256 b) public pure returns (int256) {
|
||||
return SignedSafeMath.div(a, b);
|
||||
}
|
||||
|
||||
function sub(int256 a, int256 b) public pure returns (int256) {
|
||||
return SignedSafeMath.sub(a, b);
|
||||
}
|
||||
|
||||
function add(int256 a, int256 b) public pure returns (int256) {
|
||||
return SignedSafeMath.add(a, b);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/roles/SignerRole.sol";
|
||||
|
||||
@ -8,6 +8,7 @@ contract SignerRoleMock is SignerRole {
|
||||
}
|
||||
|
||||
function onlySignerMock() public view onlySigner {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
// Causes a compilation error if super._removeSigner is not internal
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/validation/TimedCrowdsale.sol";
|
||||
|
||||
contract TimedCrowdsaleImpl is TimedCrowdsale {
|
||||
constructor (uint256 openingTime, uint256 closingTime, uint256 rate, address wallet, IERC20 token)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
18
contracts/mocks/WhitelistAdminRoleMock.sol
Normal file
18
contracts/mocks/WhitelistAdminRoleMock.sol
Normal file
@ -0,0 +1,18 @@
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/roles/WhitelistAdminRole.sol";
|
||||
|
||||
contract WhitelistAdminRoleMock is WhitelistAdminRole {
|
||||
function removeWhitelistAdmin(address account) public {
|
||||
_removeWhitelistAdmin(account);
|
||||
}
|
||||
|
||||
function onlyWhitelistAdminMock() public view onlyWhitelistAdmin {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
|
||||
// Causes a compilation error if super._removeWhitelistAdmin is not internal
|
||||
function _removeWhitelistAdmin(address account) internal {
|
||||
super._removeWhitelistAdmin(account);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/validation/WhitelistCrowdsale.sol";
|
||||
@ -6,5 +6,7 @@ import "../crowdsale/Crowdsale.sol";
|
||||
|
||||
|
||||
contract WhitelistCrowdsaleImpl is Crowdsale, WhitelistCrowdsale {
|
||||
constructor (uint256 _rate, address _wallet, IERC20 _token) Crowdsale(_rate, _wallet, _token) public {}
|
||||
constructor (uint256 _rate, address payable _wallet, IERC20 _token) public Crowdsale(_rate, _wallet, _token) {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
pragma solidity ^0.4.24;
|
||||
pragma solidity ^0.5.0;
|
||||
|
||||
import "../access/roles/WhitelistedRole.sol";
|
||||
|
||||
contract WhitelistedRoleMock is WhitelistedRole {
|
||||
function onlyWhitelistedMock() public view onlyWhitelisted {
|
||||
// solhint-disable-previous-line no-empty-blocks
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../access/roles/WhitelisterRole.sol";
|
||||
|
||||
contract WhitelisterRoleMock is WhitelisterRole {
|
||||
function removeWhitelister(address account) public {
|
||||
_removeWhitelister(account);
|
||||
}
|
||||
|
||||
function onlyWhitelisterMock() public view onlyWhitelister {
|
||||
}
|
||||
|
||||
// Causes a compilation error if super._removeWhitelister is not internal
|
||||
function _removeWhitelister(address account) internal {
|
||||
super._removeWhitelister(account);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user