Compare commits
80 Commits
v2.0.0-rc.
...
v2.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 06e265b38d | |||
| 7789814606 | |||
| 643ac86d0a | |||
| ae339333d7 | |||
| 1a4009f817 | |||
| ecae7608f9 | |||
| 47b5d61844 | |||
| 984fe23a46 | |||
| 5cdf4de1f6 | |||
| a9bffb3787 | |||
| 6e53c4e129 | |||
| 95411da289 | |||
| e237530538 | |||
| 0ead40ae03 | |||
| 2e848e12d1 | |||
| 6e055019d4 | |||
| 5ee55c4af3 | |||
| 1b27b4bb34 | |||
| 4115686b4f | |||
| 6db4f0bc8f | |||
| 5f3ecd9c64 | |||
| c126e3e81a | |||
| ab932e1873 | |||
| 4394107660 | |||
| 422b42bb6a | |||
| 3b34436b44 | |||
| c5a8680a9c | |||
| 88f48be287 | |||
| 26f9cc8e74 | |||
| 56806bb295 | |||
| 1cf96ef0d1 | |||
| 5d596fc786 | |||
| 2514959f34 | |||
| 1b79b536cd | |||
| e990525c2e | |||
| 2c40ffa011 | |||
| 10a5864fdf | |||
| 7ec6079784 | |||
| 5e82a64a01 | |||
| 3266de1b5c | |||
| 7cd0d5a452 | |||
| 620d524398 | |||
| eae40c93b6 | |||
| 109eba9273 | |||
| 13fb1f662a | |||
| 2f3f0d3c8a | |||
| 0678f67289 | |||
| b03932529c | |||
| c25a1e366f | |||
| 598a0358fc | |||
| 39db4b4b05 | |||
| a9af619c59 | |||
| 62ed8e2fe4 | |||
| e7aa8dedbc | |||
| 49d2dd9e08 | |||
| a3bb56769e | |||
| f8b0cec15b | |||
| 7ea34d9e97 | |||
| 2a8146a45d | |||
| 2e14386eda | |||
| 9f5b73df37 | |||
| a811a0be28 | |||
| 9c76d28245 | |||
| 8d6250cd5a | |||
| 66bad4ff2a | |||
| 41e74dd8d8 | |||
| 2d30918149 | |||
| 0db1f8144d | |||
| ffeae0d83e | |||
| 38ca422170 | |||
| 7c984968d8 | |||
| bd8345a153 | |||
| 76169cda40 | |||
| 08bf6bbed9 | |||
| 8c394de450 | |||
| fa5ecd03cb | |||
| 1b0c6b94b9 | |||
| 652243b7c3 | |||
| c9e8a66e85 | |||
| e7c99dd7dd |
@ -25,7 +25,7 @@
|
||||
|
||||
// Code style
|
||||
"camelcase": ["error", {"properties": "always"}],
|
||||
"comma-dangle": ["warn", "always-multiline"],
|
||||
"comma-dangle": ["error", "always-multiline"],
|
||||
"comma-spacing": ["error", {"before": false, "after": true}],
|
||||
"dot-notation": ["error", {"allowKeywords": true, "allowPattern": ""}],
|
||||
"eol-last": ["error", "always"],
|
||||
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -14,4 +14,4 @@ Fixes #
|
||||
- [ ] 📘 I've reviewed the [OpenZeppelin Contributor Guidelines](../blob/master/CONTRIBUTING.md)
|
||||
- [ ] ✅ I've added tests where applicable to test my new functionality.
|
||||
- [ ] 📖 I've made sure that my contracts are well-documented.
|
||||
- [ ] 🎨 I've run the JS/Solidity linters and fixed any issues (`npm run lint:all:fix`).
|
||||
- [ ] 🎨 I've run the JS/Solidity linters and fixed any issues (`npm run lint:fix`).
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
"extends": "solium:all",
|
||||
"plugins": ["security"],
|
||||
"rules": {
|
||||
"blank-lines": "off",
|
||||
"error-reason": "off",
|
||||
"indentation": ["error", 2],
|
||||
"lbrace": "off",
|
||||
|
||||
@ -16,11 +16,14 @@ Any exception or additions specific to our project are documented below.
|
||||
|
||||
* Try to avoid acronyms and abbreviations.
|
||||
|
||||
* All state variables should be private.
|
||||
|
||||
* Private state variables should have an underscore prefix.
|
||||
|
||||
```
|
||||
contract TestContract {
|
||||
uint256 private _privateVar;
|
||||
uint256 internal _internalVar;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -17,10 +17,14 @@ npm install openzeppelin-solidity
|
||||
To write your custom contracts, import ours and extend them through inheritance.
|
||||
|
||||
```solidity
|
||||
import 'openzeppelin-solidity/contracts/token/ERC721/ERC721.sol';
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Full.sol';
|
||||
import 'openzeppelin-solidity/contracts/token/ERC721/ERC721Mintable.sol';
|
||||
|
||||
contract MyNFT is ERC721, ERC721Mintable {
|
||||
contract MyNFT is ERC721Full, ERC721Mintable {
|
||||
constructor() ERC721Full("MyNFT", "MNFT") public {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ The following provides visibility into how OpenZeppelin's contracts are organize
|
||||
- **introspection** - An interface that can be used to make a contract comply with the ERC-165 standard as well as a contract that implements ERC-165 using a lookup table.
|
||||
- **lifecycle** - A collection of base contracts used to manage the existence and behavior of your contracts and their funds.
|
||||
- **math** - Libraries with safety checks on operations that throw on errors.
|
||||
- **mocks** - A collection of abstract contracts that are primarily used for unit testing. They also serve as good usage examples and demonstrate how to combine contracts with inheritence when developing your own custom applications.
|
||||
- **mocks** - A collection of abstract contracts that are primarily used for unit testing. They also serve as good usage examples and demonstrate how to combine contracts with inheritance when developing your own custom applications.
|
||||
- **ownership** - A collection of smart contracts that can be used to manage contract and token ownership
|
||||
- **payment** - A collection of smart contracts that can be used to manage payments through escrow arrangements, withdrawals, and claims. Includes support for both single payees and multiple payees.
|
||||
- **proposals** - A collection of smart contracts that reflect community Ethereum Improvement Proposals (EIPs). These contracts are under development and standardization. They are not recommended for production, but they are useful for experimentation with pending EIP standards. Go [here](https://github.com/OpenZeppelin/openzeppelin-solidity/wiki/ERC-Process) for more information.
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/**
|
||||
* @title Roles
|
||||
* @dev Library for managing addresses assigned to a Role.
|
||||
@ -15,6 +14,8 @@ library Roles {
|
||||
*/
|
||||
function add(Role storage role, address account) internal {
|
||||
require(account != address(0));
|
||||
require(!has(role, account));
|
||||
|
||||
role.bearer[account] = true;
|
||||
}
|
||||
|
||||
@ -23,6 +24,8 @@ library Roles {
|
||||
*/
|
||||
function remove(Role storage role, address account) internal {
|
||||
require(account != address(0));
|
||||
require(has(role, account));
|
||||
|
||||
role.bearer[account] = false;
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
|
||||
contract CapperRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
@ -11,8 +10,8 @@ contract CapperRole {
|
||||
|
||||
Roles.Role private cappers;
|
||||
|
||||
constructor() public {
|
||||
cappers.add(msg.sender);
|
||||
constructor() internal {
|
||||
_addCapper(msg.sender);
|
||||
}
|
||||
|
||||
modifier onlyCapper() {
|
||||
@ -25,12 +24,16 @@ contract CapperRole {
|
||||
}
|
||||
|
||||
function addCapper(address account) public onlyCapper {
|
||||
cappers.add(account);
|
||||
emit CapperAdded(account);
|
||||
_addCapper(account);
|
||||
}
|
||||
|
||||
function renounceCapper() public {
|
||||
cappers.remove(msg.sender);
|
||||
_removeCapper(msg.sender);
|
||||
}
|
||||
|
||||
function _addCapper(address account) internal {
|
||||
cappers.add(account);
|
||||
emit CapperAdded(account);
|
||||
}
|
||||
|
||||
function _removeCapper(address account) internal {
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
|
||||
contract MinterRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
@ -11,8 +10,8 @@ contract MinterRole {
|
||||
|
||||
Roles.Role private minters;
|
||||
|
||||
constructor() public {
|
||||
minters.add(msg.sender);
|
||||
constructor() internal {
|
||||
_addMinter(msg.sender);
|
||||
}
|
||||
|
||||
modifier onlyMinter() {
|
||||
@ -25,12 +24,16 @@ contract MinterRole {
|
||||
}
|
||||
|
||||
function addMinter(address account) public onlyMinter {
|
||||
minters.add(account);
|
||||
emit MinterAdded(account);
|
||||
_addMinter(account);
|
||||
}
|
||||
|
||||
function renounceMinter() public {
|
||||
minters.remove(msg.sender);
|
||||
_removeMinter(msg.sender);
|
||||
}
|
||||
|
||||
function _addMinter(address account) internal {
|
||||
minters.add(account);
|
||||
emit MinterAdded(account);
|
||||
}
|
||||
|
||||
function _removeMinter(address account) internal {
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
|
||||
contract PauserRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
@ -11,8 +10,8 @@ contract PauserRole {
|
||||
|
||||
Roles.Role private pausers;
|
||||
|
||||
constructor() public {
|
||||
pausers.add(msg.sender);
|
||||
constructor() internal {
|
||||
_addPauser(msg.sender);
|
||||
}
|
||||
|
||||
modifier onlyPauser() {
|
||||
@ -25,12 +24,16 @@ contract PauserRole {
|
||||
}
|
||||
|
||||
function addPauser(address account) public onlyPauser {
|
||||
pausers.add(account);
|
||||
emit PauserAdded(account);
|
||||
_addPauser(account);
|
||||
}
|
||||
|
||||
function renouncePauser() public {
|
||||
pausers.remove(msg.sender);
|
||||
_removePauser(msg.sender);
|
||||
}
|
||||
|
||||
function _addPauser(address account) internal {
|
||||
pausers.add(account);
|
||||
emit PauserAdded(account);
|
||||
}
|
||||
|
||||
function _removePauser(address account) internal {
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../Roles.sol";
|
||||
|
||||
|
||||
contract SignerRole {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
@ -11,8 +10,8 @@ contract SignerRole {
|
||||
|
||||
Roles.Role private signers;
|
||||
|
||||
constructor() public {
|
||||
signers.add(msg.sender);
|
||||
constructor() internal {
|
||||
_addSigner(msg.sender);
|
||||
}
|
||||
|
||||
modifier onlySigner() {
|
||||
@ -25,12 +24,16 @@ contract SignerRole {
|
||||
}
|
||||
|
||||
function addSigner(address account) public onlySigner {
|
||||
signers.add(account);
|
||||
emit SignerAdded(account);
|
||||
_addSigner(account);
|
||||
}
|
||||
|
||||
function renounceSigner() public {
|
||||
signers.remove(msg.sender);
|
||||
_removeSigner(msg.sender);
|
||||
}
|
||||
|
||||
function _addSigner(address account) internal {
|
||||
signers.add(account);
|
||||
emit SignerAdded(account);
|
||||
}
|
||||
|
||||
function _removeSigner(address account) internal {
|
||||
|
||||
@ -3,7 +3,7 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
|
||||
import "../utils/ReentrancyGuard.sol";
|
||||
|
||||
/**
|
||||
* @title Crowdsale
|
||||
@ -17,7 +17,7 @@ import "../token/ERC20/SafeERC20.sol";
|
||||
* the methods to add functionality. Consider using 'super' where appropriate to concatenate
|
||||
* behavior.
|
||||
*/
|
||||
contract Crowdsale {
|
||||
contract Crowdsale is ReentrancyGuard {
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
@ -58,7 +58,7 @@ contract Crowdsale {
|
||||
* @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 wallet, IERC20 token) internal {
|
||||
require(rate > 0);
|
||||
require(wallet != address(0));
|
||||
require(token != address(0));
|
||||
@ -74,6 +74,9 @@ contract Crowdsale {
|
||||
|
||||
/**
|
||||
* @dev fallback function ***DO NOT OVERRIDE***
|
||||
* Note that other contracts will transfer fund 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(msg.sender);
|
||||
@ -101,7 +104,7 @@ contract Crowdsale {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the mount of wei raised.
|
||||
* @return the amount of wei raised.
|
||||
*/
|
||||
function weiRaised() public view returns (uint256) {
|
||||
return _weiRaised;
|
||||
@ -109,9 +112,11 @@ contract Crowdsale {
|
||||
|
||||
/**
|
||||
* @dev low level token purchase ***DO NOT OVERRIDE***
|
||||
* @param beneficiary Address performing the token purchase
|
||||
* 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 payable {
|
||||
function buyTokens(address beneficiary) public nonReentrant payable {
|
||||
|
||||
uint256 weiAmount = msg.value;
|
||||
_preValidatePurchase(beneficiary, weiAmount);
|
||||
@ -153,6 +158,7 @@ contract Crowdsale {
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
require(beneficiary != address(0));
|
||||
require(weiAmount != 0);
|
||||
@ -168,6 +174,7 @@ contract Crowdsale {
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
// optional override
|
||||
}
|
||||
@ -187,7 +194,7 @@ contract Crowdsale {
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Executed when a purchase has been validated and is ready to be executed. Not necessarily emits/sends 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
|
||||
*/
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title FinalizableCrowdsale
|
||||
* @dev Extension of Crowdsale with a one-off finalization action, where one
|
||||
@ -12,10 +11,14 @@ import "../validation/TimedCrowdsale.sol";
|
||||
contract FinalizableCrowdsale is TimedCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
|
||||
bool private _finalized = false;
|
||||
bool private _finalized;
|
||||
|
||||
event CrowdsaleFinalized();
|
||||
|
||||
constructor() internal {
|
||||
_finalized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the crowdsale is finalized, false otherwise.
|
||||
*/
|
||||
@ -31,10 +34,10 @@ contract FinalizableCrowdsale is TimedCrowdsale {
|
||||
require(!_finalized);
|
||||
require(hasClosed());
|
||||
|
||||
_finalized = true;
|
||||
|
||||
_finalization();
|
||||
emit CrowdsaleFinalized();
|
||||
|
||||
_finalized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,5 +47,4 @@ contract FinalizableCrowdsale is TimedCrowdsale {
|
||||
*/
|
||||
function _finalization() internal {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title PostDeliveryCrowdsale
|
||||
* @dev Crowdsale that locks tokens from withdrawal until it ends.
|
||||
@ -14,6 +12,8 @@ contract PostDeliveryCrowdsale is TimedCrowdsale {
|
||||
|
||||
mapping(address => uint256) private _balances;
|
||||
|
||||
constructor() internal {}
|
||||
|
||||
/**
|
||||
* @dev Withdraw tokens only after crowdsale ends.
|
||||
* @param beneficiary Whose tokens will be withdrawn.
|
||||
|
||||
@ -1,15 +1,26 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
import "../../math/SafeMath.sol";
|
||||
import "./FinalizableCrowdsale.sol";
|
||||
import "../../payment/RefundEscrow.sol";
|
||||
|
||||
import "../../payment/escrow/RefundEscrow.sol";
|
||||
|
||||
/**
|
||||
* @title RefundableCrowdsale
|
||||
* @dev Extension of Crowdsale contract that adds a funding goal, and
|
||||
* the possibility of users getting a refund if goal is not met.
|
||||
* WARNING: 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. There are many possible ways to avoid this, like making the
|
||||
* the crowdsale inherit from PostDeliveryCrowdsale, or imposing
|
||||
* restrictions on token trading until the crowdsale is finalized.
|
||||
* This is being discussed in
|
||||
* https://github.com/OpenZeppelin/openzeppelin-solidity/issues/877
|
||||
* This contract will be updated when we agree on a general solution
|
||||
* for this problem.
|
||||
*/
|
||||
contract RefundableCrowdsale is FinalizableCrowdsale {
|
||||
using SafeMath for uint256;
|
||||
@ -24,7 +35,7 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
|
||||
* @dev Constructor, creates RefundEscrow.
|
||||
* @param goal Funding goal
|
||||
*/
|
||||
constructor(uint256 goal) public {
|
||||
constructor(uint256 goal) internal {
|
||||
require(goal > 0);
|
||||
_escrow = new RefundEscrow(wallet());
|
||||
_goal = goal;
|
||||
|
||||
@ -4,7 +4,7 @@ import "../Crowdsale.sol";
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
import "../../token/ERC20/SafeERC20.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
|
||||
import "../../math/Math.sol";
|
||||
|
||||
/**
|
||||
* @title AllowanceCrowdsale
|
||||
@ -20,7 +20,7 @@ contract AllowanceCrowdsale is Crowdsale {
|
||||
* @dev Constructor, takes token wallet address.
|
||||
* @param tokenWallet Address holding the tokens, which has approved allowance to the crowdsale
|
||||
*/
|
||||
constructor(address tokenWallet) public {
|
||||
constructor(address tokenWallet) internal {
|
||||
require(tokenWallet != address(0));
|
||||
_tokenWallet = tokenWallet;
|
||||
}
|
||||
@ -37,7 +37,10 @@ contract AllowanceCrowdsale is Crowdsale {
|
||||
* @return Amount of tokens left in the allowance
|
||||
*/
|
||||
function remainingTokens() public view returns (uint256) {
|
||||
return token().allowance(_tokenWallet, this);
|
||||
return Math.min(
|
||||
token().balanceOf(_tokenWallet),
|
||||
token().allowance(_tokenWallet, this)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -3,13 +3,13 @@ pragma solidity ^0.4.24;
|
||||
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 {
|
||||
constructor() internal {}
|
||||
|
||||
/**
|
||||
* @dev Overrides delivery by minting tokens upon purchase.
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../validation/TimedCrowdsale.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title IncreasingPriceCrowdsale
|
||||
* @dev Extension of Crowdsale contract that increases the price of tokens linearly in time.
|
||||
@ -21,13 +20,21 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale {
|
||||
* @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 {
|
||||
constructor(uint256 initialRate, uint256 finalRate) internal {
|
||||
require(finalRate > 0);
|
||||
require(initialRate >= finalRate);
|
||||
require(initialRate > finalRate);
|
||||
_initialRate = initialRate;
|
||||
_finalRate = finalRate;
|
||||
}
|
||||
|
||||
/**
|
||||
* The base rate function is overridden to revert, since this crowdsale doens't use it, and
|
||||
* all calls to it are a mistake.
|
||||
*/
|
||||
function rate() public view returns(uint256) {
|
||||
revert();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the initial rate of the crowdsale.
|
||||
*/
|
||||
@ -48,6 +55,10 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale {
|
||||
* @return The number of tokens a buyer gets per wei at a given time
|
||||
*/
|
||||
function getCurrentRate() public view returns (uint256) {
|
||||
if (!isOpen()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// solium-disable-next-line security/no-block-members
|
||||
uint256 elapsedTime = block.timestamp.sub(openingTime());
|
||||
uint256 timeRange = closingTime().sub(openingTime());
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title CappedCrowdsale
|
||||
* @dev Crowdsale with a limit for total contributions.
|
||||
@ -17,7 +16,7 @@ contract CappedCrowdsale is Crowdsale {
|
||||
* @dev Constructor, takes maximum amount of wei accepted in the crowdsale.
|
||||
* @param cap Max amount of wei to be contributed
|
||||
*/
|
||||
constructor(uint256 cap) public {
|
||||
constructor(uint256 cap) internal {
|
||||
require(cap > 0);
|
||||
_cap = cap;
|
||||
}
|
||||
@ -47,6 +46,7 @@ contract CappedCrowdsale is Crowdsale {
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
require(weiRaised().add(weiAmount) <= _cap);
|
||||
|
||||
@ -4,7 +4,6 @@ import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
import "../../access/roles/CapperRole.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title IndividuallyCappedCrowdsale
|
||||
* @dev Crowdsale with per-beneficiary caps.
|
||||
@ -15,6 +14,8 @@ contract IndividuallyCappedCrowdsale is Crowdsale, CapperRole {
|
||||
mapping(address => uint256) private _contributions;
|
||||
mapping(address => uint256) private _caps;
|
||||
|
||||
constructor() internal {}
|
||||
|
||||
/**
|
||||
* @dev Sets a specific beneficiary's maximum contribution.
|
||||
* @param beneficiary Address to be capped
|
||||
@ -54,6 +55,7 @@ contract IndividuallyCappedCrowdsale is Crowdsale, CapperRole {
|
||||
uint256 weiAmount
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
require(
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../Crowdsale.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title TimedCrowdsale
|
||||
* @dev Crowdsale accepting contributions only within a time frame.
|
||||
@ -27,10 +26,10 @@ contract TimedCrowdsale is Crowdsale {
|
||||
* @param openingTime Crowdsale opening time
|
||||
* @param closingTime Crowdsale closing time
|
||||
*/
|
||||
constructor(uint256 openingTime, uint256 closingTime) public {
|
||||
constructor(uint256 openingTime, uint256 closingTime) internal {
|
||||
// solium-disable-next-line security/no-block-members
|
||||
require(openingTime >= block.timestamp);
|
||||
require(closingTime >= openingTime);
|
||||
require(closingTime > openingTime);
|
||||
|
||||
_openingTime = openingTime;
|
||||
_closingTime = closingTime;
|
||||
@ -78,6 +77,7 @@ contract TimedCrowdsale is Crowdsale {
|
||||
)
|
||||
internal
|
||||
onlyWhileOpen
|
||||
view
|
||||
{
|
||||
super._preValidatePurchase(beneficiary, weiAmount);
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/**
|
||||
* @title Elliptic curve signature operations
|
||||
* @dev Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d
|
||||
@ -34,9 +33,9 @@ library ECDSA {
|
||||
// currently is to use assembly.
|
||||
// solium-disable-next-line security/no-inline-assembly
|
||||
assembly {
|
||||
r := mload(add(signature, 32))
|
||||
s := mload(add(signature, 64))
|
||||
v := byte(0, mload(add(signature, 96)))
|
||||
r := mload(add(signature, 0x20))
|
||||
s := mload(add(signature, 0x40))
|
||||
v := byte(0, mload(add(signature, 0x60)))
|
||||
}
|
||||
|
||||
// Version of signature should be 27 or 28, but 0 and 1 are also possible versions
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/**
|
||||
* @title MerkleProof
|
||||
* @dev Merkle proof verification based on
|
||||
|
||||
@ -1,87 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
import "../payment/PullPayment.sol";
|
||||
import "../ownership/Ownable.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title BreakInvariantBounty
|
||||
* @dev This bounty will pay out to a researcher if they break invariant logic of the contract.
|
||||
*/
|
||||
contract BreakInvariantBounty is PullPayment, Ownable {
|
||||
bool private _claimed;
|
||||
mapping(address => address) private _researchers;
|
||||
|
||||
event TargetCreated(address createdAddress);
|
||||
|
||||
/**
|
||||
* @dev Fallback function allowing the contract to receive funds, if they haven't already been claimed.
|
||||
*/
|
||||
function() external payable {
|
||||
require(!_claimed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Determine if the bounty was claimed.
|
||||
* @return true if the bounty was claimed, false otherwise.
|
||||
*/
|
||||
function claimed() public view returns(bool) {
|
||||
return _claimed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Create and deploy the target contract (extension of Target contract), and sets the
|
||||
* msg.sender as a researcher
|
||||
* @return A target contract
|
||||
*/
|
||||
function createTarget() public returns(Target) {
|
||||
Target target = Target(_deployContract());
|
||||
_researchers[target] = msg.sender;
|
||||
emit TargetCreated(target);
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers the contract funds to the researcher that proved the contract is broken.
|
||||
* @param target contract
|
||||
*/
|
||||
function claim(Target target) public {
|
||||
address researcher = _researchers[target];
|
||||
require(researcher != address(0));
|
||||
// Check Target contract invariants
|
||||
require(!target.checkInvariant());
|
||||
_asyncTransfer(researcher, address(this).balance);
|
||||
_claimed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers the current balance to the owner and terminates the contract.
|
||||
*/
|
||||
function destroy() public onlyOwner {
|
||||
selfdestruct(owner());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Internal function to deploy the target contract.
|
||||
* @return A target contract address
|
||||
*/
|
||||
function _deployContract() internal returns(address);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title Target
|
||||
* @dev Your main contract should inherit from this class and implement the checkInvariant method.
|
||||
*/
|
||||
contract Target {
|
||||
|
||||
/**
|
||||
* @dev Checks all values a contract assumes to be true all the time. If this function returns
|
||||
* false, the contract is broken in some way and is in an inconsistent state.
|
||||
* In order to win the bounty, security researchers will try to cause this broken state.
|
||||
* @return True if all invariant values are correct, false otherwise.
|
||||
*/
|
||||
function checkInvariant() public returns(bool);
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/**
|
||||
* @title Counter
|
||||
* @author Matt Condon (@shrugs)
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../../token/ERC20/IERC20.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title ERC-1047 Token Metadata
|
||||
* @dev See https://eips.ethereum.org/EIPS/eip-1046
|
||||
@ -13,9 +12,8 @@ contract ERC20TokenMetadata is IERC20 {
|
||||
function tokenURI() external view returns (string);
|
||||
}
|
||||
|
||||
|
||||
contract ERC20WithMetadata is ERC20TokenMetadata {
|
||||
string private _tokenURI = "";
|
||||
string private _tokenURI;
|
||||
|
||||
constructor(string tokenURI)
|
||||
public
|
||||
|
||||
@ -5,7 +5,6 @@ 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
|
||||
|
||||
@ -3,30 +3,36 @@ pragma solidity ^0.4.24;
|
||||
import "../access/roles/SignerRole.sol";
|
||||
import "../cryptography/ECDSA.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title SignatureBouncer
|
||||
* @author PhABC, Shrugs and aflesher
|
||||
* @dev SignatureBouncer allows users to submit a signature as a permission to do an action.
|
||||
* If the signature is from one of the authorized signer addresses, the signature
|
||||
* is valid.
|
||||
* @dev SignatureBouncer allows users to submit a signature as a permission to
|
||||
* do an action.
|
||||
* If the signature is from one of the authorized signer addresses, the
|
||||
* signature is valid.
|
||||
* Note that SignatureBouncer offers no protection against replay attacks, users
|
||||
* must add this themselves!
|
||||
*
|
||||
* Signer addresses can be individual servers signing grants or different
|
||||
* users within a decentralized club that have permission to invite other members.
|
||||
* This technique is useful for whitelists and airdrops; instead of putting all
|
||||
* valid addresses on-chain, simply sign a grant of the form
|
||||
* keccak256(abi.encodePacked(`:contractAddress` + `:granteeAddress`)) using a valid signer address.
|
||||
* users within a decentralized club that have permission to invite other
|
||||
* members. This technique is useful for whitelists and airdrops; instead of
|
||||
* putting all valid addresses on-chain, simply sign a grant of the form
|
||||
* keccak256(abi.encodePacked(`:contractAddress` + `:granteeAddress`)) using a
|
||||
* valid signer address.
|
||||
* Then restrict access to your crowdsale/whitelist/airdrop using the
|
||||
* `onlyValidSignature` modifier (or implement your own using _isValidSignature).
|
||||
* In addition to `onlyValidSignature`, `onlyValidSignatureAndMethod` and
|
||||
* `onlyValidSignatureAndData` can be used to restrict access to only a given method
|
||||
* or a given method with given parameters respectively.
|
||||
* `onlyValidSignatureAndData` can be used to restrict access to only a given
|
||||
* method or a given method with given parameters respectively.
|
||||
* See the tests in SignatureBouncer.test.js for specific usage examples.
|
||||
* @notice A method that uses the `onlyValidSignatureAndData` modifier must make the _signature
|
||||
* parameter the "last" parameter. You cannot sign a message that has its own
|
||||
* signature in it so the last 128 bytes of msg.data (which represents the
|
||||
* length of the _signature data and the _signaature data itself) is ignored when validating.
|
||||
* Also non fixed sized parameters make constructing the data in the signature
|
||||
* much more complex. See https://ethereum.stackexchange.com/a/50616 for more details.
|
||||
*
|
||||
* @notice A method that uses the `onlyValidSignatureAndData` modifier must make
|
||||
* the _signature parameter the "last" parameter. You cannot sign a message that
|
||||
* has its own signature in it so the last 128 bytes of msg.data (which
|
||||
* represents the length of the _signature data and the _signaature data itself)
|
||||
* is ignored when validating. Also non fixed sized parameters make constructing
|
||||
* the data in the signature much more complex.
|
||||
* See https://ethereum.stackexchange.com/a/50616 for more details.
|
||||
*/
|
||||
contract SignatureBouncer is SignerRole {
|
||||
using ECDSA for bytes32;
|
||||
@ -37,6 +43,8 @@ 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 {}
|
||||
|
||||
/**
|
||||
* @dev requires that a valid signature of a signer was provided
|
||||
*/
|
||||
|
||||
@ -6,7 +6,6 @@ import "../token/ERC20/SafeERC20.sol";
|
||||
import "../ownership/Ownable.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title TokenVesting
|
||||
* @dev A token holder contract that can release its token balance gradually like a
|
||||
@ -17,8 +16,8 @@ contract TokenVesting is Ownable {
|
||||
using SafeMath for uint256;
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
event Released(uint256 amount);
|
||||
event Revoked();
|
||||
event TokensReleased(address token, uint256 amount);
|
||||
event TokenVestingRevoked(address token);
|
||||
|
||||
// beneficiary of tokens after they are released
|
||||
address private _beneficiary;
|
||||
@ -53,6 +52,8 @@ contract TokenVesting is Ownable {
|
||||
{
|
||||
require(beneficiary != address(0));
|
||||
require(cliffDuration <= duration);
|
||||
require(duration > 0);
|
||||
require(start.add(duration) > block.timestamp);
|
||||
|
||||
_beneficiary = beneficiary;
|
||||
_revocable = revocable;
|
||||
@ -115,7 +116,7 @@ contract TokenVesting is Ownable {
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function release(IERC20 token) public {
|
||||
uint256 unreleased = releasableAmount(token);
|
||||
uint256 unreleased = _releasableAmount(token);
|
||||
|
||||
require(unreleased > 0);
|
||||
|
||||
@ -123,7 +124,7 @@ contract TokenVesting is Ownable {
|
||||
|
||||
token.safeTransfer(_beneficiary, unreleased);
|
||||
|
||||
emit Released(unreleased);
|
||||
emit TokensReleased(token, unreleased);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,29 +138,29 @@ contract TokenVesting is Ownable {
|
||||
|
||||
uint256 balance = token.balanceOf(address(this));
|
||||
|
||||
uint256 unreleased = releasableAmount(token);
|
||||
uint256 unreleased = _releasableAmount(token);
|
||||
uint256 refund = balance.sub(unreleased);
|
||||
|
||||
_revoked[token] = true;
|
||||
|
||||
token.safeTransfer(owner(), refund);
|
||||
|
||||
emit Revoked();
|
||||
emit TokenVestingRevoked(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the amount that has already vested but hasn't been released yet.
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function releasableAmount(IERC20 token) public view returns (uint256) {
|
||||
return vestedAmount(token).sub(_released[token]);
|
||||
function _releasableAmount(IERC20 token) private view returns (uint256) {
|
||||
return _vestedAmount(token).sub(_released[token]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the amount that has already vested.
|
||||
* @param token ERC20 token which is being vested
|
||||
*/
|
||||
function vestedAmount(IERC20 token) public view returns (uint256) {
|
||||
function _vestedAmount(IERC20 token) private view returns (uint256) {
|
||||
uint256 currentBalance = token.balanceOf(this);
|
||||
uint256 totalBalance = currentBalance.add(_released[token]);
|
||||
|
||||
|
||||
@ -4,21 +4,17 @@ 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 {
|
||||
|
||||
string public constant name = "Sample Crowdsale Token";
|
||||
string public constant symbol = "SCT";
|
||||
uint8 public constant decimals = 18;
|
||||
contract SampleCrowdsaleToken is ERC20Mintable, ERC20Detailed {
|
||||
constructor() public ERC20Detailed("Sample Crowdsale Token", "SCT", 18) {}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @title SampleCrowdsale
|
||||
* @dev This is an example of a fully fledged crowdsale.
|
||||
@ -26,6 +22,8 @@ contract SampleCrowdsaleToken is ERC20Mintable {
|
||||
* 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.
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title SimpleToken
|
||||
* @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "./IERC165.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title ERC165
|
||||
* @author Matt Condon (@shrugs)
|
||||
@ -19,14 +18,14 @@ contract ERC165 is IERC165 {
|
||||
/**
|
||||
* @dev a mapping of interface id to whether or not it's supported
|
||||
*/
|
||||
mapping(bytes4 => bool) internal _supportedInterfaces;
|
||||
mapping(bytes4 => bool) private _supportedInterfaces;
|
||||
|
||||
/**
|
||||
* @dev A contract implementing SupportsInterfaceWithLookup
|
||||
* implement ERC165 itself
|
||||
*/
|
||||
constructor()
|
||||
public
|
||||
internal
|
||||
{
|
||||
_registerInterface(_InterfaceId_ERC165);
|
||||
}
|
||||
@ -43,7 +42,7 @@ contract ERC165 is IERC165 {
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev private method for registering an interface
|
||||
* @dev internal method for registering an interface
|
||||
*/
|
||||
function _registerInterface(bytes4 interfaceId)
|
||||
internal
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/**
|
||||
* @title ERC165Checker
|
||||
* @dev Use `using ERC165Checker for address`; to include this library
|
||||
@ -16,21 +15,20 @@ library ERC165Checker {
|
||||
* bytes4(keccak256('supportsInterface(bytes4)'))
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @notice Query if a contract supports ERC165
|
||||
* @param account The address of the contract to query for support of ERC165
|
||||
* @return true if the contract at account implements ERC165
|
||||
*/
|
||||
function supportsERC165(address account)
|
||||
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, _InterfaceId_ERC165) &&
|
||||
!_supportsERC165Interface(account, _InterfaceId_Invalid);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -41,14 +39,14 @@ library ERC165Checker {
|
||||
* identifier interfaceId, false otherwise
|
||||
* @dev Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function supportsInterface(address account, bytes4 interfaceId)
|
||||
function _supportsInterface(address account, bytes4 interfaceId)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
// query support of both ERC165 as per the spec and support of _interfaceId
|
||||
return supportsERC165(account) &&
|
||||
supportsERC165Interface(account, interfaceId);
|
||||
return _supportsERC165(account) &&
|
||||
_supportsERC165Interface(account, interfaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,19 +57,19 @@ library ERC165Checker {
|
||||
* interfaceIds list, false otherwise
|
||||
* @dev Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function supportsInterfaces(address account, bytes4[] interfaceIds)
|
||||
function _supportsAllInterfaces(address account, bytes4[] interfaceIds)
|
||||
internal
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
// query support of ERC165 itself
|
||||
if (!supportsERC165(account)) {
|
||||
if (!_supportsERC165(account)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// query support of each interface in _interfaceIds
|
||||
for (uint256 i = 0; i < interfaceIds.length; i++) {
|
||||
if (!supportsERC165Interface(account, interfaceIds[i])) {
|
||||
if (!_supportsERC165Interface(account, interfaceIds[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -91,14 +89,14 @@ library ERC165Checker {
|
||||
* with the `supportsERC165` method in this library.
|
||||
* Interface identification is specified in ERC-165.
|
||||
*/
|
||||
function supportsERC165Interface(address account, bytes4 interfaceId)
|
||||
function _supportsERC165Interface(address account, bytes4 interfaceId)
|
||||
private
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
// success determines whether the staticcall succeeded and result determines
|
||||
// whether the contract at account indicates support of _interfaceId
|
||||
(bool success, bool result) = callERC165SupportsInterface(
|
||||
(bool success, bool result) = _callERC165SupportsInterface(
|
||||
account, interfaceId);
|
||||
|
||||
return (success && result);
|
||||
@ -112,7 +110,7 @@ library ERC165Checker {
|
||||
* @return result true if the STATICCALL succeeded and the contract at account
|
||||
* indicates support of the interface with identifier interfaceId, false otherwise
|
||||
*/
|
||||
function callERC165SupportsInterface(
|
||||
function _callERC165SupportsInterface(
|
||||
address account,
|
||||
bytes4 interfaceId
|
||||
)
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/**
|
||||
* @title IERC165
|
||||
* @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
|
||||
|
||||
@ -2,17 +2,19 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../access/roles/PauserRole.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title Pausable
|
||||
* @dev Base contract which allows children to implement an emergency stop mechanism.
|
||||
*/
|
||||
contract Pausable is PauserRole {
|
||||
event Paused();
|
||||
event Unpaused();
|
||||
event Paused(address account);
|
||||
event Unpaused(address account);
|
||||
|
||||
bool private _paused = false;
|
||||
bool private _paused;
|
||||
|
||||
constructor() internal {
|
||||
_paused = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the contract is paused, false otherwise.
|
||||
@ -42,7 +44,7 @@ contract Pausable is PauserRole {
|
||||
*/
|
||||
function pause() public onlyPauser whenNotPaused {
|
||||
_paused = true;
|
||||
emit Paused();
|
||||
emit Paused(msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,6 +52,6 @@ contract Pausable is PauserRole {
|
||||
*/
|
||||
function unpause() public onlyPauser whenPaused {
|
||||
_paused = false;
|
||||
emit Unpaused();
|
||||
emit Unpaused(msg.sender);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,19 +1,29 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/**
|
||||
* @title Math
|
||||
* @dev Assorted math operations
|
||||
*/
|
||||
library Math {
|
||||
/**
|
||||
* @dev Returns the largest of two numbers.
|
||||
*/
|
||||
function max(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return a >= b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the smallest of two numbers.
|
||||
*/
|
||||
function min(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates the average of two numbers. Since these are integers,
|
||||
* averages of an even and odd number cannot be represented, and will be
|
||||
* rounded down.
|
||||
*/
|
||||
function average(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// (a + b) / 2 can overflow, so we distribute
|
||||
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/**
|
||||
* @title SafeMath
|
||||
* @dev Math operations with safety checks that revert on error
|
||||
|
||||
14
contracts/mocks/AddressImpl.sol
Normal file
14
contracts/mocks/AddressImpl.sol
Normal file
@ -0,0 +1,14 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../utils/Address.sol";
|
||||
|
||||
contract AddressImpl {
|
||||
function isContract(address account)
|
||||
external
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return Address.isContract(account);
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/emission/AllowanceCrowdsale.sol";
|
||||
|
||||
|
||||
contract AllowanceCrowdsaleImpl is AllowanceCrowdsale {
|
||||
|
||||
constructor (
|
||||
|
||||
18
contracts/mocks/ArraysImpl.sol
Normal file
18
contracts/mocks/ArraysImpl.sol
Normal file
@ -0,0 +1,18 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../utils/Arrays.sol";
|
||||
|
||||
contract ArraysImpl {
|
||||
|
||||
using Arrays for uint256[];
|
||||
|
||||
uint256[] private array;
|
||||
|
||||
constructor(uint256[] _array) public {
|
||||
array = _array;
|
||||
}
|
||||
|
||||
function findUpperBound(uint256 _element) external view returns (uint256) {
|
||||
return array.findUpperBound(_element);
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/validation/CappedCrowdsale.sol";
|
||||
|
||||
|
||||
contract CappedCrowdsaleImpl is CappedCrowdsale {
|
||||
|
||||
constructor (
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../access/roles/CapperRole.sol";
|
||||
|
||||
|
||||
contract CapperRoleMock is CapperRole {
|
||||
function removeCapper(address account) public {
|
||||
_removeCapper(account);
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
import "../payment/ConditionalEscrow.sol";
|
||||
|
||||
import "../payment/escrow/ConditionalEscrow.sol";
|
||||
|
||||
// mock class using ConditionalEscrow
|
||||
contract ConditionalEscrowMock is ConditionalEscrow {
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../drafts/Counter.sol";
|
||||
|
||||
|
||||
contract CounterImpl {
|
||||
using Counter for Counter.Counter;
|
||||
|
||||
|
||||
9
contracts/mocks/CrowdsaleMock.sol
Normal file
9
contracts/mocks/CrowdsaleMock.sol
Normal file
@ -0,0 +1,9 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../crowdsale/Crowdsale.sol";
|
||||
|
||||
contract CrowdsaleMock is Crowdsale {
|
||||
constructor(uint256 rate, address wallet, IERC20 token) public
|
||||
Crowdsale(rate, wallet, token) {
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../token/ERC20/ERC20Detailed.sol";
|
||||
|
||||
|
||||
contract ERC20DetailedMock is ERC20, ERC20Detailed {
|
||||
constructor(
|
||||
string name,
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
import "../cryptography/ECDSA.sol";
|
||||
|
||||
|
||||
contract ECDSAMock {
|
||||
using ECDSA for bytes32;
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
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.
|
||||
@ -22,7 +21,7 @@ contract SupportsInterfaceWithLookupMock is IERC165 {
|
||||
/**
|
||||
* @dev a mapping of interface id to whether or not it's supported
|
||||
*/
|
||||
mapping(bytes4 => bool) internal supportedInterfaces;
|
||||
mapping(bytes4 => bool) private _supportedInterfaces;
|
||||
|
||||
/**
|
||||
* @dev A contract implementing SupportsInterfaceWithLookup
|
||||
@ -42,7 +41,7 @@ contract SupportsInterfaceWithLookupMock is IERC165 {
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return supportedInterfaces[interfaceId];
|
||||
return _supportedInterfaces[interfaceId];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,12 +51,10 @@ contract SupportsInterfaceWithLookupMock is IERC165 {
|
||||
internal
|
||||
{
|
||||
require(interfaceId != 0xffffffff);
|
||||
supportedInterfaces[interfaceId] = true;
|
||||
_supportedInterfaces[interfaceId] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
contract ERC165InterfacesSupported is SupportsInterfaceWithLookupMock {
|
||||
constructor (bytes4[] interfaceIds)
|
||||
public
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract ERC165NotSupported {
|
||||
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../introspection/ERC165Checker.sol";
|
||||
|
||||
|
||||
contract ERC165CheckerMock {
|
||||
using ERC165Checker for address;
|
||||
|
||||
@ -11,7 +10,7 @@ contract ERC165CheckerMock {
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return account.supportsERC165();
|
||||
return account._supportsERC165();
|
||||
}
|
||||
|
||||
function supportsInterface(address account, bytes4 interfaceId)
|
||||
@ -19,14 +18,14 @@ contract ERC165CheckerMock {
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return account.supportsInterface(interfaceId);
|
||||
return account._supportsInterface(interfaceId);
|
||||
}
|
||||
|
||||
function supportsInterfaces(address account, bytes4[] interfaceIds)
|
||||
function supportsAllInterfaces(address account, bytes4[] interfaceIds)
|
||||
public
|
||||
view
|
||||
returns (bool)
|
||||
{
|
||||
return account.supportsInterfaces(interfaceIds);
|
||||
return account._supportsAllInterfaces(interfaceIds);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../introspection/ERC165.sol";
|
||||
|
||||
|
||||
contract ERC165Mock is ERC165 {
|
||||
function registerInterface(bytes4 interfaceId)
|
||||
public
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../token/ERC20/ERC20Burnable.sol";
|
||||
|
||||
|
||||
contract ERC20BurnableMock is ERC20Burnable {
|
||||
|
||||
constructor(address initialAccount, uint256 initialBalance) public {
|
||||
|
||||
@ -3,6 +3,5 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
import "./MinterRoleMock.sol";
|
||||
|
||||
|
||||
contract ERC20MintableMock is ERC20Mintable, MinterRoleMock {
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
|
||||
|
||||
// mock class using ERC20
|
||||
contract ERC20Mock is ERC20 {
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/ERC20Pausable.sol";
|
||||
import "./PauserRoleMock.sol";
|
||||
|
||||
|
||||
// mock class using ERC20Pausable
|
||||
contract ERC20PausableMock is ERC20Pausable, PauserRoleMock {
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../drafts/ERC1046/TokenMetadata.sol";
|
||||
|
||||
|
||||
contract ERC20WithMetadataMock is ERC20, ERC20WithMetadata {
|
||||
constructor(string tokenURI) public
|
||||
ERC20WithMetadata(tokenURI)
|
||||
|
||||
@ -2,15 +2,17 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../token/ERC721/ERC721Full.sol";
|
||||
import "../token/ERC721/ERC721Mintable.sol";
|
||||
import "../token/ERC721/ERC721MetadataMintable.sol";
|
||||
import "../token/ERC721/ERC721Burnable.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title ERC721Mock
|
||||
* @title ERC721FullMock
|
||||
* This mock just provides a public mint and burn functions for testing purposes,
|
||||
* and a public setter for metadata URI
|
||||
*/
|
||||
contract ERC721FullMock is ERC721Full, ERC721Mintable, ERC721Burnable {
|
||||
contract ERC721FullMock
|
||||
is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
|
||||
|
||||
constructor(string name, string symbol) public
|
||||
ERC721Mintable()
|
||||
ERC721Full(name, symbol)
|
||||
|
||||
@ -2,14 +2,14 @@ pragma solidity ^0.4.24;
|
||||
|
||||
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, ERC721Burnable {
|
||||
is ERC721Full, ERC721Mintable, ERC721MetadataMintable, ERC721Burnable {
|
||||
|
||||
constructor()
|
||||
ERC721Mintable()
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../token/ERC721/ERC721.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title ERC721Mock
|
||||
* This mock just provides a public mint and burn functions for testing purposes
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC721/ERC721Pausable.sol";
|
||||
import "./PauserRoleMock.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title ERC721PausableMock
|
||||
* This mock just provides a public mint, burn and exists functions for testing purposes
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../token/ERC721/IERC721Receiver.sol";
|
||||
|
||||
|
||||
contract ERC721ReceiverMock is IERC721Receiver {
|
||||
bytes4 private _retval;
|
||||
bool private _reverts;
|
||||
|
||||
62
contracts/mocks/EventEmitter.sol
Normal file
62
contracts/mocks/EventEmitter.sol
Normal file
@ -0,0 +1,62 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
contract EventEmitter {
|
||||
event Argumentless();
|
||||
event ShortUint(uint8 value);
|
||||
event ShortInt(int8 value);
|
||||
event LongUint(uint256 value);
|
||||
event LongInt(int256 value);
|
||||
event Address(address value);
|
||||
event Boolean(bool value);
|
||||
event String(string value);
|
||||
event LongUintBooleanString(
|
||||
uint256 uintValue,
|
||||
bool booleanValue,
|
||||
string stringValue
|
||||
);
|
||||
|
||||
function emitArgumentless() public {
|
||||
emit Argumentless();
|
||||
}
|
||||
|
||||
function emitShortUint(uint8 value) public {
|
||||
emit ShortUint(value);
|
||||
}
|
||||
|
||||
function emitShortInt(int8 value) public {
|
||||
emit ShortInt(value);
|
||||
}
|
||||
|
||||
function emitLongUint(uint256 value) public {
|
||||
emit LongUint(value);
|
||||
}
|
||||
|
||||
function emitLongInt(int256 value) public {
|
||||
emit LongInt(value);
|
||||
}
|
||||
|
||||
function emitAddress(address value) public {
|
||||
emit Address(value);
|
||||
}
|
||||
|
||||
function emitBoolean(bool value) public {
|
||||
emit Boolean(value);
|
||||
}
|
||||
|
||||
function emitString(string value) public {
|
||||
emit String(value);
|
||||
}
|
||||
|
||||
function emitLongUintBooleanString(
|
||||
uint256 uintValue,
|
||||
bool booleanValue,
|
||||
string stringValue)
|
||||
public {
|
||||
emit LongUintBooleanString(uintValue, booleanValue, stringValue);
|
||||
}
|
||||
|
||||
function emitLongUintAndBoolean(uint256 uintValue, bool boolValue) public {
|
||||
emit LongUint(uintValue);
|
||||
emit Boolean(boolValue);
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/distribution/FinalizableCrowdsale.sol";
|
||||
|
||||
|
||||
contract FinalizableCrowdsaleImpl is FinalizableCrowdsale {
|
||||
|
||||
constructor (
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
// @title Force Ether into a contract.
|
||||
// @notice even
|
||||
// if the contract is not payable.
|
||||
// @notice To use, construct the contract with the target as argument.
|
||||
// @author Remco Bloemen <remco@neufund.org>
|
||||
contract ForceEther {
|
||||
|
||||
constructor() public payable { }
|
||||
|
||||
function destroyAndSend(address recipient) public {
|
||||
selfdestruct(recipient);
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../crowdsale/price/IncreasingPriceCrowdsale.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
|
||||
contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale {
|
||||
|
||||
constructor (
|
||||
|
||||
@ -4,7 +4,6 @@ import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol";
|
||||
import "./CapperRoleMock.sol";
|
||||
|
||||
|
||||
contract IndividuallyCappedCrowdsaleImpl
|
||||
is IndividuallyCappedCrowdsale, CapperRoleMock {
|
||||
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
// When this line is split, truffle parsing fails.
|
||||
// See: https://github.com/ethereum/solidity/issues/4871
|
||||
// solium-disable-next-line max-len
|
||||
import {BreakInvariantBounty, Target} from "../drafts/BreakInvariantBounty.sol";
|
||||
|
||||
|
||||
contract InsecureInvariantTargetMock is Target {
|
||||
function checkInvariant() public returns(bool) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract InsecureInvariantTargetBounty is BreakInvariantBounty {
|
||||
function _deployContract() internal returns (address) {
|
||||
return new InsecureInvariantTargetMock();
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,7 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
import "../math/Math.sol";
|
||||
|
||||
|
||||
contract MathMock {
|
||||
function max(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
return Math.max(a, b);
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import { MerkleProof } from "../cryptography/MerkleProof.sol";
|
||||
|
||||
|
||||
contract MerkleProofWrapper {
|
||||
|
||||
function verify(
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract MessageHelper {
|
||||
|
||||
event Show(bytes32 b32, uint256 number, string text);
|
||||
event Buy(bytes32 b32, uint256 number, string text, uint256 value);
|
||||
|
||||
function showMessage(
|
||||
bytes32 _message,
|
||||
uint256 _number,
|
||||
string _text
|
||||
)
|
||||
public
|
||||
returns (bool)
|
||||
{
|
||||
emit Show(_message, _number, _text);
|
||||
return true;
|
||||
}
|
||||
|
||||
function buyMessage(
|
||||
bytes32 _message,
|
||||
uint256 _number,
|
||||
string _text
|
||||
)
|
||||
public
|
||||
payable
|
||||
returns (bool)
|
||||
{
|
||||
emit Buy(
|
||||
_message,
|
||||
_number,
|
||||
_text,
|
||||
msg.value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function fail() public {
|
||||
require(false);
|
||||
}
|
||||
|
||||
function call(address _to, bytes _data) public returns (bool) {
|
||||
// solium-disable-next-line security/no-low-level-calls
|
||||
if (_to.call(_data))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
import "../crowdsale/emission/MintedCrowdsale.sol";
|
||||
|
||||
|
||||
contract MintedCrowdsaleImpl is MintedCrowdsale {
|
||||
|
||||
constructor (
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../access/roles/MinterRole.sol";
|
||||
|
||||
|
||||
contract MinterRoleMock is MinterRole {
|
||||
function removeMinter(address account) public {
|
||||
_removeMinter(account);
|
||||
|
||||
6
contracts/mocks/OwnableMock.sol
Normal file
6
contracts/mocks/OwnableMock.sol
Normal file
@ -0,0 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../ownership/Ownable.sol";
|
||||
|
||||
contract OwnableMock is Ownable {
|
||||
}
|
||||
@ -1,10 +1,8 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
import "../lifecycle/Pausable.sol";
|
||||
import "./PauserRoleMock.sol";
|
||||
|
||||
|
||||
// mock class using Pausable
|
||||
contract PausableMock is Pausable, PauserRoleMock {
|
||||
bool public drasticMeasureTaken;
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../access/roles/PauserRole.sol";
|
||||
|
||||
|
||||
contract PauserRoleMock is PauserRole {
|
||||
function removePauser(address account) public {
|
||||
_removePauser(account);
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/distribution/PostDeliveryCrowdsale.sol";
|
||||
|
||||
|
||||
contract PostDeliveryCrowdsaleImpl is PostDeliveryCrowdsale {
|
||||
|
||||
constructor (
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
import "../payment/PullPayment.sol";
|
||||
|
||||
|
||||
// mock class using PullPayment
|
||||
contract PullPaymentMock is PullPayment {
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
contract ReentrancyAttack {
|
||||
|
||||
function callSender(bytes4 data) public {
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../utils/ReentrancyGuard.sol";
|
||||
import "./ReentrancyAttack.sol";
|
||||
|
||||
|
||||
contract ReentrancyMock is ReentrancyGuard {
|
||||
|
||||
uint256 public counter;
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/ERC20Mintable.sol";
|
||||
import "../crowdsale/distribution/RefundableCrowdsale.sol";
|
||||
|
||||
|
||||
contract RefundableCrowdsaleImpl is RefundableCrowdsale {
|
||||
|
||||
constructor (
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../access/Roles.sol";
|
||||
|
||||
|
||||
contract RolesMock {
|
||||
using Roles for Roles.Role;
|
||||
|
||||
|
||||
@ -3,11 +3,8 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
|
||||
|
||||
contract ERC20FailingMock is IERC20 {
|
||||
function totalSupply() public view returns (uint256) {
|
||||
return 0;
|
||||
}
|
||||
contract ERC20FailingMock {
|
||||
uint256 private _allowance;
|
||||
|
||||
function transfer(address, uint256) public returns (bool) {
|
||||
return false;
|
||||
@ -21,20 +18,13 @@ contract ERC20FailingMock is IERC20 {
|
||||
return false;
|
||||
}
|
||||
|
||||
function balanceOf(address) public view returns (uint256) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
function allowance(address, address) public view returns (uint256) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract ERC20SucceedingMock is IERC20 {
|
||||
function totalSupply() public view returns (uint256) {
|
||||
return 0;
|
||||
}
|
||||
contract ERC20SucceedingMock {
|
||||
uint256 private _allowance;
|
||||
|
||||
function transfer(address, uint256) public returns (bool) {
|
||||
return true;
|
||||
@ -48,16 +38,15 @@ contract ERC20SucceedingMock is IERC20 {
|
||||
return true;
|
||||
}
|
||||
|
||||
function balanceOf(address) public view returns (uint256) {
|
||||
return 0;
|
||||
function setAllowance(uint256 allowance_) public {
|
||||
_allowance = allowance_;
|
||||
}
|
||||
|
||||
function allowance(address, address) public view returns (uint256) {
|
||||
return 0;
|
||||
return _allowance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract SafeERC20Helper {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
@ -65,10 +54,12 @@ contract SafeERC20Helper {
|
||||
IERC20 private _succeeding;
|
||||
|
||||
constructor() public {
|
||||
_failing = new ERC20FailingMock();
|
||||
_succeeding = new ERC20SucceedingMock();
|
||||
_failing = IERC20(new ERC20FailingMock());
|
||||
_succeeding = IERC20(new ERC20SucceedingMock());
|
||||
}
|
||||
|
||||
// Using _failing
|
||||
|
||||
function doFailingTransfer() public {
|
||||
_failing.safeTransfer(address(0), 0);
|
||||
}
|
||||
@ -81,6 +72,16 @@ contract SafeERC20Helper {
|
||||
_failing.safeApprove(address(0), 0);
|
||||
}
|
||||
|
||||
function doFailingIncreaseAllowance() public {
|
||||
_failing.safeIncreaseAllowance(address(0), 0);
|
||||
}
|
||||
|
||||
function doFailingDecreaseAllowance() public {
|
||||
_failing.safeDecreaseAllowance(address(0), 0);
|
||||
}
|
||||
|
||||
// Using _succeeding
|
||||
|
||||
function doSucceedingTransfer() public {
|
||||
_succeeding.safeTransfer(address(0), 0);
|
||||
}
|
||||
@ -89,7 +90,23 @@ contract SafeERC20Helper {
|
||||
_succeeding.safeTransferFrom(address(0), address(0), 0);
|
||||
}
|
||||
|
||||
function doSucceedingApprove() public {
|
||||
_succeeding.safeApprove(address(0), 0);
|
||||
function doSucceedingApprove(uint256 amount) public {
|
||||
_succeeding.safeApprove(address(0), amount);
|
||||
}
|
||||
|
||||
function doSucceedingIncreaseAllowance(uint256 amount) public {
|
||||
_succeeding.safeIncreaseAllowance(address(0), amount);
|
||||
}
|
||||
|
||||
function doSucceedingDecreaseAllowance(uint256 amount) public {
|
||||
_succeeding.safeDecreaseAllowance(address(0), amount);
|
||||
}
|
||||
|
||||
function setAllowance(uint256 allowance_) public {
|
||||
ERC20SucceedingMock(_succeeding).setAllowance(allowance_);
|
||||
}
|
||||
|
||||
function allowance() public view returns (uint256) {
|
||||
return _succeeding.allowance(address(0), address(0));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
|
||||
contract SafeMathMock {
|
||||
|
||||
function mul(uint256 a, uint256 b) public pure returns (uint256) {
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../ownership/Secondary.sol";
|
||||
|
||||
|
||||
contract SecondaryMock is Secondary {
|
||||
function onlyPrimaryMock() public view onlyPrimary {
|
||||
}
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
// When this line is split, truffle parsing fails.
|
||||
// See: https://github.com/ethereum/solidity/issues/4871
|
||||
// solium-disable-next-line max-len
|
||||
import {BreakInvariantBounty, Target} from "../drafts/BreakInvariantBounty.sol";
|
||||
|
||||
|
||||
contract SecureInvariantTargetMock is Target {
|
||||
function checkInvariant() public returns(bool) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract SecureInvariantTargetBounty is BreakInvariantBounty {
|
||||
function _deployContract() internal returns (address) {
|
||||
return new SecureInvariantTargetMock();
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../drafts/SignatureBouncer.sol";
|
||||
import "./SignerRoleMock.sol";
|
||||
|
||||
|
||||
contract SignatureBouncerMock is SignatureBouncer, SignerRoleMock {
|
||||
function checkValidSignature(address account, bytes signature)
|
||||
public
|
||||
@ -64,4 +63,11 @@ contract SignatureBouncerMock is SignatureBouncer, SignerRoleMock {
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function tooShortMsgData()
|
||||
public
|
||||
onlyValidSignatureAndData("")
|
||||
view
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../access/roles/SignerRole.sol";
|
||||
|
||||
|
||||
contract SignerRoleMock is SignerRole {
|
||||
function removeSigner(address account) public {
|
||||
_removeSigner(account);
|
||||
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "../token/ERC20/IERC20.sol";
|
||||
import "../crowdsale/validation/TimedCrowdsale.sol";
|
||||
|
||||
|
||||
contract TimedCrowdsaleImpl is TimedCrowdsale {
|
||||
|
||||
constructor (
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/**
|
||||
* @title Ownable
|
||||
* @dev The Ownable contract has an owner address, and provides basic authorization control
|
||||
@ -9,20 +8,18 @@ pragma solidity ^0.4.24;
|
||||
contract Ownable {
|
||||
address private _owner;
|
||||
|
||||
|
||||
event OwnershipRenounced(address indexed previousOwner);
|
||||
event OwnershipTransferred(
|
||||
address indexed previousOwner,
|
||||
address indexed newOwner
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
|
||||
* account.
|
||||
*/
|
||||
constructor() public {
|
||||
constructor() internal {
|
||||
_owner = msg.sender;
|
||||
emit OwnershipTransferred(address(0), _owner);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,7 +51,7 @@ contract Ownable {
|
||||
* modifier anymore.
|
||||
*/
|
||||
function renounceOwnership() public onlyOwner {
|
||||
emit OwnershipRenounced(_owner);
|
||||
emit OwnershipTransferred(_owner, address(0));
|
||||
_owner = address(0);
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
|
||||
/**
|
||||
* @title Secondary
|
||||
* @dev A Secondary contract can only be used by its primary account (the one that created it)
|
||||
@ -8,11 +7,16 @@ pragma solidity ^0.4.24;
|
||||
contract Secondary {
|
||||
address private _primary;
|
||||
|
||||
event PrimaryTransferred(
|
||||
address recipient
|
||||
);
|
||||
|
||||
/**
|
||||
* @dev Sets the primary account to the one that is creating the Secondary contract.
|
||||
*/
|
||||
constructor() public {
|
||||
constructor() internal {
|
||||
_primary = msg.sender;
|
||||
emit PrimaryTransferred(_primary);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -23,13 +27,20 @@ contract Secondary {
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the address of the primary.
|
||||
*/
|
||||
function primary() public view returns (address) {
|
||||
return _primary;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @dev Transfers contract to a new primary.
|
||||
* @param recipient The address of new primary.
|
||||
*/
|
||||
function transferPrimary(address recipient) public onlyPrimary {
|
||||
require(recipient != address(0));
|
||||
|
||||
_primary = recipient;
|
||||
emit PrimaryTransferred(_primary);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,17 +2,20 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title SplitPayment
|
||||
* @title PaymentSplitter
|
||||
* @dev This contract can be used when payments need to be received by a group
|
||||
* of people and split proportionately to some number of shares they own.
|
||||
*/
|
||||
contract SplitPayment {
|
||||
contract PaymentSplitter {
|
||||
using SafeMath for uint256;
|
||||
|
||||
uint256 private _totalShares = 0;
|
||||
uint256 private _totalReleased = 0;
|
||||
event PayeeAdded(address account, uint256 shares);
|
||||
event PaymentReleased(address to, uint256 amount);
|
||||
event PaymentReceived(address from, uint256 amount);
|
||||
|
||||
uint256 private _totalShares;
|
||||
uint256 private _totalReleased;
|
||||
|
||||
mapping(address => uint256) private _shares;
|
||||
mapping(address => uint256) private _released;
|
||||
@ -33,7 +36,9 @@ contract SplitPayment {
|
||||
/**
|
||||
* @dev payable fallback
|
||||
*/
|
||||
function () external payable {}
|
||||
function () external payable {
|
||||
emit PaymentReceived(msg.sender, msg.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the total shares of the contract.
|
||||
@ -85,12 +90,12 @@ contract SplitPayment {
|
||||
);
|
||||
|
||||
require(payment != 0);
|
||||
assert(address(this).balance >= payment);
|
||||
|
||||
_released[account] = _released[account].add(payment);
|
||||
_totalReleased = _totalReleased.add(payment);
|
||||
|
||||
account.transfer(payment);
|
||||
emit PaymentReleased(account, payment);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +103,7 @@ contract SplitPayment {
|
||||
* @param account The address of the payee to add.
|
||||
* @param shares_ The number of shares owned by the payee.
|
||||
*/
|
||||
function _addPayee(address account, uint256 shares_) internal {
|
||||
function _addPayee(address account, uint256 shares_) private {
|
||||
require(account != address(0));
|
||||
require(shares_ > 0);
|
||||
require(_shares[account] == 0);
|
||||
@ -106,5 +111,6 @@ contract SplitPayment {
|
||||
_payees.push(account);
|
||||
_shares[account] = shares_;
|
||||
_totalShares = _totalShares.add(shares_);
|
||||
emit PayeeAdded(account, shares_);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "./Escrow.sol";
|
||||
|
||||
import "./escrow/Escrow.sol";
|
||||
|
||||
/**
|
||||
* @title PullPayment
|
||||
@ -11,7 +10,7 @@ import "./Escrow.sol";
|
||||
contract PullPayment {
|
||||
Escrow private _escrow;
|
||||
|
||||
constructor() public {
|
||||
constructor() internal {
|
||||
_escrow = new Escrow();
|
||||
}
|
||||
|
||||
|
||||
@ -2,10 +2,10 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "./Escrow.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title ConditionalEscrow
|
||||
* @dev Base abstract escrow to only allow withdrawal if a condition is met.
|
||||
* @dev Intended usage: See Escrow.sol. Same usage guidelines apply here.
|
||||
*/
|
||||
contract ConditionalEscrow is Escrow {
|
||||
/**
|
||||
@ -1,15 +1,19 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "../math/SafeMath.sol";
|
||||
import "../ownership/Secondary.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
import "../../ownership/Secondary.sol";
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* @title Escrow
|
||||
* @dev Base escrow contract, holds funds destinated to a payee until they
|
||||
* withdraw them. The contract that uses the escrow as its payment method
|
||||
* should be its primary, and provide public methods redirecting to the escrow's
|
||||
* deposit and withdraw.
|
||||
* @dev Base escrow contract, holds funds designated for a payee until they
|
||||
* withdraw them.
|
||||
* @dev Intended usage: This contract (and derived escrow contracts) should be a
|
||||
* standalone contract, that only interacts with the contract that instantiated
|
||||
* it. That way, it is guaranteed that all Ether will be handled according to
|
||||
* the Escrow rules, and there is no need to check for payable functions or
|
||||
* transfers in the inheritance tree. The contract that uses the escrow as its
|
||||
* payment method should be its primary, and provide public methods redirecting
|
||||
* to the escrow's deposit and withdraw.
|
||||
*/
|
||||
contract Escrow is Secondary {
|
||||
using SafeMath for uint256;
|
||||
@ -40,7 +44,6 @@ contract Escrow is Secondary {
|
||||
*/
|
||||
function withdraw(address payee) public onlyPrimary {
|
||||
uint256 payment = _deposits[payee];
|
||||
assert(address(this).balance >= payment);
|
||||
|
||||
_deposits[payee] = 0;
|
||||
|
||||
@ -1,19 +1,22 @@
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
import "./ConditionalEscrow.sol";
|
||||
import "../ownership/Secondary.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title RefundEscrow
|
||||
* @dev Escrow that holds funds for a beneficiary, deposited from multiple parties.
|
||||
* The primary account may close the deposit period, and allow for either withdrawal
|
||||
* by the beneficiary, or refunds to the depositors.
|
||||
* @dev Escrow that holds funds for a beneficiary, deposited from multiple
|
||||
* parties.
|
||||
* @dev Intended usage: See Escrow.sol. Same usage guidelines apply here.
|
||||
* @dev The primary account (that is, the contract that instantiates this
|
||||
* contract) may deposit, close the deposit period, and allow for either
|
||||
* withdrawal by the beneficiary, or refunds to the depositors. All interactions
|
||||
* with RefundEscrow will be made through the primary contract. See the
|
||||
* RefundableCrowdsale contract for an example of RefundEscrow’s use.
|
||||
*/
|
||||
contract RefundEscrow is Secondary, ConditionalEscrow {
|
||||
contract RefundEscrow is ConditionalEscrow {
|
||||
enum State { Active, Refunding, Closed }
|
||||
|
||||
event Closed();
|
||||
event RefundsClosed();
|
||||
event RefundsEnabled();
|
||||
|
||||
State private _state;
|
||||
@ -59,7 +62,7 @@ contract RefundEscrow is Secondary, ConditionalEscrow {
|
||||
function close() public onlyPrimary {
|
||||
require(_state == State.Active);
|
||||
_state = State.Closed;
|
||||
emit Closed();
|
||||
emit RefundsClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3,7 +3,6 @@ pragma solidity ^0.4.24;
|
||||
import "./IERC20.sol";
|
||||
import "../../math/SafeMath.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title Standard ERC20 token
|
||||
*
|
||||
@ -29,7 +28,7 @@ contract ERC20 is IERC20 {
|
||||
|
||||
/**
|
||||
* @dev Gets the balance of the specified address.
|
||||
* @param owner The address to query the the balance of.
|
||||
* @param owner The address to query the balance of.
|
||||
* @return An uint256 representing the amount owned by the passed address.
|
||||
*/
|
||||
function balanceOf(address owner) public view returns (uint256) {
|
||||
@ -59,12 +58,7 @@ contract ERC20 is IERC20 {
|
||||
* @param value The amount to be transferred.
|
||||
*/
|
||||
function transfer(address to, uint256 value) public returns (bool) {
|
||||
require(value <= _balances[msg.sender]);
|
||||
require(to != address(0));
|
||||
|
||||
_balances[msg.sender] = _balances[msg.sender].sub(value);
|
||||
_balances[to] = _balances[to].add(value);
|
||||
emit Transfer(msg.sender, to, value);
|
||||
_transfer(msg.sender, to, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -99,14 +93,10 @@ contract ERC20 is IERC20 {
|
||||
public
|
||||
returns (bool)
|
||||
{
|
||||
require(value <= _balances[from]);
|
||||
require(value <= _allowed[from][msg.sender]);
|
||||
require(to != address(0));
|
||||
|
||||
_balances[from] = _balances[from].sub(value);
|
||||
_balances[to] = _balances[to].add(value);
|
||||
_allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);
|
||||
emit Transfer(from, to, value);
|
||||
_transfer(from, to, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -158,33 +148,48 @@ contract ERC20 is IERC20 {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfer token for a specified addresses
|
||||
* @param from The address to transfer from.
|
||||
* @param to The address to transfer to.
|
||||
* @param value The amount to be transferred.
|
||||
*/
|
||||
function _transfer(address from, address to, uint256 value) internal {
|
||||
require(value <= _balances[from]);
|
||||
require(to != address(0));
|
||||
|
||||
_balances[from] = _balances[from].sub(value);
|
||||
_balances[to] = _balances[to].add(value);
|
||||
emit Transfer(from, to, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Internal function that mints an amount of the token and assigns it to
|
||||
* an account. This encapsulates the modification of balances such that the
|
||||
* proper events are emitted.
|
||||
* @param account The account that will receive the created tokens.
|
||||
* @param amount The amount that will be created.
|
||||
* @param value The amount that will be created.
|
||||
*/
|
||||
function _mint(address account, uint256 amount) internal {
|
||||
function _mint(address account, uint256 value) internal {
|
||||
require(account != 0);
|
||||
_totalSupply = _totalSupply.add(amount);
|
||||
_balances[account] = _balances[account].add(amount);
|
||||
emit Transfer(address(0), account, amount);
|
||||
_totalSupply = _totalSupply.add(value);
|
||||
_balances[account] = _balances[account].add(value);
|
||||
emit Transfer(address(0), account, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Internal function that burns an amount of the token of a given
|
||||
* account.
|
||||
* @param account The account whose tokens will be burnt.
|
||||
* @param amount The amount that will be burnt.
|
||||
* @param value The amount that will be burnt.
|
||||
*/
|
||||
function _burn(address account, uint256 amount) internal {
|
||||
function _burn(address account, uint256 value) internal {
|
||||
require(account != 0);
|
||||
require(amount <= _balances[account]);
|
||||
require(value <= _balances[account]);
|
||||
|
||||
_totalSupply = _totalSupply.sub(amount);
|
||||
_balances[account] = _balances[account].sub(amount);
|
||||
emit Transfer(account, address(0), amount);
|
||||
_totalSupply = _totalSupply.sub(value);
|
||||
_balances[account] = _balances[account].sub(value);
|
||||
emit Transfer(account, address(0), value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -192,15 +197,15 @@ contract ERC20 is IERC20 {
|
||||
* account, deducting from the sender's allowance for said account. Uses the
|
||||
* internal burn function.
|
||||
* @param account The account whose tokens will be burnt.
|
||||
* @param amount The amount that will be burnt.
|
||||
* @param value The amount that will be burnt.
|
||||
*/
|
||||
function _burnFrom(address account, uint256 amount) internal {
|
||||
require(amount <= _allowed[account][msg.sender]);
|
||||
function _burnFrom(address account, uint256 value) internal {
|
||||
require(value <= _allowed[account][msg.sender]);
|
||||
|
||||
// Should https://github.com/OpenZeppelin/zeppelin-solidity/issues/707 be accepted,
|
||||
// this function needs to emit an event with the updated approval.
|
||||
_allowed[account][msg.sender] = _allowed[account][msg.sender].sub(
|
||||
amount);
|
||||
_burn(account, amount);
|
||||
value);
|
||||
_burn(account, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "./ERC20.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title Burnable Token
|
||||
* @dev Token that can be irreversibly burned (destroyed).
|
||||
@ -25,12 +24,4 @@ contract ERC20Burnable is ERC20 {
|
||||
function burnFrom(address from, uint256 value) public {
|
||||
_burnFrom(from, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Overrides ERC20._burn in order for burn and burnFrom to emit
|
||||
* an additional Burn event.
|
||||
*/
|
||||
function _burn(address who, uint256 value) internal {
|
||||
super._burn(who, value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "./ERC20Mintable.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title Capped token
|
||||
* @dev Mintable token with a token cap.
|
||||
@ -25,22 +24,8 @@ contract ERC20Capped is ERC20Mintable {
|
||||
return _cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Function to mint tokens
|
||||
* @param to The address that will receive the minted tokens.
|
||||
* @param amount The amount of tokens to mint.
|
||||
* @return A boolean that indicates if the operation was successful.
|
||||
*/
|
||||
function mint(
|
||||
address to,
|
||||
uint256 amount
|
||||
)
|
||||
public
|
||||
returns (bool)
|
||||
{
|
||||
require(totalSupply().add(amount) <= _cap);
|
||||
|
||||
return super.mint(to, amount);
|
||||
function _mint(address account, uint256 value) internal {
|
||||
require(totalSupply().add(value) <= _cap);
|
||||
super._mint(account, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ pragma solidity ^0.4.24;
|
||||
|
||||
import "./IERC20.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title ERC20Detailed token
|
||||
* @dev The decimals are only for visualization purposes.
|
||||
|
||||
@ -3,59 +3,26 @@ pragma solidity ^0.4.24;
|
||||
import "./ERC20.sol";
|
||||
import "../../access/roles/MinterRole.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title ERC20Mintable
|
||||
* @dev ERC20 minting logic
|
||||
*/
|
||||
contract ERC20Mintable is ERC20, MinterRole {
|
||||
event MintingFinished();
|
||||
|
||||
bool private _mintingFinished = false;
|
||||
|
||||
modifier onlyBeforeMintingFinished() {
|
||||
require(!_mintingFinished);
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the minting is finished.
|
||||
*/
|
||||
function mintingFinished() public view returns(bool) {
|
||||
return _mintingFinished;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Function to mint tokens
|
||||
* @param to The address that will receive the minted tokens.
|
||||
* @param amount The amount of tokens to mint.
|
||||
* @param value The amount of tokens to mint.
|
||||
* @return A boolean that indicates if the operation was successful.
|
||||
*/
|
||||
function mint(
|
||||
address to,
|
||||
uint256 amount
|
||||
uint256 value
|
||||
)
|
||||
public
|
||||
onlyMinter
|
||||
onlyBeforeMintingFinished
|
||||
returns (bool)
|
||||
{
|
||||
_mint(to, amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Function to stop minting new tokens.
|
||||
* @return True if the operation was successful.
|
||||
*/
|
||||
function finishMinting()
|
||||
public
|
||||
onlyMinter
|
||||
onlyBeforeMintingFinished
|
||||
returns (bool)
|
||||
{
|
||||
_mintingFinished = true;
|
||||
emit MintingFinished();
|
||||
_mint(to, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user