Compare commits

...

51 Commits

Author SHA1 Message Date
cc9fa57777 v1.11.0 2018-07-13 17:07:14 -03:00
eb4dfea6e9 v1.11.0-rc.1 2018-07-03 19:32:58 -03:00
8fd072cf8e Escrows (#1014)
* Added basic Escrow

* PullPayment now uses an Escrow, removing all trust from the contract

* Abstracted the Escrow tests to a behaviour

* Added ConditionalEscrow

* Added RefundableEscrow.

* RefundableCrowdsale now uses a RefundEscrow, removed RefundVault.

* Renaming after code review.

* Added log test helper.

* Now allowing empty deposits and withdrawals.

* Style fixes.

* Minor review comments.

* Add Deposited and Withdrawn events, removed Refunded

* The base Escrow is now Ownable, users of it (owners) must provide methods to access it.
2018-07-03 18:54:55 -03:00
c2ad8c3f57 Update the use of call() with selector only. (#1033) 2018-06-30 17:55:03 -03:00
fd253d6b8d Fix dependency warnings (#1053)
* update package-lock generated by npm

* run npm audit fix
2018-06-30 17:39:28 -03:00
7d8e3ca8b2 Align ERC721 Receiver with current ERC721 standard. (#1047)
* Align ERC721 Receiver with current ERC721 standard.
Adds a second address field to onERC721Received
onERC721Received(address,address,uint256,bytes)
Updates the function signature to 0x150b7a02 from 0xf0b9e5ba

* Add _operator to onERC721Received

* Fix error caused by formatOnSave

* Fixed comments on ERC721Receiver
Removed "Must use 50,000 gas or less"
Corrected the function signature
2018-06-28 20:11:18 -07:00
6b37ba36a1 Remove ERC827 token. (#1045)
Implementing this token is unsafe as per comments here:
https://github.com/ethereum/EIPs/issues/827#issuecomment-397857455
2018-06-28 13:32:07 -03:00
dc1e352cc4 Don't emit Approval event when approval is cleared on transfer (#1039) 2018-06-24 23:04:57 -07:00
f18c3bc438 feat: initial implementation of ERC1046 (#933)
* feat: initial implementation of ERC1046
2018-06-17 16:21:05 -07:00
0047e79681 ignore truffle generated file (#1019) 2018-06-16 19:30:48 -03:00
74a62a1314 using SafeERC20 to implement safeTransfer in Crowdsale (#1006)
* introduced safeTransfer to Crowdsale

* Removed .node-xmlhttprequest-sync-7601
2018-06-16 12:46:19 -03:00
92b695f2fb Fix/whitelisted crowdsale (#981)
* fix: swithc WhitelistedCrowdsale to use Whitelist.sol

* feat: refactor whitelist.sol, rbac.sol and whitelistedcrowdsale.sol

* feat: add event arg assets and update whitelist

* fix: update modifier comment and also test isWhitelisted

* fix: remove onlyWhitelisted backwards compat attempt, fix explicit inheritance

* fix: remove underscore prefix from event args

* fix: user access/Whitelist
2018-06-15 14:11:50 -07:00
Rob
ee78f67985 fixing comment - changing '_to' to '_spender' (#1007) 2018-06-15 12:08:28 -03:00
07020e9544 Remove redundant @dev tags (#995)
* Remove redundant @dev tags

* Remove redundant @notice tags
2018-06-14 15:19:59 -07:00
b4406d385f Use abi.encodeWithSignature together with raw call() (#1008) 2018-06-14 18:50:39 -03:00
78e39aa2ad Do not use implicit type conversion for address literals (#1002)
Uses the explicit address(0) for the zero address
2018-06-13 16:21:24 -07:00
e4ed8f0705 Added explicit integer sizes to uint variables in StandardToken (#1004) 2018-06-13 11:54:54 -07:00
5daaf60d11 Make contracts 4.24 compatible (#951)
* Make contracts 4.24 compatible
2018-06-13 11:34:32 -07:00
e1dc1411fc WIP: Fix/erc721 (#993)
* fix: defer lookup-specific info to implementations

* fix: change inheritance order, fix import
2018-06-12 18:46:32 -03:00
9f1d294ba4 Move Whitelist contract to access directory (#994) 2018-06-11 19:35:29 -03:00
9951acf6d8 Added aflesher as an author to SignatureBouncer.sol (#996) 2018-06-11 13:48:00 -07:00
72792a724d ownable: add a notice on renounceOwnership (#937)
* ownable: add a notice on renounceOwnership

* Apply the suggestion by @shrugs
2018-06-10 16:39:54 -03:00
b0292cf628 Add isValidSignatureAndData to Bouncer to verify method calls (#973) 2018-06-09 14:45:53 -07:00
39385f9f4e Addressed unchecked return value in AllowanceCrowdsale #945 using SafeERC20 (#946)
* addressed unchecked return value in AllowanceCrowdsale #945 using SafeERC20
2018-06-08 17:00:46 -07:00
7a61371b19 Updated documentation Uppercasing function name for ERC02 basic token (#720) 2018-06-08 16:30:48 -07:00
259b9da3e6 add 165 to 721 (#972)
* make _tokenId indexed in Transfer and Approval events

via: https://github.com/ethereum/EIPs/pull/1124/files

* fix: make name() and symbol() external instead of public

* feat: implement ERC721's ERC165

* feat: erc165 tests

* fix: don't use chai-as-promised in direct await

* fix: reorganize to /introspection

* feat: abstract all erc165 tests to a behavior

* feat: disallow registering 0xffffffff
2018-06-08 18:50:12 -03:00
5326e7c36e Removed redundant modifiers from CappedToken. (#969) 2018-06-06 11:29:54 -07:00
feb665136c 1.10.0 2018-06-05 17:40:24 -03:00
7fb84b42d5 Refactoring Superuser contract to allow Owners to transfer ownership … (#978)
* Refactoring Superuser contract to allow Owners to transfer ownership when they are not superusers #50

* Refactoring tests to create a contract instance for each of them #50
2018-06-05 17:28:42 -03:00
5db0d7d1a0 included command to add upstream (#959) 2018-06-04 18:31:32 -07:00
512e8218ca Add a comment on Detailed ERC20 token #953 (#960)
* add a comment on detailed erc20 token #953
2018-06-04 18:13:09 -07:00
9d6ffae8cb removed mentions of 'development' branch in Contribution Guidelines (#966) 2018-06-04 17:34:04 -07:00
2a997a8e92 Fixed wrong variable name in SampleCrowdsale.test.js. (#916) 2018-06-04 16:49:46 -07:00
5651538045 Clarified the rationaly behind the mul branch test. (#970) 2018-06-04 16:04:08 -07:00
10e84aecaf Fix Node 10 compatibility (#949)
*  update sha3 1.2.0 -> 1.2.2 for node 10 compatibility

* update nan 2.6.2 -> 2.10.0 for node 10 compatibility

* commit new package-lock.json format generated by npm 6
2018-06-04 17:26:23 -03:00
2637bd89be fix: add comment about rbacwithadmin being rather powerful (#936)
* fix: add comment about rbacwithadmin being rather powerful
* fix: move RBACWithAdmin to examples
2018-06-04 12:32:57 -07:00
32ec8b5398 Add Status Embark to README (#956)
* Update README.md

* update embark import to use the v1.9.0 tag instead of master

* Update README.md
2018-06-04 15:21:55 -03:00
a0c03ee61c Adding new Superuser contract with test (#952)
* Adding new Superuser contract + tests
2018-06-03 16:14:30 -07:00
e3f866c982 fix: remove daylimit.sol, closes #925 (#964) 2018-06-01 13:16:47 -07:00
5ab9024b6a update balance syntax for solidity 0.4.23 (#940) 2018-05-30 16:10:08 -07:00
d5f06ab32f addressed TokenVesting contstructor natspec updates in #742 (#935) 2018-05-29 10:45:40 -06:00
746673a94f style: use the max-len solidity rule (#944) 2018-05-14 11:42:32 -06:00
ba4cf03da7 contracts mocks: replace deprecated constant with view (#931) 2018-05-10 10:43:15 -06:00
39370ff690 Adding RBAC Mintable token (#923)
* added the RBACMintableToken
* added MintedCrowdsale with RBACMintableToken test
* added a mintable behaviour for tests
* moved minting tests in behaviour
* created a minted crowdsale behaviour to be tested with both mintable and rbacmintable token
2018-05-09 18:01:25 -07:00
ad12381549 update constructor syntax for solidity 0.4.23 in numerous contracts (#921)
* update solidity-coverage to ^0.5.0

* update truffle dependency to ^4.1.8

* update solium to ^1.1.7

* update all contracts to solidity ^0.4.23
2018-05-08 18:02:00 -07:00
20b85be6aa Ownable behavior (#929)
* added function to renounce ownership

* Provide an Ownable behavior for testing (#905)

* Fix indentation

* Convert to use should assertions
2018-05-08 17:33:37 -07:00
4223c9d50e feat: refactor whitelist.sol to use RBAC (#893)
* feat: refactor whitelist.sol to use RBAC

* fix: remove poor backwards compat attempt
2018-05-08 17:20:28 -07:00
f0eea31bdf Fix ERC721Token.sol code indent (#909) 2018-05-07 11:39:54 -07:00
ce0a928a6c Fix typos in ERC721BasicToken comments (#889) 2018-05-07 11:20:12 -07:00
85f079ee89 Removing more asserts in favor of require (#834)
* Removed asserts and replaced them in favor of require

* Adapted tests to work with requires
2018-05-03 14:04:02 -03:00
7e44204d9b added function to renounce ownership (#907) 2018-05-03 13:25:18 -03:00
160 changed files with 7953 additions and 5388 deletions

3
.gitignore vendored
View File

@ -34,3 +34,6 @@ build/
# lol macs # lol macs
.DS_Store/ .DS_Store/
# truffle
.node-xmlhttprequest-*

View File

@ -5,7 +5,8 @@
"quotes": ["error", "double"], "quotes": ["error", "double"],
"no-empty-blocks": "off", "no-empty-blocks": "off",
"indentation": ["error", 2], "indentation": ["error", 2],
"arg-overflow": ["warning", 3], "max-len": ["warning", 79],
"no-constant": ["error"],
"security/enforce-explicit-visibility": ["error"], "security/enforce-explicit-visibility": ["error"],
"security/no-block-members": ["warning"], "security/no-block-members": ["warning"],
"security/no-inline-assembly": ["warning"] "security/no-inline-assembly": ["warning"]

View File

@ -20,13 +20,13 @@ As a contributor, you are expected to fork this repository, work on your own for
``` ```
cd openzeppelin-solidity cd openzeppelin-solidity
git remote add upstream https://github.com/OpenZeppelin/openzeppelin-solidity.git
git fetch upstream git fetch upstream
git checkout development git pull --rebase upstream master
git pull --rebase upstream development
``` ```
NOTE: The directory `openzeppelin-solidity` represents your fork's local copy. NOTE: The directory `openzeppelin-solidity` represents your fork's local copy.
2) Branch out from `development` into `fix/some-bug-#123`: 2) Branch out from `master` into `fix/some-bug-#123`:
(Postfixing #123 will associate your PR with the issue #123 and make everyone's life easier =D) (Postfixing #123 will associate your PR with the issue #123 and make everyone's life easier =D)
``` ```
git checkout -b fix/some-bug-#123 git checkout -b fix/some-bug-#123

View File

@ -13,7 +13,11 @@ With OpenZeppelin, you can build distributed applications, protocols and organiz
## Getting Started ## Getting Started
OpenZeppelin integrates with [Truffle](https://github.com/ConsenSys/truffle), an Ethereum development environment. Please install Truffle and initialize your project with `truffle init`. OpenZeppelin integrates with [Truffle](https://github.com/ConsenSys/truffle) and [Embark](https://github.com/embark-framework/embark/).
## Truffle
To use with Truffle, first install it and initialize your project with `truffle init`.
```sh ```sh
npm install -g truffle npm install -g truffle
@ -21,7 +25,20 @@ mkdir myproject && cd myproject
truffle init truffle init
``` ```
To install the OpenZeppelin library, run the following in your Solidity project root directory: ## Embark
To use with Embark, first install it and initialize your project with `embark new MyApp`.
```sh
npm install -g embark
embark new MyApp
cd MyApp
```
## Installing OpenZeppelin
After installing either Framework, to install the OpenZeppelin library, run the following in your Solidity project root directory:
```sh ```sh
npm init -y npm init -y
npm install -E openzeppelin-solidity npm install -E openzeppelin-solidity
@ -39,6 +56,15 @@ contract MyContract is Ownable {
} }
``` ```
If you are using Embark, you can also import directly from github:
```solidity
import "github.com/OpenZeppelin/openzeppelin-solidity/contracts/ownership/Ownable.sol#v1.9.0";
contract MyContract is Ownable {
...
}
```
## Security ## Security
OpenZeppelin is meant to provide secure, tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problem you might experience. OpenZeppelin is meant to provide secure, tested and community-audited code, but please use common sense when doing anything that deals with real money! We take no responsibility for your implementation decisions and any security problem you might experience.

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
/** /**
@ -21,7 +21,8 @@ library AddressUtils {
// for more details about how this works. // for more details about how this works.
// TODO Check this again before the Serenity release, because all addresses will be // TODO Check this again before the Serenity release, because all addresses will be
// contracts then. // contracts then.
assembly { size := extcodesize(addr) } // solium-disable-line security/no-inline-assembly // solium-disable-next-line security/no-inline-assembly
assembly { size := extcodesize(addr) }
return size > 0; return size > 0;
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./payment/PullPayment.sol"; import "./payment/PullPayment.sol";
@ -35,15 +35,15 @@ contract Bounty is PullPayment, Destructible {
} }
/** /**
* @dev Sends the contract funds to the researcher that proved the contract is broken. * @dev Transfers the contract funds to the researcher that proved the contract is broken.
* @param target contract * @param target contract
*/ */
function claim(Target target) public { function claim(Target target) public {
address researcher = researchers[target]; address researcher = researchers[target];
require(researcher != 0); require(researcher != address(0));
// Check Target contract invariants // Check Target contract invariants
require(!target.checkInvariant()); require(!target.checkInvariant());
asyncSend(researcher, address(this).balance); asyncTransfer(researcher, address(this).balance);
claimed = true; claimed = true;
} }

View File

@ -1,75 +0,0 @@
pragma solidity ^0.4.21;
/**
* @title DayLimit
* @dev Base contract that enables methods to be protected by placing a linear limit (specifiable)
* on a particular resource per calendar day. Is multiowned to allow the limit to be altered.
*/
contract DayLimit {
uint256 public dailyLimit;
uint256 public spentToday;
uint256 public lastDay;
/**
* @dev Constructor that sets the passed value as a dailyLimit.
* @param _limit uint256 to represent the daily limit.
*/
function DayLimit(uint256 _limit) public {
dailyLimit = _limit;
lastDay = today();
}
/**
* @dev sets the daily limit. Does not alter the amount already spent today.
* @param _newLimit uint256 to represent the new limit.
*/
function _setDailyLimit(uint256 _newLimit) internal {
dailyLimit = _newLimit;
}
/**
* @dev Resets the amount already spent today.
*/
function _resetSpentToday() internal {
spentToday = 0;
}
/**
* @dev Checks to see if there is enough resource to spend today. If true, the resource may be expended.
* @param _value uint256 representing the amount of resource to spend.
* @return A boolean that is True if the resource was spent and false otherwise.
*/
function underLimit(uint256 _value) internal returns (bool) {
// reset the spend limit if we're on a different day to last time.
if (today() > lastDay) {
spentToday = 0;
lastDay = today();
}
// check to see if there's enough left - if so, subtract and return true.
// overflow protection // dailyLimit check
if (spentToday + _value >= spentToday && spentToday + _value <= dailyLimit) {
spentToday += _value;
return true;
}
return false;
}
/**
* @dev Private function to determine today's index
* @return uint256 of today's index.
*/
function today() private view returns (uint256) {
// solium-disable-next-line security/no-block-members
return block.timestamp / 1 days;
}
/**
* @dev Simple modifier for daily limit.
*/
modifier limitedDaily(uint256 _value) {
require(underLimit(_value));
_;
}
}

View File

@ -1,14 +1,11 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
/** /**
* @title Eliptic curve signature operations * @title Eliptic curve signature operations
*
* @dev Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d * @dev Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d
*
* TODO Remove this library once solidity supports passing a signature to ecrecover. * TODO Remove this library once solidity supports passing a signature to ecrecover.
* See https://github.com/ethereum/solidity/issues/864 * See https://github.com/ethereum/solidity/issues/864
*
*/ */
library ECRecovery { library ECRecovery {
@ -59,7 +56,7 @@ library ECRecovery {
/** /**
* toEthSignedMessageHash * toEthSignedMessageHash
* @dev prefix a bytes32 value with "\x19Ethereum Signed Message:" * @dev prefix a bytes32 value with "\x19Ethereum Signed Message:"
* @dev and hash the result * and hash the result
*/ */
function toEthSignedMessageHash(bytes32 hash) function toEthSignedMessageHash(bytes32 hash)
internal internal
@ -69,8 +66,7 @@ library ECRecovery {
// 32 is the length in bytes of hash, // 32 is the length in bytes of hash,
// enforced by the type signature above // enforced by the type signature above
return keccak256( return keccak256(
"\x19Ethereum Signed Message:\n32", abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)
hash
); );
} }
} }

View File

@ -1,11 +1,11 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
/** /**
* @title LimitBalance * @title LimitBalance
* @dev Simple contract to limit the balance of child contract. * @dev Simple contract to limit the balance of child contract.
* @dev Note this doesn't prevent other contracts to send funds by using selfdestruct(address); * Note this doesn't prevent other contracts to send funds by using selfdestruct(address);
* @dev See: https://github.com/ConsenSys/smart-contract-best-practices#remember-that-ether-can-be-forcibly-sent-to-an-account * See: https://github.com/ConsenSys/smart-contract-best-practices#remember-that-ether-can-be-forcibly-sent-to-an-account
*/ */
contract LimitBalance { contract LimitBalance {
@ -15,7 +15,7 @@ contract LimitBalance {
* @dev Constructor that sets the passed value as a limit. * @dev Constructor that sets the passed value as a limit.
* @param _limit uint256 to represent the limit. * @param _limit uint256 to represent the limit.
*/ */
function LimitBalance(uint256 _limit) public { constructor(uint256 _limit) public {
limit = _limit; limit = _limit;
} }

View File

@ -1,10 +1,10 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
/* /*
* @title MerkleProof * @title MerkleProof
* @dev Merkle proof verification * @dev Merkle proof verification based on
* @note Based on https://github.com/ameensol/merkle-tree-solidity/blob/master/src/MerkleProof.sol * https://github.com/ameensol/merkle-tree-solidity/blob/master/src/MerkleProof.sol
*/ */
library MerkleProof { library MerkleProof {
/* /*
@ -14,7 +14,15 @@ library MerkleProof {
* @param _root Merkle root * @param _root Merkle root
* @param _leaf Leaf of Merkle tree * @param _leaf Leaf of Merkle tree
*/ */
function verifyProof(bytes32[] _proof, bytes32 _root, bytes32 _leaf) internal pure returns (bool) { function verifyProof(
bytes32[] _proof,
bytes32 _root,
bytes32 _leaf
)
internal
pure
returns (bool)
{
bytes32 computedHash = _leaf; bytes32 computedHash = _leaf;
for (uint256 i = 0; i < _proof.length; i++) { for (uint256 i = 0; i < _proof.length; i++) {
@ -22,10 +30,10 @@ library MerkleProof {
if (computedHash < proofElement) { if (computedHash < proofElement) {
// Hash(current computed hash + current element of the proof) // Hash(current computed hash + current element of the proof)
computedHash = keccak256(computedHash, proofElement); computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
} else { } else {
// Hash(current element of the proof + current computed hash) // Hash(current element of the proof + current computed hash)
computedHash = keccak256(proofElement, computedHash); computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
} }
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
/** /**

View File

@ -1,30 +1,41 @@
pragma solidity ^0.4.18; pragma solidity ^0.4.24;
import "../ownership/Ownable.sol"; import "../ownership/Ownable.sol";
import "../ownership/rbac/RBAC.sol"; import "../ownership/rbac/RBAC.sol";
import "../ECRecovery.sol"; import "../ECRecovery.sol";
/** /**
* @title SignatureBouncer * @title SignatureBouncer
* @author PhABC and Shrugs * @author PhABC, Shrugs and aflesher
* @dev Bouncer allows users to submit a signature as a permission to do an action. * @dev Bouncer allows users to submit a signature as a permission to do an action.
* @dev If the signature is from one of the authorized bouncer addresses, the signature * If the signature is from one of the authorized bouncer addresses, the signature
* @dev is valid. The owner of the contract adds/removes bouncers. * is valid. The owner of the contract adds/removes bouncers.
* @dev Bouncer addresses can be individual servers signing grants or different * Bouncer addresses can be individual servers signing grants or different
* @dev users within a decentralized club that have permission to invite other members. * users within a decentralized club that have permission to invite other members.
* @dev * This technique is useful for whitelists and airdrops; instead of putting all
* @dev This technique is useful for whitelists and airdrops; instead of putting all * valid addresses on-chain, simply sign a grant of the form
* @dev valid addresses on-chain, simply sign a grant of the form * keccak256(abi.encodePacked(`:contractAddress` + `:granteeAddress`)) using a valid bouncer address.
* @dev keccak256(`:contractAddress` + `:granteeAddress`) using a valid bouncer address. * Then restrict access to your crowdsale/whitelist/airdrop using the
* @dev Then restrict access to your crowdsale/whitelist/airdrop using the * `onlyValidSignature` modifier (or implement your own using isValidSignature).
* @dev `onlyValidSignature` modifier (or implement your own using isValidSignature). * In addition to `onlyValidSignature`, `onlyValidSignatureAndMethod` and
* @dev * `onlyValidSignatureAndData` can be used to restrict access to only a given method
* @dev See the tests Bouncer.test.js for specific usage examples. * or a given method with given parameters respectively.
* See the tests Bouncer.test.js for specific usage examples.
* @notice A method that uses the `onlyValidSignatureAndData` modifier must make the _sig
* 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 _sig data and the _sig 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 Ownable, RBAC { contract SignatureBouncer is Ownable, RBAC {
using ECRecovery for bytes32; using ECRecovery for bytes32;
string public constant ROLE_BOUNCER = "bouncer"; string public constant ROLE_BOUNCER = "bouncer";
uint constant METHOD_ID_SIZE = 4;
// (signature length size) 32 bytes + (signature size 65 bytes padded) 96 bytes
uint constant SIGNATURE_SIZE = 128;
/** /**
* @dev requires that a valid signature of a bouncer was provided * @dev requires that a valid signature of a bouncer was provided
@ -35,6 +46,24 @@ contract SignatureBouncer is Ownable, RBAC {
_; _;
} }
/**
* @dev requires that a valid signature with a specifed method of a bouncer was provided
*/
modifier onlyValidSignatureAndMethod(bytes _sig)
{
require(isValidSignatureAndMethod(msg.sender, _sig));
_;
}
/**
* @dev requires that a valid signature with a specifed method and params of a bouncer was provided
*/
modifier onlyValidSignatureAndData(bytes _sig)
{
require(isValidSignatureAndData(msg.sender, _sig));
_;
}
/** /**
* @dev allows the owner to add additional bouncer addresses * @dev allows the owner to add additional bouncer addresses
*/ */
@ -67,14 +96,54 @@ contract SignatureBouncer is Ownable, RBAC {
returns (bool) returns (bool)
{ {
return isValidDataHash( return isValidDataHash(
keccak256(address(this), _address), keccak256(abi.encodePacked(address(this), _address)),
_sig
);
}
/**
* @dev is the signature of `this + sender + methodId` from a bouncer?
* @return bool
*/
function isValidSignatureAndMethod(address _address, bytes _sig)
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];
}
return isValidDataHash(
keccak256(abi.encodePacked(address(this), _address, data)),
_sig
);
}
/**
* @dev is the signature of `this + sender + methodId + params(s)` from a bouncer?
* @notice the _sig parameter of the method being validated must be the "last" parameter
* @return bool
*/
function isValidSignatureAndData(address _address, bytes _sig)
internal
view
returns (bool)
{
require(msg.data.length > SIGNATURE_SIZE);
bytes memory data = new bytes(msg.data.length - SIGNATURE_SIZE);
for (uint i = 0; i < data.length; i++) {
data[i] = msg.data[i];
}
return isValidDataHash(
keccak256(abi.encodePacked(address(this), _address, data)),
_sig _sig
); );
} }
/** /**
* @dev internal function to convert a hash to an eth signed message * @dev internal function to convert a hash to an eth signed message
* @dev and then recover the signature and check it against the bouncer role * and then recover the signature and check it against the bouncer role
* @return bool * @return bool
*/ */
function isValidDataHash(bytes32 hash, bytes _sig) function isValidDataHash(bytes32 hash, bytes _sig)

View File

@ -0,0 +1,91 @@
pragma solidity ^0.4.24;
import "../ownership/Ownable.sol";
import "../ownership/rbac/RBAC.sol";
/**
* @title Whitelist
* @dev The Whitelist contract has a whitelist of addresses, and provides basic authorization control functions.
* This simplifies the implementation of "user permissions".
*/
contract Whitelist is Ownable, RBAC {
string public constant ROLE_WHITELISTED = "whitelist";
/**
* @dev Throws if operator is not whitelisted.
* @param _operator address
*/
modifier onlyIfWhitelisted(address _operator) {
checkRole(_operator, ROLE_WHITELISTED);
_;
}
/**
* @dev add an address to the whitelist
* @param _operator address
* @return true if the address was added to the whitelist, false if the address was already in the whitelist
*/
function addAddressToWhitelist(address _operator)
onlyOwner
public
{
addRole(_operator, ROLE_WHITELISTED);
}
/**
* @dev getter to determine if address is in whitelist
*/
function whitelist(address _operator)
public
view
returns (bool)
{
return hasRole(_operator, ROLE_WHITELISTED);
}
/**
* @dev add addresses to the whitelist
* @param _operators addresses
* @return true if at least one address was added to the whitelist,
* false if all addresses were already in the whitelist
*/
function addAddressesToWhitelist(address[] _operators)
onlyOwner
public
{
for (uint256 i = 0; i < _operators.length; i++) {
addAddressToWhitelist(_operators[i]);
}
}
/**
* @dev remove an address from the whitelist
* @param _operator address
* @return true if the address was removed from the whitelist,
* false if the address wasn't in the whitelist in the first place
*/
function removeAddressFromWhitelist(address _operator)
onlyOwner
public
{
removeRole(_operator, ROLE_WHITELISTED);
}
/**
* @dev remove addresses from the whitelist
* @param _operators addresses
* @return true if at least one address was removed from the whitelist,
* false if all addresses weren't in the whitelist in the first place
*/
function removeAddressesFromWhitelist(address[] _operators)
onlyOwner
public
{
for (uint256 i = 0; i < _operators.length; i++) {
removeAddressFromWhitelist(_operators[i]);
}
}
}

View File

@ -1,7 +1,8 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
import "../math/SafeMath.sol"; import "../math/SafeMath.sol";
import "../token/ERC20/SafeERC20.sol";
/** /**
@ -18,6 +19,7 @@ import "../math/SafeMath.sol";
*/ */
contract Crowdsale { contract Crowdsale {
using SafeMath for uint256; using SafeMath for uint256;
using SafeERC20 for ERC20;
// The token being sold // The token being sold
ERC20 public token; ERC20 public token;
@ -25,7 +27,10 @@ contract Crowdsale {
// Address where funds are collected // Address where funds are collected
address public wallet; address public wallet;
// How many token units a buyer gets per wei // How many token units a buyer gets per wei.
// The rate is the conversion between wei and the smallest and indivisible token unit.
// So, if you are using a rate of 1 with a DetailedERC20 token with 3 decimals called TOK
// 1 wei will give you 1 unit, or 0.001 TOK.
uint256 public rate; uint256 public rate;
// Amount of wei raised // Amount of wei raised
@ -38,14 +43,19 @@ contract Crowdsale {
* @param value weis paid for purchase * @param value weis paid for purchase
* @param amount amount of tokens purchased * @param amount amount of tokens purchased
*/ */
event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount); event TokenPurchase(
address indexed purchaser,
address indexed beneficiary,
uint256 value,
uint256 amount
);
/** /**
* @param _rate Number of token units a buyer gets per wei * @param _rate Number of token units a buyer gets per wei
* @param _wallet Address where collected funds will be forwarded to * @param _wallet Address where collected funds will be forwarded to
* @param _token Address of the token being sold * @param _token Address of the token being sold
*/ */
function Crowdsale(uint256 _rate, address _wallet, ERC20 _token) public { constructor(uint256 _rate, address _wallet, ERC20 _token) public {
require(_rate > 0); require(_rate > 0);
require(_wallet != address(0)); require(_wallet != address(0));
require(_token != address(0)); require(_token != address(0));
@ -104,7 +114,12 @@ contract Crowdsale {
* @param _beneficiary Address performing the token purchase * @param _beneficiary Address performing the token purchase
* @param _weiAmount Value in wei involved in the purchase * @param _weiAmount Value in wei involved in the purchase
*/ */
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal { function _preValidatePurchase(
address _beneficiary,
uint256 _weiAmount
)
internal
{
require(_beneficiary != address(0)); require(_beneficiary != address(0));
require(_weiAmount != 0); require(_weiAmount != 0);
} }
@ -114,7 +129,12 @@ contract Crowdsale {
* @param _beneficiary Address performing the token purchase * @param _beneficiary Address performing the token purchase
* @param _weiAmount Value in wei involved in the purchase * @param _weiAmount Value in wei involved in the purchase
*/ */
function _postValidatePurchase(address _beneficiary, uint256 _weiAmount) internal { function _postValidatePurchase(
address _beneficiary,
uint256 _weiAmount
)
internal
{
// optional override // optional override
} }
@ -123,8 +143,13 @@ contract Crowdsale {
* @param _beneficiary Address performing the token purchase * @param _beneficiary Address performing the token purchase
* @param _tokenAmount Number of tokens to be emitted * @param _tokenAmount Number of tokens to be emitted
*/ */
function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal { function _deliverTokens(
token.transfer(_beneficiary, _tokenAmount); address _beneficiary,
uint256 _tokenAmount
)
internal
{
token.safeTransfer(_beneficiary, _tokenAmount);
} }
/** /**
@ -132,7 +157,12 @@ contract Crowdsale {
* @param _beneficiary Address receiving the tokens * @param _beneficiary Address receiving the tokens
* @param _tokenAmount Number of tokens to be purchased * @param _tokenAmount Number of tokens to be purchased
*/ */
function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal { function _processPurchase(
address _beneficiary,
uint256 _tokenAmount
)
internal
{
_deliverTokens(_beneficiary, _tokenAmount); _deliverTokens(_beneficiary, _tokenAmount);
} }
@ -141,7 +171,12 @@ contract Crowdsale {
* @param _beneficiary Address receiving the tokens * @param _beneficiary Address receiving the tokens
* @param _weiAmount Value in wei involved in the purchase * @param _weiAmount Value in wei involved in the purchase
*/ */
function _updatePurchasingState(address _beneficiary, uint256 _weiAmount) internal { function _updatePurchasingState(
address _beneficiary,
uint256 _weiAmount
)
internal
{
// optional override // optional override
} }
@ -150,7 +185,9 @@ contract Crowdsale {
* @param _weiAmount Value in wei to be converted into tokens * @param _weiAmount Value in wei to be converted into tokens
* @return Number of tokens that can be purchased with the specified _weiAmount * @return Number of tokens that can be purchased with the specified _weiAmount
*/ */
function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) { function _getTokenAmount(uint256 _weiAmount)
internal view returns (uint256)
{
return _weiAmount.mul(rate); return _weiAmount.mul(rate);
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
import "../../ownership/Ownable.sol"; import "../../ownership/Ownable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../validation/TimedCrowdsale.sol"; import "../validation/TimedCrowdsale.sol";
import "../../token/ERC20/ERC20.sol"; import "../../token/ERC20/ERC20.sol";
@ -30,7 +30,12 @@ contract PostDeliveryCrowdsale is TimedCrowdsale {
* @param _beneficiary Token purchaser * @param _beneficiary Token purchaser
* @param _tokenAmount Amount of tokens purchased * @param _tokenAmount Amount of tokens purchased
*/ */
function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal { function _processPurchase(
address _beneficiary,
uint256 _tokenAmount
)
internal
{
balances[_beneficiary] = balances[_beneficiary].add(_tokenAmount); balances[_beneficiary] = balances[_beneficiary].add(_tokenAmount);
} }

View File

@ -1,16 +1,15 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
import "./FinalizableCrowdsale.sol"; import "./FinalizableCrowdsale.sol";
import "./utils/RefundVault.sol"; import "../../payment/RefundEscrow.sol";
/** /**
* @title RefundableCrowdsale * @title RefundableCrowdsale
* @dev Extension of Crowdsale contract that adds a funding goal, and * @dev Extension of Crowdsale contract that adds a funding goal, and
* the possibility of users getting a refund if goal is not met. * the possibility of users getting a refund if goal is not met.
* Uses a RefundVault as the crowdsale's vault.
*/ */
contract RefundableCrowdsale is FinalizableCrowdsale { contract RefundableCrowdsale is FinalizableCrowdsale {
using SafeMath for uint256; using SafeMath for uint256;
@ -18,16 +17,16 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
// minimum amount of funds to be raised in weis // minimum amount of funds to be raised in weis
uint256 public goal; uint256 public goal;
// refund vault used to hold funds while crowdsale is running // refund escrow used to hold funds while crowdsale is running
RefundVault public vault; RefundEscrow private escrow;
/** /**
* @dev Constructor, creates RefundVault. * @dev Constructor, creates RefundEscrow.
* @param _goal Funding goal * @param _goal Funding goal
*/ */
function RefundableCrowdsale(uint256 _goal) public { constructor(uint256 _goal) public {
require(_goal > 0); require(_goal > 0);
vault = new RefundVault(wallet); escrow = new RefundEscrow(wallet);
goal = _goal; goal = _goal;
} }
@ -38,7 +37,7 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
require(isFinalized); require(isFinalized);
require(!goalReached()); require(!goalReached());
vault.refund(msg.sender); escrow.withdraw(msg.sender);
} }
/** /**
@ -50,23 +49,24 @@ contract RefundableCrowdsale is FinalizableCrowdsale {
} }
/** /**
* @dev vault finalization task, called when owner calls finalize() * @dev escrow finalization task, called when owner calls finalize()
*/ */
function finalization() internal { function finalization() internal {
if (goalReached()) { if (goalReached()) {
vault.close(); escrow.close();
escrow.beneficiaryWithdraw();
} else { } else {
vault.enableRefunds(); escrow.enableRefunds();
} }
super.finalization(); super.finalization();
} }
/** /**
* @dev Overrides Crowdsale fund forwarding, sending funds to vault. * @dev Overrides Crowdsale fund forwarding, sending funds to escrow.
*/ */
function _forwardFunds() internal { function _forwardFunds() internal {
vault.deposit.value(msg.value)(msg.sender); escrow.deposit.value(msg.value)(msg.sender);
} }
} }

View File

@ -1,66 +0,0 @@
pragma solidity ^0.4.21;
import "../../../math/SafeMath.sol";
import "../../../ownership/Ownable.sol";
/**
* @title RefundVault
* @dev This contract is used for storing funds while a crowdsale
* is in progress. Supports refunding the money if crowdsale fails,
* and forwarding it if crowdsale is successful.
*/
contract RefundVault is Ownable {
using SafeMath for uint256;
enum State { Active, Refunding, Closed }
mapping (address => uint256) public deposited;
address public wallet;
State public state;
event Closed();
event RefundsEnabled();
event Refunded(address indexed beneficiary, uint256 weiAmount);
/**
* @param _wallet Vault address
*/
function RefundVault(address _wallet) public {
require(_wallet != address(0));
wallet = _wallet;
state = State.Active;
}
/**
* @param investor Investor address
*/
function deposit(address investor) onlyOwner public payable {
require(state == State.Active);
deposited[investor] = deposited[investor].add(msg.value);
}
function close() onlyOwner public {
require(state == State.Active);
state = State.Closed;
emit Closed();
wallet.transfer(address(this).balance);
}
function enableRefunds() onlyOwner public {
require(state == State.Active);
state = State.Refunding;
emit RefundsEnabled();
}
/**
* @param investor Investor address
*/
function refund(address investor) public {
require(state == State.Refunding);
uint256 depositedValue = deposited[investor];
deposited[investor] = 0;
investor.transfer(depositedValue);
emit Refunded(investor, depositedValue);
}
}

View File

@ -1,16 +1,17 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../Crowdsale.sol"; import "../Crowdsale.sol";
import "../../token/ERC20/ERC20.sol"; import "../../token/ERC20/ERC20.sol";
import "../../token/ERC20/ERC20Basic.sol";
import "../../token/ERC20/SafeERC20.sol";
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
/** /**
* @title AllowanceCrowdsale * @title AllowanceCrowdsale
* @dev Extension of Crowdsale where tokens are held by a wallet, which approves an allowance to the crowdsale. * @dev Extension of Crowdsale where tokens are held by a wallet, which approves an allowance to the crowdsale.
*/ */
contract AllowanceCrowdsale is Crowdsale { contract AllowanceCrowdsale is Crowdsale {
using SafeMath for uint256; using SafeMath for uint256;
using SafeERC20 for ERC20;
address public tokenWallet; address public tokenWallet;
@ -18,7 +19,7 @@ contract AllowanceCrowdsale is Crowdsale {
* @dev Constructor, takes token wallet address. * @dev Constructor, takes token wallet address.
* @param _tokenWallet Address holding the tokens, which has approved allowance to the crowdsale * @param _tokenWallet Address holding the tokens, which has approved allowance to the crowdsale
*/ */
function AllowanceCrowdsale(address _tokenWallet) public { constructor(address _tokenWallet) public {
require(_tokenWallet != address(0)); require(_tokenWallet != address(0));
tokenWallet = _tokenWallet; tokenWallet = _tokenWallet;
} }
@ -36,7 +37,12 @@ contract AllowanceCrowdsale is Crowdsale {
* @param _beneficiary Token purchaser * @param _beneficiary Token purchaser
* @param _tokenAmount Amount of tokens purchased * @param _tokenAmount Amount of tokens purchased
*/ */
function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal { function _deliverTokens(
token.transferFrom(tokenWallet, _beneficiary, _tokenAmount); address _beneficiary,
uint256 _tokenAmount
)
internal
{
token.safeTransferFrom(tokenWallet, _beneficiary, _tokenAmount);
} }
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../Crowdsale.sol"; import "../Crowdsale.sol";
import "../../token/ERC20/MintableToken.sol"; import "../../token/ERC20/MintableToken.sol";
@ -16,7 +16,12 @@ contract MintedCrowdsale is Crowdsale {
* @param _beneficiary Token purchaser * @param _beneficiary Token purchaser
* @param _tokenAmount Number of tokens to be minted * @param _tokenAmount Number of tokens to be minted
*/ */
function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal { function _deliverTokens(
address _beneficiary,
uint256 _tokenAmount
)
internal
{
require(MintableToken(token).mint(_beneficiary, _tokenAmount)); require(MintableToken(token).mint(_beneficiary, _tokenAmount));
} }
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../validation/TimedCrowdsale.sol"; import "../validation/TimedCrowdsale.sol";
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
@ -21,7 +21,7 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale {
* @param _initialRate Number of tokens a buyer gets per wei at the start of the crowdsale * @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 * @param _finalRate Number of tokens a buyer gets per wei at the end of the crowdsale
*/ */
function IncreasingPriceCrowdsale(uint256 _initialRate, uint256 _finalRate) public { constructor(uint256 _initialRate, uint256 _finalRate) public {
require(_initialRate >= _finalRate); require(_initialRate >= _finalRate);
require(_finalRate > 0); require(_finalRate > 0);
initialRate = _initialRate; initialRate = _initialRate;
@ -46,7 +46,9 @@ contract IncreasingPriceCrowdsale is TimedCrowdsale {
* @param _weiAmount The value in wei to be converted into tokens * @param _weiAmount The value in wei to be converted into tokens
* @return The number of tokens _weiAmount wei will buy at present time * @return The number of tokens _weiAmount wei will buy at present time
*/ */
function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) { function _getTokenAmount(uint256 _weiAmount)
internal view returns (uint256)
{
uint256 currentRate = getCurrentRate(); uint256 currentRate = getCurrentRate();
return currentRate.mul(_weiAmount); return currentRate.mul(_weiAmount);
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
import "../Crowdsale.sol"; import "../Crowdsale.sol";
@ -17,7 +17,7 @@ contract CappedCrowdsale is Crowdsale {
* @dev Constructor, takes maximum amount of wei accepted in the crowdsale. * @dev Constructor, takes maximum amount of wei accepted in the crowdsale.
* @param _cap Max amount of wei to be contributed * @param _cap Max amount of wei to be contributed
*/ */
function CappedCrowdsale(uint256 _cap) public { constructor(uint256 _cap) public {
require(_cap > 0); require(_cap > 0);
cap = _cap; cap = _cap;
} }
@ -35,7 +35,12 @@ contract CappedCrowdsale is Crowdsale {
* @param _beneficiary Token purchaser * @param _beneficiary Token purchaser
* @param _weiAmount Amount of wei contributed * @param _weiAmount Amount of wei contributed
*/ */
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal { function _preValidatePurchase(
address _beneficiary,
uint256 _weiAmount
)
internal
{
super._preValidatePurchase(_beneficiary, _weiAmount); super._preValidatePurchase(_beneficiary, _weiAmount);
require(weiRaised.add(_weiAmount) <= cap); require(weiRaised.add(_weiAmount) <= cap);
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
import "../Crowdsale.sol"; import "../Crowdsale.sol";
@ -29,7 +29,13 @@ contract IndividuallyCappedCrowdsale is Crowdsale, Ownable {
* @param _beneficiaries List of addresses to be capped * @param _beneficiaries List of addresses to be capped
* @param _cap Wei limit for individual contribution * @param _cap Wei limit for individual contribution
*/ */
function setGroupCap(address[] _beneficiaries, uint256 _cap) external onlyOwner { function setGroupCap(
address[] _beneficiaries,
uint256 _cap
)
external
onlyOwner
{
for (uint256 i = 0; i < _beneficiaries.length; i++) { for (uint256 i = 0; i < _beneficiaries.length; i++) {
caps[_beneficiaries[i]] = _cap; caps[_beneficiaries[i]] = _cap;
} }
@ -49,7 +55,9 @@ contract IndividuallyCappedCrowdsale is Crowdsale, Ownable {
* @param _beneficiary Address of contributor * @param _beneficiary Address of contributor
* @return User contribution so far * @return User contribution so far
*/ */
function getUserContribution(address _beneficiary) public view returns (uint256) { function getUserContribution(address _beneficiary)
public view returns (uint256)
{
return contributions[_beneficiary]; return contributions[_beneficiary];
} }
@ -58,7 +66,12 @@ contract IndividuallyCappedCrowdsale is Crowdsale, Ownable {
* @param _beneficiary Token purchaser * @param _beneficiary Token purchaser
* @param _weiAmount Amount of wei contributed * @param _weiAmount Amount of wei contributed
*/ */
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal { function _preValidatePurchase(
address _beneficiary,
uint256 _weiAmount
)
internal
{
super._preValidatePurchase(_beneficiary, _weiAmount); super._preValidatePurchase(_beneficiary, _weiAmount);
require(contributions[_beneficiary].add(_weiAmount) <= caps[_beneficiary]); require(contributions[_beneficiary].add(_weiAmount) <= caps[_beneficiary]);
} }
@ -68,7 +81,12 @@ contract IndividuallyCappedCrowdsale is Crowdsale, Ownable {
* @param _beneficiary Token purchaser * @param _beneficiary Token purchaser
* @param _weiAmount Amount of wei contributed * @param _weiAmount Amount of wei contributed
*/ */
function _updatePurchasingState(address _beneficiary, uint256 _weiAmount) internal { function _updatePurchasingState(
address _beneficiary,
uint256 _weiAmount
)
internal
{
super._updatePurchasingState(_beneficiary, _weiAmount); super._updatePurchasingState(_beneficiary, _weiAmount);
contributions[_beneficiary] = contributions[_beneficiary].add(_weiAmount); contributions[_beneficiary] = contributions[_beneficiary].add(_weiAmount);
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../../math/SafeMath.sol"; import "../../math/SafeMath.sol";
import "../Crowdsale.sol"; import "../Crowdsale.sol";
@ -28,7 +28,7 @@ contract TimedCrowdsale is Crowdsale {
* @param _openingTime Crowdsale opening time * @param _openingTime Crowdsale opening time
* @param _closingTime Crowdsale closing time * @param _closingTime Crowdsale closing time
*/ */
function TimedCrowdsale(uint256 _openingTime, uint256 _closingTime) public { constructor(uint256 _openingTime, uint256 _closingTime) public {
// solium-disable-next-line security/no-block-members // solium-disable-next-line security/no-block-members
require(_openingTime >= block.timestamp); require(_openingTime >= block.timestamp);
require(_closingTime >= _openingTime); require(_closingTime >= _openingTime);
@ -51,7 +51,13 @@ contract TimedCrowdsale is Crowdsale {
* @param _beneficiary Token purchaser * @param _beneficiary Token purchaser
* @param _weiAmount Amount of wei contributed * @param _weiAmount Amount of wei contributed
*/ */
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal onlyWhileOpen { function _preValidatePurchase(
address _beneficiary,
uint256 _weiAmount
)
internal
onlyWhileOpen
{
super._preValidatePurchase(_beneficiary, _weiAmount); super._preValidatePurchase(_beneficiary, _weiAmount);
} }

View File

@ -1,57 +1,26 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../Crowdsale.sol"; import "../Crowdsale.sol";
import "../../ownership/Ownable.sol"; import "../../access/Whitelist.sol";
/** /**
* @title WhitelistedCrowdsale * @title WhitelistedCrowdsale
* @dev Crowdsale in which only whitelisted users can contribute. * @dev Crowdsale in which only whitelisted users can contribute.
*/ */
contract WhitelistedCrowdsale is Crowdsale, Ownable { contract WhitelistedCrowdsale is Whitelist, Crowdsale {
mapping(address => bool) public whitelist;
/**
* @dev Reverts if beneficiary is not whitelisted. Can be used when extending this contract.
*/
modifier isWhitelisted(address _beneficiary) {
require(whitelist[_beneficiary]);
_;
}
/**
* @dev Adds single address to whitelist.
* @param _beneficiary Address to be added to the whitelist
*/
function addToWhitelist(address _beneficiary) external onlyOwner {
whitelist[_beneficiary] = true;
}
/**
* @dev Adds list of addresses to whitelist. Not overloaded due to limitations with truffle testing.
* @param _beneficiaries Addresses to be added to the whitelist
*/
function addManyToWhitelist(address[] _beneficiaries) external onlyOwner {
for (uint256 i = 0; i < _beneficiaries.length; i++) {
whitelist[_beneficiaries[i]] = true;
}
}
/**
* @dev Removes single address from whitelist.
* @param _beneficiary Address to be removed to the whitelist
*/
function removeFromWhitelist(address _beneficiary) external onlyOwner {
whitelist[_beneficiary] = false;
}
/** /**
* @dev Extend parent behavior requiring beneficiary to be in whitelist. * @dev Extend parent behavior requiring beneficiary to be in whitelist.
* @param _beneficiary Token beneficiary * @param _beneficiary Token beneficiary
* @param _weiAmount Amount of wei contributed * @param _weiAmount Amount of wei contributed
*/ */
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal isWhitelisted(_beneficiary) { function _preValidatePurchase(
address _beneficiary,
uint256 _weiAmount
)
onlyIfWhitelisted(_beneficiary)
internal
{
super._preValidatePurchase(_beneficiary, _weiAmount); super._preValidatePurchase(_beneficiary, _weiAmount);
} }

View File

@ -1,13 +1,19 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./RBAC.sol"; import "../ownership/rbac/RBAC.sol";
/** /**
* @title RBACWithAdmin * @title RBACWithAdmin
* @author Matt Condon (@Shrugs) * @author Matt Condon (@Shrugs)
* @dev It's recommended that you define constants in the contract, * @dev It's recommended that you define constants in the contract,
* @dev like ROLE_ADMIN below, to avoid typos. * like ROLE_ADMIN below, to avoid typos.
* @notice RBACWithAdmin is probably too expansive and powerful for your
* application; an admin is actually able to change any address to any role
* which is a very large API surface. It's recommended that you follow a strategy
* of strictly defining the abilities of your roles
* and the API-surface of your contract.
* This is just an example for example's sake.
*/ */
contract RBACWithAdmin is RBAC { contract RBACWithAdmin is RBAC {
/** /**
@ -28,7 +34,7 @@ contract RBACWithAdmin is RBAC {
/** /**
* @dev constructor. Sets msg.sender as admin by default * @dev constructor. Sets msg.sender as admin by default
*/ */
function RBACWithAdmin() constructor()
public public
{ {
addRole(msg.sender, ROLE_ADMIN); addRole(msg.sender, ROLE_ADMIN);

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../crowdsale/validation/CappedCrowdsale.sol"; import "../crowdsale/validation/CappedCrowdsale.sol";
import "../crowdsale/distribution/RefundableCrowdsale.sol"; import "../crowdsale/distribution/RefundableCrowdsale.sol";
@ -13,7 +13,8 @@ import "../token/ERC20/MintableToken.sol";
*/ */
contract SampleCrowdsaleToken is MintableToken { contract SampleCrowdsaleToken is MintableToken {
string public constant name = "Sample Crowdsale Token"; // solium-disable-line uppercase // solium-disable-next-line uppercase
string public constant name = "Sample Crowdsale Token";
string public constant symbol = "SCT"; // solium-disable-line uppercase string public constant symbol = "SCT"; // solium-disable-line uppercase
uint8 public constant decimals = 18; // solium-disable-line uppercase uint8 public constant decimals = 18; // solium-disable-line uppercase
@ -31,9 +32,14 @@ contract SampleCrowdsaleToken is MintableToken {
* After adding multiple features it's good practice to run integration tests * After adding multiple features it's good practice to run integration tests
* to ensure that subcontracts works together as intended. * 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 { contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale, MintedCrowdsale {
function SampleCrowdsale( constructor(
uint256 _openingTime, uint256 _openingTime,
uint256 _closingTime, uint256 _closingTime,
uint256 _rate, uint256 _rate,

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../ownership/Heritable.sol"; import "../ownership/Heritable.sol";
@ -19,7 +19,7 @@ contract SimpleSavingsWallet is Heritable {
event Received(address indexed payer, uint256 amount, uint256 balance); event Received(address indexed payer, uint256 amount, uint256 balance);
function SimpleSavingsWallet(uint256 _heartbeatTimeout) Heritable(_heartbeatTimeout) public {} constructor(uint256 _heartbeatTimeout) Heritable(_heartbeatTimeout) public {}
/** /**
* @dev wallet can receive funds. * @dev wallet can receive funds.
@ -32,7 +32,7 @@ contract SimpleSavingsWallet is Heritable {
* @dev wallet can send funds * @dev wallet can send funds
*/ */
function sendTo(address payee, uint256 amount) public onlyOwner { function sendTo(address payee, uint256 amount) public onlyOwner {
require(payee != 0 && payee != address(this)); require(payee != address(0) && payee != address(this));
require(amount > 0); require(amount > 0);
payee.transfer(amount); payee.transfer(amount);
emit Sent(payee, amount, address(this).balance); emit Sent(payee, amount, address(this).balance);

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/StandardToken.sol"; import "../token/ERC20/StandardToken.sol";
@ -21,10 +21,10 @@ contract SimpleToken is StandardToken {
/** /**
* @dev Constructor that gives msg.sender all of existing tokens. * @dev Constructor that gives msg.sender all of existing tokens.
*/ */
function SimpleToken() public { constructor() public {
totalSupply_ = INITIAL_SUPPLY; totalSupply_ = INITIAL_SUPPLY;
balances[msg.sender] = INITIAL_SUPPLY; balances[msg.sender] = INITIAL_SUPPLY;
emit Transfer(0x0, msg.sender, INITIAL_SUPPLY); emit Transfer(address(0), msg.sender, INITIAL_SUPPLY);
} }
} }

View File

@ -0,0 +1,20 @@
pragma solidity ^0.4.24;
/**
* @title ERC165
* @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
*/
interface ERC165 {
/**
* @notice Query if a contract implements an interface
* @param _interfaceId The interface identifier, as specified in ERC-165
* @dev Interface identification is specified in ERC-165. This function
* uses less than 30,000 gas.
*/
function supportsInterface(bytes4 _interfaceId)
external
view
returns (bool);
}

View File

@ -0,0 +1,53 @@
pragma solidity ^0.4.24;
import "./ERC165.sol";
/**
* @title SupportsInterfaceWithLookup
* @author Matt Condon (@shrugs)
* @dev Implements ERC165 using a lookup table.
*/
contract SupportsInterfaceWithLookup is ERC165 {
bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7;
/**
* 0x01ffc9a7 ===
* bytes4(keccak256('supportsInterface(bytes4)'))
*/
/**
* @dev a mapping of interface id to whether or not it's supported
*/
mapping(bytes4 => bool) internal supportedInterfaces;
/**
* @dev A contract implementing SupportsInterfaceWithLookup
* implement ERC165 itself
*/
constructor()
public
{
_registerInterface(InterfaceId_ERC165);
}
/**
* @dev implement supportsInterface(bytes4) using a lookup table
*/
function supportsInterface(bytes4 _interfaceId)
external
view
returns (bool)
{
return supportedInterfaces[_interfaceId];
}
/**
* @dev private method for registering an interface
*/
function _registerInterface(bytes4 _interfaceId)
internal
{
require(_interfaceId != 0xffffffff);
supportedInterfaces[_interfaceId] = true;
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../ownership/Ownable.sol"; import "../ownership/Ownable.sol";
@ -10,7 +10,7 @@ import "../ownership/Ownable.sol";
*/ */
contract Destructible is Ownable { contract Destructible is Ownable {
function Destructible() public payable { } constructor() public payable { }
/** /**
* @dev Transfers the current balance to the owner and terminates the contract. * @dev Transfers the current balance to the owner and terminates the contract.

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../ownership/Ownable.sol"; import "../ownership/Ownable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../ownership/Ownable.sol"; import "../ownership/Ownable.sol";
import "../token/ERC20/ERC20Basic.sol"; import "../token/ERC20/ERC20Basic.sol";
@ -12,7 +12,7 @@ import "../token/ERC20/ERC20Basic.sol";
*/ */
contract TokenDestructible is Ownable { contract TokenDestructible is Ownable {
function TokenDestructible() public payable { } constructor() public payable { }
/** /**
* @notice Terminate contract and refund to owner * @notice Terminate contract and refund to owner

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
/** /**

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
/** /**
@ -11,9 +11,13 @@ library SafeMath {
* @dev Multiplies two numbers, throws on overflow. * @dev Multiplies two numbers, throws on overflow.
*/ */
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
// Gas optimization: this is cheaper than asserting '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) { if (a == 0) {
return 0; return 0;
} }
c = a * b; c = a * b;
assert(c / a == b); assert(c / a == b);
return c; return c;

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
import "../crowdsale/emission/AllowanceCrowdsale.sol"; import "../crowdsale/emission/AllowanceCrowdsale.sol";
@ -6,7 +6,7 @@ import "../crowdsale/emission/AllowanceCrowdsale.sol";
contract AllowanceCrowdsaleImpl is AllowanceCrowdsale { contract AllowanceCrowdsaleImpl is AllowanceCrowdsale {
function AllowanceCrowdsaleImpl ( constructor (
uint256 _rate, uint256 _rate,
address _wallet, address _wallet,
ERC20 _token, ERC20 _token,

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/BasicToken.sol"; import "../token/ERC20/BasicToken.sol";
@ -7,7 +7,7 @@ import "../token/ERC20/BasicToken.sol";
// mock class using BasicToken // mock class using BasicToken
contract BasicTokenMock is BasicToken { contract BasicTokenMock is BasicToken {
function BasicTokenMock(address initialAccount, uint256 initialBalance) public { constructor(address initialAccount, uint256 initialBalance) public {
balances[initialAccount] = initialBalance; balances[initialAccount] = initialBalance;
totalSupply_ = initialBalance; totalSupply_ = initialBalance;
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.18; pragma solidity ^0.4.24;
import "../access/SignatureBouncer.sol"; import "../access/SignatureBouncer.sol";
@ -19,4 +19,36 @@ contract SignatureBouncerMock is SignatureBouncer {
{ {
} }
function checkValidSignatureAndMethod(address _address, bytes _sig)
public
view
returns (bool)
{
return isValidSignatureAndMethod(_address, _sig);
}
function onlyWithValidSignatureAndMethod(bytes _sig)
onlyValidSignatureAndMethod(_sig)
public
view
{
}
function checkValidSignatureAndData(address _address, bytes _bytes, uint _val, bytes _sig)
public
view
returns (bool)
{
return isValidSignatureAndData(_address, _sig);
}
function onlyWithValidSignatureAndData(uint _val, bytes _sig)
onlyValidSignatureAndData(_sig)
public
view
{
}
} }

View File

@ -1,11 +1,11 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/BurnableToken.sol"; import "../token/ERC20/BurnableToken.sol";
contract BurnableTokenMock is BurnableToken { contract BurnableTokenMock is BurnableToken {
function BurnableTokenMock(address initialAccount, uint initialBalance) public { constructor(address initialAccount, uint initialBalance) public {
balances[initialAccount] = initialBalance; balances[initialAccount] = initialBalance;
totalSupply_ = initialBalance; totalSupply_ = initialBalance;
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
import "../crowdsale/validation/CappedCrowdsale.sol"; import "../crowdsale/validation/CappedCrowdsale.sol";
@ -6,7 +6,7 @@ import "../crowdsale/validation/CappedCrowdsale.sol";
contract CappedCrowdsaleImpl is CappedCrowdsale { contract CappedCrowdsaleImpl is CappedCrowdsale {
function CappedCrowdsaleImpl ( constructor (
uint256 _rate, uint256 _rate,
address _wallet, address _wallet,
ERC20 _token, ERC20 _token,

View File

@ -0,0 +1,18 @@
pragma solidity ^0.4.24;
import "../payment/ConditionalEscrow.sol";
// mock class using ConditionalEscrow
contract ConditionalEscrowMock is ConditionalEscrow {
mapping(address => bool) public allowed;
function setAllowed(address _payee, bool _allowed) public {
allowed[_payee] = _allowed;
}
function withdrawalAllowed(address _payee) public view returns (bool) {
return allowed[_payee];
}
}

View File

@ -1,25 +0,0 @@
pragma solidity ^0.4.21;
import "../../contracts/DayLimit.sol";
contract DayLimitMock is DayLimit {
uint256 public totalSpending;
function DayLimitMock(uint256 _value) public DayLimit(_value) {
totalSpending = 0;
}
function attemptSpend(uint256 _value) external limitedDaily(_value) {
totalSpending += _value;
}
function setDailyLimit(uint256 _newLimit) external {
_setDailyLimit(_newLimit);
}
function resetSpentToday() external {
_resetSpentToday();
}
}

View File

@ -1,9 +1,16 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/StandardToken.sol"; import "../token/ERC20/StandardToken.sol";
import "../token/ERC20/DetailedERC20.sol"; import "../token/ERC20/DetailedERC20.sol";
contract DetailedERC20Mock is StandardToken, DetailedERC20 { contract DetailedERC20Mock is StandardToken, DetailedERC20 {
function DetailedERC20Mock(string _name, string _symbol, uint8 _decimals) DetailedERC20(_name, _symbol, _decimals) public {} constructor(
string _name,
string _symbol,
uint8 _decimals
)
DetailedERC20(_name, _symbol, _decimals)
public
{}
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../ECRecovery.sol"; import "../ECRecovery.sol";

View File

@ -0,0 +1,13 @@
pragma solidity ^0.4.21;
import "../token/ERC20/StandardToken.sol";
import "../proposals/ERC1046/TokenMetadata.sol";
contract ERC20WithMetadataMock is StandardToken, ERC20WithMetadata {
function ERC20WithMetadataMock(string _tokenURI)
ERC20WithMetadata(_tokenURI)
public
{
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/BasicToken.sol"; import "../token/ERC20/BasicToken.sol";
@ -10,7 +10,7 @@ contract ERC223ContractInterface {
contract ERC223TokenMock is BasicToken { contract ERC223TokenMock is BasicToken {
function ERC223TokenMock(address initialAccount, uint256 initialBalance) public { constructor(address initialAccount, uint256 initialBalance) public {
balances[initialAccount] = initialBalance; balances[initialAccount] = initialBalance;
totalSupply_ = initialBalance; totalSupply_ = initialBalance;
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC721/ERC721BasicToken.sol"; import "../token/ERC721/ERC721BasicToken.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC721/ERC721Receiver.sol"; import "../token/ERC721/ERC721Receiver.sol";
@ -7,15 +7,22 @@ contract ERC721ReceiverMock is ERC721Receiver {
bytes4 retval; bytes4 retval;
bool reverts; bool reverts;
event Received(address _address, uint256 _tokenId, bytes _data, uint256 _gas); event Received(
address _operator,
address _from,
uint256 _tokenId,
bytes _data,
uint256 _gas
);
function ERC721ReceiverMock(bytes4 _retval, bool _reverts) public { constructor(bytes4 _retval, bool _reverts) public {
retval = _retval; retval = _retval;
reverts = _reverts; reverts = _reverts;
} }
function onERC721Received( function onERC721Received(
address _address, address _operator,
address _from,
uint256 _tokenId, uint256 _tokenId,
bytes _data bytes _data
) )
@ -24,7 +31,8 @@ contract ERC721ReceiverMock is ERC721Receiver {
{ {
require(!reverts); require(!reverts);
emit Received( emit Received(
_address, _operator,
_from,
_tokenId, _tokenId,
_data, _data,
gasleft() // msg.gas was deprecated in solidityv0.4.21 gasleft() // msg.gas was deprecated in solidityv0.4.21

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC721/ERC721Token.sol"; import "../token/ERC721/ERC721Token.sol";
@ -9,7 +9,7 @@ import "../token/ERC721/ERC721Token.sol";
* and a public setter for metadata URI * and a public setter for metadata URI
*/ */
contract ERC721TokenMock is ERC721Token { contract ERC721TokenMock is ERC721Token {
function ERC721TokenMock(string name, string symbol) public constructor(string name, string symbol) public
ERC721Token(name, symbol) ERC721Token(name, symbol)
{ } { }

View File

@ -1,15 +0,0 @@
pragma solidity ^0.4.21;
import "../token/ERC827/ERC827Token.sol";
// mock class using ERC827 Token
contract ERC827TokenMock is ERC827Token {
function ERC827TokenMock(address initialAccount, uint256 initialBalance) public {
balances[initialAccount] = initialBalance;
totalSupply_ = initialBalance;
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/MintableToken.sol"; import "../token/ERC20/MintableToken.sol";
import "../crowdsale/distribution/FinalizableCrowdsale.sol"; import "../crowdsale/distribution/FinalizableCrowdsale.sol";
@ -6,7 +6,7 @@ import "../crowdsale/distribution/FinalizableCrowdsale.sol";
contract FinalizableCrowdsaleImpl is FinalizableCrowdsale { contract FinalizableCrowdsaleImpl is FinalizableCrowdsale {
function FinalizableCrowdsaleImpl ( constructor (
uint256 _openingTime, uint256 _openingTime,
uint256 _closingTime, uint256 _closingTime,
uint256 _rate, uint256 _rate,

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
// @title Force Ether into a contract. // @title Force Ether into a contract.
@ -8,7 +8,7 @@ pragma solidity ^0.4.21;
// @author Remco Bloemen <remco@neufund.org> // @author Remco Bloemen <remco@neufund.org>
contract ForceEther { contract ForceEther {
function ForceEther() public payable { } constructor() public payable { }
function destroyAndSend(address _recipient) public { function destroyAndSend(address _recipient) public {
selfdestruct(_recipient); selfdestruct(_recipient);

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../../contracts/ownership/HasNoEther.sol"; import "../../contracts/ownership/HasNoEther.sol";
@ -6,7 +6,7 @@ import "../../contracts/ownership/HasNoEther.sol";
contract HasNoEtherTest is HasNoEther { contract HasNoEtherTest is HasNoEther {
// Constructor with explicit payable — should still fail // Constructor with explicit payable — should still fail
function HasNoEtherTest() public payable { constructor() public payable {
} }
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../crowdsale/price/IncreasingPriceCrowdsale.sol"; import "../crowdsale/price/IncreasingPriceCrowdsale.sol";
import "../math/SafeMath.sol"; import "../math/SafeMath.sol";
@ -6,7 +6,7 @@ import "../math/SafeMath.sol";
contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale { contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale {
function IncreasingPriceCrowdsaleImpl ( constructor (
uint256 _openingTime, uint256 _openingTime,
uint256 _closingTime, uint256 _closingTime,
address _wallet, address _wallet,

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol"; import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol";
@ -6,7 +6,7 @@ import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol";
contract IndividuallyCappedCrowdsaleImpl is IndividuallyCappedCrowdsale { contract IndividuallyCappedCrowdsaleImpl is IndividuallyCappedCrowdsale {
function IndividuallyCappedCrowdsaleImpl ( constructor (
uint256 _rate, uint256 _rate,
address _wallet, address _wallet,
ERC20 _token ERC20 _token

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import {Bounty, Target} from "../../contracts/Bounty.sol"; import {Bounty, Target} from "../../contracts/Bounty.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../LimitBalance.sol"; import "../LimitBalance.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../../contracts/math/Math.sol"; import "../../contracts/math/Math.sol";

View File

@ -1,11 +1,19 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import { MerkleProof } from "../MerkleProof.sol"; import { MerkleProof } from "../MerkleProof.sol";
contract MerkleProofWrapper { contract MerkleProofWrapper {
function verifyProof(bytes32[] _proof, bytes32 _root, bytes32 _leaf) public pure returns (bool) { function verifyProof(
bytes32[] _proof,
bytes32 _root,
bytes32 _leaf
)
public
pure
returns (bool)
{
return MerkleProof.verifyProof(_proof, _root, _leaf); return MerkleProof.verifyProof(_proof, _root, _leaf);
} }
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
contract MessageHelper { contract MessageHelper {
@ -6,12 +6,27 @@ contract MessageHelper {
event Show(bytes32 b32, uint256 number, string text); event Show(bytes32 b32, uint256 number, string text);
event Buy(bytes32 b32, uint256 number, string text, uint256 value); event Buy(bytes32 b32, uint256 number, string text, uint256 value);
function showMessage( bytes32 message, uint256 number, string text ) public returns (bool) { function showMessage(
bytes32 message,
uint256 number,
string text
)
public
returns (bool)
{
emit Show(message, number, text); emit Show(message, number, text);
return true; return true;
} }
function buyMessage( bytes32 message, uint256 number, string text ) public payable returns (bool) { function buyMessage(
bytes32 message,
uint256 number,
string text
)
public
payable
returns (bool)
{
emit Buy( emit Buy(
message, message,
number, number,

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/MintableToken.sol"; import "../token/ERC20/MintableToken.sol";
import "../crowdsale/emission/MintedCrowdsale.sol"; import "../crowdsale/emission/MintedCrowdsale.sol";
@ -6,7 +6,7 @@ import "../crowdsale/emission/MintedCrowdsale.sol";
contract MintedCrowdsaleImpl is MintedCrowdsale { contract MintedCrowdsaleImpl is MintedCrowdsale {
function MintedCrowdsaleImpl ( constructor (
uint256 _rate, uint256 _rate,
address _wallet, address _wallet,
MintableToken _token MintableToken _token

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../lifecycle/Pausable.sol"; import "../lifecycle/Pausable.sol";
@ -9,7 +9,7 @@ contract PausableMock is Pausable {
bool public drasticMeasureTaken; bool public drasticMeasureTaken;
uint256 public count; uint256 public count;
function PausableMock() public { constructor() public {
drasticMeasureTaken = false; drasticMeasureTaken = false;
count = 0; count = 0;
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/PausableToken.sol"; import "../token/ERC20/PausableToken.sol";
@ -6,7 +6,7 @@ import "../token/ERC20/PausableToken.sol";
// mock class using PausableToken // mock class using PausableToken
contract PausableTokenMock is PausableToken { contract PausableTokenMock is PausableToken {
function PausableTokenMock(address initialAccount, uint initialBalance) public { constructor(address initialAccount, uint initialBalance) public {
balances[initialAccount] = initialBalance; balances[initialAccount] = initialBalance;
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
import "../crowdsale/distribution/PostDeliveryCrowdsale.sol"; import "../crowdsale/distribution/PostDeliveryCrowdsale.sol";
@ -6,7 +6,7 @@ import "../crowdsale/distribution/PostDeliveryCrowdsale.sol";
contract PostDeliveryCrowdsaleImpl is PostDeliveryCrowdsale { contract PostDeliveryCrowdsaleImpl is PostDeliveryCrowdsale {
function PostDeliveryCrowdsaleImpl ( constructor (
uint256 _openingTime, uint256 _openingTime,
uint256 _closingTime, uint256 _closingTime,
uint256 _rate, uint256 _rate,

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../payment/PullPayment.sol"; import "../payment/PullPayment.sol";
@ -7,11 +7,11 @@ import "../payment/PullPayment.sol";
// mock class using PullPayment // mock class using PullPayment
contract PullPaymentMock is PullPayment { contract PullPaymentMock is PullPayment {
function PullPaymentMock() public payable { } constructor() public payable { }
// test helper function to call asyncSend // test helper function to call asyncTransfer
function callSend(address dest, uint256 amount) public { function callTransfer(address dest, uint256 amount) public {
asyncSend(dest, amount); asyncTransfer(dest, amount);
} }
} }

View File

@ -0,0 +1,13 @@
pragma solidity ^0.4.24;
import "../token/ERC20/RBACMintableToken.sol";
import "../token/ERC20/CappedToken.sol";
contract RBACCappedTokenMock is CappedToken, RBACMintableToken {
constructor(
uint256 _cap
)
CappedToken(_cap)
public
{}
}

View File

@ -1,6 +1,6 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../ownership/rbac/RBACWithAdmin.sol"; import "../examples/RBACWithAdmin.sol";
contract RBACMock is RBACWithAdmin { contract RBACMock is RBACWithAdmin {
@ -16,7 +16,7 @@ contract RBACMock is RBACWithAdmin {
_; _;
} }
function RBACMock(address[] _advisors) constructor(address[] _advisors)
public public
{ {
addRole(msg.sender, ROLE_ADVISOR); addRole(msg.sender, ROLE_ADVISOR);

View File

@ -1,11 +1,11 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
contract ReentrancyAttack { contract ReentrancyAttack {
function callSender(bytes4 data) public { function callSender(bytes4 data) public {
// solium-disable-next-line security/no-low-level-calls // solium-disable-next-line security/no-low-level-calls
require(msg.sender.call(data)); require(msg.sender.call(abi.encodeWithSelector(data)));
} }
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../ReentrancyGuard.sol"; import "../ReentrancyGuard.sol";
import "./ReentrancyAttack.sol"; import "./ReentrancyAttack.sol";
@ -8,7 +8,7 @@ contract ReentrancyMock is ReentrancyGuard {
uint256 public counter; uint256 public counter;
function ReentrancyMock() public { constructor() public {
counter = 0; counter = 0;
} }
@ -24,11 +24,10 @@ contract ReentrancyMock is ReentrancyGuard {
} }
function countThisRecursive(uint256 n) public nonReentrant { function countThisRecursive(uint256 n) public nonReentrant {
bytes4 func = bytes4(keccak256("countThisRecursive(uint256)"));
if (n > 0) { if (n > 0) {
count(); count();
// solium-disable-next-line security/no-low-level-calls // solium-disable-next-line security/no-low-level-calls
bool result = address(this).call(func, n - 1); bool result = address(this).call(abi.encodeWithSignature("countThisRecursive(uint256)", n - 1));
require(result == true); require(result == true);
} }
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/MintableToken.sol"; import "../token/ERC20/MintableToken.sol";
import "../crowdsale/distribution/RefundableCrowdsale.sol"; import "../crowdsale/distribution/RefundableCrowdsale.sol";
@ -6,7 +6,7 @@ import "../crowdsale/distribution/RefundableCrowdsale.sol";
contract RefundableCrowdsaleImpl is RefundableCrowdsale { contract RefundableCrowdsaleImpl is RefundableCrowdsale {
function RefundableCrowdsaleImpl ( constructor (
uint256 _openingTime, uint256 _openingTime,
uint256 _closingTime, uint256 _closingTime,
uint256 _rate, uint256 _rate,

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
import "../token/ERC20/SafeERC20.sol"; import "../token/ERC20/SafeERC20.sol";
@ -21,11 +21,11 @@ contract ERC20FailingMock is ERC20 {
return false; return false;
} }
function balanceOf(address) public constant returns (uint256) { function balanceOf(address) public view returns (uint256) {
return 0; return 0;
} }
function allowance(address, address) public constant returns (uint256) { function allowance(address, address) public view returns (uint256) {
return 0; return 0;
} }
} }
@ -48,11 +48,11 @@ contract ERC20SucceedingMock is ERC20 {
return true; return true;
} }
function balanceOf(address) public constant returns (uint256) { function balanceOf(address) public view returns (uint256) {
return 0; return 0;
} }
function allowance(address, address) public constant returns (uint256) { function allowance(address, address) public view returns (uint256) {
return 0; return 0;
} }
} }
@ -64,32 +64,32 @@ contract SafeERC20Helper {
ERC20 failing; ERC20 failing;
ERC20 succeeding; ERC20 succeeding;
function SafeERC20Helper() public { constructor() public {
failing = new ERC20FailingMock(); failing = new ERC20FailingMock();
succeeding = new ERC20SucceedingMock(); succeeding = new ERC20SucceedingMock();
} }
function doFailingTransfer() public { function doFailingTransfer() public {
failing.safeTransfer(0, 0); failing.safeTransfer(address(0), 0);
} }
function doFailingTransferFrom() public { function doFailingTransferFrom() public {
failing.safeTransferFrom(0, 0, 0); failing.safeTransferFrom(address(0), address(0), 0);
} }
function doFailingApprove() public { function doFailingApprove() public {
failing.safeApprove(0, 0); failing.safeApprove(address(0), 0);
} }
function doSucceedingTransfer() public { function doSucceedingTransfer() public {
succeeding.safeTransfer(0, 0); succeeding.safeTransfer(address(0), 0);
} }
function doSucceedingTransferFrom() public { function doSucceedingTransferFrom() public {
succeeding.safeTransferFrom(0, 0, 0); succeeding.safeTransferFrom(address(0), address(0), 0);
} }
function doSucceedingApprove() public { function doSucceedingApprove() public {
succeeding.safeApprove(0, 0); succeeding.safeApprove(address(0), 0);
} }
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../math/SafeMath.sol"; import "../math/SafeMath.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import {Bounty, Target} from "../../contracts/Bounty.sol"; import {Bounty, Target} from "../../contracts/Bounty.sol";

View File

@ -1,11 +1,11 @@
pragma solidity ^0.4.18; pragma solidity ^0.4.24;
import "../token/ERC20/StandardBurnableToken.sol"; import "../token/ERC20/StandardBurnableToken.sol";
contract StandardBurnableTokenMock is StandardBurnableToken { contract StandardBurnableTokenMock is StandardBurnableToken {
function StandardBurnableTokenMock(address initialAccount, uint initialBalance) public { constructor(address initialAccount, uint initialBalance) public {
balances[initialAccount] = initialBalance; balances[initialAccount] = initialBalance;
totalSupply_ = initialBalance; totalSupply_ = initialBalance;
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/StandardToken.sol"; import "../token/ERC20/StandardToken.sol";
@ -6,7 +6,7 @@ import "../token/ERC20/StandardToken.sol";
// mock class using StandardToken // mock class using StandardToken
contract StandardTokenMock is StandardToken { contract StandardTokenMock is StandardToken {
function StandardTokenMock(address initialAccount, uint256 initialBalance) public { constructor(address initialAccount, uint256 initialBalance) public {
balances[initialAccount] = initialBalance; balances[initialAccount] = initialBalance;
totalSupply_ = initialBalance; totalSupply_ = initialBalance;
} }

View File

@ -0,0 +1,12 @@
pragma solidity ^0.4.24;
import "../introspection/SupportsInterfaceWithLookup.sol";
contract SupportsInterfaceWithLookupMock is SupportsInterfaceWithLookup {
function registerInterface(bytes4 _interfaceId)
public
{
_registerInterface(_interfaceId);
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
import "../crowdsale/validation/TimedCrowdsale.sol"; import "../crowdsale/validation/TimedCrowdsale.sol";
@ -6,7 +6,7 @@ import "../crowdsale/validation/TimedCrowdsale.sol";
contract TimedCrowdsaleImpl is TimedCrowdsale { contract TimedCrowdsaleImpl is TimedCrowdsale {
function TimedCrowdsaleImpl ( constructor (
uint256 _openingTime, uint256 _openingTime,
uint256 _closingTime, uint256 _closingTime,
uint256 _rate, uint256 _rate,

View File

@ -1,12 +1,11 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../ownership/Whitelist.sol";
import "../access/Whitelist.sol";
contract WhitelistMock is Whitelist { contract WhitelistMock is Whitelist {
function onlyWhitelistedCanDoThis() function onlyWhitelistedCanDoThis()
onlyWhitelisted onlyIfWhitelisted(msg.sender)
view view
external external
{ {

View File

@ -1,19 +1,19 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../token/ERC20/ERC20.sol"; import "../token/ERC20/ERC20.sol";
import "../crowdsale/validation/WhitelistedCrowdsale.sol"; import "../crowdsale/validation/WhitelistedCrowdsale.sol";
import "../crowdsale/Crowdsale.sol";
contract WhitelistedCrowdsaleImpl is WhitelistedCrowdsale { contract WhitelistedCrowdsaleImpl is Crowdsale, WhitelistedCrowdsale {
function WhitelistedCrowdsaleImpl ( constructor (
uint256 _rate, uint256 _rate,
address _wallet, address _wallet,
ERC20 _token ERC20 _token
) )
public
Crowdsale(_rate, _wallet, _token) Crowdsale(_rate, _wallet, _token)
public
{ {
} }
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./Ownable.sol"; import "./Ownable.sol";
import "../token/ERC20/ERC20Basic.sol"; import "../token/ERC20/ERC20Basic.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./Ownable.sol"; import "./Ownable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./Ownable.sol"; import "./Ownable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./Claimable.sol"; import "./Claimable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./Ownable.sol"; import "./Ownable.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./Ownable.sol"; import "./Ownable.sol";
@ -17,12 +17,12 @@ contract HasNoEther is Ownable {
/** /**
* @dev Constructor that rejects incoming Ether * @dev Constructor that rejects incoming Ether
* @dev The `payable` flag is added so we can access `msg.value` without compiler warning. If we * The `payable` flag is added so we can access `msg.value` without compiler warning. If we
* leave out payable, then Solidity will allow inheriting contracts to implement a payable * leave out payable, then Solidity will allow inheriting contracts to implement a payable
* constructor. By doing it this way we prevent a payable constructor from working. Alternatively * constructor. By doing it this way we prevent a payable constructor from working. Alternatively
* we could use assembly to access msg.value. * we could use assembly to access msg.value.
*/ */
function HasNoEther() public payable { constructor() public payable {
require(msg.value == 0); require(msg.value == 0);
} }
@ -36,7 +36,6 @@ contract HasNoEther is Ownable {
* @dev Transfer all Ether held by the contract to the owner. * @dev Transfer all Ether held by the contract to the owner.
*/ */
function reclaimEther() external onlyOwner { function reclaimEther() external onlyOwner {
// solium-disable-next-line security/no-send owner.transfer(address(this).balance);
assert(owner.send(address(this).balance));
} }
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./CanReclaimToken.sol"; import "./CanReclaimToken.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./Ownable.sol"; import "./Ownable.sol";
@ -21,8 +21,15 @@ contract Heritable is Ownable {
event HeirChanged(address indexed owner, address indexed newHeir); event HeirChanged(address indexed owner, address indexed newHeir);
event OwnerHeartbeated(address indexed owner); event OwnerHeartbeated(address indexed owner);
event OwnerProclaimedDead(address indexed owner, address indexed heir, uint256 timeOfDeath); event OwnerProclaimedDead(
event HeirOwnershipClaimed(address indexed previousOwner, address indexed newOwner); address indexed owner,
address indexed heir,
uint256 timeOfDeath
);
event HeirOwnershipClaimed(
address indexed previousOwner,
address indexed newOwner
);
/** /**
@ -39,7 +46,7 @@ contract Heritable is Ownable {
* @param _heartbeatTimeout time available for the owner to notify they are alive, * @param _heartbeatTimeout time available for the owner to notify they are alive,
* before the heir can take ownership. * before the heir can take ownership.
*/ */
function Heritable(uint256 _heartbeatTimeout) public { constructor(uint256 _heartbeatTimeout) public {
setHeartbeatTimeout(_heartbeatTimeout); setHeartbeatTimeout(_heartbeatTimeout);
} }
@ -71,7 +78,7 @@ contract Heritable is Ownable {
*/ */
function removeHeir() public onlyOwner { function removeHeir() public onlyOwner {
heartbeat(); heartbeat();
heir_ = 0; heir_ = address(0);
} }
/** /**
@ -106,7 +113,9 @@ contract Heritable is Ownable {
timeOfDeath_ = 0; timeOfDeath_ = 0;
} }
function setHeartbeatTimeout(uint256 newHeartbeatTimeout) internal onlyOwner { function setHeartbeatTimeout(uint256 newHeartbeatTimeout)
internal onlyOwner
{
require(ownerLives()); require(ownerLives());
heartbeatTimeout_ = newHeartbeatTimeout; heartbeatTimeout_ = newHeartbeatTimeout;
} }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./HasNoEther.sol"; import "./HasNoEther.sol";
import "./HasNoTokens.sol"; import "./HasNoTokens.sol";

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
/** /**
@ -10,14 +10,18 @@ contract Ownable {
address public owner; address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 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 * @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account. * account.
*/ */
function Ownable() public { constructor() public {
owner = msg.sender; owner = msg.sender;
} }
@ -30,13 +34,31 @@ contract Ownable {
} }
/** /**
* @dev Allows the current owner to transfer control of the contract to a newOwner. * @dev Allows the current owner to relinquish control of the contract.
* @param newOwner The address to transfer ownership to. * @notice Renouncing to ownership will leave the contract without an owner.
* It will not be possible to call the functions with the `onlyOwner`
* modifier anymore.
*/ */
function transferOwnership(address newOwner) public onlyOwner { function renounceOwnership() public onlyOwner {
require(newOwner != address(0)); emit OwnershipRenounced(owner);
emit OwnershipTransferred(owner, newOwner); owner = address(0);
owner = newOwner;
} }
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function transferOwnership(address _newOwner) public onlyOwner {
_transferOwnership(_newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function _transferOwnership(address _newOwner) internal {
require(_newOwner != address(0));
emit OwnershipTransferred(owner, _newOwner);
owner = _newOwner;
}
} }

View File

@ -0,0 +1,62 @@
pragma solidity ^0.4.24;
import "./Ownable.sol";
import "./rbac/RBAC.sol";
/**
* @title Superuser
* @dev The Superuser contract defines a single superuser who can transfer the ownership
* of a contract to a new address, even if he is not the owner.
* A superuser can transfer his role to a new address.
*/
contract Superuser is Ownable, RBAC {
string public constant ROLE_SUPERUSER = "superuser";
constructor () public {
addRole(msg.sender, ROLE_SUPERUSER);
}
/**
* @dev Throws if called by any account that's not a superuser.
*/
modifier onlySuperuser() {
checkRole(msg.sender, ROLE_SUPERUSER);
_;
}
modifier onlyOwnerOrSuperuser() {
require(msg.sender == owner || isSuperuser(msg.sender));
_;
}
/**
* @dev getter to determine if address has superuser role
*/
function isSuperuser(address _addr)
public
view
returns (bool)
{
return hasRole(_addr, ROLE_SUPERUSER);
}
/**
* @dev Allows the current superuser to transfer his role to a newSuperuser.
* @param _newSuperuser The address to transfer ownership to.
*/
function transferSuperuser(address _newSuperuser) public onlySuperuser {
require(_newSuperuser != address(0));
removeRole(msg.sender, ROLE_SUPERUSER);
addRole(_newSuperuser, ROLE_SUPERUSER);
}
/**
* @dev Allows the current superuser or owner to transfer control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function transferOwnership(address _newOwner) public onlyOwnerOrSuperuser {
_transferOwnership(_newOwner);
}
}

View File

@ -1,81 +0,0 @@
pragma solidity ^0.4.21;
import "./Ownable.sol";
/**
* @title Whitelist
* @dev The Whitelist contract has a whitelist of addresses, and provides basic authorization control functions.
* @dev This simplifies the implementation of "user permissions".
*/
contract Whitelist is Ownable {
mapping(address => bool) public whitelist;
event WhitelistedAddressAdded(address addr);
event WhitelistedAddressRemoved(address addr);
/**
* @dev Throws if called by any account that's not whitelisted.
*/
modifier onlyWhitelisted() {
require(whitelist[msg.sender]);
_;
}
/**
* @dev add an address to the whitelist
* @param addr address
* @return true if the address was added to the whitelist, false if the address was already in the whitelist
*/
function addAddressToWhitelist(address addr) onlyOwner public returns(bool success) {
if (!whitelist[addr]) {
whitelist[addr] = true;
emit WhitelistedAddressAdded(addr);
success = true;
}
}
/**
* @dev add addresses to the whitelist
* @param addrs addresses
* @return true if at least one address was added to the whitelist,
* false if all addresses were already in the whitelist
*/
function addAddressesToWhitelist(address[] addrs) onlyOwner public returns(bool success) {
for (uint256 i = 0; i < addrs.length; i++) {
if (addAddressToWhitelist(addrs[i])) {
success = true;
}
}
}
/**
* @dev remove an address from the whitelist
* @param addr address
* @return true if the address was removed from the whitelist,
* false if the address wasn't in the whitelist in the first place
*/
function removeAddressFromWhitelist(address addr) onlyOwner public returns(bool success) {
if (whitelist[addr]) {
whitelist[addr] = false;
emit WhitelistedAddressRemoved(addr);
success = true;
}
}
/**
* @dev remove addresses from the whitelist
* @param addrs addresses
* @return true if at least one address was removed from the whitelist,
* false if all addresses weren't in the whitelist in the first place
*/
function removeAddressesFromWhitelist(address[] addrs) onlyOwner public returns(bool success) {
for (uint256 i = 0; i < addrs.length; i++) {
if (removeAddressFromWhitelist(addrs[i])) {
success = true;
}
}
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./Roles.sol"; import "./Roles.sol";
@ -7,8 +7,8 @@ import "./Roles.sol";
* @title RBAC (Role-Based Access Control) * @title RBAC (Role-Based Access Control)
* @author Matt Condon (@Shrugs) * @author Matt Condon (@Shrugs)
* @dev Stores and provides setters and getters for roles and addresses. * @dev Stores and provides setters and getters for roles and addresses.
* @dev Supports unlimited numbers of roles and addresses. * Supports unlimited numbers of roles and addresses.
* @dev See //contracts/mocks/RBACMock.sol for an example of usage. * See //contracts/mocks/RBACMock.sol for an example of usage.
* This RBAC method uses strings to key roles. It may be beneficial * This RBAC method uses strings to key roles. It may be beneficial
* for you to write your own implementation of this interface using Enums or similar. * for you to write your own implementation of this interface using Enums or similar.
* It's also recommended that you define constants in the contract, like ROLE_ADMIN below, * It's also recommended that you define constants in the contract, like ROLE_ADMIN below,
@ -19,83 +19,83 @@ contract RBAC {
mapping (string => Roles.Role) private roles; mapping (string => Roles.Role) private roles;
event RoleAdded(address addr, string roleName); event RoleAdded(address indexed operator, string role);
event RoleRemoved(address addr, string roleName); event RoleRemoved(address indexed operator, string role);
/** /**
* @dev reverts if addr does not have role * @dev reverts if addr does not have role
* @param addr address * @param _operator address
* @param roleName the name of the role * @param _role the name of the role
* // reverts * // reverts
*/ */
function checkRole(address addr, string roleName) function checkRole(address _operator, string _role)
view view
public public
{ {
roles[roleName].check(addr); roles[_role].check(_operator);
} }
/** /**
* @dev determine if addr has role * @dev determine if addr has role
* @param addr address * @param _operator address
* @param roleName the name of the role * @param _role the name of the role
* @return bool * @return bool
*/ */
function hasRole(address addr, string roleName) function hasRole(address _operator, string _role)
view view
public public
returns (bool) returns (bool)
{ {
return roles[roleName].has(addr); return roles[_role].has(_operator);
} }
/** /**
* @dev add a role to an address * @dev add a role to an address
* @param addr address * @param _operator address
* @param roleName the name of the role * @param _role the name of the role
*/ */
function addRole(address addr, string roleName) function addRole(address _operator, string _role)
internal internal
{ {
roles[roleName].add(addr); roles[_role].add(_operator);
emit RoleAdded(addr, roleName); emit RoleAdded(_operator, _role);
} }
/** /**
* @dev remove a role from an address * @dev remove a role from an address
* @param addr address * @param _operator address
* @param roleName the name of the role * @param _role the name of the role
*/ */
function removeRole(address addr, string roleName) function removeRole(address _operator, string _role)
internal internal
{ {
roles[roleName].remove(addr); roles[_role].remove(_operator);
emit RoleRemoved(addr, roleName); emit RoleRemoved(_operator, _role);
} }
/** /**
* @dev modifier to scope access to a single role (uses msg.sender as addr) * @dev modifier to scope access to a single role (uses msg.sender as addr)
* @param roleName the name of the role * @param _role the name of the role
* // reverts * // reverts
*/ */
modifier onlyRole(string roleName) modifier onlyRole(string _role)
{ {
checkRole(msg.sender, roleName); checkRole(msg.sender, _role);
_; _;
} }
/** /**
* @dev modifier to scope access to a set of roles (uses msg.sender as addr) * @dev modifier to scope access to a set of roles (uses msg.sender as addr)
* @param roleNames the names of the roles to scope access to * @param _roles the names of the roles to scope access to
* // reverts * // reverts
* *
* @TODO - when solidity supports dynamic arrays as arguments to modifiers, provide this * @TODO - when solidity supports dynamic arrays as arguments to modifiers, provide this
* see: https://github.com/ethereum/solidity/issues/2467 * see: https://github.com/ethereum/solidity/issues/2467
*/ */
// modifier onlyRoles(string[] roleNames) { // modifier onlyRoles(string[] _roles) {
// bool hasAnyRole = false; // bool hasAnyRole = false;
// for (uint8 i = 0; i < roleNames.length; i++) { // for (uint8 i = 0; i < _roles.length; i++) {
// if (hasRole(msg.sender, roleNames[i])) { // if (hasRole(msg.sender, _roles[i])) {
// hasAnyRole = true; // hasAnyRole = true;
// break; // break;
// } // }

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
/** /**

View File

@ -0,0 +1,22 @@
pragma solidity ^0.4.23;
import "./Escrow.sol";
/**
* @title ConditionalEscrow
* @dev Base abstract escrow to only allow withdrawal if a condition is met.
*/
contract ConditionalEscrow is Escrow {
/**
* @dev Returns whether an address is allowed to withdraw their funds. To be
* implemented by derived contracts.
* @param _payee The destination address of the funds.
*/
function withdrawalAllowed(address _payee) public view returns (bool);
function withdraw(address _payee) public {
require(withdrawalAllowed(_payee));
super.withdraw(_payee);
}
}

View File

@ -0,0 +1,51 @@
pragma solidity ^0.4.23;
import "../math/SafeMath.sol";
import "../ownership/Ownable.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 owner, and provide public methods redirecting to the escrow's
* deposit and withdraw.
*/
contract Escrow is Ownable {
using SafeMath for uint256;
event Deposited(address indexed payee, uint256 weiAmount);
event Withdrawn(address indexed payee, uint256 weiAmount);
mapping(address => uint256) private deposits;
function depositsOf(address _payee) public view returns (uint256) {
return deposits[_payee];
}
/**
* @dev Stores the sent amount as credit to be withdrawn.
* @param _payee The destination address of the funds.
*/
function deposit(address _payee) public onlyOwner payable {
uint256 amount = msg.value;
deposits[_payee] = deposits[_payee].add(amount);
emit Deposited(_payee, amount);
}
/**
* @dev Withdraw accumulated balance for a payee.
* @param _payee The address whose funds will be withdrawn and transferred to.
*/
function withdraw(address _payee) public onlyOwner {
uint256 payment = deposits[_payee];
assert(address(this).balance >= payment);
deposits[_payee] = 0;
_payee.transfer(payment);
emit Withdrawn(_payee, payment);
}
}

View File

@ -1,43 +1,42 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "./Escrow.sol";
import "../math/SafeMath.sol";
/** /**
* @title PullPayment * @title PullPayment
* @dev Base contract supporting async send for pull payments. Inherit from this * @dev Base contract supporting async send for pull payments. Inherit from this
* contract and use asyncSend instead of send or transfer. * contract and use asyncTransfer instead of send or transfer.
*/ */
contract PullPayment { contract PullPayment {
using SafeMath for uint256; Escrow private escrow;
mapping(address => uint256) public payments; constructor() public {
uint256 public totalPayments; escrow = new Escrow();
}
/** /**
* @dev Withdraw accumulated balance, called by payee. * @dev Withdraw accumulated balance, called by payee.
*/ */
function withdrawPayments() public { function withdrawPayments() public {
address payee = msg.sender; address payee = msg.sender;
uint256 payment = payments[payee]; escrow.withdraw(payee);
}
require(payment != 0); /**
require(address(this).balance >= payment); * @dev Returns the credit owed to an address.
* @param _dest The creditor's address.
totalPayments = totalPayments.sub(payment); */
payments[payee] = 0; function payments(address _dest) public view returns (uint256) {
return escrow.depositsOf(_dest);
payee.transfer(payment);
} }
/** /**
* @dev Called by the payer to store the sent amount as credit to be pulled. * @dev Called by the payer to store the sent amount as credit to be pulled.
* @param dest The destination address of the funds. * @param _dest The destination address of the funds.
* @param amount The amount to transfer. * @param _amount The amount to transfer.
*/ */
function asyncSend(address dest, uint256 amount) internal { function asyncTransfer(address _dest, uint256 _amount) internal {
payments[dest] = payments[dest].add(amount); escrow.deposit.value(_amount)(_dest);
totalPayments = totalPayments.add(amount);
} }
} }

View File

@ -0,0 +1,74 @@
pragma solidity ^0.4.23;
import "./ConditionalEscrow.sol";
import "../ownership/Ownable.sol";
/**
* @title RefundEscrow
* @dev Escrow that holds funds for a beneficiary, deposited from multiple parties.
* The contract owner may close the deposit period, and allow for either withdrawal
* by the beneficiary, or refunds to the depositors.
*/
contract RefundEscrow is Ownable, ConditionalEscrow {
enum State { Active, Refunding, Closed }
event Closed();
event RefundsEnabled();
State public state;
address public beneficiary;
/**
* @dev Constructor.
* @param _beneficiary The beneficiary of the deposits.
*/
constructor(address _beneficiary) public {
require(_beneficiary != address(0));
beneficiary = _beneficiary;
state = State.Active;
}
/**
* @dev Stores funds that may later be refunded.
* @param _refundee The address funds will be sent to if a refund occurs.
*/
function deposit(address _refundee) public payable {
require(state == State.Active);
super.deposit(_refundee);
}
/**
* @dev Allows for the beneficiary to withdraw their funds, rejecting
* further deposits.
*/
function close() public onlyOwner {
require(state == State.Active);
state = State.Closed;
emit Closed();
}
/**
* @dev Allows for refunds to take place, rejecting further deposits.
*/
function enableRefunds() public onlyOwner {
require(state == State.Active);
state = State.Refunding;
emit RefundsEnabled();
}
/**
* @dev Withdraws the beneficiary's funds.
*/
function beneficiaryWithdraw() public {
require(state == State.Closed);
beneficiary.transfer(address(this).balance);
}
/**
* @dev Returns whether refundees can withdraw their deposits (be refunded).
*/
function withdrawalAllowed(address _payee) public view returns (bool) {
return state == State.Refunding;
}
}

View File

@ -1,4 +1,4 @@
pragma solidity ^0.4.21; pragma solidity ^0.4.24;
import "../math/SafeMath.sol"; import "../math/SafeMath.sol";
@ -21,7 +21,7 @@ contract SplitPayment {
/** /**
* @dev Constructor * @dev Constructor
*/ */
function SplitPayment(address[] _payees, uint256[] _shares) public payable { constructor(address[] _payees, uint256[] _shares) public payable {
require(_payees.length == _shares.length); require(_payees.length == _shares.length);
for (uint256 i = 0; i < _payees.length; i++) { for (uint256 i = 0; i < _payees.length; i++) {
@ -43,7 +43,11 @@ contract SplitPayment {
require(shares[payee] > 0); require(shares[payee] > 0);
uint256 totalReceived = address(this).balance.add(totalReleased); uint256 totalReceived = address(this).balance.add(totalReleased);
uint256 payment = totalReceived.mul(shares[payee]).div(totalShares).sub(released[payee]); uint256 payment = totalReceived.mul(
shares[payee]).div(
totalShares).sub(
released[payee]
);
require(payment != 0); require(payment != 0);
require(address(this).balance >= payment); require(address(this).balance >= payment);

View File

Some files were not shown because too many files have changed in this diff Show More