diff --git a/contracts/Bounty.sol b/contracts/Bounty.sol deleted file mode 100644 index 2f9879d96..000000000 --- a/contracts/Bounty.sol +++ /dev/null @@ -1,72 +0,0 @@ -pragma solidity ^0.4.21; - - -import "./payment/PullPayment.sol"; -import "./lifecycle/Destructible.sol"; - - -/** - * @title Bounty - * @dev This bounty will pay out to a researcher if they break invariant logic of the contract. - */ -contract Bounty is PullPayment, Destructible { - bool public claimed; - mapping(address => address) public researchers; - - event TargetCreated(address createdAddress); - - /** - * @dev Fallback function allowing the contract to receive funds, if they haven't already been claimed. - */ - function() external payable { - require(!claimed); - } - - /** - * @dev Create and deploy the target contract (extension of Target contract), and sets the - * msg.sender as a researcher - * @return A target contract - */ - function createTarget() public returns(Target) { - Target target = Target(deployContract()); - researchers[target] = msg.sender; - emit TargetCreated(target); - return target; - } - - /** - * @dev Sends the contract funds to the researcher that proved the contract is broken. - * @param target contract - */ - function claim(Target target) public { - address researcher = researchers[target]; - require(researcher != 0); - // Check Target contract invariants - require(!target.checkInvariant()); - asyncSend(researcher, address(this).balance); - claimed = true; - } - - /** - * @dev Internal function to deploy the target contract. - * @return A target contract address - */ - function deployContract() internal returns(address); - -} - - -/** - * @title Target - * @dev Your main contract should inherit from this class and implement the checkInvariant method. - */ -contract Target { - - /** - * @dev Checks all values a contract assumes to be true all the time. If this function returns - * false, the contract is broken in some way and is in an inconsistent state. - * In order to win the bounty, security researchers will try to cause this broken state. - * @return True if all invariant values are correct, false otherwise. - */ - function checkInvariant() public returns(bool); -} diff --git a/contracts/DayLimit.sol b/contracts/DayLimit.sol deleted file mode 100644 index 0bfa9b6d0..000000000 --- a/contracts/DayLimit.sol +++ /dev/null @@ -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)); - _; - } -} diff --git a/contracts/ECRecovery.sol b/contracts/ECRecovery.sol deleted file mode 100644 index b2076f0e3..000000000 --- a/contracts/ECRecovery.sol +++ /dev/null @@ -1,76 +0,0 @@ -pragma solidity ^0.4.21; - - -/** - * @title Eliptic curve signature operations - * - * @dev Based on https://gist.github.com/axic/5b33912c6f61ae6fd96d6c4a47afde6d - * - * TODO Remove this library once solidity supports passing a signature to ecrecover. - * See https://github.com/ethereum/solidity/issues/864 - * - */ - -library ECRecovery { - - /** - * @dev Recover signer address from a message by using their signature - * @param hash bytes32 message, the hash is the signed message. What is recovered is the signer address. - * @param sig bytes signature, the signature is generated using web3.eth.sign() - */ - function recover(bytes32 hash, bytes sig) - internal - pure - returns (address) - { - bytes32 r; - bytes32 s; - uint8 v; - - // Check the signature length - if (sig.length != 65) { - return (address(0)); - } - - // Divide the signature in r, s and v variables - // ecrecover takes the signature parameters, and the only way to get them - // currently is to use assembly. - // solium-disable-next-line security/no-inline-assembly - assembly { - r := mload(add(sig, 32)) - s := mload(add(sig, 64)) - v := byte(0, mload(add(sig, 96))) - } - - // Version of signature should be 27 or 28, but 0 and 1 are also possible versions - if (v < 27) { - v += 27; - } - - // If the version is correct return the signer address - if (v != 27 && v != 28) { - return (address(0)); - } else { - // solium-disable-next-line arg-overflow - return ecrecover(hash, v, r, s); - } - } - - /** - * toEthSignedMessageHash - * @dev prefix a bytes32 value with "\x19Ethereum Signed Message:" - * @dev and hash the result - */ - function toEthSignedMessageHash(bytes32 hash) - internal - pure - returns (bytes32) - { - // 32 is the length in bytes of hash, - // enforced by the type signature above - return keccak256( - "\x19Ethereum Signed Message:\n32", - hash - ); - } -} diff --git a/contracts/LimitBalance.sol b/contracts/LimitBalance.sol deleted file mode 100644 index e3f28cac1..000000000 --- a/contracts/LimitBalance.sol +++ /dev/null @@ -1,31 +0,0 @@ -pragma solidity ^0.4.21; - - -/** - * @title LimitBalance - * @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); - * @dev See: https://github.com/ConsenSys/smart-contract-best-practices#remember-that-ether-can-be-forcibly-sent-to-an-account - */ -contract LimitBalance { - - uint256 public limit; - - /** - * @dev Constructor that sets the passed value as a limit. - * @param _limit uint256 to represent the limit. - */ - function LimitBalance(uint256 _limit) public { - limit = _limit; - } - - /** - * @dev Checks if limit was reached. Case true, it throws. - */ - modifier limitedPayable() { - require(address(this).balance <= limit); - _; - - } - -} diff --git a/contracts/MerkleProof.sol b/contracts/MerkleProof.sol deleted file mode 100644 index a7000c6f2..000000000 --- a/contracts/MerkleProof.sol +++ /dev/null @@ -1,35 +0,0 @@ -pragma solidity ^0.4.21; - - -/* - * @title MerkleProof - * @dev Merkle proof verification - * @note Based on https://github.com/ameensol/merkle-tree-solidity/blob/master/src/MerkleProof.sol - */ -library MerkleProof { - /* - * @dev Verifies a Merkle proof proving the existence of a leaf in a Merkle tree. Assumes that each pair of leaves - * and each pair of pre-images is sorted. - * @param _proof Merkle proof containing sibling hashes on the branch from the leaf to the root of the Merkle tree - * @param _root Merkle root - * @param _leaf Leaf of Merkle tree - */ - function verifyProof(bytes32[] _proof, bytes32 _root, bytes32 _leaf) internal pure returns (bool) { - bytes32 computedHash = _leaf; - - for (uint256 i = 0; i < _proof.length; i++) { - bytes32 proofElement = _proof[i]; - - if (computedHash < proofElement) { - // Hash(current computed hash + current element of the proof) - computedHash = keccak256(computedHash, proofElement); - } else { - // Hash(current element of the proof + current computed hash) - computedHash = keccak256(proofElement, computedHash); - } - } - - // Check if the computed hash (root) is equal to the provided root - return computedHash == _root; - } -} diff --git a/contracts/ReentrancyGuard.sol b/contracts/ReentrancyGuard.sol deleted file mode 100644 index 1b55ceebc..000000000 --- a/contracts/ReentrancyGuard.sol +++ /dev/null @@ -1,32 +0,0 @@ -pragma solidity ^0.4.21; - - -/** - * @title Helps contracts guard agains reentrancy attacks. - * @author Remco Bloemen - * @notice If you mark a function `nonReentrant`, you should also - * mark it `external`. - */ -contract ReentrancyGuard { - - /** - * @dev We use a single lock for the whole contract. - */ - bool private reentrancyLock = false; - - /** - * @dev Prevents a contract from calling itself, directly or indirectly. - * @notice If you mark a function `nonReentrant`, you should also - * mark it `external`. Calling one nonReentrant function from - * another is not supported. Instead, you can implement a - * `private` function doing the actual work, and a `external` - * wrapper marked as `nonReentrant`. - */ - modifier nonReentrant() { - require(!reentrancyLock); - reentrancyLock = true; - _; - reentrancyLock = false; - } - -} diff --git a/contracts/access/SignatureBouncer.sol b/contracts/access/SignatureBouncer.sol deleted file mode 100644 index ad0267de1..000000000 --- a/contracts/access/SignatureBouncer.sol +++ /dev/null @@ -1,90 +0,0 @@ -pragma solidity ^0.4.18; - -import "../ownership/Ownable.sol"; -import "../ownership/rbac/RBAC.sol"; -import "../ECRecovery.sol"; - -/** - * @title SignatureBouncer - * @author PhABC and Shrugs - * @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 - * @dev is valid. The owner of the contract adds/removes bouncers. - * @dev Bouncer addresses can be individual servers signing grants or different - * @dev users within a decentralized club that have permission to invite other members. - * @dev - * @dev This technique is useful for whitelists and airdrops; instead of putting all - * @dev valid addresses on-chain, simply sign a grant of the form - * @dev keccak256(`:contractAddress` + `:granteeAddress`) using a valid bouncer address. - * @dev Then restrict access to your crowdsale/whitelist/airdrop using the - * @dev `onlyValidSignature` modifier (or implement your own using isValidSignature). - * @dev - * @dev See the tests Bouncer.test.js for specific usage examples. - */ -contract SignatureBouncer is Ownable, RBAC { - using ECRecovery for bytes32; - - string public constant ROLE_BOUNCER = "bouncer"; - - /** - * @dev requires that a valid signature of a bouncer was provided - */ - modifier onlyValidSignature(bytes _sig) - { - require(isValidSignature(msg.sender, _sig)); - _; - } - - /** - * @dev allows the owner to add additional bouncer addresses - */ - function addBouncer(address _bouncer) - onlyOwner - public - { - require(_bouncer != address(0)); - addRole(_bouncer, ROLE_BOUNCER); - } - - /** - * @dev allows the owner to remove bouncer addresses - */ - function removeBouncer(address _bouncer) - onlyOwner - public - { - require(_bouncer != address(0)); - removeRole(_bouncer, ROLE_BOUNCER); - } - - /** - * @dev is the signature of `this + sender` from a bouncer? - * @return bool - */ - function isValidSignature(address _address, bytes _sig) - internal - view - returns (bool) - { - return isValidDataHash( - keccak256(address(this), _address), - _sig - ); - } - - /** - * @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 - * @return bool - */ - function isValidDataHash(bytes32 hash, bytes _sig) - internal - view - returns (bool) - { - address signer = hash - .toEthSignedMessageHash() - .recover(_sig); - return hasRole(signer, ROLE_BOUNCER); - } -} diff --git a/contracts/crowdsale/Crowdsale.sol b/contracts/crowdsale/Crowdsale.sol deleted file mode 100644 index cbb59eabc..000000000 --- a/contracts/crowdsale/Crowdsale.sol +++ /dev/null @@ -1,163 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/ERC20.sol"; -import "../math/SafeMath.sol"; - - -/** - * @title Crowdsale - * @dev Crowdsale is a base contract for managing a token crowdsale, - * allowing investors to purchase tokens with ether. This contract implements - * such functionality in its most fundamental form and can be extended to provide additional - * functionality and/or custom behavior. - * The external interface represents the basic interface for purchasing tokens, and conform - * the base architecture for crowdsales. They are *not* intended to be modified / overriden. - * The internal interface conforms the extensible and modifiable surface of crowdsales. Override - * the methods to add functionality. Consider using 'super' where appropiate to concatenate - * behavior. - */ -contract Crowdsale { - using SafeMath for uint256; - - // The token being sold - ERC20 public token; - - // Address where funds are collected - address public wallet; - - // How many token units a buyer gets per wei - uint256 public rate; - - // Amount of wei raised - uint256 public weiRaised; - - /** - * Event for token purchase logging - * @param purchaser who paid for the tokens - * @param beneficiary who got the tokens - * @param value weis paid for purchase - * @param amount amount of tokens purchased - */ - event TokenPurchase(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount); - - /** - * @param _rate Number of token units a buyer gets per wei - * @param _wallet Address where collected funds will be forwarded to - * @param _token Address of the token being sold - */ - function Crowdsale(uint256 _rate, address _wallet, ERC20 _token) public { - require(_rate > 0); - require(_wallet != address(0)); - require(_token != address(0)); - - rate = _rate; - wallet = _wallet; - token = _token; - } - - // ----------------------------------------- - // Crowdsale external interface - // ----------------------------------------- - - /** - * @dev fallback function ***DO NOT OVERRIDE*** - */ - function () external payable { - buyTokens(msg.sender); - } - - /** - * @dev low level token purchase ***DO NOT OVERRIDE*** - * @param _beneficiary Address performing the token purchase - */ - function buyTokens(address _beneficiary) public payable { - - uint256 weiAmount = msg.value; - _preValidatePurchase(_beneficiary, weiAmount); - - // calculate token amount to be created - uint256 tokens = _getTokenAmount(weiAmount); - - // update state - weiRaised = weiRaised.add(weiAmount); - - _processPurchase(_beneficiary, tokens); - emit TokenPurchase( - msg.sender, - _beneficiary, - weiAmount, - tokens - ); - - _updatePurchasingState(_beneficiary, weiAmount); - - _forwardFunds(); - _postValidatePurchase(_beneficiary, weiAmount); - } - - // ----------------------------------------- - // Internal interface (extensible) - // ----------------------------------------- - - /** - * @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met. Use super to concatenate validations. - * @param _beneficiary Address performing the token purchase - * @param _weiAmount Value in wei involved in the purchase - */ - function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal { - require(_beneficiary != address(0)); - require(_weiAmount != 0); - } - - /** - * @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid conditions are not met. - * @param _beneficiary Address performing the token purchase - * @param _weiAmount Value in wei involved in the purchase - */ - function _postValidatePurchase(address _beneficiary, uint256 _weiAmount) internal { - // optional override - } - - /** - * @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends its tokens. - * @param _beneficiary Address performing the token purchase - * @param _tokenAmount Number of tokens to be emitted - */ - function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal { - token.transfer(_beneficiary, _tokenAmount); - } - - /** - * @dev Executed when a purchase has been validated and is ready to be executed. Not necessarily emits/sends tokens. - * @param _beneficiary Address receiving the tokens - * @param _tokenAmount Number of tokens to be purchased - */ - function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal { - _deliverTokens(_beneficiary, _tokenAmount); - } - - /** - * @dev Override for extensions that require an internal state to check for validity (current user contributions, etc.) - * @param _beneficiary Address receiving the tokens - * @param _weiAmount Value in wei involved in the purchase - */ - function _updatePurchasingState(address _beneficiary, uint256 _weiAmount) internal { - // optional override - } - - /** - * @dev Override to extend the way in which ether is converted to tokens. - * @param _weiAmount Value in wei to be converted into tokens - * @return Number of tokens that can be purchased with the specified _weiAmount - */ - function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) { - return _weiAmount.mul(rate); - } - - /** - * @dev Determines how ETH is stored/forwarded on purchases. - */ - function _forwardFunds() internal { - wallet.transfer(msg.value); - } -} diff --git a/contracts/crowdsale/distribution/FinalizableCrowdsale.sol b/contracts/crowdsale/distribution/FinalizableCrowdsale.sol deleted file mode 100644 index d15d4f62b..000000000 --- a/contracts/crowdsale/distribution/FinalizableCrowdsale.sol +++ /dev/null @@ -1,42 +0,0 @@ -pragma solidity ^0.4.21; - -import "../../math/SafeMath.sol"; -import "../../ownership/Ownable.sol"; -import "../validation/TimedCrowdsale.sol"; - - -/** - * @title FinalizableCrowdsale - * @dev Extension of Crowdsale where an owner can do extra work - * after finishing. - */ -contract FinalizableCrowdsale is TimedCrowdsale, Ownable { - using SafeMath for uint256; - - bool public isFinalized = false; - - event Finalized(); - - /** - * @dev Must be called after crowdsale ends, to do some extra finalization - * work. Calls the contract's finalization function. - */ - function finalize() onlyOwner public { - require(!isFinalized); - require(hasClosed()); - - finalization(); - emit Finalized(); - - isFinalized = true; - } - - /** - * @dev Can be overridden to add finalization logic. The overriding function - * should call super.finalization() to ensure the chain of finalization is - * executed entirely. - */ - function finalization() internal { - } - -} diff --git a/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol b/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol deleted file mode 100644 index ac5daff99..000000000 --- a/contracts/crowdsale/distribution/PostDeliveryCrowdsale.sol +++ /dev/null @@ -1,37 +0,0 @@ -pragma solidity ^0.4.21; - -import "../validation/TimedCrowdsale.sol"; -import "../../token/ERC20/ERC20.sol"; -import "../../math/SafeMath.sol"; - - -/** - * @title PostDeliveryCrowdsale - * @dev Crowdsale that locks tokens from withdrawal until it ends. - */ -contract PostDeliveryCrowdsale is TimedCrowdsale { - using SafeMath for uint256; - - mapping(address => uint256) public balances; - - /** - * @dev Withdraw tokens only after crowdsale ends. - */ - function withdrawTokens() public { - require(hasClosed()); - uint256 amount = balances[msg.sender]; - require(amount > 0); - balances[msg.sender] = 0; - _deliverTokens(msg.sender, amount); - } - - /** - * @dev Overrides parent by storing balances instead of issuing tokens right away. - * @param _beneficiary Token purchaser - * @param _tokenAmount Amount of tokens purchased - */ - function _processPurchase(address _beneficiary, uint256 _tokenAmount) internal { - balances[_beneficiary] = balances[_beneficiary].add(_tokenAmount); - } - -} diff --git a/contracts/crowdsale/distribution/RefundableCrowdsale.sol b/contracts/crowdsale/distribution/RefundableCrowdsale.sol deleted file mode 100644 index 9b3819ea4..000000000 --- a/contracts/crowdsale/distribution/RefundableCrowdsale.sol +++ /dev/null @@ -1,72 +0,0 @@ -pragma solidity ^0.4.21; - - -import "../../math/SafeMath.sol"; -import "./FinalizableCrowdsale.sol"; -import "./utils/RefundVault.sol"; - - -/** - * @title RefundableCrowdsale - * @dev Extension of Crowdsale contract that adds a funding goal, and - * the possibility of users getting a refund if goal is not met. - * Uses a RefundVault as the crowdsale's vault. - */ -contract RefundableCrowdsale is FinalizableCrowdsale { - using SafeMath for uint256; - - // minimum amount of funds to be raised in weis - uint256 public goal; - - // refund vault used to hold funds while crowdsale is running - RefundVault public vault; - - /** - * @dev Constructor, creates RefundVault. - * @param _goal Funding goal - */ - function RefundableCrowdsale(uint256 _goal) public { - require(_goal > 0); - vault = new RefundVault(wallet); - goal = _goal; - } - - /** - * @dev Investors can claim refunds here if crowdsale is unsuccessful - */ - function claimRefund() public { - require(isFinalized); - require(!goalReached()); - - vault.refund(msg.sender); - } - - /** - * @dev Checks whether funding goal was reached. - * @return Whether funding goal was reached - */ - function goalReached() public view returns (bool) { - return weiRaised >= goal; - } - - /** - * @dev vault finalization task, called when owner calls finalize() - */ - function finalization() internal { - if (goalReached()) { - vault.close(); - } else { - vault.enableRefunds(); - } - - super.finalization(); - } - - /** - * @dev Overrides Crowdsale fund forwarding, sending funds to vault. - */ - function _forwardFunds() internal { - vault.deposit.value(msg.value)(msg.sender); - } - -} diff --git a/contracts/crowdsale/distribution/utils/RefundVault.sol b/contracts/crowdsale/distribution/utils/RefundVault.sol deleted file mode 100644 index 17a69b08c..000000000 --- a/contracts/crowdsale/distribution/utils/RefundVault.sol +++ /dev/null @@ -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); - } -} diff --git a/contracts/crowdsale/emission/AllowanceCrowdsale.sol b/contracts/crowdsale/emission/AllowanceCrowdsale.sol deleted file mode 100644 index ae8fe5992..000000000 --- a/contracts/crowdsale/emission/AllowanceCrowdsale.sol +++ /dev/null @@ -1,42 +0,0 @@ -pragma solidity ^0.4.21; - -import "../Crowdsale.sol"; -import "../../token/ERC20/ERC20.sol"; -import "../../math/SafeMath.sol"; - - -/** - * @title AllowanceCrowdsale - * @dev Extension of Crowdsale where tokens are held by a wallet, which approves an allowance to the crowdsale. - */ -contract AllowanceCrowdsale is Crowdsale { - using SafeMath for uint256; - - address public tokenWallet; - - /** - * @dev Constructor, takes token wallet address. - * @param _tokenWallet Address holding the tokens, which has approved allowance to the crowdsale - */ - function AllowanceCrowdsale(address _tokenWallet) public { - require(_tokenWallet != address(0)); - tokenWallet = _tokenWallet; - } - - /** - * @dev Checks the amount of tokens left in the allowance. - * @return Amount of tokens left in the allowance - */ - function remainingTokens() public view returns (uint256) { - return token.allowance(tokenWallet, this); - } - - /** - * @dev Overrides parent behavior by transferring tokens from wallet. - * @param _beneficiary Token purchaser - * @param _tokenAmount Amount of tokens purchased - */ - function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal { - token.transferFrom(tokenWallet, _beneficiary, _tokenAmount); - } -} diff --git a/contracts/crowdsale/emission/MintedCrowdsale.sol b/contracts/crowdsale/emission/MintedCrowdsale.sol deleted file mode 100644 index 4d30de156..000000000 --- a/contracts/crowdsale/emission/MintedCrowdsale.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.21; - -import "../Crowdsale.sol"; -import "../../token/ERC20/MintableToken.sol"; - - -/** - * @title MintedCrowdsale - * @dev Extension of Crowdsale contract whose tokens are minted in each purchase. - * Token ownership should be transferred to MintedCrowdsale for minting. - */ -contract MintedCrowdsale is Crowdsale { - - /** - * @dev Overrides delivery by minting tokens upon purchase. - * @param _beneficiary Token purchaser - * @param _tokenAmount Number of tokens to be minted - */ - function _deliverTokens(address _beneficiary, uint256 _tokenAmount) internal { - require(MintableToken(token).mint(_beneficiary, _tokenAmount)); - } -} diff --git a/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol b/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol deleted file mode 100644 index c9f773bf4..000000000 --- a/contracts/crowdsale/price/IncreasingPriceCrowdsale.sol +++ /dev/null @@ -1,54 +0,0 @@ -pragma solidity ^0.4.21; - -import "../validation/TimedCrowdsale.sol"; -import "../../math/SafeMath.sol"; - - -/** - * @title IncreasingPriceCrowdsale - * @dev Extension of Crowdsale contract that increases the price of tokens linearly in time. - * Note that what should be provided to the constructor is the initial and final _rates_, that is, - * the amount of tokens per wei contributed. Thus, the initial rate must be greater than the final rate. - */ -contract IncreasingPriceCrowdsale is TimedCrowdsale { - using SafeMath for uint256; - - uint256 public initialRate; - uint256 public finalRate; - - /** - * @dev Constructor, takes intial and final rates of tokens received per wei contributed. - * @param _initialRate Number of tokens a buyer gets per wei at the start of the crowdsale - * @param _finalRate Number of tokens a buyer gets per wei at the end of the crowdsale - */ - function IncreasingPriceCrowdsale(uint256 _initialRate, uint256 _finalRate) public { - require(_initialRate >= _finalRate); - require(_finalRate > 0); - initialRate = _initialRate; - finalRate = _finalRate; - } - - /** - * @dev Returns the rate of tokens per wei at the present time. - * Note that, as price _increases_ with time, the rate _decreases_. - * @return The number of tokens a buyer gets per wei at a given time - */ - function getCurrentRate() public view returns (uint256) { - // solium-disable-next-line security/no-block-members - uint256 elapsedTime = block.timestamp.sub(openingTime); - uint256 timeRange = closingTime.sub(openingTime); - uint256 rateRange = initialRate.sub(finalRate); - return initialRate.sub(elapsedTime.mul(rateRange).div(timeRange)); - } - - /** - * @dev Overrides parent method taking into account variable rate. - * @param _weiAmount The value in wei to be converted into tokens - * @return The number of tokens _weiAmount wei will buy at present time - */ - function _getTokenAmount(uint256 _weiAmount) internal view returns (uint256) { - uint256 currentRate = getCurrentRate(); - return currentRate.mul(_weiAmount); - } - -} diff --git a/contracts/crowdsale/validation/CappedCrowdsale.sol b/contracts/crowdsale/validation/CappedCrowdsale.sol deleted file mode 100644 index 0b899665a..000000000 --- a/contracts/crowdsale/validation/CappedCrowdsale.sol +++ /dev/null @@ -1,43 +0,0 @@ -pragma solidity ^0.4.21; - -import "../../math/SafeMath.sol"; -import "../Crowdsale.sol"; - - -/** - * @title CappedCrowdsale - * @dev Crowdsale with a limit for total contributions. - */ -contract CappedCrowdsale is Crowdsale { - using SafeMath for uint256; - - uint256 public cap; - - /** - * @dev Constructor, takes maximum amount of wei accepted in the crowdsale. - * @param _cap Max amount of wei to be contributed - */ - function CappedCrowdsale(uint256 _cap) public { - require(_cap > 0); - cap = _cap; - } - - /** - * @dev Checks whether the cap has been reached. - * @return Whether the cap was reached - */ - function capReached() public view returns (bool) { - return weiRaised >= cap; - } - - /** - * @dev Extend parent behavior requiring purchase to respect the funding cap. - * @param _beneficiary Token purchaser - * @param _weiAmount Amount of wei contributed - */ - function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal { - super._preValidatePurchase(_beneficiary, _weiAmount); - require(weiRaised.add(_weiAmount) <= cap); - } - -} diff --git a/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol b/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol deleted file mode 100644 index ee363deb8..000000000 --- a/contracts/crowdsale/validation/IndividuallyCappedCrowdsale.sol +++ /dev/null @@ -1,76 +0,0 @@ -pragma solidity ^0.4.21; - -import "../../math/SafeMath.sol"; -import "../Crowdsale.sol"; -import "../../ownership/Ownable.sol"; - - -/** - * @title IndividuallyCappedCrowdsale - * @dev Crowdsale with per-user caps. - */ -contract IndividuallyCappedCrowdsale is Crowdsale, Ownable { - using SafeMath for uint256; - - mapping(address => uint256) public contributions; - mapping(address => uint256) public caps; - - /** - * @dev Sets a specific user's maximum contribution. - * @param _beneficiary Address to be capped - * @param _cap Wei limit for individual contribution - */ - function setUserCap(address _beneficiary, uint256 _cap) external onlyOwner { - caps[_beneficiary] = _cap; - } - - /** - * @dev Sets a group of users' maximum contribution. - * @param _beneficiaries List of addresses to be capped - * @param _cap Wei limit for individual contribution - */ - function setGroupCap(address[] _beneficiaries, uint256 _cap) external onlyOwner { - for (uint256 i = 0; i < _beneficiaries.length; i++) { - caps[_beneficiaries[i]] = _cap; - } - } - - /** - * @dev Returns the cap of a specific user. - * @param _beneficiary Address whose cap is to be checked - * @return Current cap for individual user - */ - function getUserCap(address _beneficiary) public view returns (uint256) { - return caps[_beneficiary]; - } - - /** - * @dev Returns the amount contributed so far by a sepecific user. - * @param _beneficiary Address of contributor - * @return User contribution so far - */ - function getUserContribution(address _beneficiary) public view returns (uint256) { - return contributions[_beneficiary]; - } - - /** - * @dev Extend parent behavior requiring purchase to respect the user's funding cap. - * @param _beneficiary Token purchaser - * @param _weiAmount Amount of wei contributed - */ - function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal { - super._preValidatePurchase(_beneficiary, _weiAmount); - require(contributions[_beneficiary].add(_weiAmount) <= caps[_beneficiary]); - } - - /** - * @dev Extend parent behavior to update user contributions - * @param _beneficiary Token purchaser - * @param _weiAmount Amount of wei contributed - */ - function _updatePurchasingState(address _beneficiary, uint256 _weiAmount) internal { - super._updatePurchasingState(_beneficiary, _weiAmount); - contributions[_beneficiary] = contributions[_beneficiary].add(_weiAmount); - } - -} diff --git a/contracts/crowdsale/validation/TimedCrowdsale.sol b/contracts/crowdsale/validation/TimedCrowdsale.sol deleted file mode 100644 index 9977990a7..000000000 --- a/contracts/crowdsale/validation/TimedCrowdsale.sol +++ /dev/null @@ -1,58 +0,0 @@ -pragma solidity ^0.4.21; - -import "../../math/SafeMath.sol"; -import "../Crowdsale.sol"; - - -/** - * @title TimedCrowdsale - * @dev Crowdsale accepting contributions only within a time frame. - */ -contract TimedCrowdsale is Crowdsale { - using SafeMath for uint256; - - uint256 public openingTime; - uint256 public closingTime; - - /** - * @dev Reverts if not in crowdsale time range. - */ - modifier onlyWhileOpen { - // solium-disable-next-line security/no-block-members - require(block.timestamp >= openingTime && block.timestamp <= closingTime); - _; - } - - /** - * @dev Constructor, takes crowdsale opening and closing times. - * @param _openingTime Crowdsale opening time - * @param _closingTime Crowdsale closing time - */ - function TimedCrowdsale(uint256 _openingTime, uint256 _closingTime) public { - // solium-disable-next-line security/no-block-members - require(_openingTime >= block.timestamp); - require(_closingTime >= _openingTime); - - openingTime = _openingTime; - closingTime = _closingTime; - } - - /** - * @dev Checks whether the period in which the crowdsale is open has already elapsed. - * @return Whether crowdsale period has elapsed - */ - function hasClosed() public view returns (bool) { - // solium-disable-next-line security/no-block-members - return block.timestamp > closingTime; - } - - /** - * @dev Extend parent behavior requiring to be within contributing period - * @param _beneficiary Token purchaser - * @param _weiAmount Amount of wei contributed - */ - function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal onlyWhileOpen { - super._preValidatePurchase(_beneficiary, _weiAmount); - } - -} diff --git a/contracts/crowdsale/validation/WhitelistedCrowdsale.sol b/contracts/crowdsale/validation/WhitelistedCrowdsale.sol deleted file mode 100644 index bbccd58a4..000000000 --- a/contracts/crowdsale/validation/WhitelistedCrowdsale.sol +++ /dev/null @@ -1,58 +0,0 @@ -pragma solidity ^0.4.21; - -import "../Crowdsale.sol"; -import "../../ownership/Ownable.sol"; - - -/** - * @title WhitelistedCrowdsale - * @dev Crowdsale in which only whitelisted users can contribute. - */ -contract WhitelistedCrowdsale is Crowdsale, Ownable { - - 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. - * @param _beneficiary Token beneficiary - * @param _weiAmount Amount of wei contributed - */ - function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal isWhitelisted(_beneficiary) { - super._preValidatePurchase(_beneficiary, _weiAmount); - } - -} diff --git a/contracts/examples/SampleCrowdsale.sol b/contracts/examples/SampleCrowdsale.sol deleted file mode 100644 index 8067a5aa9..000000000 --- a/contracts/examples/SampleCrowdsale.sol +++ /dev/null @@ -1,55 +0,0 @@ -pragma solidity ^0.4.21; - -import "../crowdsale/validation/CappedCrowdsale.sol"; -import "../crowdsale/distribution/RefundableCrowdsale.sol"; -import "../crowdsale/emission/MintedCrowdsale.sol"; -import "../token/ERC20/MintableToken.sol"; - - -/** - * @title SampleCrowdsaleToken - * @dev Very simple ERC20 Token that can be minted. - * It is meant to be used in a crowdsale contract. - */ -contract SampleCrowdsaleToken is MintableToken { - - string public constant name = "Sample Crowdsale Token"; // solium-disable-line uppercase - string public constant symbol = "SCT"; // solium-disable-line uppercase - uint8 public constant decimals = 18; // solium-disable-line uppercase - -} - - -/** - * @title SampleCrowdsale - * @dev This is an example of a fully fledged crowdsale. - * The way to add new features to a base crowdsale is by multiple inheritance. - * In this example we are providing following extensions: - * CappedCrowdsale - sets a max boundary for raised funds - * RefundableCrowdsale - set a min goal to be reached and returns funds if it's not met - * - * After adding multiple features it's good practice to run integration tests - * to ensure that subcontracts works together as intended. - */ -contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale, MintedCrowdsale { - - function SampleCrowdsale( - uint256 _openingTime, - uint256 _closingTime, - uint256 _rate, - address _wallet, - uint256 _cap, - MintableToken _token, - uint256 _goal - ) - public - Crowdsale(_rate, _wallet, _token) - CappedCrowdsale(_cap) - TimedCrowdsale(_openingTime, _closingTime) - RefundableCrowdsale(_goal) - { - //As goal needs to be met for a successful crowdsale - //the value needs to less or equal than a cap which is limit for accepted funds - require(_goal <= _cap); - } -} diff --git a/contracts/examples/SimpleSavingsWallet.sol b/contracts/examples/SimpleSavingsWallet.sol deleted file mode 100644 index ea02acec2..000000000 --- a/contracts/examples/SimpleSavingsWallet.sol +++ /dev/null @@ -1,40 +0,0 @@ -pragma solidity ^0.4.21; - -import "../ownership/Heritable.sol"; - - -/** - * @title SimpleSavingsWallet - * @dev Simplest form of savings wallet whose ownership can be claimed by a heir - * if owner dies. - * In this example, we take a very simple savings wallet providing two operations - * (to send and receive funds) and extend its capabilities by making it Heritable. - * The account that creates the contract is set as owner, who has the authority to - * choose an heir account. Heir account can reclaim the contract ownership in the - * case that the owner dies. - */ -contract SimpleSavingsWallet is Heritable { - - event Sent(address indexed payee, uint256 amount, uint256 balance); - event Received(address indexed payer, uint256 amount, uint256 balance); - - - function SimpleSavingsWallet(uint256 _heartbeatTimeout) Heritable(_heartbeatTimeout) public {} - - /** - * @dev wallet can receive funds. - */ - function () public payable { - emit Received(msg.sender, msg.value, address(this).balance); - } - - /** - * @dev wallet can send funds - */ - function sendTo(address payee, uint256 amount) public onlyOwner { - require(payee != 0 && payee != address(this)); - require(amount > 0); - payee.transfer(amount); - emit Sent(payee, amount, address(this).balance); - } -} diff --git a/contracts/examples/SimpleToken.sol b/contracts/examples/SimpleToken.sol deleted file mode 100644 index a394f9dc7..000000000 --- a/contracts/examples/SimpleToken.sol +++ /dev/null @@ -1,30 +0,0 @@ -pragma solidity ^0.4.21; - - -import "../token/ERC20/StandardToken.sol"; - - -/** - * @title SimpleToken - * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator. - * Note they can later distribute these tokens as they wish using `transfer` and other - * `StandardToken` functions. - */ -contract SimpleToken is StandardToken { - - string public constant name = "SimpleToken"; // solium-disable-line uppercase - string public constant symbol = "SIM"; // solium-disable-line uppercase - uint8 public constant decimals = 18; // solium-disable-line uppercase - - uint256 public constant INITIAL_SUPPLY = 10000 * (10 ** uint256(decimals)); - - /** - * @dev Constructor that gives msg.sender all of existing tokens. - */ - function SimpleToken() public { - totalSupply_ = INITIAL_SUPPLY; - balances[msg.sender] = INITIAL_SUPPLY; - emit Transfer(0x0, msg.sender, INITIAL_SUPPLY); - } - -} diff --git a/contracts/lifecycle/Destructible.sol b/contracts/lifecycle/Destructible.sol deleted file mode 100644 index cfb288d4e..000000000 --- a/contracts/lifecycle/Destructible.sol +++ /dev/null @@ -1,25 +0,0 @@ -pragma solidity ^0.4.21; - - -import "../ownership/Ownable.sol"; - - -/** - * @title Destructible - * @dev Base contract that can be destroyed by owner. All funds in contract will be sent to the owner. - */ -contract Destructible is Ownable { - - function Destructible() public payable { } - - /** - * @dev Transfers the current balance to the owner and terminates the contract. - */ - function destroy() onlyOwner public { - selfdestruct(owner); - } - - function destroyAndSend(address _recipient) onlyOwner public { - selfdestruct(_recipient); - } -} diff --git a/contracts/lifecycle/TokenDestructible.sol b/contracts/lifecycle/TokenDestructible.sol deleted file mode 100644 index 6ebe9c015..000000000 --- a/contracts/lifecycle/TokenDestructible.sol +++ /dev/null @@ -1,36 +0,0 @@ -pragma solidity ^0.4.21; - -import "../ownership/Ownable.sol"; -import "../token/ERC20/ERC20Basic.sol"; - - -/** - * @title TokenDestructible: - * @author Remco Bloemen - * @dev Base contract that can be destroyed by owner. All funds in contract including - * listed tokens will be sent to the owner. - */ -contract TokenDestructible is Ownable { - - function TokenDestructible() public payable { } - - /** - * @notice Terminate contract and refund to owner - * @param tokens List of addresses of ERC20 or ERC20Basic token contracts to - refund. - * @notice The called token contracts could try to re-enter this contract. Only - supply token contracts you trust. - */ - function destroy(address[] tokens) onlyOwner public { - - // Transfer tokens to owner - for (uint256 i = 0; i < tokens.length; i++) { - ERC20Basic token = ERC20Basic(tokens[i]); - uint256 balance = token.balanceOf(this); - token.transfer(owner, balance); - } - - // Transfer Eth to owner and terminate contract - selfdestruct(owner); - } -} diff --git a/contracts/math/Math.sol b/contracts/math/Math.sol deleted file mode 100644 index 0532ecb30..000000000 --- a/contracts/math/Math.sol +++ /dev/null @@ -1,24 +0,0 @@ -pragma solidity ^0.4.21; - - -/** - * @title Math - * @dev Assorted math operations - */ -library Math { - function max64(uint64 a, uint64 b) internal pure returns (uint64) { - return a >= b ? a : b; - } - - function min64(uint64 a, uint64 b) internal pure returns (uint64) { - return a < b ? a : b; - } - - function max256(uint256 a, uint256 b) internal pure returns (uint256) { - return a >= b ? a : b; - } - - function min256(uint256 a, uint256 b) internal pure returns (uint256) { - return a < b ? a : b; - } -} diff --git a/contracts/mocks/AllowanceCrowdsaleImpl.sol b/contracts/mocks/AllowanceCrowdsaleImpl.sol deleted file mode 100644 index e3ffabed3..000000000 --- a/contracts/mocks/AllowanceCrowdsaleImpl.sol +++ /dev/null @@ -1,21 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/ERC20.sol"; -import "../crowdsale/emission/AllowanceCrowdsale.sol"; - - -contract AllowanceCrowdsaleImpl is AllowanceCrowdsale { - - function AllowanceCrowdsaleImpl ( - uint256 _rate, - address _wallet, - ERC20 _token, - address _tokenWallet - ) - public - Crowdsale(_rate, _wallet, _token) - AllowanceCrowdsale(_tokenWallet) - { - } - -} diff --git a/contracts/mocks/BouncerMock.sol b/contracts/mocks/BouncerMock.sol deleted file mode 100644 index 2add95874..000000000 --- a/contracts/mocks/BouncerMock.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.18; - -import "../access/SignatureBouncer.sol"; - - -contract SignatureBouncerMock is SignatureBouncer { - function checkValidSignature(address _address, bytes _sig) - public - view - returns (bool) - { - return isValidSignature(_address, _sig); - } - - function onlyWithValidSignature(bytes _sig) - onlyValidSignature(_sig) - public - view - { - - } -} diff --git a/contracts/mocks/CappedCrowdsaleImpl.sol b/contracts/mocks/CappedCrowdsaleImpl.sol deleted file mode 100644 index 5666d4fd9..000000000 --- a/contracts/mocks/CappedCrowdsaleImpl.sol +++ /dev/null @@ -1,21 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/ERC20.sol"; -import "../crowdsale/validation/CappedCrowdsale.sol"; - - -contract CappedCrowdsaleImpl is CappedCrowdsale { - - function CappedCrowdsaleImpl ( - uint256 _rate, - address _wallet, - ERC20 _token, - uint256 _cap - ) - public - Crowdsale(_rate, _wallet, _token) - CappedCrowdsale(_cap) - { - } - -} diff --git a/contracts/mocks/DayLimitMock.sol b/contracts/mocks/DayLimitMock.sol deleted file mode 100644 index 0081966b6..000000000 --- a/contracts/mocks/DayLimitMock.sol +++ /dev/null @@ -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(); - } - -} diff --git a/contracts/mocks/ECRecoveryMock.sol b/contracts/mocks/ECRecoveryMock.sol deleted file mode 100644 index 091055161..000000000 --- a/contracts/mocks/ECRecoveryMock.sol +++ /dev/null @@ -1,25 +0,0 @@ -pragma solidity ^0.4.21; - - -import "../ECRecovery.sol"; - - -contract ECRecoveryMock { - using ECRecovery for bytes32; - - function recover(bytes32 hash, bytes sig) - public - pure - returns (address) - { - return hash.recover(sig); - } - - function toEthSignedMessageHash(bytes32 hash) - public - pure - returns (bytes32) - { - return hash.toEthSignedMessageHash(); - } -} diff --git a/contracts/mocks/ERC223TokenMock.sol b/contracts/mocks/ERC223TokenMock.sol deleted file mode 100644 index fbe47fcc8..000000000 --- a/contracts/mocks/ERC223TokenMock.sol +++ /dev/null @@ -1,34 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/BasicToken.sol"; - - -contract ERC223ContractInterface { - function tokenFallback(address _from, uint256 _value, bytes _data) external; -} - - -contract ERC223TokenMock is BasicToken { - - function ERC223TokenMock(address initialAccount, uint256 initialBalance) public { - balances[initialAccount] = initialBalance; - totalSupply_ = initialBalance; - } - - // ERC223 compatible transfer function (except the name) - function transferERC223(address _to, uint256 _value, bytes _data) public - returns (bool success) - { - transfer(_to, _value); - bool isContract = false; - // solium-disable-next-line security/no-inline-assembly - assembly { - isContract := not(iszero(extcodesize(_to))) - } - if (isContract) { - ERC223ContractInterface receiver = ERC223ContractInterface(_to); - receiver.tokenFallback(msg.sender, _value, _data); - } - return true; - } -} diff --git a/contracts/mocks/ERC827TokenMock.sol b/contracts/mocks/ERC827TokenMock.sol deleted file mode 100644 index 1107a73e7..000000000 --- a/contracts/mocks/ERC827TokenMock.sol +++ /dev/null @@ -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; - } - -} diff --git a/contracts/mocks/FinalizableCrowdsaleImpl.sol b/contracts/mocks/FinalizableCrowdsaleImpl.sol deleted file mode 100644 index 82d0a5500..000000000 --- a/contracts/mocks/FinalizableCrowdsaleImpl.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/MintableToken.sol"; -import "../crowdsale/distribution/FinalizableCrowdsale.sol"; - - -contract FinalizableCrowdsaleImpl is FinalizableCrowdsale { - - function FinalizableCrowdsaleImpl ( - uint256 _openingTime, - uint256 _closingTime, - uint256 _rate, - address _wallet, - MintableToken _token - ) - public - Crowdsale(_rate, _wallet, _token) - TimedCrowdsale(_openingTime, _closingTime) - { - } - -} diff --git a/contracts/mocks/ForceEther.sol b/contracts/mocks/ForceEther.sol deleted file mode 100644 index 7bbbf85fa..000000000 --- a/contracts/mocks/ForceEther.sol +++ /dev/null @@ -1,16 +0,0 @@ -pragma solidity ^0.4.21; - - -// @title Force Ether into a contract. -// @notice even -// if the contract is not payable. -// @notice To use, construct the contract with the target as argument. -// @author Remco Bloemen -contract ForceEther { - - function ForceEther() public payable { } - - function destroyAndSend(address _recipient) public { - selfdestruct(_recipient); - } -} diff --git a/contracts/mocks/HasNoEtherTest.sol b/contracts/mocks/HasNoEtherTest.sol deleted file mode 100644 index bbf9dfdb4..000000000 --- a/contracts/mocks/HasNoEtherTest.sol +++ /dev/null @@ -1,12 +0,0 @@ -pragma solidity ^0.4.21; - -import "../../contracts/ownership/HasNoEther.sol"; - - -contract HasNoEtherTest is HasNoEther { - - // Constructor with explicit payable — should still fail - function HasNoEtherTest() public payable { - } - -} diff --git a/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol b/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol deleted file mode 100644 index ea1466122..000000000 --- a/contracts/mocks/IncreasingPriceCrowdsaleImpl.sol +++ /dev/null @@ -1,24 +0,0 @@ -pragma solidity ^0.4.21; - -import "../crowdsale/price/IncreasingPriceCrowdsale.sol"; -import "../math/SafeMath.sol"; - - -contract IncreasingPriceCrowdsaleImpl is IncreasingPriceCrowdsale { - - function IncreasingPriceCrowdsaleImpl ( - uint256 _openingTime, - uint256 _closingTime, - address _wallet, - ERC20 _token, - uint256 _initialRate, - uint256 _finalRate - ) - public - Crowdsale(_initialRate, _wallet, _token) - TimedCrowdsale(_openingTime, _closingTime) - IncreasingPriceCrowdsale(_initialRate, _finalRate) - { - } - -} diff --git a/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol b/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol deleted file mode 100644 index 7ac944d0b..000000000 --- a/contracts/mocks/IndividuallyCappedCrowdsaleImpl.sol +++ /dev/null @@ -1,19 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/ERC20.sol"; -import "../crowdsale/validation/IndividuallyCappedCrowdsale.sol"; - - -contract IndividuallyCappedCrowdsaleImpl is IndividuallyCappedCrowdsale { - - function IndividuallyCappedCrowdsaleImpl ( - uint256 _rate, - address _wallet, - ERC20 _token - ) - public - Crowdsale(_rate, _wallet, _token) - { - } - -} diff --git a/contracts/mocks/InsecureTargetBounty.sol b/contracts/mocks/InsecureTargetBounty.sol deleted file mode 100644 index 74bc531b2..000000000 --- a/contracts/mocks/InsecureTargetBounty.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma solidity ^0.4.21; - -import {Bounty, Target} from "../../contracts/Bounty.sol"; - - -contract InsecureTargetMock is Target { - function checkInvariant() public returns(bool) { - return false; - } -} - - -contract InsecureTargetBounty is Bounty { - function deployContract() internal returns (address) { - return new InsecureTargetMock(); - } -} diff --git a/contracts/mocks/LimitBalanceMock.sol b/contracts/mocks/LimitBalanceMock.sol deleted file mode 100644 index a5ed18c5c..000000000 --- a/contracts/mocks/LimitBalanceMock.sol +++ /dev/null @@ -1,13 +0,0 @@ -pragma solidity ^0.4.21; - - -import "../LimitBalance.sol"; - - -// mock class using LimitBalance -contract LimitBalanceMock is LimitBalance(1000) { - - function limitedDeposit() public payable limitedPayable { - } - -} diff --git a/contracts/mocks/MathMock.sol b/contracts/mocks/MathMock.sol deleted file mode 100644 index c2c9f3fba..000000000 --- a/contracts/mocks/MathMock.sol +++ /dev/null @@ -1,26 +0,0 @@ -pragma solidity ^0.4.21; - - -import "../../contracts/math/Math.sol"; - - -contract MathMock { - uint64 public result64; - uint256 public result256; - - function max64(uint64 a, uint64 b) public { - result64 = Math.max64(a, b); - } - - function min64(uint64 a, uint64 b) public { - result64 = Math.min64(a, b); - } - - function max256(uint256 a, uint256 b) public { - result256 = Math.max256(a, b); - } - - function min256(uint256 a, uint256 b) public { - result256 = Math.min256(a, b); - } -} diff --git a/contracts/mocks/MerkleProofWrapper.sol b/contracts/mocks/MerkleProofWrapper.sol deleted file mode 100644 index aa830e63a..000000000 --- a/contracts/mocks/MerkleProofWrapper.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity ^0.4.21; - -import { MerkleProof } from "../MerkleProof.sol"; - - -contract MerkleProofWrapper { - - function verifyProof(bytes32[] _proof, bytes32 _root, bytes32 _leaf) public pure returns (bool) { - return MerkleProof.verifyProof(_proof, _root, _leaf); - } -} diff --git a/contracts/mocks/MessageHelper.sol b/contracts/mocks/MessageHelper.sol deleted file mode 100644 index b44b6496a..000000000 --- a/contracts/mocks/MessageHelper.sol +++ /dev/null @@ -1,25 +0,0 @@ -pragma solidity ^0.4.21; - - -contract MessageHelper { - - event Show(bytes32 b32, uint256 number, string text); - - function showMessage( bytes32 message, uint256 number, string text ) public returns (bool) { - emit Show(message, number, text); - return true; - } - - function fail() public { - require(false); - } - - function call(address to, bytes data) public returns (bool) { - // solium-disable-next-line security/no-low-level-calls - if (to.call(data)) - return true; - else - return false; - } - -} diff --git a/contracts/mocks/MintedCrowdsaleImpl.sol b/contracts/mocks/MintedCrowdsaleImpl.sol deleted file mode 100644 index f6999b021..000000000 --- a/contracts/mocks/MintedCrowdsaleImpl.sol +++ /dev/null @@ -1,19 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/MintableToken.sol"; -import "../crowdsale/emission/MintedCrowdsale.sol"; - - -contract MintedCrowdsaleImpl is MintedCrowdsale { - - function MintedCrowdsaleImpl ( - uint256 _rate, - address _wallet, - MintableToken _token - ) - public - Crowdsale(_rate, _wallet, _token) - { - } - -} diff --git a/contracts/mocks/PostDeliveryCrowdsaleImpl.sol b/contracts/mocks/PostDeliveryCrowdsaleImpl.sol deleted file mode 100644 index 09db38067..000000000 --- a/contracts/mocks/PostDeliveryCrowdsaleImpl.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/ERC20.sol"; -import "../crowdsale/distribution/PostDeliveryCrowdsale.sol"; - - -contract PostDeliveryCrowdsaleImpl is PostDeliveryCrowdsale { - - function PostDeliveryCrowdsaleImpl ( - uint256 _openingTime, - uint256 _closingTime, - uint256 _rate, - address _wallet, - ERC20 _token - ) - public - TimedCrowdsale(_openingTime, _closingTime) - Crowdsale(_rate, _wallet, _token) - { - } - -} diff --git a/contracts/mocks/PullPaymentMock.sol b/contracts/mocks/PullPaymentMock.sol deleted file mode 100644 index fb4a1231b..000000000 --- a/contracts/mocks/PullPaymentMock.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma solidity ^0.4.21; - - -import "../payment/PullPayment.sol"; - - -// mock class using PullPayment -contract PullPaymentMock is PullPayment { - - function PullPaymentMock() public payable { } - - // test helper function to call asyncSend - function callSend(address dest, uint256 amount) public { - asyncSend(dest, amount); - } - -} diff --git a/contracts/mocks/RBACMock.sol b/contracts/mocks/RBACMock.sol deleted file mode 100644 index 7dfa2a985..000000000 --- a/contracts/mocks/RBACMock.sol +++ /dev/null @@ -1,69 +0,0 @@ -pragma solidity ^0.4.21; - -import "../ownership/rbac/RBACWithAdmin.sol"; - - -contract RBACMock is RBACWithAdmin { - - string constant ROLE_ADVISOR = "advisor"; - - modifier onlyAdminOrAdvisor() - { - require( - hasRole(msg.sender, ROLE_ADMIN) || - hasRole(msg.sender, ROLE_ADVISOR) - ); - _; - } - - function RBACMock(address[] _advisors) - public - { - addRole(msg.sender, ROLE_ADVISOR); - - for (uint256 i = 0; i < _advisors.length; i++) { - addRole(_advisors[i], ROLE_ADVISOR); - } - } - - function onlyAdminsCanDoThis() - onlyAdmin - view - external - { - } - - function onlyAdvisorsCanDoThis() - onlyRole(ROLE_ADVISOR) - view - external - { - } - - function eitherAdminOrAdvisorCanDoThis() - onlyAdminOrAdvisor - view - external - { - } - - function nobodyCanDoThis() - onlyRole("unknown") - view - external - { - } - - // admins can remove advisor's role - function removeAdvisor(address _addr) - onlyAdmin - public - { - // revert if the user isn't an advisor - // (perhaps you want to soft-fail here instead?) - checkRole(_addr, ROLE_ADVISOR); - - // remove the advisor's role - removeRole(_addr, ROLE_ADVISOR); - } -} diff --git a/contracts/mocks/ReentrancyAttack.sol b/contracts/mocks/ReentrancyAttack.sol deleted file mode 100644 index 5caebb1d6..000000000 --- a/contracts/mocks/ReentrancyAttack.sol +++ /dev/null @@ -1,11 +0,0 @@ -pragma solidity ^0.4.21; - - -contract ReentrancyAttack { - - function callSender(bytes4 data) public { - // solium-disable-next-line security/no-low-level-calls - require(msg.sender.call(data)); - } - -} diff --git a/contracts/mocks/ReentrancyMock.sol b/contracts/mocks/ReentrancyMock.sol deleted file mode 100644 index 72f4a284f..000000000 --- a/contracts/mocks/ReentrancyMock.sol +++ /dev/null @@ -1,46 +0,0 @@ -pragma solidity ^0.4.21; - -import "../ReentrancyGuard.sol"; -import "./ReentrancyAttack.sol"; - - -contract ReentrancyMock is ReentrancyGuard { - - uint256 public counter; - - function ReentrancyMock() public { - counter = 0; - } - - function callback() external nonReentrant { - count(); - } - - function countLocalRecursive(uint256 n) public nonReentrant { - if (n > 0) { - count(); - countLocalRecursive(n - 1); - } - } - - function countThisRecursive(uint256 n) public nonReentrant { - bytes4 func = bytes4(keccak256("countThisRecursive(uint256)")); - if (n > 0) { - count(); - // solium-disable-next-line security/no-low-level-calls - bool result = address(this).call(func, n - 1); - require(result == true); - } - } - - function countAndCall(ReentrancyAttack attacker) public nonReentrant { - count(); - bytes4 func = bytes4(keccak256("callback()")); - attacker.callSender(func); - } - - function count() private { - counter += 1; - } - -} diff --git a/contracts/mocks/RefundableCrowdsaleImpl.sol b/contracts/mocks/RefundableCrowdsaleImpl.sol deleted file mode 100644 index 08ee14512..000000000 --- a/contracts/mocks/RefundableCrowdsaleImpl.sol +++ /dev/null @@ -1,24 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/MintableToken.sol"; -import "../crowdsale/distribution/RefundableCrowdsale.sol"; - - -contract RefundableCrowdsaleImpl is RefundableCrowdsale { - - function RefundableCrowdsaleImpl ( - uint256 _openingTime, - uint256 _closingTime, - uint256 _rate, - address _wallet, - MintableToken _token, - uint256 _goal - ) - public - Crowdsale(_rate, _wallet, _token) - TimedCrowdsale(_openingTime, _closingTime) - RefundableCrowdsale(_goal) - { - } - -} diff --git a/contracts/mocks/SecureTargetBounty.sol b/contracts/mocks/SecureTargetBounty.sol deleted file mode 100644 index 1b69176a1..000000000 --- a/contracts/mocks/SecureTargetBounty.sol +++ /dev/null @@ -1,17 +0,0 @@ -pragma solidity ^0.4.21; - -import {Bounty, Target} from "../../contracts/Bounty.sol"; - - -contract SecureTargetMock is Target { - function checkInvariant() public returns(bool) { - return true; - } -} - - -contract SecureTargetBounty is Bounty { - function deployContract() internal returns (address) { - return new SecureTargetMock(); - } -} diff --git a/contracts/mocks/TimedCrowdsaleImpl.sol b/contracts/mocks/TimedCrowdsaleImpl.sol deleted file mode 100644 index b66566239..000000000 --- a/contracts/mocks/TimedCrowdsaleImpl.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/ERC20.sol"; -import "../crowdsale/validation/TimedCrowdsale.sol"; - - -contract TimedCrowdsaleImpl is TimedCrowdsale { - - function TimedCrowdsaleImpl ( - uint256 _openingTime, - uint256 _closingTime, - uint256 _rate, - address _wallet, - ERC20 _token - ) - public - Crowdsale(_rate, _wallet, _token) - TimedCrowdsale(_openingTime, _closingTime) - { - } - -} diff --git a/contracts/mocks/WhitelistMock.sol b/contracts/mocks/WhitelistMock.sol deleted file mode 100644 index 9c50405b0..000000000 --- a/contracts/mocks/WhitelistMock.sol +++ /dev/null @@ -1,14 +0,0 @@ -pragma solidity ^0.4.21; - -import "../ownership/Whitelist.sol"; - - -contract WhitelistMock is Whitelist { - - function onlyWhitelistedCanDoThis() - onlyWhitelisted - view - external - { - } -} diff --git a/contracts/mocks/WhitelistedCrowdsaleImpl.sol b/contracts/mocks/WhitelistedCrowdsaleImpl.sol deleted file mode 100644 index 16dc45434..000000000 --- a/contracts/mocks/WhitelistedCrowdsaleImpl.sol +++ /dev/null @@ -1,19 +0,0 @@ -pragma solidity ^0.4.21; - -import "../token/ERC20/ERC20.sol"; -import "../crowdsale/validation/WhitelistedCrowdsale.sol"; - - -contract WhitelistedCrowdsaleImpl is WhitelistedCrowdsale { - - function WhitelistedCrowdsaleImpl ( - uint256 _rate, - address _wallet, - ERC20 _token - ) - public - Crowdsale(_rate, _wallet, _token) - { - } - -} diff --git a/contracts/ownership/CanReclaimToken.sol b/contracts/ownership/CanReclaimToken.sol deleted file mode 100644 index 474baae4e..000000000 --- a/contracts/ownership/CanReclaimToken.sol +++ /dev/null @@ -1,26 +0,0 @@ -pragma solidity ^0.4.21; - -import "./Ownable.sol"; -import "../token/ERC20/ERC20Basic.sol"; -import "../token/ERC20/SafeERC20.sol"; - - -/** - * @title Contracts that should be able to recover tokens - * @author SylTi - * @dev This allow a contract to recover any ERC20 token received in a contract by transferring the balance to the contract owner. - * This will prevent any accidental loss of tokens. - */ -contract CanReclaimToken is Ownable { - using SafeERC20 for ERC20Basic; - - /** - * @dev Reclaim all ERC20Basic compatible tokens - * @param token ERC20Basic The address of the token contract - */ - function reclaimToken(ERC20Basic token) external onlyOwner { - uint256 balance = token.balanceOf(this); - token.safeTransfer(owner, balance); - } - -} diff --git a/contracts/ownership/Claimable.sol b/contracts/ownership/Claimable.sol deleted file mode 100644 index f1ebd76dd..000000000 --- a/contracts/ownership/Claimable.sol +++ /dev/null @@ -1,39 +0,0 @@ -pragma solidity ^0.4.21; - - -import "./Ownable.sol"; - - -/** - * @title Claimable - * @dev Extension for the Ownable contract, where the ownership needs to be claimed. - * This allows the new owner to accept the transfer. - */ -contract Claimable is Ownable { - address public pendingOwner; - - /** - * @dev Modifier throws if called by any account other than the pendingOwner. - */ - modifier onlyPendingOwner() { - require(msg.sender == pendingOwner); - _; - } - - /** - * @dev Allows the current owner to set the pendingOwner address. - * @param newOwner The address to transfer ownership to. - */ - function transferOwnership(address newOwner) onlyOwner public { - pendingOwner = newOwner; - } - - /** - * @dev Allows the pendingOwner address to finalize the transfer. - */ - function claimOwnership() onlyPendingOwner public { - emit OwnershipTransferred(owner, pendingOwner); - owner = pendingOwner; - pendingOwner = address(0); - } -} diff --git a/contracts/ownership/Contactable.sol b/contracts/ownership/Contactable.sol deleted file mode 100644 index adeeaa02a..000000000 --- a/contracts/ownership/Contactable.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.21; - -import "./Ownable.sol"; - - -/** - * @title Contactable token - * @dev Basic version of a contactable contract, allowing the owner to provide a string with their - * contact information. - */ -contract Contactable is Ownable { - - string public contactInformation; - - /** - * @dev Allows the owner to set a string with their contact information. - * @param info The contact information to attach to the contract. - */ - function setContactInformation(string info) onlyOwner public { - contactInformation = info; - } -} diff --git a/contracts/ownership/DelayedClaimable.sol b/contracts/ownership/DelayedClaimable.sol deleted file mode 100644 index f221afb56..000000000 --- a/contracts/ownership/DelayedClaimable.sol +++ /dev/null @@ -1,40 +0,0 @@ -pragma solidity ^0.4.21; - -import "./Claimable.sol"; - - -/** - * @title DelayedClaimable - * @dev Extension for the Claimable contract, where the ownership needs to be claimed before/after - * a certain block number. - */ -contract DelayedClaimable is Claimable { - - uint256 public end; - uint256 public start; - - /** - * @dev Used to specify the time period during which a pending - * owner can claim ownership. - * @param _start The earliest time ownership can be claimed. - * @param _end The latest time ownership can be claimed. - */ - function setLimits(uint256 _start, uint256 _end) onlyOwner public { - require(_start <= _end); - end = _end; - start = _start; - } - - /** - * @dev Allows the pendingOwner address to finalize the transfer, as long as it is called within - * the specified start and end time. - */ - function claimOwnership() onlyPendingOwner public { - require((block.number <= end) && (block.number >= start)); - emit OwnershipTransferred(owner, pendingOwner); - owner = pendingOwner; - pendingOwner = address(0); - end = 0; - } - -} diff --git a/contracts/ownership/HasNoContracts.sol b/contracts/ownership/HasNoContracts.sol deleted file mode 100644 index 19e8d0ff9..000000000 --- a/contracts/ownership/HasNoContracts.sol +++ /dev/null @@ -1,22 +0,0 @@ -pragma solidity ^0.4.21; - -import "./Ownable.sol"; - - -/** - * @title Contracts that should not own Contracts - * @author Remco Bloemen - * @dev Should contracts (anything Ownable) end up being owned by this contract, it allows the owner - * of this contract to reclaim ownership of the contracts. - */ -contract HasNoContracts is Ownable { - - /** - * @dev Reclaim ownership of Ownable contracts - * @param contractAddr The address of the Ownable to be reclaimed. - */ - function reclaimContract(address contractAddr) external onlyOwner { - Ownable contractInst = Ownable(contractAddr); - contractInst.transferOwnership(owner); - } -} diff --git a/contracts/ownership/HasNoEther.sol b/contracts/ownership/HasNoEther.sol deleted file mode 100644 index 8808e2fc3..000000000 --- a/contracts/ownership/HasNoEther.sol +++ /dev/null @@ -1,42 +0,0 @@ -pragma solidity ^0.4.21; - -import "./Ownable.sol"; - - -/** - * @title Contracts that should not own Ether - * @author Remco Bloemen - * @dev This tries to block incoming ether to prevent accidental loss of Ether. Should Ether end up - * in the contract, it will allow the owner to reclaim this ether. - * @notice Ether can still be sent to this contract by: - * calling functions labeled `payable` - * `selfdestruct(contract_address)` - * mining directly to the contract address - */ -contract HasNoEther is Ownable { - - /** - * @dev Constructor that rejects incoming Ether - * @dev 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 - * constructor. By doing it this way we prevent a payable constructor from working. Alternatively - * we could use assembly to access msg.value. - */ - function HasNoEther() public payable { - require(msg.value == 0); - } - - /** - * @dev Disallows direct send by settings a default function without the `payable` flag. - */ - function() external { - } - - /** - * @dev Transfer all Ether held by the contract to the owner. - */ - function reclaimEther() external onlyOwner { - // solium-disable-next-line security/no-send - assert(owner.send(address(this).balance)); - } -} diff --git a/contracts/ownership/HasNoTokens.sol b/contracts/ownership/HasNoTokens.sol deleted file mode 100644 index eaede63ae..000000000 --- a/contracts/ownership/HasNoTokens.sol +++ /dev/null @@ -1,28 +0,0 @@ -pragma solidity ^0.4.21; - -import "./CanReclaimToken.sol"; - - -/** - * @title Contracts that should not own Tokens - * @author Remco Bloemen - * @dev This blocks incoming ERC223 tokens to prevent accidental loss of tokens. - * Should tokens (any ERC20Basic compatible) end up in the contract, it allows the - * owner to reclaim the tokens. - */ -contract HasNoTokens is CanReclaimToken { - - /** - * @dev Reject all ERC223 compatible tokens - * @param from_ address The address that is transferring the tokens - * @param value_ uint256 the amount of the specified token - * @param data_ Bytes The data passed from the caller. - */ - function tokenFallback(address from_, uint256 value_, bytes data_) external { - from_; - value_; - data_; - revert(); - } - -} diff --git a/contracts/ownership/Heritable.sol b/contracts/ownership/Heritable.sol deleted file mode 100644 index 3b592a0a5..000000000 --- a/contracts/ownership/Heritable.sol +++ /dev/null @@ -1,117 +0,0 @@ -pragma solidity ^0.4.21; - - -import "./Ownable.sol"; - - -/** - * @title Heritable - * @dev The Heritable contract provides ownership transfer capabilities, in the - * case that the current owner stops "heartbeating". Only the heir can pronounce the - * owner's death. - */ -contract Heritable is Ownable { - address private heir_; - - // Time window the owner has to notify they are alive. - uint256 private heartbeatTimeout_; - - // Timestamp of the owner's death, as pronounced by the heir. - uint256 private timeOfDeath_; - - event HeirChanged(address indexed owner, address indexed newHeir); - event OwnerHeartbeated(address indexed owner); - event OwnerProclaimedDead(address indexed owner, address indexed heir, uint256 timeOfDeath); - event HeirOwnershipClaimed(address indexed previousOwner, address indexed newOwner); - - - /** - * @dev Throw an exception if called by any account other than the heir's. - */ - modifier onlyHeir() { - require(msg.sender == heir_); - _; - } - - - /** - * @notice Create a new Heritable Contract with heir address 0x0. - * @param _heartbeatTimeout time available for the owner to notify they are alive, - * before the heir can take ownership. - */ - function Heritable(uint256 _heartbeatTimeout) public { - setHeartbeatTimeout(_heartbeatTimeout); - } - - function setHeir(address newHeir) public onlyOwner { - require(newHeir != owner); - heartbeat(); - emit HeirChanged(owner, newHeir); - heir_ = newHeir; - } - - /** - * @dev Use these getter functions to access the internal variables in - * an inherited contract. - */ - function heir() public view returns(address) { - return heir_; - } - - function heartbeatTimeout() public view returns(uint256) { - return heartbeatTimeout_; - } - - function timeOfDeath() public view returns(uint256) { - return timeOfDeath_; - } - - /** - * @dev set heir = 0x0 - */ - function removeHeir() public onlyOwner { - heartbeat(); - heir_ = 0; - } - - /** - * @dev Heir can pronounce the owners death. To claim the ownership, they will - * have to wait for `heartbeatTimeout` seconds. - */ - function proclaimDeath() public onlyHeir { - require(ownerLives()); - emit OwnerProclaimedDead(owner, heir_, timeOfDeath_); - // solium-disable-next-line security/no-block-members - timeOfDeath_ = block.timestamp; - } - - /** - * @dev Owner can send a heartbeat if they were mistakenly pronounced dead. - */ - function heartbeat() public onlyOwner { - emit OwnerHeartbeated(owner); - timeOfDeath_ = 0; - } - - /** - * @dev Allows heir to transfer ownership only if heartbeat has timed out. - */ - function claimHeirOwnership() public onlyHeir { - require(!ownerLives()); - // solium-disable-next-line security/no-block-members - require(block.timestamp >= timeOfDeath_ + heartbeatTimeout_); - emit OwnershipTransferred(owner, heir_); - emit HeirOwnershipClaimed(owner, heir_); - owner = heir_; - timeOfDeath_ = 0; - } - - function setHeartbeatTimeout(uint256 newHeartbeatTimeout) internal onlyOwner { - require(ownerLives()); - heartbeatTimeout_ = newHeartbeatTimeout; - } - - function ownerLives() internal view returns (bool) { - return timeOfDeath_ == 0; - } -} diff --git a/contracts/ownership/NoOwner.sol b/contracts/ownership/NoOwner.sol deleted file mode 100644 index 9b4c7c93b..000000000 --- a/contracts/ownership/NoOwner.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma solidity ^0.4.21; - -import "./HasNoEther.sol"; -import "./HasNoTokens.sol"; -import "./HasNoContracts.sol"; - - -/** - * @title Base contract for contracts that should not own things. - * @author Remco Bloemen - * @dev Solves a class of errors where a contract accidentally becomes owner of Ether, Tokens or - * Owned contracts. See respective base contracts for details. - */ -contract NoOwner is HasNoEther, HasNoTokens, HasNoContracts { -} diff --git a/contracts/ownership/Whitelist.sol b/contracts/ownership/Whitelist.sol deleted file mode 100644 index 4d6e2a70a..000000000 --- a/contracts/ownership/Whitelist.sol +++ /dev/null @@ -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; - } - } - } - -} diff --git a/contracts/ownership/rbac/RBAC.sol b/contracts/ownership/rbac/RBAC.sol deleted file mode 100644 index 998d334f8..000000000 --- a/contracts/ownership/rbac/RBAC.sol +++ /dev/null @@ -1,108 +0,0 @@ -pragma solidity ^0.4.21; - -import "./Roles.sol"; - - -/** - * @title RBAC (Role-Based Access Control) - * @author Matt Condon (@Shrugs) - * @dev Stores and provides setters and getters for roles and addresses. - * @dev Supports unlimited numbers of roles and addresses. - * @dev See //contracts/mocks/RBACMock.sol for an example of usage. - * 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. - * It's also recommended that you define constants in the contract, like ROLE_ADMIN below, - * to avoid typos. - */ -contract RBAC { - using Roles for Roles.Role; - - mapping (string => Roles.Role) private roles; - - event RoleAdded(address addr, string roleName); - event RoleRemoved(address addr, string roleName); - - /** - * @dev reverts if addr does not have role - * @param addr address - * @param roleName the name of the role - * // reverts - */ - function checkRole(address addr, string roleName) - view - public - { - roles[roleName].check(addr); - } - - /** - * @dev determine if addr has role - * @param addr address - * @param roleName the name of the role - * @return bool - */ - function hasRole(address addr, string roleName) - view - public - returns (bool) - { - return roles[roleName].has(addr); - } - - /** - * @dev add a role to an address - * @param addr address - * @param roleName the name of the role - */ - function addRole(address addr, string roleName) - internal - { - roles[roleName].add(addr); - emit RoleAdded(addr, roleName); - } - - /** - * @dev remove a role from an address - * @param addr address - * @param roleName the name of the role - */ - function removeRole(address addr, string roleName) - internal - { - roles[roleName].remove(addr); - emit RoleRemoved(addr, roleName); - } - - /** - * @dev modifier to scope access to a single role (uses msg.sender as addr) - * @param roleName the name of the role - * // reverts - */ - modifier onlyRole(string roleName) - { - checkRole(msg.sender, roleName); - _; - } - - /** - * @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 - * // reverts - * - * @TODO - when solidity supports dynamic arrays as arguments to modifiers, provide this - * see: https://github.com/ethereum/solidity/issues/2467 - */ - // modifier onlyRoles(string[] roleNames) { - // bool hasAnyRole = false; - // for (uint8 i = 0; i < roleNames.length; i++) { - // if (hasRole(msg.sender, roleNames[i])) { - // hasAnyRole = true; - // break; - // } - // } - - // require(hasAnyRole); - - // _; - // } -} diff --git a/contracts/ownership/rbac/RBACWithAdmin.sol b/contracts/ownership/rbac/RBACWithAdmin.sol deleted file mode 100644 index 90eb187a1..000000000 --- a/contracts/ownership/rbac/RBACWithAdmin.sol +++ /dev/null @@ -1,60 +0,0 @@ -pragma solidity ^0.4.21; - -import "./RBAC.sol"; - - -/** - * @title RBACWithAdmin - * @author Matt Condon (@Shrugs) - * @dev It's recommended that you define constants in the contract, - * @dev like ROLE_ADMIN below, to avoid typos. - */ -contract RBACWithAdmin is RBAC { - /** - * A constant role name for indicating admins. - */ - string public constant ROLE_ADMIN = "admin"; - - /** - * @dev modifier to scope access to admins - * // reverts - */ - modifier onlyAdmin() - { - checkRole(msg.sender, ROLE_ADMIN); - _; - } - - /** - * @dev constructor. Sets msg.sender as admin by default - */ - function RBACWithAdmin() - public - { - addRole(msg.sender, ROLE_ADMIN); - } - - /** - * @dev add a role to an address - * @param addr address - * @param roleName the name of the role - */ - function adminAddRole(address addr, string roleName) - onlyAdmin - public - { - addRole(addr, roleName); - } - - /** - * @dev remove a role from an address - * @param addr address - * @param roleName the name of the role - */ - function adminRemoveRole(address addr, string roleName) - onlyAdmin - public - { - removeRole(addr, roleName); - } -} diff --git a/contracts/ownership/rbac/Roles.sol b/contracts/ownership/rbac/Roles.sol deleted file mode 100644 index c9dbd73af..000000000 --- a/contracts/ownership/rbac/Roles.sol +++ /dev/null @@ -1,55 +0,0 @@ -pragma solidity ^0.4.21; - - -/** - * @title Roles - * @author Francisco Giordano (@frangio) - * @dev Library for managing addresses assigned to a Role. - * See RBAC.sol for example usage. - */ -library Roles { - struct Role { - mapping (address => bool) bearer; - } - - /** - * @dev give an address access to this role - */ - function add(Role storage role, address addr) - internal - { - role.bearer[addr] = true; - } - - /** - * @dev remove an address' access to this role - */ - function remove(Role storage role, address addr) - internal - { - role.bearer[addr] = false; - } - - /** - * @dev check if an address has this role - * // reverts - */ - function check(Role storage role, address addr) - view - internal - { - require(has(role, addr)); - } - - /** - * @dev check if an address has this role - * @return bool - */ - function has(Role storage role, address addr) - view - internal - returns (bool) - { - return role.bearer[addr]; - } -} diff --git a/contracts/payment/PullPayment.sol b/contracts/payment/PullPayment.sol deleted file mode 100644 index 030e971b3..000000000 --- a/contracts/payment/PullPayment.sol +++ /dev/null @@ -1,43 +0,0 @@ -pragma solidity ^0.4.21; - - -import "../math/SafeMath.sol"; - - -/** - * @title PullPayment - * @dev Base contract supporting async send for pull payments. Inherit from this - * contract and use asyncSend instead of send or transfer. - */ -contract PullPayment { - using SafeMath for uint256; - - mapping(address => uint256) public payments; - uint256 public totalPayments; - - /** - * @dev Withdraw accumulated balance, called by payee. - */ - function withdrawPayments() public { - address payee = msg.sender; - uint256 payment = payments[payee]; - - require(payment != 0); - require(address(this).balance >= payment); - - totalPayments = totalPayments.sub(payment); - payments[payee] = 0; - - payee.transfer(payment); - } - - /** - * @dev Called by the payer to store the sent amount as credit to be pulled. - * @param dest The destination address of the funds. - * @param amount The amount to transfer. - */ - function asyncSend(address dest, uint256 amount) internal { - payments[dest] = payments[dest].add(amount); - totalPayments = totalPayments.add(amount); - } -} diff --git a/contracts/payment/SplitPayment.sol b/contracts/payment/SplitPayment.sol deleted file mode 100644 index 019eba694..000000000 --- a/contracts/payment/SplitPayment.sol +++ /dev/null @@ -1,71 +0,0 @@ -pragma solidity ^0.4.21; - -import "../math/SafeMath.sol"; - - -/** - * @title SplitPayment - * @dev Base contract that supports multiple payees claiming funds sent to this contract - * according to the proportion they own. - */ -contract SplitPayment { - using SafeMath for uint256; - - uint256 public totalShares = 0; - uint256 public totalReleased = 0; - - mapping(address => uint256) public shares; - mapping(address => uint256) public released; - address[] public payees; - - /** - * @dev Constructor - */ - function SplitPayment(address[] _payees, uint256[] _shares) public payable { - require(_payees.length == _shares.length); - - for (uint256 i = 0; i < _payees.length; i++) { - addPayee(_payees[i], _shares[i]); - } - } - - /** - * @dev payable fallback - */ - function () public payable {} - - /** - * @dev Claim your share of the balance. - */ - function claim() public { - address payee = msg.sender; - - require(shares[payee] > 0); - - uint256 totalReceived = address(this).balance.add(totalReleased); - uint256 payment = totalReceived.mul(shares[payee]).div(totalShares).sub(released[payee]); - - require(payment != 0); - require(address(this).balance >= payment); - - released[payee] = released[payee].add(payment); - totalReleased = totalReleased.add(payment); - - payee.transfer(payment); - } - - /** - * @dev Add a new payee to the contract. - * @param _payee The address of the payee to add. - * @param _shares The number of shares owned by the payee. - */ - function addPayee(address _payee, uint256 _shares) internal { - require(_payee != address(0)); - require(_shares > 0); - require(shares[_payee] == 0); - - payees.push(_payee); - shares[_payee] = _shares; - totalShares = totalShares.add(_shares); - } -} diff --git a/contracts/token/ERC20/CappedToken.sol b/contracts/token/ERC20/CappedToken.sol deleted file mode 100644 index 47cd4fb4d..000000000 --- a/contracts/token/ERC20/CappedToken.sol +++ /dev/null @@ -1,31 +0,0 @@ -pragma solidity ^0.4.21; - -import "./MintableToken.sol"; - - -/** - * @title Capped token - * @dev Mintable token with a token cap. - */ -contract CappedToken is MintableToken { - - uint256 public cap; - - function CappedToken(uint256 _cap) public { - require(_cap > 0); - cap = _cap; - } - - /** - * @dev Function to mint tokens - * @param _to The address that will receive the minted tokens. - * @param _amount The amount of tokens to mint. - * @return A boolean that indicates if the operation was successful. - */ - function mint(address _to, uint256 _amount) onlyOwner canMint public returns (bool) { - require(totalSupply_.add(_amount) <= cap); - - return super.mint(_to, _amount); - } - -} diff --git a/contracts/token/ERC721/DeprecatedERC721.sol b/contracts/token/ERC721/DeprecatedERC721.sol deleted file mode 100644 index fa9d9a3d3..000000000 --- a/contracts/token/ERC721/DeprecatedERC721.sol +++ /dev/null @@ -1,15 +0,0 @@ -pragma solidity ^0.4.21; - -import "./ERC721.sol"; - - -/** - * @title ERC-721 methods shipped in OpenZeppelin v1.7.0, removed in the latest version of the standard - * @dev Only use this interface for compatibility with previously deployed contracts - * @dev Use ERC721 for interacting with new contracts which are standard-compliant - */ -contract DeprecatedERC721 is ERC721 { - function takeOwnership(uint256 _tokenId) public; - function transfer(address _to, uint256 _tokenId) public; - function tokensOf(address _owner) public view returns (uint256[]); -} diff --git a/contracts/token/ERC827/ERC827.sol b/contracts/token/ERC827/ERC827.sol deleted file mode 100644 index a0ee18036..000000000 --- a/contracts/token/ERC827/ERC827.sol +++ /dev/null @@ -1,25 +0,0 @@ -pragma solidity ^0.4.21; - - -import "../ERC20/ERC20.sol"; - - -/** - * @title ERC827 interface, an extension of ERC20 token standard - * - * @dev Interface of a ERC827 token, following the ERC20 standard with extra - * @dev methods to transfer value and data and execute calls in transfers and - * @dev approvals. - */ -contract ERC827 is ERC20 { - function approve(address _spender, uint256 _value, bytes _data) public returns (bool); - function transfer(address _to, uint256 _value, bytes _data) public returns (bool); - function transferFrom( - address _from, - address _to, - uint256 _value, - bytes _data - ) - public - returns (bool); -} diff --git a/contracts/token/ERC827/ERC827Token.sol b/contracts/token/ERC827/ERC827Token.sol deleted file mode 100644 index 28dbfceea..000000000 --- a/contracts/token/ERC827/ERC827Token.sol +++ /dev/null @@ -1,139 +0,0 @@ -/* solium-disable security/no-low-level-calls */ - -pragma solidity ^0.4.21; - -import "./ERC827.sol"; -import "../ERC20/StandardToken.sol"; - - -/** - * @title ERC827, an extension of ERC20 token standard - * - * @dev Implementation the ERC827, following the ERC20 standard with extra - * @dev methods to transfer value and data and execute calls in transfers and - * @dev approvals. - * - * @dev Uses OpenZeppelin StandardToken. - */ -contract ERC827Token is ERC827, StandardToken { - - /** - * @dev Addition to ERC20 token methods. It allows to - * @dev approve the transfer of value and execute a call with the sent data. - * - * @dev Beware that changing an allowance with this method brings the risk that - * @dev someone may use both the old and the new allowance by unfortunate - * @dev transaction ordering. One possible solution to mitigate this race condition - * @dev is to first reduce the spender's allowance to 0 and set the desired value - * @dev afterwards: - * @dev https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - * - * @param _spender The address that will spend the funds. - * @param _value The amount of tokens to be spent. - * @param _data ABI-encoded contract call to call `_to` address. - * - * @return true if the call function was executed successfully - */ - function approve(address _spender, uint256 _value, bytes _data) public returns (bool) { - require(_spender != address(this)); - - super.approve(_spender, _value); - - require(_spender.call(_data)); - - return true; - } - - /** - * @dev Addition to ERC20 token methods. Transfer tokens to a specified - * @dev address and execute a call with the sent data on the same transaction - * - * @param _to address The address which you want to transfer to - * @param _value uint256 the amout of tokens to be transfered - * @param _data ABI-encoded contract call to call `_to` address. - * - * @return true if the call function was executed successfully - */ - function transfer(address _to, uint256 _value, bytes _data) public returns (bool) { - require(_to != address(this)); - - super.transfer(_to, _value); - - require(_to.call(_data)); - return true; - } - - /** - * @dev Addition to ERC20 token methods. Transfer tokens from one address to - * @dev another and make a contract call on the same transaction - * - * @param _from The address which you want to send tokens from - * @param _to The address which you want to transfer to - * @param _value The amout of tokens to be transferred - * @param _data ABI-encoded contract call to call `_to` address. - * - * @return true if the call function was executed successfully - */ - function transferFrom( - address _from, - address _to, - uint256 _value, - bytes _data - ) - public returns (bool) - { - require(_to != address(this)); - - super.transferFrom(_from, _to, _value); - - require(_to.call(_data)); - return true; - } - - /** - * @dev Addition to StandardToken methods. Increase the amount of tokens that - * @dev an owner allowed to a spender and execute a call with the sent data. - * - * @dev approve should be called when allowed[_spender] == 0. To increment - * @dev allowed value is better to use this function to avoid 2 calls (and wait until - * @dev the first transaction is mined) - * @dev From MonolithDAO Token.sol - * - * @param _spender The address which will spend the funds. - * @param _addedValue The amount of tokens to increase the allowance by. - * @param _data ABI-encoded contract call to call `_spender` address. - */ - function increaseApproval(address _spender, uint _addedValue, bytes _data) public returns (bool) { - require(_spender != address(this)); - - super.increaseApproval(_spender, _addedValue); - - require(_spender.call(_data)); - - return true; - } - - /** - * @dev Addition to StandardToken methods. Decrease the amount of tokens that - * @dev an owner allowed to a spender and execute a call with the sent data. - * - * @dev approve should be called when allowed[_spender] == 0. To decrement - * @dev allowed value is better to use this function to avoid 2 calls (and wait until - * @dev the first transaction is mined) - * @dev From MonolithDAO Token.sol - * - * @param _spender The address which will spend the funds. - * @param _subtractedValue The amount of tokens to decrease the allowance by. - * @param _data ABI-encoded contract call to call `_spender` address. - */ - function decreaseApproval(address _spender, uint _subtractedValue, bytes _data) public returns (bool) { - require(_spender != address(this)); - - super.decreaseApproval(_spender, _subtractedValue); - - require(_spender.call(_data)); - - return true; - } - -} diff --git a/test/Bounty.test.js b/test/Bounty.test.js deleted file mode 100644 index b440f399c..000000000 --- a/test/Bounty.test.js +++ /dev/null @@ -1,111 +0,0 @@ - -let sendReward = function (sender, receiver, value) { - web3.eth.sendTransaction({ - from: sender, - to: receiver, - value: value, - }); -}; -var SecureTargetBounty = artifacts.require('SecureTargetBounty'); -var InsecureTargetBounty = artifacts.require('InsecureTargetBounty'); - -function awaitEvent (event, handler) { - return new Promise((resolve, reject) => { - function wrappedHandler (...args) { - Promise.resolve(handler(...args)).then(resolve).catch(reject); - } - - event.watch(wrappedHandler); - }); -} - -contract('Bounty', function (accounts) { - it('sets reward', async function () { - let owner = accounts[0]; - let reward = web3.toWei(1, 'ether'); - let bounty = await SecureTargetBounty.new(); - sendReward(owner, bounty.address, reward); - - assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()); - }); - - it('empties itself when destroyed', async function () { - let owner = accounts[0]; - let reward = web3.toWei(1, 'ether'); - let bounty = await SecureTargetBounty.new(); - sendReward(owner, bounty.address, reward); - - assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()); - - await bounty.destroy(); - assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()); - }); - - describe('Against secure contract', function () { - it('cannot claim reward', async function () { - let owner = accounts[0]; - let researcher = accounts[1]; - let reward = web3.toWei(1, 'ether'); - let bounty = await SecureTargetBounty.new(); - let event = bounty.TargetCreated({}); - - let watcher = async function (err, result) { - event.stopWatching(); - if (err) { throw err; } - - var targetAddress = result.args.createdAddress; - sendReward(owner, bounty.address, reward); - - assert.equal(reward, - web3.eth.getBalance(bounty.address).toNumber()); - - try { - await bounty.claim(targetAddress, { from: researcher }); - assert.isTrue(false); // should never reach here - } catch (error) { - let reClaimedBounty = await bounty.claimed.call(); - assert.isFalse(reClaimedBounty); - } - try { - await bounty.withdrawPayments({ from: researcher }); - assert.isTrue(false); // should never reach here - } catch (err) { - assert.equal(reward, - web3.eth.getBalance(bounty.address).toNumber()); - } - }; - await bounty.createTarget({ from: researcher }); - await awaitEvent(event, watcher); - }); - }); - - describe('Against broken contract', function () { - it('claims reward', async function () { - let owner = accounts[0]; - let researcher = accounts[1]; - let reward = web3.toWei(1, 'ether'); - let bounty = await InsecureTargetBounty.new(); - let event = bounty.TargetCreated({}); - - let watcher = async function (err, result) { - event.stopWatching(); - if (err) { throw err; } - let targetAddress = result.args.createdAddress; - sendReward(owner, bounty.address, reward); - - assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()); - - await bounty.claim(targetAddress, { from: researcher }); - let claim = await bounty.claimed.call(); - - assert.isTrue(claim); - - await bounty.withdrawPayments({ from: researcher }); - - assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()); - }; - await bounty.createTarget({ from: researcher }); - await awaitEvent(event, watcher); - }); - }); -}); diff --git a/test/DayLimit.test.js b/test/DayLimit.test.js deleted file mode 100644 index ab2aa903f..000000000 --- a/test/DayLimit.test.js +++ /dev/null @@ -1,88 +0,0 @@ - -import latestTime from './helpers/latestTime'; -import { increaseTimeTo, duration } from './helpers/increaseTime'; - -import assertRevert from './helpers/assertRevert'; - -const DayLimitMock = artifacts.require('DayLimitMock'); - -contract('DayLimit', function (accounts) { - let dayLimit; - let initLimit = 10; - - beforeEach(async function () { - this.startTime = latestTime(); - dayLimit = await DayLimitMock.new(initLimit); - }); - - it('should construct with the passed daily limit', async function () { - let dailyLimit = await dayLimit.dailyLimit(); - assert.equal(initLimit, dailyLimit); - }); - - it('should be able to spend if daily limit is not reached', async function () { - await dayLimit.attemptSpend(8); - let spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 8); - - await dayLimit.attemptSpend(2); - spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 10); - }); - - it('should prevent spending if daily limit is reached', async function () { - await dayLimit.attemptSpend(8); - let spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 8); - await assertRevert(dayLimit.attemptSpend(3)); - }); - - it('should allow spending if daily limit is reached and then set higher', async function () { - await dayLimit.attemptSpend(8); - let spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 8); - - await assertRevert(dayLimit.attemptSpend(3)); - spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 8); - - await dayLimit.setDailyLimit(15); - await dayLimit.attemptSpend(3); - spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 11); - }); - - it('should allow spending if daily limit is reached and then amount spent is reset', async function () { - await dayLimit.attemptSpend(8); - let spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 8); - - await assertRevert(dayLimit.attemptSpend(3)); - spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 8); - - await dayLimit.resetSpentToday(); - await dayLimit.attemptSpend(3); - spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 3); - }); - - it('should allow spending if daily limit is reached and then the next has come', async function () { - let limit = 10; - let dayLimit = await DayLimitMock.new(limit); - - await dayLimit.attemptSpend(8); - let spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 8); - - await assertRevert(dayLimit.attemptSpend(3)); - spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 8); - - await increaseTimeTo(this.startTime + duration.days(1)); - - await dayLimit.attemptSpend(3); - spentToday = await dayLimit.spentToday(); - assert.equal(spentToday, 3); - }); -}); diff --git a/test/Heritable.test.js b/test/Heritable.test.js deleted file mode 100644 index 2124a5279..000000000 --- a/test/Heritable.test.js +++ /dev/null @@ -1,136 +0,0 @@ -import increaseTime from './helpers/increaseTime'; -import expectThrow from './helpers/expectThrow'; -import assertRevert from './helpers/assertRevert'; - -const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; - -const Heritable = artifacts.require('Heritable'); - -contract('Heritable', function (accounts) { - let heritable; - let owner; - - beforeEach(async function () { - heritable = await Heritable.new(4141); - owner = await heritable.owner(); - }); - - it('should start off with an owner, but without heir', async function () { - const heir = await heritable.heir(); - - assert.equal(typeof (owner), 'string'); - assert.equal(typeof (heir), 'string'); - assert.notStrictEqual( - owner, NULL_ADDRESS, - 'Owner shouldn\'t be the null address' - ); - assert.isTrue( - heir === NULL_ADDRESS, - 'Heir should be the null address' - ); - }); - - it('only owner should set heir', async function () { - const newHeir = accounts[1]; - const someRandomAddress = accounts[2]; - assert.isTrue(owner !== someRandomAddress); - - await heritable.setHeir(newHeir, { from: owner }); - await expectThrow(heritable.setHeir(newHeir, { from: someRandomAddress })); - }); - - it('owner can\'t be heir', async function () { - await assertRevert(heritable.setHeir(owner, { from: owner })); - }); - - it('owner can remove heir', async function () { - const newHeir = accounts[1]; - await heritable.setHeir(newHeir, { from: owner }); - let heir = await heritable.heir(); - - assert.notStrictEqual(heir, NULL_ADDRESS); - await heritable.removeHeir(); - heir = await heritable.heir(); - assert.isTrue(heir === NULL_ADDRESS); - }); - - it('heir can claim ownership only if owner is dead and timeout was reached', async function () { - const heir = accounts[1]; - await heritable.setHeir(heir, { from: owner }); - await expectThrow(heritable.claimHeirOwnership({ from: heir })); - - await heritable.proclaimDeath({ from: heir }); - await increaseTime(1); - await expectThrow(heritable.claimHeirOwnership({ from: heir })); - - await increaseTime(4141); - await heritable.claimHeirOwnership({ from: heir }); - assert.isTrue(await heritable.heir() === heir); - }); - - it('only heir can proclaim death', async function () { - const someRandomAddress = accounts[2]; - await assertRevert(heritable.proclaimDeath({ from: owner })); - await assertRevert(heritable.proclaimDeath({ from: someRandomAddress })); - }); - - it('heir can\'t proclaim death if owner is death', async function () { - const heir = accounts[1]; - await heritable.setHeir(heir, { from: owner }); - await heritable.proclaimDeath({ from: heir }); - await assertRevert(heritable.proclaimDeath({ from: heir })); - }); - - it('heir can\'t claim ownership if owner heartbeats', async function () { - const heir = accounts[1]; - await heritable.setHeir(heir, { from: owner }); - - await heritable.proclaimDeath({ from: heir }); - await heritable.heartbeat({ from: owner }); - await expectThrow(heritable.claimHeirOwnership({ from: heir })); - - await heritable.proclaimDeath({ from: heir }); - await increaseTime(4141); - await heritable.heartbeat({ from: owner }); - await expectThrow(heritable.claimHeirOwnership({ from: heir })); - }); - - it('should log events appropriately', async function () { - const heir = accounts[1]; - - const setHeirLogs = (await heritable.setHeir(heir, { from: owner })).logs; - const setHeirEvent = setHeirLogs.find(e => e.event === 'HeirChanged'); - - assert.isTrue(setHeirEvent.args.owner === owner); - assert.isTrue(setHeirEvent.args.newHeir === heir); - - const heartbeatLogs = (await heritable.heartbeat({ from: owner })).logs; - const heartbeatEvent = heartbeatLogs.find(e => e.event === 'OwnerHeartbeated'); - - assert.isTrue(heartbeatEvent.args.owner === owner); - - const proclaimDeathLogs = (await heritable.proclaimDeath({ from: heir })).logs; - const ownerDeadEvent = proclaimDeathLogs.find(e => e.event === 'OwnerProclaimedDead'); - - assert.isTrue(ownerDeadEvent.args.owner === owner); - assert.isTrue(ownerDeadEvent.args.heir === heir); - - await increaseTime(4141); - const claimHeirOwnershipLogs = (await heritable.claimHeirOwnership({ from: heir })).logs; - const ownershipTransferredEvent = claimHeirOwnershipLogs.find(e => e.event === 'OwnershipTransferred'); - const heirOwnershipClaimedEvent = claimHeirOwnershipLogs.find(e => e.event === 'HeirOwnershipClaimed'); - - assert.isTrue(ownershipTransferredEvent.args.previousOwner === owner); - assert.isTrue(ownershipTransferredEvent.args.newOwner === heir); - assert.isTrue(heirOwnershipClaimedEvent.args.previousOwner === owner); - assert.isTrue(heirOwnershipClaimedEvent.args.newOwner === heir); - }); - - it('timeOfDeath can be queried', async function () { - assert.equal(await heritable.timeOfDeath(), 0); - }); - - it('heartbeatTimeout can be queried', async function () { - assert.equal(await heritable.heartbeatTimeout(), 4141); - }); -}); diff --git a/test/LimitBalance.test.js b/test/LimitBalance.test.js deleted file mode 100644 index 9df8b0dc8..000000000 --- a/test/LimitBalance.test.js +++ /dev/null @@ -1,47 +0,0 @@ -import assertRevert from './helpers/assertRevert'; -var LimitBalanceMock = artifacts.require('LimitBalanceMock'); - -contract('LimitBalance', function (accounts) { - let lb; - - beforeEach(async function () { - lb = await LimitBalanceMock.new(); - }); - - let LIMIT = 1000; - - it('should expose limit', async function () { - let limit = await lb.limit(); - assert.equal(limit, LIMIT); - }); - - it('should allow sending below limit', async function () { - let amount = 1; - await lb.limitedDeposit({ value: amount }); - - assert.equal(web3.eth.getBalance(lb.address), amount); - }); - - it('shouldnt allow sending above limit', async function () { - let amount = 1110; - await assertRevert(lb.limitedDeposit({ value: amount })); - }); - - it('should allow multiple sends below limit', async function () { - let amount = 500; - await lb.limitedDeposit({ value: amount }); - - assert.equal(web3.eth.getBalance(lb.address), amount); - - await lb.limitedDeposit({ value: amount }); - assert.equal(web3.eth.getBalance(lb.address), amount * 2); - }); - - it('shouldnt allow multiple sends above limit', async function () { - let amount = 500; - await lb.limitedDeposit({ value: amount }); - - assert.equal(web3.eth.getBalance(lb.address), amount); - await assertRevert(lb.limitedDeposit({ value: amount + 1 })); - }); -}); diff --git a/test/ReentrancyGuard.test.js b/test/ReentrancyGuard.test.js deleted file mode 100644 index 0e32cf369..000000000 --- a/test/ReentrancyGuard.test.js +++ /dev/null @@ -1,31 +0,0 @@ - -import expectThrow from './helpers/expectThrow'; -const ReentrancyMock = artifacts.require('ReentrancyMock'); -const ReentrancyAttack = artifacts.require('ReentrancyAttack'); - -contract('ReentrancyGuard', function (accounts) { - let reentrancyMock; - - beforeEach(async function () { - reentrancyMock = await ReentrancyMock.new(); - let initialCounter = await reentrancyMock.counter(); - assert.equal(initialCounter, 0); - }); - - it('should not allow remote callback', async function () { - let attacker = await ReentrancyAttack.new(); - await expectThrow(reentrancyMock.countAndCall(attacker.address)); - }); - - // The following are more side-effects than intended behaviour: - // I put them here as documentation, and to monitor any changes - // in the side-effects. - - it('should not allow local recursion', async function () { - await expectThrow(reentrancyMock.countLocalRecursive(10)); - }); - - it('should not allow indirect local recursion', async function () { - await expectThrow(reentrancyMock.countThisRecursive(10)); - }); -}); diff --git a/test/SimpleSavingsWallet.test.js b/test/SimpleSavingsWallet.test.js deleted file mode 100644 index 07787c2de..000000000 --- a/test/SimpleSavingsWallet.test.js +++ /dev/null @@ -1,33 +0,0 @@ - -import expectThrow from './helpers/expectThrow'; - -const SimpleSavingsWallet = artifacts.require('SimpleSavingsWallet'); - -contract('SimpleSavingsWallet', function (accounts) { - let savingsWallet; - let owner; - - const paymentAmount = 4242; - - beforeEach(async function () { - savingsWallet = await SimpleSavingsWallet.new(4141); - owner = await savingsWallet.owner(); - }); - - it('should receive funds', async function () { - await web3.eth.sendTransaction({ from: owner, to: savingsWallet.address, value: paymentAmount }); - assert.isTrue((new web3.BigNumber(paymentAmount)).equals(web3.eth.getBalance(savingsWallet.address))); - }); - - it('owner can send funds', async function () { - // Receive payment so we have some money to spend. - await web3.eth.sendTransaction({ from: accounts[9], to: savingsWallet.address, value: 1000000 }); - await expectThrow(savingsWallet.sendTo(0, paymentAmount, { from: owner })); - await expectThrow(savingsWallet.sendTo(savingsWallet.address, paymentAmount, { from: owner })); - await expectThrow(savingsWallet.sendTo(accounts[1], 0, { from: owner })); - - const balance = web3.eth.getBalance(accounts[1]); - await savingsWallet.sendTo(accounts[1], paymentAmount, { from: owner }); - assert.isTrue(balance.plus(paymentAmount).equals(web3.eth.getBalance(accounts[1]))); - }); -}); diff --git a/test/access/SignatureBouncer.test.js b/test/access/SignatureBouncer.test.js deleted file mode 100644 index 472a41226..000000000 --- a/test/access/SignatureBouncer.test.js +++ /dev/null @@ -1,119 +0,0 @@ - -import assertRevert from '../helpers/assertRevert'; -import { signHex } from '../helpers/sign'; - -const Bouncer = artifacts.require('SignatureBouncerMock'); - -require('chai') - .use(require('chai-as-promised')) - .should(); - -export const getSigner = (contract, signer, data = '') => (addr) => { - // via: https://github.com/OpenZeppelin/zeppelin-solidity/pull/812/files - const message = contract.address.substr(2) + addr.substr(2) + data; - // ^ substr to remove `0x` because in solidity the address is a set of byes, not a string `0xabcd` - return signHex(signer, message); -}; - -contract('Bouncer', ([_, owner, authorizedUser, anyone, bouncerAddress, newBouncer]) => { - before(async function () { - this.bouncer = await Bouncer.new({ from: owner }); - this.roleBouncer = await this.bouncer.ROLE_BOUNCER(); - this.genSig = getSigner(this.bouncer, bouncerAddress); - }); - - it('should have a default owner of self', async function () { - const theOwner = await this.bouncer.owner(); - theOwner.should.eq(owner); - }); - - it('should allow owner to add a bouncer', async function () { - await this.bouncer.addBouncer(bouncerAddress, { from: owner }); - const hasRole = await this.bouncer.hasRole(bouncerAddress, this.roleBouncer); - hasRole.should.eq(true); - }); - - it('should not allow anyone to add a bouncer', async function () { - await assertRevert( - this.bouncer.addBouncer(bouncerAddress, { from: anyone }) - ); - }); - - context('modifiers', () => { - it('should allow valid signature for sender', async function () { - await this.bouncer.onlyWithValidSignature( - this.genSig(authorizedUser), - { from: authorizedUser } - ); - }); - it('should not allow invalid signature for sender', async function () { - await assertRevert( - this.bouncer.onlyWithValidSignature( - 'abcd', - { from: authorizedUser } - ) - ); - }); - }); - - context('signatures', () => { - it('should accept valid message for valid user', async function () { - const isValid = await this.bouncer.checkValidSignature( - authorizedUser, - this.genSig(authorizedUser) - ); - isValid.should.eq(true); - }); - it('should not accept invalid message for valid user', async function () { - const isValid = await this.bouncer.checkValidSignature( - authorizedUser, - this.genSig(anyone) - ); - isValid.should.eq(false); - }); - it('should not accept invalid message for invalid user', async function () { - const isValid = await this.bouncer.checkValidSignature( - anyone, - 'abcd' - ); - isValid.should.eq(false); - }); - it('should not accept valid message for invalid user', async function () { - const isValid = await this.bouncer.checkValidSignature( - anyone, - this.genSig(authorizedUser) - ); - isValid.should.eq(false); - }); - }); - - context('management', () => { - it('should not allow anyone to add bouncers', async function () { - await assertRevert( - this.bouncer.addBouncer(newBouncer, { from: anyone }) - ); - }); - - it('should be able to add bouncers', async function () { - await this.bouncer.addBouncer(newBouncer, { from: owner }) - .should.be.fulfilled; - }); - - it('should not allow adding invalid address', async function () { - await assertRevert( - this.bouncer.addBouncer('0x0', { from: owner }) - ); - }); - - it('should not allow anyone to remove bouncer', async function () { - await assertRevert( - this.bouncer.removeBouncer(newBouncer, { from: anyone }) - ); - }); - - it('should be able to remove bouncers', async function () { - await this.bouncer.removeBouncer(newBouncer, { from: owner }) - .should.be.fulfilled; - }); - }); -}); diff --git a/test/crowdsale/AllowanceCrowdsale.test.js b/test/crowdsale/AllowanceCrowdsale.test.js deleted file mode 100644 index 44799010a..000000000 --- a/test/crowdsale/AllowanceCrowdsale.test.js +++ /dev/null @@ -1,77 +0,0 @@ -import ether from '../helpers/ether'; -import assertRevert from '../helpers/assertRevert'; - -const BigNumber = web3.BigNumber; - -const should = require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const AllowanceCrowdsale = artifacts.require('AllowanceCrowdsaleImpl'); -const SimpleToken = artifacts.require('SimpleToken'); - -contract('AllowanceCrowdsale', function ([_, investor, wallet, purchaser, tokenWallet]) { - const rate = new BigNumber(1); - const value = ether(0.42); - const expectedTokenAmount = rate.mul(value); - const tokenAllowance = new BigNumber('1e22'); - const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; - - beforeEach(async function () { - this.token = await SimpleToken.new({ from: tokenWallet }); - this.crowdsale = await AllowanceCrowdsale.new(rate, wallet, this.token.address, tokenWallet); - await this.token.approve(this.crowdsale.address, tokenAllowance, { from: tokenWallet }); - }); - - describe('accepting payments', function () { - it('should accept sends', async function () { - await this.crowdsale.send(value).should.be.fulfilled; - }); - - it('should accept payments', async function () { - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }).should.be.fulfilled; - }); - }); - - describe('high-level purchase', function () { - it('should log purchase', async function () { - const { logs } = await this.crowdsale.sendTransaction({ value: value, from: investor }); - const event = logs.find(e => e.event === 'TokenPurchase'); - should.exist(event); - event.args.purchaser.should.equal(investor); - event.args.beneficiary.should.equal(investor); - event.args.value.should.be.bignumber.equal(value); - event.args.amount.should.be.bignumber.equal(expectedTokenAmount); - }); - - it('should assign tokens to sender', async function () { - await this.crowdsale.sendTransaction({ value: value, from: investor }); - let balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(expectedTokenAmount); - }); - - it('should forward funds to wallet', async function () { - const pre = web3.eth.getBalance(wallet); - await this.crowdsale.sendTransaction({ value, from: investor }); - const post = web3.eth.getBalance(wallet); - post.minus(pre).should.be.bignumber.equal(value); - }); - }); - - describe('check remaining allowance', function () { - it('should report correct allowace left', async function () { - let remainingAllowance = tokenAllowance - expectedTokenAmount; - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - let tokensRemaining = await this.crowdsale.remainingTokens(); - tokensRemaining.should.be.bignumber.equal(remainingAllowance); - }); - }); - - describe('when token wallet is different from token address', function () { - it('creation reverts', async function () { - this.token = await SimpleToken.new({ from: tokenWallet }); - await assertRevert(AllowanceCrowdsale.new(rate, wallet, this.token.address, ZERO_ADDRESS)); - }); - }); -}); diff --git a/test/crowdsale/CappedCrowdsale.test.js b/test/crowdsale/CappedCrowdsale.test.js deleted file mode 100644 index a3dd9660f..000000000 --- a/test/crowdsale/CappedCrowdsale.test.js +++ /dev/null @@ -1,69 +0,0 @@ -import ether from '../helpers/ether'; -import EVMRevert from '../helpers/EVMRevert'; - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const CappedCrowdsale = artifacts.require('CappedCrowdsaleImpl'); -const SimpleToken = artifacts.require('SimpleToken'); - -contract('CappedCrowdsale', function ([_, wallet]) { - const rate = new BigNumber(1); - const cap = ether(100); - const lessThanCap = ether(60); - const tokenSupply = new BigNumber('1e22'); - - beforeEach(async function () { - this.token = await SimpleToken.new(); - this.crowdsale = await CappedCrowdsale.new(rate, wallet, this.token.address, cap); - await this.token.transfer(this.crowdsale.address, tokenSupply); - }); - - describe('creating a valid crowdsale', function () { - it('should fail with zero cap', async function () { - await CappedCrowdsale.new(rate, wallet, 0, this.token.address).should.be.rejectedWith(EVMRevert); - }); - }); - - describe('accepting payments', function () { - it('should accept payments within cap', async function () { - await this.crowdsale.send(cap.minus(lessThanCap)).should.be.fulfilled; - await this.crowdsale.send(lessThanCap).should.be.fulfilled; - }); - - it('should reject payments outside cap', async function () { - await this.crowdsale.send(cap); - await this.crowdsale.send(1).should.be.rejectedWith(EVMRevert); - }); - - it('should reject payments that exceed cap', async function () { - await this.crowdsale.send(cap.plus(1)).should.be.rejectedWith(EVMRevert); - }); - }); - - describe('ending', function () { - it('should not reach cap if sent under cap', async function () { - let capReached = await this.crowdsale.capReached(); - capReached.should.equal(false); - await this.crowdsale.send(lessThanCap); - capReached = await this.crowdsale.capReached(); - capReached.should.equal(false); - }); - - it('should not reach cap if sent just under cap', async function () { - await this.crowdsale.send(cap.minus(1)); - let capReached = await this.crowdsale.capReached(); - capReached.should.equal(false); - }); - - it('should reach cap if cap sent', async function () { - await this.crowdsale.send(cap); - let capReached = await this.crowdsale.capReached(); - capReached.should.equal(true); - }); - }); -}); diff --git a/test/crowdsale/Crowdsale.test.js b/test/crowdsale/Crowdsale.test.js deleted file mode 100644 index 4053dca37..000000000 --- a/test/crowdsale/Crowdsale.test.js +++ /dev/null @@ -1,81 +0,0 @@ -import ether from '../helpers/ether'; - -const BigNumber = web3.BigNumber; - -const should = require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const Crowdsale = artifacts.require('Crowdsale'); -const SimpleToken = artifacts.require('SimpleToken'); - -contract('Crowdsale', function ([_, investor, wallet, purchaser]) { - const rate = new BigNumber(1); - const value = ether(42); - const tokenSupply = new BigNumber('1e22'); - const expectedTokenAmount = rate.mul(value); - - beforeEach(async function () { - this.token = await SimpleToken.new(); - this.crowdsale = await Crowdsale.new(rate, wallet, this.token.address); - await this.token.transfer(this.crowdsale.address, tokenSupply); - }); - - describe('accepting payments', function () { - it('should accept payments', async function () { - await this.crowdsale.send(value).should.be.fulfilled; - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }).should.be.fulfilled; - }); - }); - - describe('high-level purchase', function () { - it('should log purchase', async function () { - const { logs } = await this.crowdsale.sendTransaction({ value: value, from: investor }); - const event = logs.find(e => e.event === 'TokenPurchase'); - should.exist(event); - event.args.purchaser.should.equal(investor); - event.args.beneficiary.should.equal(investor); - event.args.value.should.be.bignumber.equal(value); - event.args.amount.should.be.bignumber.equal(expectedTokenAmount); - }); - - it('should assign tokens to sender', async function () { - await this.crowdsale.sendTransaction({ value: value, from: investor }); - let balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(expectedTokenAmount); - }); - - it('should forward funds to wallet', async function () { - const pre = web3.eth.getBalance(wallet); - await this.crowdsale.sendTransaction({ value, from: investor }); - const post = web3.eth.getBalance(wallet); - post.minus(pre).should.be.bignumber.equal(value); - }); - }); - - describe('low-level purchase', function () { - it('should log purchase', async function () { - const { logs } = await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - const event = logs.find(e => e.event === 'TokenPurchase'); - should.exist(event); - event.args.purchaser.should.equal(purchaser); - event.args.beneficiary.should.equal(investor); - event.args.value.should.be.bignumber.equal(value); - event.args.amount.should.be.bignumber.equal(expectedTokenAmount); - }); - - it('should assign tokens to beneficiary', async function () { - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - const balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(expectedTokenAmount); - }); - - it('should forward funds to wallet', async function () { - const pre = web3.eth.getBalance(wallet); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - const post = web3.eth.getBalance(wallet); - post.minus(pre).should.be.bignumber.equal(value); - }); - }); -}); diff --git a/test/crowdsale/FinalizableCrowdsale.test.js b/test/crowdsale/FinalizableCrowdsale.test.js deleted file mode 100644 index 9a6c16a6f..000000000 --- a/test/crowdsale/FinalizableCrowdsale.test.js +++ /dev/null @@ -1,62 +0,0 @@ -import { advanceBlock } from '../helpers/advanceToBlock'; -import { increaseTimeTo, duration } from '../helpers/increaseTime'; -import latestTime from '../helpers/latestTime'; -import EVMRevert from '../helpers/EVMRevert'; - -const BigNumber = web3.BigNumber; - -const should = require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const FinalizableCrowdsale = artifacts.require('FinalizableCrowdsaleImpl'); -const MintableToken = artifacts.require('MintableToken'); - -contract('FinalizableCrowdsale', function ([_, owner, wallet, thirdparty]) { - const rate = new BigNumber(1000); - - before(async function () { - // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache - await advanceBlock(); - }); - - beforeEach(async function () { - this.openingTime = latestTime() + duration.weeks(1); - this.closingTime = this.openingTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); - - this.token = await MintableToken.new(); - this.crowdsale = await FinalizableCrowdsale.new( - this.openingTime, this.closingTime, rate, wallet, this.token.address, { from: owner } - ); - await this.token.transferOwnership(this.crowdsale.address); - }); - - it('cannot be finalized before ending', async function () { - await this.crowdsale.finalize({ from: owner }).should.be.rejectedWith(EVMRevert); - }); - - it('cannot be finalized by third party after ending', async function () { - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.finalize({ from: thirdparty }).should.be.rejectedWith(EVMRevert); - }); - - it('can be finalized by owner after ending', async function () { - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.finalize({ from: owner }).should.be.fulfilled; - }); - - it('cannot be finalized twice', async function () { - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.finalize({ from: owner }); - await this.crowdsale.finalize({ from: owner }).should.be.rejectedWith(EVMRevert); - }); - - it('logs finalized', async function () { - await increaseTimeTo(this.afterClosingTime); - const { logs } = await this.crowdsale.finalize({ from: owner }); - const event = logs.find(e => e.event === 'Finalized'); - should.exist(event); - }); -}); diff --git a/test/crowdsale/IncreasingPriceCrowdsale.test.js b/test/crowdsale/IncreasingPriceCrowdsale.test.js deleted file mode 100644 index 76f82ab02..000000000 --- a/test/crowdsale/IncreasingPriceCrowdsale.test.js +++ /dev/null @@ -1,92 +0,0 @@ -import ether from '../helpers/ether'; -import { advanceBlock } from '../helpers/advanceToBlock'; -import { increaseTimeTo, duration } from '../helpers/increaseTime'; -import latestTime from '../helpers/latestTime'; - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const IncreasingPriceCrowdsale = artifacts.require('IncreasingPriceCrowdsaleImpl'); -const SimpleToken = artifacts.require('SimpleToken'); - -contract('IncreasingPriceCrowdsale', function ([_, investor, wallet, purchaser]) { - const value = ether(1); - const tokenSupply = new BigNumber('1e22'); - - describe('rate during crowdsale should change at a fixed step every block', async function () { - let balance; - const initialRate = new BigNumber(9166); - const finalRate = new BigNumber(5500); - const rateAtTime150 = new BigNumber(9166); - const rateAtTime300 = new BigNumber(9165); - const rateAtTime1500 = new BigNumber(9157); - const rateAtTime30 = new BigNumber(9166); - const rateAtTime150000 = new BigNumber(8257); - const rateAtTime450000 = new BigNumber(6439); - - beforeEach(async function () { - await advanceBlock(); - this.startTime = latestTime() + duration.weeks(1); - this.closingTime = this.startTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); - this.token = await SimpleToken.new(); - this.crowdsale = await IncreasingPriceCrowdsale.new( - this.startTime, this.closingTime, wallet, this.token.address, initialRate, finalRate - ); - await this.token.transfer(this.crowdsale.address, tokenSupply); - }); - - it('at start', async function () { - await increaseTimeTo(this.startTime); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(value.mul(initialRate)); - }); - - it('at time 150', async function () { - await increaseTimeTo(this.startTime + 150); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(value.mul(rateAtTime150)); - }); - - it('at time 300', async function () { - await increaseTimeTo(this.startTime + 300); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(value.mul(rateAtTime300)); - }); - - it('at time 1500', async function () { - await increaseTimeTo(this.startTime + 1500); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(value.mul(rateAtTime1500)); - }); - - it('at time 30', async function () { - await increaseTimeTo(this.startTime + 30); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(value.mul(rateAtTime30)); - }); - - it('at time 150000', async function () { - await increaseTimeTo(this.startTime + 150000); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(value.mul(rateAtTime150000)); - }); - - it('at time 450000', async function () { - await increaseTimeTo(this.startTime + 450000); - await this.crowdsale.buyTokens(investor, { value, from: purchaser }); - balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(value.mul(rateAtTime450000)); - }); - }); -}); diff --git a/test/crowdsale/IndividuallyCappedCrowdsale.test.js b/test/crowdsale/IndividuallyCappedCrowdsale.test.js deleted file mode 100644 index e8585ad6d..000000000 --- a/test/crowdsale/IndividuallyCappedCrowdsale.test.js +++ /dev/null @@ -1,107 +0,0 @@ -import ether from '../helpers/ether'; -import EVMRevert from '../helpers/EVMRevert'; - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const CappedCrowdsale = artifacts.require('IndividuallyCappedCrowdsaleImpl'); -const SimpleToken = artifacts.require('SimpleToken'); - -contract('IndividuallyCappedCrowdsale', function ([_, wallet, alice, bob, charlie]) { - const rate = new BigNumber(1); - const capAlice = ether(10); - const capBob = ether(2); - const lessThanCapAlice = ether(6); - const lessThanCapBoth = ether(1); - const tokenSupply = new BigNumber('1e22'); - - describe('individual capping', function () { - beforeEach(async function () { - this.token = await SimpleToken.new(); - this.crowdsale = await CappedCrowdsale.new(rate, wallet, this.token.address); - await this.crowdsale.setUserCap(alice, capAlice); - await this.crowdsale.setUserCap(bob, capBob); - await this.token.transfer(this.crowdsale.address, tokenSupply); - }); - - describe('accepting payments', function () { - it('should accept payments within cap', async function () { - await this.crowdsale.buyTokens(alice, { value: lessThanCapAlice }).should.be.fulfilled; - await this.crowdsale.buyTokens(bob, { value: lessThanCapBoth }).should.be.fulfilled; - }); - - it('should reject payments outside cap', async function () { - await this.crowdsale.buyTokens(alice, { value: capAlice }); - await this.crowdsale.buyTokens(alice, { value: 1 }).should.be.rejectedWith(EVMRevert); - }); - - it('should reject payments that exceed cap', async function () { - await this.crowdsale.buyTokens(alice, { value: capAlice.plus(1) }).should.be.rejectedWith(EVMRevert); - await this.crowdsale.buyTokens(bob, { value: capBob.plus(1) }).should.be.rejectedWith(EVMRevert); - }); - - it('should manage independent caps', async function () { - await this.crowdsale.buyTokens(alice, { value: lessThanCapAlice }).should.be.fulfilled; - await this.crowdsale.buyTokens(bob, { value: lessThanCapAlice }).should.be.rejectedWith(EVMRevert); - }); - - it('should default to a cap of zero', async function () { - await this.crowdsale.buyTokens(charlie, { value: lessThanCapBoth }).should.be.rejectedWith(EVMRevert); - }); - }); - - describe('reporting state', function () { - it('should report correct cap', async function () { - let retrievedCap = await this.crowdsale.getUserCap(alice); - retrievedCap.should.be.bignumber.equal(capAlice); - }); - - it('should report actual contribution', async function () { - await this.crowdsale.buyTokens(alice, { value: lessThanCapAlice }); - let retrievedContribution = await this.crowdsale.getUserContribution(alice); - retrievedContribution.should.be.bignumber.equal(lessThanCapAlice); - }); - }); - }); - - describe('group capping', function () { - beforeEach(async function () { - this.token = await SimpleToken.new(); - this.crowdsale = await CappedCrowdsale.new(rate, wallet, this.token.address); - await this.crowdsale.setGroupCap([bob, charlie], capBob); - await this.token.transfer(this.crowdsale.address, tokenSupply); - }); - - describe('accepting payments', function () { - it('should accept payments within cap', async function () { - await this.crowdsale.buyTokens(bob, { value: lessThanCapBoth }).should.be.fulfilled; - await this.crowdsale.buyTokens(charlie, { value: lessThanCapBoth }).should.be.fulfilled; - }); - - it('should reject payments outside cap', async function () { - await this.crowdsale.buyTokens(bob, { value: capBob }); - await this.crowdsale.buyTokens(bob, { value: 1 }).should.be.rejectedWith(EVMRevert); - await this.crowdsale.buyTokens(charlie, { value: capBob }); - await this.crowdsale.buyTokens(charlie, { value: 1 }).should.be.rejectedWith(EVMRevert); - }); - - it('should reject payments that exceed cap', async function () { - await this.crowdsale.buyTokens(bob, { value: capBob.plus(1) }).should.be.rejectedWith(EVMRevert); - await this.crowdsale.buyTokens(charlie, { value: capBob.plus(1) }).should.be.rejectedWith(EVMRevert); - }); - }); - - describe('reporting state', function () { - it('should report correct cap', async function () { - let retrievedCapBob = await this.crowdsale.getUserCap(bob); - retrievedCapBob.should.be.bignumber.equal(capBob); - let retrievedCapCharlie = await this.crowdsale.getUserCap(charlie); - retrievedCapCharlie.should.be.bignumber.equal(capBob); - }); - }); - }); -}); diff --git a/test/crowdsale/MintedCrowdsale.test.js b/test/crowdsale/MintedCrowdsale.test.js deleted file mode 100644 index 362dc23af..000000000 --- a/test/crowdsale/MintedCrowdsale.test.js +++ /dev/null @@ -1,61 +0,0 @@ -import ether from '../helpers/ether'; - -const BigNumber = web3.BigNumber; - -const should = require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const MintedCrowdsale = artifacts.require('MintedCrowdsaleImpl'); -const MintableToken = artifacts.require('MintableToken'); - -contract('MintedCrowdsale', function ([_, investor, wallet, purchaser]) { - const rate = new BigNumber(1000); - const value = ether(42); - - const expectedTokenAmount = rate.mul(value); - - beforeEach(async function () { - this.token = await MintableToken.new(); - this.crowdsale = await MintedCrowdsale.new(rate, wallet, this.token.address); - await this.token.transferOwnership(this.crowdsale.address); - }); - - describe('accepting payments', function () { - it('should be token owner', async function () { - const owner = await this.token.owner(); - owner.should.equal(this.crowdsale.address); - }); - - it('should accept payments', async function () { - await this.crowdsale.send(value).should.be.fulfilled; - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }).should.be.fulfilled; - }); - }); - - describe('high-level purchase', function () { - it('should log purchase', async function () { - const { logs } = await this.crowdsale.sendTransaction({ value: value, from: investor }); - const event = logs.find(e => e.event === 'TokenPurchase'); - should.exist(event); - event.args.purchaser.should.equal(investor); - event.args.beneficiary.should.equal(investor); - event.args.value.should.be.bignumber.equal(value); - event.args.amount.should.be.bignumber.equal(expectedTokenAmount); - }); - - it('should assign tokens to sender', async function () { - await this.crowdsale.sendTransaction({ value: value, from: investor }); - let balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(expectedTokenAmount); - }); - - it('should forward funds to wallet', async function () { - const pre = web3.eth.getBalance(wallet); - await this.crowdsale.sendTransaction({ value, from: investor }); - const post = web3.eth.getBalance(wallet); - post.minus(pre).should.be.bignumber.equal(value); - }); - }); -}); diff --git a/test/crowdsale/PostDeliveryCrowdsale.test.js b/test/crowdsale/PostDeliveryCrowdsale.test.js deleted file mode 100644 index 1860a8dea..000000000 --- a/test/crowdsale/PostDeliveryCrowdsale.test.js +++ /dev/null @@ -1,67 +0,0 @@ -import { advanceBlock } from '../helpers/advanceToBlock'; -import { increaseTimeTo, duration } from '../helpers/increaseTime'; -import latestTime from '../helpers/latestTime'; -import EVMRevert from '../helpers/EVMRevert'; -import ether from '../helpers/ether'; - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const PostDeliveryCrowdsale = artifacts.require('PostDeliveryCrowdsaleImpl'); -const SimpleToken = artifacts.require('SimpleToken'); - -contract('PostDeliveryCrowdsale', function ([_, investor, wallet, purchaser]) { - const rate = new BigNumber(1); - const value = ether(42); - const tokenSupply = new BigNumber('1e22'); - - before(async function () { - // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache - await advanceBlock(); - }); - - beforeEach(async function () { - this.openingTime = latestTime() + duration.weeks(1); - this.closingTime = this.openingTime + duration.weeks(1); - this.beforeEndTime = this.closingTime - duration.hours(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); - this.token = await SimpleToken.new(); - this.crowdsale = await PostDeliveryCrowdsale.new( - this.openingTime, this.closingTime, rate, wallet, this.token.address - ); - await this.token.transfer(this.crowdsale.address, tokenSupply); - }); - - it('should not immediately assign tokens to beneficiary', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - const balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(0); - }); - - it('should not allow beneficiaries to withdraw tokens before crowdsale ends', async function () { - await increaseTimeTo(this.beforeEndTime); - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - await this.crowdsale.withdrawTokens({ from: investor }).should.be.rejectedWith(EVMRevert); - }); - - it('should allow beneficiaries to withdraw tokens after crowdsale ends', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.withdrawTokens({ from: investor }).should.be.fulfilled; - }); - - it('should return the amount of tokens bought', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }); - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.withdrawTokens({ from: investor }); - const balance = await this.token.balanceOf(investor); - balance.should.be.bignumber.equal(value); - }); -}); diff --git a/test/crowdsale/RefundVault.test.js b/test/crowdsale/RefundVault.test.js deleted file mode 100644 index e3b88dfce..000000000 --- a/test/crowdsale/RefundVault.test.js +++ /dev/null @@ -1,59 +0,0 @@ -import ether from '../helpers/ether'; -import EVMRevert from '../helpers/EVMRevert'; - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const RefundVault = artifacts.require('RefundVault'); - -contract('RefundVault', function ([_, owner, wallet, investor]) { - const value = ether(42); - - beforeEach(async function () { - this.vault = await RefundVault.new(wallet, { from: owner }); - }); - - it('should accept contributions', async function () { - await this.vault.deposit(investor, { value, from: owner }).should.be.fulfilled; - }); - - it('should not refund contribution during active state', async function () { - await this.vault.deposit(investor, { value, from: owner }); - await this.vault.refund(investor).should.be.rejectedWith(EVMRevert); - }); - - it('only owner can enter refund mode', async function () { - await this.vault.enableRefunds({ from: _ }).should.be.rejectedWith(EVMRevert); - await this.vault.enableRefunds({ from: owner }).should.be.fulfilled; - }); - - it('should refund contribution after entering refund mode', async function () { - await this.vault.deposit(investor, { value, from: owner }); - await this.vault.enableRefunds({ from: owner }); - - const pre = web3.eth.getBalance(investor); - await this.vault.refund(investor); - const post = web3.eth.getBalance(investor); - - post.minus(pre).should.be.bignumber.equal(value); - }); - - it('only owner can close', async function () { - await this.vault.close({ from: _ }).should.be.rejectedWith(EVMRevert); - await this.vault.close({ from: owner }).should.be.fulfilled; - }); - - it('should forward funds to wallet after closing', async function () { - await this.vault.deposit(investor, { value, from: owner }); - - const pre = web3.eth.getBalance(wallet); - await this.vault.close({ from: owner }); - const post = web3.eth.getBalance(wallet); - - post.minus(pre).should.be.bignumber.equal(value); - }); -}); diff --git a/test/crowdsale/RefundableCrowdsale.test.js b/test/crowdsale/RefundableCrowdsale.test.js deleted file mode 100644 index 551e65c98..000000000 --- a/test/crowdsale/RefundableCrowdsale.test.js +++ /dev/null @@ -1,82 +0,0 @@ -import ether from '../helpers/ether'; -import { advanceBlock } from '../helpers/advanceToBlock'; -import { increaseTimeTo, duration } from '../helpers/increaseTime'; -import latestTime from '../helpers/latestTime'; -import EVMRevert from '../helpers/EVMRevert'; - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const RefundableCrowdsale = artifacts.require('RefundableCrowdsaleImpl'); -const SimpleToken = artifacts.require('SimpleToken'); - -contract('RefundableCrowdsale', function ([_, owner, wallet, investor, purchaser]) { - const rate = new BigNumber(1); - const goal = ether(50); - const lessThanGoal = ether(45); - const tokenSupply = new BigNumber('1e22'); - - before(async function () { - // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache - await advanceBlock(); - }); - - beforeEach(async function () { - this.openingTime = latestTime() + duration.weeks(1); - this.closingTime = this.openingTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); - - this.token = await SimpleToken.new(); - this.crowdsale = await RefundableCrowdsale.new( - this.openingTime, this.closingTime, rate, wallet, this.token.address, goal, { from: owner } - ); - await this.token.transfer(this.crowdsale.address, tokenSupply); - }); - - describe('creating a valid crowdsale', function () { - it('should fail with zero goal', async function () { - await RefundableCrowdsale.new( - this.openingTime, this.closingTime, rate, wallet, this.token.address, 0, { from: owner } - ).should.be.rejectedWith(EVMRevert); - }); - }); - - it('should deny refunds before end', async function () { - await this.crowdsale.claimRefund({ from: investor }).should.be.rejectedWith(EVMRevert); - await increaseTimeTo(this.openingTime); - await this.crowdsale.claimRefund({ from: investor }).should.be.rejectedWith(EVMRevert); - }); - - it('should deny refunds after end if goal was reached', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.sendTransaction({ value: goal, from: investor }); - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.claimRefund({ from: investor }).should.be.rejectedWith(EVMRevert); - }); - - it('should allow refunds after end if goal was not reached', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.sendTransaction({ value: lessThanGoal, from: investor }); - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.finalize({ from: owner }); - const pre = web3.eth.getBalance(investor); - await this.crowdsale.claimRefund({ from: investor, gasPrice: 0 }) - .should.be.fulfilled; - const post = web3.eth.getBalance(investor); - post.minus(pre).should.be.bignumber.equal(lessThanGoal); - }); - - it('should forward funds to wallet after end if goal was reached', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.sendTransaction({ value: goal, from: investor }); - await increaseTimeTo(this.afterClosingTime); - const pre = web3.eth.getBalance(wallet); - await this.crowdsale.finalize({ from: owner }); - const post = web3.eth.getBalance(wallet); - post.minus(pre).should.be.bignumber.equal(goal); - }); -}); diff --git a/test/crowdsale/TimedCrowdsale.test.js b/test/crowdsale/TimedCrowdsale.test.js deleted file mode 100644 index ad54792a4..000000000 --- a/test/crowdsale/TimedCrowdsale.test.js +++ /dev/null @@ -1,62 +0,0 @@ -import ether from '../helpers/ether'; -import { advanceBlock } from '../helpers/advanceToBlock'; -import { increaseTimeTo, duration } from '../helpers/increaseTime'; -import latestTime from '../helpers/latestTime'; -import EVMRevert from '../helpers/EVMRevert'; - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const TimedCrowdsale = artifacts.require('TimedCrowdsaleImpl'); -const SimpleToken = artifacts.require('SimpleToken'); - -contract('TimedCrowdsale', function ([_, investor, wallet, purchaser]) { - const rate = new BigNumber(1); - const value = ether(42); - const tokenSupply = new BigNumber('1e22'); - - before(async function () { - // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache - await advanceBlock(); - }); - - beforeEach(async function () { - this.openingTime = latestTime() + duration.weeks(1); - this.closingTime = this.openingTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); - this.token = await SimpleToken.new(); - this.crowdsale = await TimedCrowdsale.new(this.openingTime, this.closingTime, rate, wallet, this.token.address); - await this.token.transfer(this.crowdsale.address, tokenSupply); - }); - - it('should be ended only after end', async function () { - let ended = await this.crowdsale.hasClosed(); - ended.should.equal(false); - await increaseTimeTo(this.afterClosingTime); - ended = await this.crowdsale.hasClosed(); - ended.should.equal(true); - }); - - describe('accepting payments', function () { - it('should reject payments before start', async function () { - await this.crowdsale.send(value).should.be.rejectedWith(EVMRevert); - await this.crowdsale.buyTokens(investor, { from: purchaser, value: value }).should.be.rejectedWith(EVMRevert); - }); - - it('should accept payments after start', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.send(value).should.be.fulfilled; - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }).should.be.fulfilled; - }); - - it('should reject payments after end', async function () { - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.send(value).should.be.rejectedWith(EVMRevert); - await this.crowdsale.buyTokens(investor, { value: value, from: purchaser }).should.be.rejectedWith(EVMRevert); - }); - }); -}); diff --git a/test/crowdsale/WhitelistedCrowdsale.test.js b/test/crowdsale/WhitelistedCrowdsale.test.js deleted file mode 100644 index e62016ace..000000000 --- a/test/crowdsale/WhitelistedCrowdsale.test.js +++ /dev/null @@ -1,93 +0,0 @@ -import ether from '../helpers/ether'; - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-as-promised')) - .should(); - -const WhitelistedCrowdsale = artifacts.require('WhitelistedCrowdsaleImpl'); -const SimpleToken = artifacts.require('SimpleToken'); - -contract('WhitelistedCrowdsale', function ([_, wallet, authorized, unauthorized, anotherAuthorized]) { - const rate = 1; - const value = ether(42); - const tokenSupply = new BigNumber('1e22'); - - describe('single user whitelisting', function () { - beforeEach(async function () { - this.token = await SimpleToken.new(); - this.crowdsale = await WhitelistedCrowdsale.new(rate, wallet, this.token.address); - await this.token.transfer(this.crowdsale.address, tokenSupply); - await this.crowdsale.addToWhitelist(authorized); - }); - - describe('accepting payments', function () { - it('should accept payments to whitelisted (from whichever buyers)', async function () { - await this.crowdsale.buyTokens(authorized, { value: value, from: authorized }).should.be.fulfilled; - await this.crowdsale.buyTokens(authorized, { value: value, from: unauthorized }).should.be.fulfilled; - }); - - it('should reject payments to not whitelisted (from whichever buyers)', async function () { - await this.crowdsale.send(value).should.be.rejected; - await this.crowdsale.buyTokens(unauthorized, { value: value, from: unauthorized }).should.be.rejected; - await this.crowdsale.buyTokens(unauthorized, { value: value, from: authorized }).should.be.rejected; - }); - - it('should reject payments to addresses removed from whitelist', async function () { - await this.crowdsale.removeFromWhitelist(authorized); - await this.crowdsale.buyTokens(authorized, { value: value, from: authorized }).should.be.rejected; - }); - }); - - describe('reporting whitelisted', function () { - it('should correctly report whitelisted addresses', async function () { - let isAuthorized = await this.crowdsale.whitelist(authorized); - isAuthorized.should.equal(true); - let isntAuthorized = await this.crowdsale.whitelist(unauthorized); - isntAuthorized.should.equal(false); - }); - }); - }); - - describe('many user whitelisting', function () { - beforeEach(async function () { - this.token = await SimpleToken.new(); - this.crowdsale = await WhitelistedCrowdsale.new(rate, wallet, this.token.address); - await this.token.transfer(this.crowdsale.address, tokenSupply); - await this.crowdsale.addManyToWhitelist([authorized, anotherAuthorized]); - }); - - describe('accepting payments', function () { - it('should accept payments to whitelisted (from whichever buyers)', async function () { - await this.crowdsale.buyTokens(authorized, { value: value, from: authorized }).should.be.fulfilled; - await this.crowdsale.buyTokens(authorized, { value: value, from: unauthorized }).should.be.fulfilled; - await this.crowdsale.buyTokens(anotherAuthorized, { value: value, from: authorized }).should.be.fulfilled; - await this.crowdsale.buyTokens(anotherAuthorized, { value: value, from: unauthorized }).should.be.fulfilled; - }); - - it('should reject payments to not whitelisted (with whichever buyers)', async function () { - await this.crowdsale.send(value).should.be.rejected; - await this.crowdsale.buyTokens(unauthorized, { value: value, from: unauthorized }).should.be.rejected; - await this.crowdsale.buyTokens(unauthorized, { value: value, from: authorized }).should.be.rejected; - }); - - it('should reject payments to addresses removed from whitelist', async function () { - await this.crowdsale.removeFromWhitelist(anotherAuthorized); - await this.crowdsale.buyTokens(authorized, { value: value, from: authorized }).should.be.fulfilled; - await this.crowdsale.buyTokens(anotherAuthorized, { value: value, from: authorized }).should.be.rejected; - }); - }); - - describe('reporting whitelisted', function () { - it('should correctly report whitelisted addresses', async function () { - let isAuthorized = await this.crowdsale.whitelist(authorized); - isAuthorized.should.equal(true); - let isAnotherAuthorized = await this.crowdsale.whitelist(anotherAuthorized); - isAnotherAuthorized.should.equal(true); - let isntAuthorized = await this.crowdsale.whitelist(unauthorized); - isntAuthorized.should.equal(false); - }); - }); - }); -}); diff --git a/test/examples/SampleCrowdsale.test.js b/test/examples/SampleCrowdsale.test.js deleted file mode 100644 index 45d0c216e..000000000 --- a/test/examples/SampleCrowdsale.test.js +++ /dev/null @@ -1,126 +0,0 @@ -import ether from '../helpers/ether'; -import { advanceBlock } from '../helpers/advanceToBlock'; -import { increaseTimeTo, duration } from '../helpers/increaseTime'; -import latestTime from '../helpers/latestTime'; -import EVMRevert from '../helpers/EVMRevert'; -import assertRevert from '../helpers/assertRevert'; - -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const SampleCrowdsale = artifacts.require('SampleCrowdsale'); -const SampleCrowdsaleToken = artifacts.require('SampleCrowdsaleToken'); -const RefundVault = artifacts.require('RefundVault'); - -contract('SampleCrowdsale', function ([owner, wallet, investor]) { - const RATE = new BigNumber(10); - const GOAL = ether(10); - const CAP = ether(20); - - before(async function () { - // Advance to the next block to correctly read time in the solidity "now" function interpreted by ganache - await advanceBlock(); - }); - - beforeEach(async function () { - this.openingTime = latestTime() + duration.weeks(1); - this.closingTime = this.openingTime + duration.weeks(1); - this.afterClosingTime = this.closingTime + duration.seconds(1); - - this.token = await SampleCrowdsaleToken.new({ from: owner }); - this.vault = await RefundVault.new(wallet, { from: owner }); - this.crowdsale = await SampleCrowdsale.new( - this.openingTime, this.closingTime, RATE, wallet, CAP, this.token.address, GOAL - ); - await this.token.transferOwnership(this.crowdsale.address); - await this.vault.transferOwnership(this.crowdsale.address); - }); - - it('should create crowdsale with correct parameters', async function () { - this.crowdsale.should.exist; - this.token.should.exist; - - const openingTime = await this.crowdsale.openingTime(); - const closingTime = await this.crowdsale.closingTime(); - const rate = await this.crowdsale.rate(); - const walletAddress = await this.crowdsale.wallet(); - const goal = await this.crowdsale.goal(); - const cap = await this.crowdsale.cap(); - - openingTime.should.be.bignumber.equal(this.openingTime); - closingTime.should.be.bignumber.equal(this.closingTime); - rate.should.be.bignumber.equal(RATE); - walletAddress.should.be.equal(wallet); - goal.should.be.bignumber.equal(GOAL); - cap.should.be.bignumber.equal(CAP); - }); - - it('should not accept payments before start', async function () { - await this.crowdsale.send(ether(1)).should.be.rejectedWith(EVMRevert); - await this.crowdsale.buyTokens(investor, { from: investor, value: ether(1) }).should.be.rejectedWith(EVMRevert); - }); - - it('should accept payments during the sale', async function () { - const investmentAmount = ether(1); - const expectedTokenAmount = RATE.mul(investmentAmount); - - await increaseTimeTo(this.openingTime); - await this.crowdsale.buyTokens(investor, { value: investmentAmount, from: investor }).should.be.fulfilled; - - (await this.token.balanceOf(investor)).should.be.bignumber.equal(expectedTokenAmount); - (await this.token.totalSupply()).should.be.bignumber.equal(expectedTokenAmount); - }); - - it('should reject payments after end', async function () { - await increaseTimeTo(this.afterEnd); - await this.crowdsale.send(ether(1)).should.be.rejectedWith(EVMRevert); - await this.crowdsale.buyTokens(investor, { value: ether(1), from: investor }).should.be.rejectedWith(EVMRevert); - }); - - it('should reject payments over cap', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.send(CAP); - await this.crowdsale.send(1).should.be.rejectedWith(EVMRevert); - }); - - it('should allow finalization and transfer funds to wallet if the goal is reached', async function () { - await increaseTimeTo(this.openingTime); - await this.crowdsale.send(GOAL); - - const beforeFinalization = web3.eth.getBalance(wallet); - await increaseTimeTo(this.afterClosingTime); - await this.crowdsale.finalize({ from: owner }); - const afterFinalization = web3.eth.getBalance(wallet); - - afterFinalization.minus(beforeFinalization).should.be.bignumber.equal(GOAL); - }); - - it('should allow refunds if the goal is not reached', async function () { - const balanceBeforeInvestment = web3.eth.getBalance(investor); - - await increaseTimeTo(this.openingTime); - await this.crowdsale.sendTransaction({ value: ether(1), from: investor, gasPrice: 0 }); - await increaseTimeTo(this.afterClosingTime); - - await this.crowdsale.finalize({ from: owner }); - await this.crowdsale.claimRefund({ from: investor, gasPrice: 0 }).should.be.fulfilled; - - const balanceAfterRefund = web3.eth.getBalance(investor); - balanceBeforeInvestment.should.be.bignumber.equal(balanceAfterRefund); - }); - - describe('when goal > cap', function () { - // goal > cap - const HIGH_GOAL = ether(30); - - it('creation reverts', async function () { - await assertRevert(SampleCrowdsale.new( - this.openingTime, this.closingTime, RATE, wallet, CAP, this.token.address, HIGH_GOAL - )); - }); - }); -}); diff --git a/test/examples/SimpleToken.test.js b/test/examples/SimpleToken.test.js deleted file mode 100644 index 3d173ca35..000000000 --- a/test/examples/SimpleToken.test.js +++ /dev/null @@ -1,41 +0,0 @@ -import decodeLogs from '../helpers/decodeLogs'; -const SimpleToken = artifacts.require('SimpleToken'); - -contract('SimpleToken', accounts => { - let token; - const creator = accounts[0]; - - beforeEach(async function () { - token = await SimpleToken.new({ from: creator }); - }); - - it('has a name', async function () { - const name = await token.name(); - assert.equal(name, 'SimpleToken'); - }); - - it('has a symbol', async function () { - const symbol = await token.symbol(); - assert.equal(symbol, 'SIM'); - }); - - it('has 18 decimals', async function () { - const decimals = await token.decimals(); - assert(decimals.eq(18)); - }); - - it('assigns the initial total supply to the creator', async function () { - const totalSupply = await token.totalSupply(); - const creatorBalance = await token.balanceOf(creator); - - assert(creatorBalance.eq(totalSupply)); - - const receipt = web3.eth.getTransactionReceipt(token.transactionHash); - const logs = decodeLogs(receipt.logs, SimpleToken, token.address); - assert.equal(logs.length, 1); - assert.equal(logs[0].event, 'Transfer'); - assert.equal(logs[0].args.from.valueOf(), 0x0); - assert.equal(logs[0].args.to.valueOf(), creator); - assert(logs[0].args.value.eq(totalSupply)); - }); -}); diff --git a/test/library/ECRecovery.test.js b/test/library/ECRecovery.test.js deleted file mode 100644 index 7ea55823f..000000000 --- a/test/library/ECRecovery.test.js +++ /dev/null @@ -1,77 +0,0 @@ - -import { - hashMessage, - signMessage, -} from '../helpers/sign'; -const ECRecoveryMock = artifacts.require('ECRecoveryMock'); - -require('chai') - .use(require('chai-as-promised')) - .should(); - -contract('ECRecovery', function (accounts) { - let ecrecovery; - const TEST_MESSAGE = 'OpenZeppelin'; - - before(async function () { - ecrecovery = await ECRecoveryMock.new(); - }); - - it('recover v0', async function () { - // Signature generated outside ganache with method web3.eth.sign(signer, message) - let signer = '0x2cc1166f6212628a0deef2b33befb2187d35b86c'; - let message = web3.sha3(TEST_MESSAGE); - // eslint-disable-next-line max-len - let signature = '0x5d99b6f7f6d1f73d1a26497f2b1c89b24c0993913f86e9a2d02cd69887d9c94f3c880358579d811b21dd1b7fd9bb01c1d81d10e69f0384e675c32b39643be89200'; - const addrRecovered = await ecrecovery.recover(message, signature); - addrRecovered.should.eq(signer); - }); - - it('recover v1', async function () { - // Signature generated outside ganache with method web3.eth.sign(signer, message) - let signer = '0x1e318623ab09fe6de3c9b8672098464aeda9100e'; - let message = web3.sha3(TEST_MESSAGE); - // eslint-disable-next-line max-len - let signature = '0x331fe75a821c982f9127538858900d87d3ec1f9f737338ad67cad133fa48feff48e6fa0c18abc62e42820f05943e47af3e9fbe306ce74d64094bdf1691ee53e001'; - const addrRecovered = await ecrecovery.recover(message, signature); - addrRecovered.should.eq(signer); - }); - - it('recover using web3.eth.sign()', async function () { - // Create the signature using account[0] - const signature = signMessage(accounts[0], TEST_MESSAGE); - - // Recover the signer address from the generated message and signature. - const addrRecovered = await ecrecovery.recover( - hashMessage(TEST_MESSAGE), - signature - ); - addrRecovered.should.eq(accounts[0]); - }); - - it('recover using web3.eth.sign() should return wrong signer', async function () { - // Create the signature using account[0] - const signature = signMessage(accounts[0], TEST_MESSAGE); - - // Recover the signer address from the generated message and wrong signature. - const addrRecovered = await ecrecovery.recover(hashMessage('Test'), signature); - assert.notEqual(accounts[0], addrRecovered); - }); - - it('recover should fail when a wrong hash is sent', async function () { - // Create the signature using account[0] - let signature = signMessage(accounts[0], TEST_MESSAGE); - - // Recover the signer address from the generated message and wrong signature. - const addrRecovered = await ecrecovery.recover(hashMessage(TEST_MESSAGE).substring(2), signature); - addrRecovered.should.eq('0x0000000000000000000000000000000000000000'); - }); - - context('toEthSignedMessage', () => { - it('should prefix hashes correctly', async function () { - const hashedMessage = web3.sha3(TEST_MESSAGE); - const ethMessage = await ecrecovery.toEthSignedMessageHash(hashedMessage); - ethMessage.should.eq(hashMessage(TEST_MESSAGE)); - }); - }); -}); diff --git a/test/library/Math.test.js b/test/library/Math.test.js deleted file mode 100644 index c671bc85f..000000000 --- a/test/library/Math.test.js +++ /dev/null @@ -1,43 +0,0 @@ -var MathMock = artifacts.require('MathMock'); - -contract('Math', function (accounts) { - let math; - - before(async function () { - math = await MathMock.new(); - }); - - it('returns max64 correctly', async function () { - let a = 5678; - let b = 1234; - await math.max64(a, b); - let result = await math.result64(); - assert.equal(result, a); - }); - - it('returns min64 correctly', async function () { - let a = 5678; - let b = 1234; - await math.min64(a, b); - let result = await math.result64(); - - assert.equal(result, b); - }); - - it('returns max256 correctly', async function () { - let a = 5678; - let b = 1234; - await math.max256(a, b); - let result = await math.result256(); - assert.equal(result, a); - }); - - it('returns min256 correctly', async function () { - let a = 5678; - let b = 1234; - await math.min256(a, b); - let result = await math.result256(); - - assert.equal(result, b); - }); -}); diff --git a/test/library/MerkleProof.test.js b/test/library/MerkleProof.test.js deleted file mode 100644 index 1e8da3c8f..000000000 --- a/test/library/MerkleProof.test.js +++ /dev/null @@ -1,61 +0,0 @@ - -import MerkleTree from '../helpers/merkleTree.js'; -import { sha3, bufferToHex } from 'ethereumjs-util'; - -var MerkleProofWrapper = artifacts.require('MerkleProofWrapper'); - -contract('MerkleProof', function (accounts) { - let merkleProof; - - before(async function () { - merkleProof = await MerkleProofWrapper.new(); - }); - - describe('verifyProof', function () { - it('should return true for a valid Merkle proof', async function () { - const elements = ['a', 'b', 'c', 'd']; - const merkleTree = new MerkleTree(elements); - - const root = merkleTree.getHexRoot(); - - const proof = merkleTree.getHexProof(elements[0]); - - const leaf = bufferToHex(sha3(elements[0])); - - const result = await merkleProof.verifyProof(proof, root, leaf); - assert.isOk(result, 'verifyProof did not return true for a valid proof'); - }); - - it('should return false for an invalid Merkle proof', async function () { - const correctElements = ['a', 'b', 'c']; - const correctMerkleTree = new MerkleTree(correctElements); - - const correctRoot = correctMerkleTree.getHexRoot(); - - const correctLeaf = bufferToHex(sha3(correctElements[0])); - - const badElements = ['d', 'e', 'f']; - const badMerkleTree = new MerkleTree(badElements); - - const badProof = badMerkleTree.getHexProof(badElements[0]); - - const result = await merkleProof.verifyProof(badProof, correctRoot, correctLeaf); - assert.isNotOk(result, 'verifyProof did not return false for an invalid proof'); - }); - - it('should return false for a Merkle proof of invalid length', async function () { - const elements = ['a', 'b', 'c']; - const merkleTree = new MerkleTree(elements); - - const root = merkleTree.getHexRoot(); - - const proof = merkleTree.getHexProof(elements[0]); - const badProof = proof.slice(0, proof.length - 5); - - const leaf = bufferToHex(sha3(elements[0])); - - const result = await merkleProof.verifyProof(badProof, root, leaf); - assert.isNotOk(result, 'verifyProof did not return false for proof of invalid length'); - }); - }); -}); diff --git a/test/lifecycle/Destructible.test.js b/test/lifecycle/Destructible.test.js deleted file mode 100644 index 2757d76cd..000000000 --- a/test/lifecycle/Destructible.test.js +++ /dev/null @@ -1,23 +0,0 @@ - -var Destructible = artifacts.require('Destructible'); -require('../helpers/transactionMined.js'); - -contract('Destructible', function (accounts) { - it('should send balance to owner after destruction', async function () { - let destructible = await Destructible.new({ from: accounts[0], value: web3.toWei('10', 'ether') }); - let owner = await destructible.owner(); - let initBalance = web3.eth.getBalance(owner); - await destructible.destroy({ from: owner }); - let newBalance = web3.eth.getBalance(owner); - assert.isTrue(newBalance > initBalance); - }); - - it('should send balance to recepient after destruction', async function () { - let destructible = await Destructible.new({ from: accounts[0], value: web3.toWei('10', 'ether') }); - let owner = await destructible.owner(); - let initBalance = web3.eth.getBalance(accounts[1]); - await destructible.destroyAndSend(accounts[1], { from: owner }); - let newBalance = web3.eth.getBalance(accounts[1]); - assert.isTrue(newBalance.greaterThan(initBalance)); - }); -}); diff --git a/test/lifecycle/TokenDestructible.test.js b/test/lifecycle/TokenDestructible.test.js deleted file mode 100644 index 8566bf190..000000000 --- a/test/lifecycle/TokenDestructible.test.js +++ /dev/null @@ -1,37 +0,0 @@ - -var TokenDestructible = artifacts.require('TokenDestructible'); -var StandardTokenMock = artifacts.require('StandardTokenMock'); -require('../helpers/transactionMined.js'); - -contract('TokenDestructible', function (accounts) { - let destructible; - - beforeEach(async function () { - destructible = await TokenDestructible.new({ - from: accounts[0], - value: web3.toWei('10', 'ether'), - }); - }); - - it('should send balance to owner after destruction', async function () { - let owner = await destructible.owner(); - let initBalance = web3.eth.getBalance(owner); - await destructible.destroy([], { from: owner }); - let newBalance = web3.eth.getBalance(owner); - assert.isTrue(newBalance > initBalance); - }); - - it('should send tokens to owner after destruction', async function () { - let owner = await destructible.owner(); - let token = await StandardTokenMock.new(destructible.address, 100); - let initContractBalance = await token.balanceOf(destructible.address); - let initOwnerBalance = await token.balanceOf(owner); - assert.equal(initContractBalance, 100); - assert.equal(initOwnerBalance, 0); - await destructible.destroy([token.address], { from: owner }); - let newContractBalance = await token.balanceOf(destructible.address); - let newOwnerBalance = await token.balanceOf(owner); - assert.equal(newContractBalance, 0); - assert.equal(newOwnerBalance, 100); - }); -}); diff --git a/test/ownership/CanReclaimToken.test.js b/test/ownership/CanReclaimToken.test.js deleted file mode 100644 index 6f0f2c671..000000000 --- a/test/ownership/CanReclaimToken.test.js +++ /dev/null @@ -1,35 +0,0 @@ - -import expectThrow from '../helpers/expectThrow'; - -const CanReclaimToken = artifacts.require('CanReclaimToken'); -const BasicTokenMock = artifacts.require('BasicTokenMock'); - -contract('CanReclaimToken', function (accounts) { - let token = null; - let canReclaimToken = null; - - beforeEach(async function () { - // Create contract and token - token = await BasicTokenMock.new(accounts[0], 100); - canReclaimToken = await CanReclaimToken.new(); - // Force token into contract - await token.transfer(canReclaimToken.address, 10); - const startBalance = await token.balanceOf(canReclaimToken.address); - assert.equal(startBalance, 10); - }); - - it('should allow owner to reclaim tokens', async function () { - const ownerStartBalance = await token.balanceOf(accounts[0]); - await canReclaimToken.reclaimToken(token.address); - const ownerFinalBalance = await token.balanceOf(accounts[0]); - const finalBalance = await token.balanceOf(canReclaimToken.address); - assert.equal(finalBalance, 0); - assert.equal(ownerFinalBalance - ownerStartBalance, 10); - }); - - it('should allow only owner to reclaim tokens', async function () { - await expectThrow( - canReclaimToken.reclaimToken(token.address, { from: accounts[1] }), - ); - }); -}); diff --git a/test/ownership/Claimable.test.js b/test/ownership/Claimable.test.js deleted file mode 100644 index 52340fb94..000000000 --- a/test/ownership/Claimable.test.js +++ /dev/null @@ -1,53 +0,0 @@ - -import assertRevert from '../helpers/assertRevert'; - -var Claimable = artifacts.require('Claimable'); - -contract('Claimable', function (accounts) { - let claimable; - - beforeEach(async function () { - claimable = await Claimable.new(); - }); - - it('should have an owner', async function () { - let owner = await claimable.owner(); - assert.isTrue(owner !== 0); - }); - - it('changes pendingOwner after transfer', async function () { - let newOwner = accounts[1]; - await claimable.transferOwnership(newOwner); - let pendingOwner = await claimable.pendingOwner(); - - assert.isTrue(pendingOwner === newOwner); - }); - - it('should prevent to claimOwnership from no pendingOwner', async function () { - await assertRevert(claimable.claimOwnership({ from: accounts[2] })); - }); - - it('should prevent non-owners from transfering', async function () { - const other = accounts[2]; - const owner = await claimable.owner.call(); - - assert.isTrue(owner !== other); - await assertRevert(claimable.transferOwnership(other, { from: other })); - }); - - describe('after initiating a transfer', function () { - let newOwner; - - beforeEach(async function () { - newOwner = accounts[1]; - await claimable.transferOwnership(newOwner); - }); - - it('changes allow pending owner to claim ownership', async function () { - await claimable.claimOwnership({ from: newOwner }); - let owner = await claimable.owner(); - - assert.isTrue(owner === newOwner); - }); - }); -}); diff --git a/test/ownership/Contactable.test.js b/test/ownership/Contactable.test.js deleted file mode 100644 index 901ba4824..000000000 --- a/test/ownership/Contactable.test.js +++ /dev/null @@ -1,28 +0,0 @@ - -var Contactable = artifacts.require('Contactable'); - -contract('Contactable', function (accounts) { - let contactable; - - beforeEach(async function () { - contactable = await Contactable.new(); - }); - - it('should have an empty contact info', async function () { - let info = await contactable.contactInformation(); - assert.isTrue(info === ''); - }); - - describe('after setting the contact information', function () { - let contactInfo = 'contact information'; - - beforeEach(async function () { - await contactable.setContactInformation(contactInfo); - }); - - it('should return the setted contact information', async function () { - let info = await contactable.contactInformation(); - assert.isTrue(info === contactInfo); - }); - }); -}); diff --git a/test/ownership/DelayedClaimable.test.js b/test/ownership/DelayedClaimable.test.js deleted file mode 100644 index 90be7fbc9..000000000 --- a/test/ownership/DelayedClaimable.test.js +++ /dev/null @@ -1,55 +0,0 @@ -import assertRevert from '../helpers/assertRevert'; - -var DelayedClaimable = artifacts.require('DelayedClaimable'); - -contract('DelayedClaimable', function (accounts) { - var delayedClaimable; - - beforeEach(function () { - return DelayedClaimable.new().then(function (deployed) { - delayedClaimable = deployed; - }); - }); - - it('can set claim blocks', async function () { - await delayedClaimable.transferOwnership(accounts[2]); - await delayedClaimable.setLimits(0, 1000); - let end = await delayedClaimable.end(); - assert.equal(end, 1000); - let start = await delayedClaimable.start(); - assert.equal(start, 0); - }); - - it('changes pendingOwner after transfer successful', async function () { - await delayedClaimable.transferOwnership(accounts[2]); - await delayedClaimable.setLimits(0, 1000); - let end = await delayedClaimable.end(); - assert.equal(end, 1000); - let start = await delayedClaimable.start(); - assert.equal(start, 0); - let pendingOwner = await delayedClaimable.pendingOwner(); - assert.equal(pendingOwner, accounts[2]); - await delayedClaimable.claimOwnership({ from: accounts[2] }); - let owner = await delayedClaimable.owner(); - assert.equal(owner, accounts[2]); - }); - - it('changes pendingOwner after transfer fails', async function () { - await delayedClaimable.transferOwnership(accounts[1]); - await delayedClaimable.setLimits(100, 110); - let end = await delayedClaimable.end(); - assert.equal(end, 110); - let start = await delayedClaimable.start(); - assert.equal(start, 100); - let pendingOwner = await delayedClaimable.pendingOwner(); - assert.equal(pendingOwner, accounts[1]); - await assertRevert(delayedClaimable.claimOwnership({ from: accounts[1] })); - let owner = await delayedClaimable.owner(); - assert.isTrue(owner !== accounts[1]); - }); - - it('set end and start invalid values fail', async function () { - await delayedClaimable.transferOwnership(accounts[1]); - await assertRevert(delayedClaimable.setLimits(1001, 1000)); - }); -}); diff --git a/test/ownership/HasNoContracts.test.js b/test/ownership/HasNoContracts.test.js deleted file mode 100644 index f2020a173..000000000 --- a/test/ownership/HasNoContracts.test.js +++ /dev/null @@ -1,33 +0,0 @@ - -import expectThrow from '../helpers/expectThrow'; - -const Ownable = artifacts.require('Ownable'); -const HasNoContracts = artifacts.require('HasNoContracts'); - -contract('HasNoContracts', function (accounts) { - let hasNoContracts = null; - let ownable = null; - - beforeEach(async () => { - // Create contract and token - hasNoContracts = await HasNoContracts.new(); - ownable = await Ownable.new(); - - // Force ownership into contract - await ownable.transferOwnership(hasNoContracts.address); - const owner = await ownable.owner(); - assert.equal(owner, hasNoContracts.address); - }); - - it('should allow owner to reclaim contracts', async function () { - await hasNoContracts.reclaimContract(ownable.address); - const owner = await ownable.owner(); - assert.equal(owner, accounts[0]); - }); - - it('should allow only owner to reclaim contracts', async function () { - await expectThrow( - hasNoContracts.reclaimContract(ownable.address, { from: accounts[1] }), - ); - }); -}); diff --git a/test/ownership/HasNoEther.test.js b/test/ownership/HasNoEther.test.js deleted file mode 100644 index ff95e998f..000000000 --- a/test/ownership/HasNoEther.test.js +++ /dev/null @@ -1,64 +0,0 @@ - -import expectThrow from '../helpers/expectThrow'; -import toPromise from '../helpers/toPromise'; -const HasNoEtherTest = artifacts.require('HasNoEtherTest'); -const ForceEther = artifacts.require('ForceEther'); - -contract('HasNoEther', function (accounts) { - const amount = web3.toWei('1', 'ether'); - - it('should be constructorable', async function () { - await HasNoEtherTest.new(); - }); - - it('should not accept ether in constructor', async function () { - await expectThrow(HasNoEtherTest.new({ value: amount })); - }); - - it('should not accept ether', async function () { - let hasNoEther = await HasNoEtherTest.new(); - - await expectThrow( - toPromise(web3.eth.sendTransaction)({ - from: accounts[1], - to: hasNoEther.address, - value: amount, - }), - ); - }); - - it('should allow owner to reclaim ether', async function () { - // Create contract - let hasNoEther = await HasNoEtherTest.new(); - const startBalance = await web3.eth.getBalance(hasNoEther.address); - assert.equal(startBalance, 0); - - // Force ether into it - let forceEther = await ForceEther.new({ value: amount }); - await forceEther.destroyAndSend(hasNoEther.address); - const forcedBalance = await web3.eth.getBalance(hasNoEther.address); - assert.equal(forcedBalance, amount); - - // Reclaim - const ownerStartBalance = await web3.eth.getBalance(accounts[0]); - await hasNoEther.reclaimEther(); - const ownerFinalBalance = await web3.eth.getBalance(accounts[0]); - const finalBalance = await web3.eth.getBalance(hasNoEther.address); - assert.equal(finalBalance, 0); - assert.isAbove(ownerFinalBalance, ownerStartBalance); - }); - - it('should allow only owner to reclaim ether', async function () { - // Create contract - let hasNoEther = await HasNoEtherTest.new({ from: accounts[0] }); - - // Force ether into it - let forceEther = await ForceEther.new({ value: amount }); - await forceEther.destroyAndSend(hasNoEther.address); - const forcedBalance = await web3.eth.getBalance(hasNoEther.address); - assert.equal(forcedBalance, amount); - - // Reclaim - await expectThrow(hasNoEther.reclaimEther({ from: accounts[1] })); - }); -}); diff --git a/test/ownership/HasNoTokens.test.js b/test/ownership/HasNoTokens.test.js deleted file mode 100644 index e9c14a7f5..000000000 --- a/test/ownership/HasNoTokens.test.js +++ /dev/null @@ -1,40 +0,0 @@ - -import expectThrow from '../helpers/expectThrow'; - -const HasNoTokens = artifacts.require('HasNoTokens'); -const ERC223TokenMock = artifacts.require('ERC223TokenMock'); - -contract('HasNoTokens', function (accounts) { - let hasNoTokens = null; - let token = null; - - beforeEach(async () => { - // Create contract and token - hasNoTokens = await HasNoTokens.new(); - token = await ERC223TokenMock.new(accounts[0], 100); - - // Force token into contract - await token.transfer(hasNoTokens.address, 10); - const startBalance = await token.balanceOf(hasNoTokens.address); - assert.equal(startBalance, 10); - }); - - it('should not accept ERC223 tokens', async function () { - await expectThrow(token.transferERC223(hasNoTokens.address, 10, '')); - }); - - it('should allow owner to reclaim tokens', async function () { - const ownerStartBalance = await token.balanceOf(accounts[0]); - await hasNoTokens.reclaimToken(token.address); - const ownerFinalBalance = await token.balanceOf(accounts[0]); - const finalBalance = await token.balanceOf(hasNoTokens.address); - assert.equal(finalBalance, 0); - assert.equal(ownerFinalBalance - ownerStartBalance, 10); - }); - - it('should allow only owner to reclaim tokens', async function () { - await expectThrow( - hasNoTokens.reclaimToken(token.address, { from: accounts[1] }), - ); - }); -}); diff --git a/test/ownership/Whitelist.test.js b/test/ownership/Whitelist.test.js deleted file mode 100644 index e0ae29f96..000000000 --- a/test/ownership/Whitelist.test.js +++ /dev/null @@ -1,103 +0,0 @@ -import expectThrow from '../helpers/expectThrow'; -import expectEvent from '../helpers/expectEvent'; - -const WhitelistMock = artifacts.require('WhitelistMock'); - -require('chai') - .use(require('chai-as-promised')) - .should(); - -contract('Whitelist', function (accounts) { - let mock; - - const [ - owner, - whitelistedAddress1, - whitelistedAddress2, - anyone, - ] = accounts; - - const whitelistedAddresses = [whitelistedAddress1, whitelistedAddress2]; - - before(async function () { - mock = await WhitelistMock.new(); - }); - - context('in normal conditions', () => { - it('should add address to the whitelist', async function () { - await expectEvent.inTransaction( - mock.addAddressToWhitelist(whitelistedAddress1, { from: owner }), - 'WhitelistedAddressAdded' - ); - const isWhitelisted = await mock.whitelist(whitelistedAddress1); - isWhitelisted.should.be.equal(true); - }); - - it('should add addresses to the whitelist', async function () { - await expectEvent.inTransaction( - mock.addAddressesToWhitelist(whitelistedAddresses, { from: owner }), - 'WhitelistedAddressAdded' - ); - for (let addr of whitelistedAddresses) { - const isWhitelisted = await mock.whitelist(addr); - isWhitelisted.should.be.equal(true); - } - }); - - it('should not announce WhitelistedAddressAdded event if address is already in the whitelist', async function () { - const { logs } = await mock.addAddressToWhitelist(whitelistedAddress1, { from: owner }); - logs.should.be.empty; - }); - - it('should remove address from the whitelist', async function () { - await expectEvent.inTransaction( - mock.removeAddressFromWhitelist(whitelistedAddress1, { from: owner }), - 'WhitelistedAddressRemoved' - ); - let isWhitelisted = await mock.whitelist(whitelistedAddress1); - isWhitelisted.should.be.equal(false); - }); - - it('should remove addresses from the the whitelist', async function () { - await expectEvent.inTransaction( - mock.removeAddressesFromWhitelist(whitelistedAddresses, { from: owner }), - 'WhitelistedAddressRemoved' - ); - for (let addr of whitelistedAddresses) { - const isWhitelisted = await mock.whitelist(addr); - isWhitelisted.should.be.equal(false); - } - }); - - it('should not announce WhitelistedAddressRemoved event if address is not in the whitelist', async function () { - const { logs } = await mock.removeAddressFromWhitelist(whitelistedAddress1, { from: owner }); - logs.should.be.empty; - }); - - it('should allow whitelisted address to call #onlyWhitelistedCanDoThis', async () => { - await mock.addAddressToWhitelist(whitelistedAddress1, { from: owner }); - await mock.onlyWhitelistedCanDoThis({ from: whitelistedAddress1 }) - .should.be.fulfilled; - }); - }); - - context('in adversarial conditions', () => { - it('should not allow "anyone" to add to the whitelist', async () => { - await expectThrow( - mock.addAddressToWhitelist(whitelistedAddress1, { from: anyone }) - ); - }); - - it('should not allow "anyone" to remove from the whitelist', async () => { - await expectThrow( - mock.removeAddressFromWhitelist(whitelistedAddress1, { from: anyone }) - ); - }); - - it('should not allow "anyone" to call #onlyWhitelistedCanDoThis', async () => { - await expectThrow( - mock.onlyWhitelistedCanDoThis({ from: anyone }) - ); - }); - }); -}); diff --git a/test/ownership/rbac/RBAC.test.js b/test/ownership/rbac/RBAC.test.js deleted file mode 100644 index e748efba5..000000000 --- a/test/ownership/rbac/RBAC.test.js +++ /dev/null @@ -1,98 +0,0 @@ -import expectThrow from '../../helpers/expectThrow'; -import expectEvent from '../../helpers/expectEvent'; - -const RBACMock = artifacts.require('RBACMock'); - -require('chai') - .use(require('chai-as-promised')) - .should(); - -const ROLE_ADVISOR = 'advisor'; - -contract('RBAC', function (accounts) { - let mock; - - const [ - admin, - anyone, - futureAdvisor, - ...advisors - ] = accounts; - - before(async () => { - mock = await RBACMock.new(advisors, { from: admin }); - }); - - context('in normal conditions', () => { - it('allows admin to call #onlyAdminsCanDoThis', async () => { - await mock.onlyAdminsCanDoThis({ from: admin }) - .should.be.fulfilled; - }); - it('allows admin to call #onlyAdvisorsCanDoThis', async () => { - await mock.onlyAdvisorsCanDoThis({ from: admin }) - .should.be.fulfilled; - }); - it('allows advisors to call #onlyAdvisorsCanDoThis', async () => { - await mock.onlyAdvisorsCanDoThis({ from: advisors[0] }) - .should.be.fulfilled; - }); - it('allows admin to call #eitherAdminOrAdvisorCanDoThis', async () => { - await mock.eitherAdminOrAdvisorCanDoThis({ from: admin }) - .should.be.fulfilled; - }); - it('allows advisors to call #eitherAdminOrAdvisorCanDoThis', async () => { - await mock.eitherAdminOrAdvisorCanDoThis({ from: advisors[0] }) - .should.be.fulfilled; - }); - it('does not allow admins to call #nobodyCanDoThis', async () => { - await expectThrow( - mock.nobodyCanDoThis({ from: admin }) - ); - }); - it('does not allow advisors to call #nobodyCanDoThis', async () => { - await expectThrow( - mock.nobodyCanDoThis({ from: advisors[0] }) - ); - }); - it('does not allow anyone to call #nobodyCanDoThis', async () => { - await expectThrow( - mock.nobodyCanDoThis({ from: anyone }) - ); - }); - it('allows an admin to remove an advisor\'s role', async () => { - await mock.removeAdvisor(advisors[0], { from: admin }) - .should.be.fulfilled; - }); - it('allows admins to #adminRemoveRole', async () => { - await mock.adminRemoveRole(advisors[3], ROLE_ADVISOR, { from: admin }) - .should.be.fulfilled; - }); - - it('announces a RoleAdded event on addRole', async () => { - await expectEvent.inTransaction( - mock.adminAddRole(futureAdvisor, ROLE_ADVISOR, { from: admin }), - 'RoleAdded' - ); - }); - - it('announces a RoleRemoved event on removeRole', async () => { - await expectEvent.inTransaction( - mock.adminRemoveRole(futureAdvisor, ROLE_ADVISOR, { from: admin }), - 'RoleRemoved' - ); - }); - }); - - context('in adversarial conditions', () => { - it('does not allow an advisor to remove another advisor', async () => { - await expectThrow( - mock.removeAdvisor(advisors[1], { from: advisors[0] }) - ); - }); - it('does not allow "anyone" to remove an advisor', async () => { - await expectThrow( - mock.removeAdvisor(advisors[0], { from: anyone }) - ); - }); - }); -}); diff --git a/test/payment/PullPayment.test.js b/test/payment/PullPayment.test.js deleted file mode 100644 index 8f5a4e41a..000000000 --- a/test/payment/PullPayment.test.js +++ /dev/null @@ -1,71 +0,0 @@ -var PullPaymentMock = artifacts.require('PullPaymentMock'); - -contract('PullPayment', function (accounts) { - let ppce; - let amount = 17 * 1e18; - - beforeEach(async function () { - ppce = await PullPaymentMock.new({ value: amount }); - }); - - it('can\'t call asyncSend externally', async function () { - assert.isUndefined(ppce.asyncSend); - }); - - it('can record an async payment correctly', async function () { - let AMOUNT = 100; - await ppce.callSend(accounts[0], AMOUNT); - let paymentsToAccount0 = await ppce.payments(accounts[0]); - let totalPayments = await ppce.totalPayments(); - - assert.equal(totalPayments, AMOUNT); - assert.equal(paymentsToAccount0, AMOUNT); - }); - - it('can add multiple balances on one account', async function () { - await ppce.callSend(accounts[0], 200); - await ppce.callSend(accounts[0], 300); - let paymentsToAccount0 = await ppce.payments(accounts[0]); - let totalPayments = await ppce.totalPayments(); - - assert.equal(totalPayments, 500); - assert.equal(paymentsToAccount0, 500); - }); - - it('can add balances on multiple accounts', async function () { - await ppce.callSend(accounts[0], 200); - await ppce.callSend(accounts[1], 300); - - let paymentsToAccount0 = await ppce.payments(accounts[0]); - assert.equal(paymentsToAccount0, 200); - - let paymentsToAccount1 = await ppce.payments(accounts[1]); - assert.equal(paymentsToAccount1, 300); - - let totalPayments = await ppce.totalPayments(); - assert.equal(totalPayments, 500); - }); - - it('can withdraw payment', async function () { - let payee = accounts[1]; - let initialBalance = web3.eth.getBalance(payee); - - await ppce.callSend(payee, amount); - - let payment1 = await ppce.payments(payee); - assert.equal(payment1, amount); - - let totalPayments = await ppce.totalPayments(); - assert.equal(totalPayments, amount); - - await ppce.withdrawPayments({ from: payee }); - let payment2 = await ppce.payments(payee); - assert.equal(payment2, 0); - - totalPayments = await ppce.totalPayments(); - assert.equal(totalPayments, 0); - - let balance = web3.eth.getBalance(payee); - assert(Math.abs(balance - initialBalance - amount) < 1e16); - }); -}); diff --git a/test/payment/SplitPayment.test.js b/test/payment/SplitPayment.test.js deleted file mode 100644 index dd18eaeac..000000000 --- a/test/payment/SplitPayment.test.js +++ /dev/null @@ -1,78 +0,0 @@ -const BigNumber = web3.BigNumber; - -require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -const EVMThrow = require('../helpers/EVMThrow.js'); -const SplitPayment = artifacts.require('SplitPayment'); - -contract('SplitPayment', function ([owner, payee1, payee2, payee3, nonpayee1, payer1]) { - const amount = web3.toWei(1.0, 'ether'); - - beforeEach(async function () { - this.payees = [payee1, payee2, payee3]; - this.shares = [20, 10, 70]; - - this.contract = await SplitPayment.new(this.payees, this.shares); - }); - - it('should accept payments', async function () { - await web3.eth.sendTransaction({ from: owner, to: this.contract.address, value: amount }); - - const balance = web3.eth.getBalance(this.contract.address); - balance.should.be.bignumber.equal(amount); - }); - - it('should store shares if address is payee', async function () { - const shares = await this.contract.shares.call(payee1); - shares.should.be.bignumber.not.equal(0); - }); - - it('should not store shares if address is not payee', async function () { - const shares = await this.contract.shares.call(nonpayee1); - shares.should.be.bignumber.equal(0); - }); - - it('should throw if no funds to claim', async function () { - await this.contract.claim({ from: payee1 }).should.be.rejectedWith(EVMThrow); - }); - - it('should throw if non-payee want to claim', async function () { - await web3.eth.sendTransaction({ from: payer1, to: this.contract.address, value: amount }); - await this.contract.claim({ from: nonpayee1 }).should.be.rejectedWith(EVMThrow); - }); - - it('should distribute funds to payees', async function () { - await web3.eth.sendTransaction({ from: payer1, to: this.contract.address, value: amount }); - - // receive funds - const initBalance = web3.eth.getBalance(this.contract.address); - initBalance.should.be.bignumber.equal(amount); - - // distribute to payees - const initAmount1 = web3.eth.getBalance(payee1); - await this.contract.claim({ from: payee1 }); - const profit1 = web3.eth.getBalance(payee1) - initAmount1; - assert(Math.abs(profit1 - web3.toWei(0.20, 'ether')) < 1e16); - - const initAmount2 = web3.eth.getBalance(payee2); - await this.contract.claim({ from: payee2 }); - const profit2 = web3.eth.getBalance(payee2) - initAmount2; - assert(Math.abs(profit2 - web3.toWei(0.10, 'ether')) < 1e16); - - const initAmount3 = web3.eth.getBalance(payee3); - await this.contract.claim({ from: payee3 }); - const profit3 = web3.eth.getBalance(payee3) - initAmount3; - assert(Math.abs(profit3 - web3.toWei(0.70, 'ether')) < 1e16); - - // end balance should be zero - const endBalance = web3.eth.getBalance(this.contract.address); - endBalance.should.be.bignumber.equal(0); - - // check correct funds released accounting - const totalReleased = await this.contract.totalReleased.call(); - totalReleased.should.be.bignumber.equal(initBalance); - }); -}); diff --git a/test/token/ERC20/CappedToken.test.js b/test/token/ERC20/CappedToken.test.js deleted file mode 100644 index c3fa5af6b..000000000 --- a/test/token/ERC20/CappedToken.test.js +++ /dev/null @@ -1,36 +0,0 @@ - -import expectThrow from '../../helpers/expectThrow'; -import ether from '../../helpers/ether'; - -var CappedToken = artifacts.require('CappedToken'); - -contract('Capped', function (accounts) { - const cap = ether(1000); - - let token; - - beforeEach(async function () { - token = await CappedToken.new(cap); - }); - - it('should start with the correct cap', async function () { - let _cap = await token.cap(); - - assert(cap.eq(_cap)); - }); - - it('should mint when amount is less than cap', async function () { - const result = await token.mint(accounts[0], 100); - assert.equal(result.logs[0].event, 'Mint'); - }); - - it('should fail to mint if the ammount exceeds the cap', async function () { - await token.mint(accounts[0], cap.sub(1)); - await expectThrow(token.mint(accounts[0], 100)); - }); - - it('should fail to mint after cap is reached', async function () { - await token.mint(accounts[0], cap); - await expectThrow(token.mint(accounts[0], 1)); - }); -}); diff --git a/test/token/ERC827/ERC827Token.js b/test/token/ERC827/ERC827Token.js deleted file mode 100644 index f82f3fdf0..000000000 --- a/test/token/ERC827/ERC827Token.js +++ /dev/null @@ -1,374 +0,0 @@ - -import EVMRevert from '../../helpers/EVMRevert'; -var Message = artifacts.require('MessageHelper'); -var ERC827TokenMock = artifacts.require('ERC827TokenMock'); - -var BigNumber = web3.BigNumber; -var _ = require('lodash'); -var ethjsABI = require('ethjs-abi'); -require('chai') - .use(require('chai-as-promised')) - .use(require('chai-bignumber')(BigNumber)) - .should(); - -contract('ERC827 Token', function (accounts) { - let token; - - function findMethod (abi, name, args) { - for (var i = 0; i < abi.length; i++) { - const methodArgs = _.map(abi[i].inputs, 'type').join(','); - if ((abi[i].name === name) && (methodArgs === args)) { - return abi[i]; - } - } - } - - beforeEach(async function () { - token = await ERC827TokenMock.new(accounts[0], 100); - }); - - it('should return the correct totalSupply after construction', async function () { - let totalSupply = await token.totalSupply(); - - assert.equal(totalSupply, 100); - }); - - it('should return the correct allowance amount after approval', async function () { - let token = await ERC827TokenMock.new(accounts[0], 100); - await token.approve(accounts[1], 100); - let allowance = await token.allowance(accounts[0], accounts[1]); - - assert.equal(allowance, 100); - }); - - it('should return correct balances after transfer', async function () { - await token.transfer(accounts[1], 100); - let balance0 = await token.balanceOf(accounts[0]); - assert.equal(balance0, 0); - - let balance1 = await token.balanceOf(accounts[1]); - assert.equal(balance1, 100); - }); - - it('should throw an error when trying to transfer more than balance', async function () { - await token.transfer(accounts[1], 101).should.be.rejectedWith(EVMRevert); - }); - - it('should return correct balances after transfering from another account', async function () { - await token.approve(accounts[1], 100); - await token.transferFrom(accounts[0], accounts[2], 100, { from: accounts[1] }); - - let balance0 = await token.balanceOf(accounts[0]); - assert.equal(balance0, 0); - - let balance1 = await token.balanceOf(accounts[2]); - assert.equal(balance1, 100); - - let balance2 = await token.balanceOf(accounts[1]); - assert.equal(balance2, 0); - }); - - it('should throw an error when trying to transfer more than allowed', async function () { - await token.approve(accounts[1], 99); - await token.transferFrom( - accounts[0], accounts[2], 100, - { from: accounts[1] } - ).should.be.rejectedWith(EVMRevert); - }); - - it('should throw an error when trying to transferFrom more than _from has', async function () { - let balance0 = await token.balanceOf(accounts[0]); - await token.approve(accounts[1], 99); - await token.transferFrom( - accounts[0], accounts[2], balance0 + 1, - { from: accounts[1] } - ).should.be.rejectedWith(EVMRevert); - }); - - describe('validating allowance updates to spender', function () { - let preApproved; - - it('should start with zero', async function () { - preApproved = await token.allowance(accounts[0], accounts[1]); - assert.equal(preApproved, 0); - }); - - it('should increase by 50 then decrease by 10', async function () { - const abiMethod = findMethod(token.abi, 'increaseApproval', 'address,uint256'); - const increaseApprovalData = ethjsABI.encodeMethod(abiMethod, - [accounts[1], 50] - ); - await token.sendTransaction( - { from: accounts[0], data: increaseApprovalData } - ); - let postIncrease = await token.allowance(accounts[0], accounts[1]); - preApproved.plus(50).should.be.bignumber.equal(postIncrease); - await token.decreaseApproval(accounts[1], 10); - let postDecrease = await token.allowance(accounts[0], accounts[1]); - postIncrease.minus(10).should.be.bignumber.equal(postDecrease); - }); - }); - - it('should increase by 50 then set to 0 when decreasing by more than 50', async function () { - await token.approve(accounts[1], 50); - await token.decreaseApproval(accounts[1], 60); - let postDecrease = await token.allowance(accounts[0], accounts[1]); - postDecrease.should.be.bignumber.equal(0); - }); - - it('should throw an error when trying to transfer to 0x0', async function () { - await token.transfer(0x0, 100).should.be.rejectedWith(EVMRevert); - }); - - it('should throw an error when trying to transferFrom to 0x0', async function () { - await token.approve(accounts[1], 100); - await token.transferFrom(accounts[0], 0x0, 100, { from: accounts[1] }) - .should.be.rejectedWith(EVMRevert); - }); - - describe('Test ERC827 methods', function () { - it( - 'should return correct balances after transfer (with data) and show the event on receiver contract' - , async function () { - const message = await Message.new(); - - const extraData = message.contract.showMessage.getData( - web3.toHex(123456), 666, 'Transfer Done' - ); - const abiMethod = findMethod(token.abi, 'transfer', 'address,uint256,bytes'); - const transferData = ethjsABI.encodeMethod(abiMethod, - [message.contract.address, 100, extraData] - ); - const transaction = await token.sendTransaction( - { from: accounts[0], data: transferData } - ); - - assert.equal(2, transaction.receipt.logs.length); - - new BigNumber(100).should.be.bignumber.equal( - await token.balanceOf(message.contract.address) - ); - }); - - it( - 'should return correct allowance after approve (with data) and show the event on receiver contract' - , async function () { - const message = await Message.new(); - - const extraData = message.contract.showMessage.getData( - web3.toHex(123456), 666, 'Transfer Done' - ); - - const abiMethod = findMethod(token.abi, 'approve', 'address,uint256,bytes'); - const approveData = ethjsABI.encodeMethod(abiMethod, - [message.contract.address, 100, extraData] - ); - const transaction = await token.sendTransaction( - { from: accounts[0], data: approveData } - ); - - assert.equal(2, transaction.receipt.logs.length); - - new BigNumber(100).should.be.bignumber.equal( - await token.allowance(accounts[0], message.contract.address) - ); - }); - - it( - 'should return correct allowance after increaseApproval (with data) and show the event on receiver contract' - , async function () { - const message = await Message.new(); - - const extraData = message.contract.showMessage.getData( - web3.toHex(123456), 666, 'Transfer Done' - ); - - await token.approve(message.contract.address, 10); - new BigNumber(10).should.be.bignumber.equal( - await token.allowance(accounts[0], message.contract.address) - ); - - const abiMethod = findMethod(token.abi, 'increaseApproval', 'address,uint256,bytes'); - const increaseApprovalData = ethjsABI.encodeMethod(abiMethod, - [message.contract.address, 50, extraData] - ); - const transaction = await token.sendTransaction( - { from: accounts[0], data: increaseApprovalData } - ); - - assert.equal(2, transaction.receipt.logs.length); - - new BigNumber(60).should.be.bignumber.equal( - await token.allowance(accounts[0], message.contract.address) - ); - }); - - it( - 'should return correct allowance after decreaseApproval (with data) and show the event on receiver contract' - , async function () { - const message = await Message.new(); - - await token.approve(message.contract.address, 100); - - new BigNumber(100).should.be.bignumber.equal( - await token.allowance(accounts[0], message.contract.address) - ); - - const extraData = message.contract.showMessage.getData( - web3.toHex(123456), 666, 'Transfer Done' - ); - - const abiMethod = findMethod(token.abi, 'decreaseApproval', 'address,uint256,bytes'); - const decreaseApprovalData = ethjsABI.encodeMethod(abiMethod, - [message.contract.address, 60, extraData] - ); - const transaction = await token.sendTransaction( - { from: accounts[0], data: decreaseApprovalData } - ); - - assert.equal(2, transaction.receipt.logs.length); - - new BigNumber(40).should.be.bignumber.equal( - await token.allowance(accounts[0], message.contract.address) - ); - }); - - it( - 'should return correct balances after transferFrom (with data) and show the event on receiver contract' - , async function () { - const message = await Message.new(); - - const extraData = message.contract.showMessage.getData( - web3.toHex(123456), 666, 'Transfer Done' - ); - - await token.approve(accounts[1], 100, { from: accounts[0] }); - - new BigNumber(100).should.be.bignumber.equal( - await token.allowance(accounts[0], accounts[1]) - ); - - const abiMethod = findMethod(token.abi, 'transferFrom', 'address,address,uint256,bytes'); - const transferFromData = ethjsABI.encodeMethod(abiMethod, - [accounts[0], message.contract.address, 100, extraData] - ); - const transaction = await token.sendTransaction( - { from: accounts[1], data: transferFromData } - ); - - assert.equal(2, transaction.receipt.logs.length); - - new BigNumber(100).should.be.bignumber.equal( - await token.balanceOf(message.contract.address) - ); - }); - - it('should fail inside approve (with data)', async function () { - const message = await Message.new(); - - const extraData = message.contract.fail.getData(); - - const abiMethod = findMethod(token.abi, 'approve', 'address,uint256,bytes'); - const approveData = ethjsABI.encodeMethod(abiMethod, - [message.contract.address, 10, extraData] - ); - await token.sendTransaction( - { from: accounts[0], data: approveData } - ).should.be.rejectedWith(EVMRevert); - - // approval should not have gone through so allowance is still 0 - new BigNumber(0).should.be.bignumber - .equal(await token.allowance(accounts[1], message.contract.address)); - }); - - it('should fail inside transfer (with data)', async function () { - const message = await Message.new(); - - const extraData = message.contract.fail.getData(); - - const abiMethod = findMethod(token.abi, 'transfer', 'address,uint256,bytes'); - const transferData = ethjsABI.encodeMethod(abiMethod, - [message.contract.address, 10, extraData] - ); - await token.sendTransaction( - { from: accounts[0], data: transferData } - ).should.be.rejectedWith(EVMRevert); - - // transfer should not have gone through, so balance is still 0 - new BigNumber(0).should.be.bignumber - .equal(await token.balanceOf(message.contract.address)); - }); - - it('should fail inside transferFrom (with data)', async function () { - const message = await Message.new(); - - const extraData = message.contract.fail.getData(); - - await token.approve(accounts[1], 10, { from: accounts[2] }); - - const abiMethod = findMethod(token.abi, 'transferFrom', 'address,address,uint256,bytes'); - const transferFromData = ethjsABI.encodeMethod(abiMethod, - [accounts[2], message.contract.address, 10, extraData] - ); - await token.sendTransaction( - { from: accounts[1], data: transferFromData } - ).should.be.rejectedWith(EVMRevert); - - // transferFrom should have failed so balance is still 0 but allowance is 10 - new BigNumber(10).should.be.bignumber - .equal(await token.allowance(accounts[2], accounts[1])); - new BigNumber(0).should.be.bignumber - .equal(await token.balanceOf(message.contract.address)); - }); - - it('should fail approve (with data) when using token contract address as receiver', async function () { - const message = await Message.new(); - - const extraData = message.contract.showMessage.getData( - web3.toHex(123456), 666, 'Transfer Done' - ); - - const abiMethod = findMethod(token.abi, 'approve', 'address,uint256,bytes'); - const approveData = ethjsABI.encodeMethod(abiMethod, - [token.contract.address, 100, extraData] - ); - await token.sendTransaction( - { from: accounts[0], data: approveData } - ).should.be.rejectedWith(EVMRevert); - }); - - it('should fail transfer (with data) when using token contract address as receiver', async function () { - const message = await Message.new(); - - const extraData = message.contract.showMessage.getData( - web3.toHex(123456), 666, 'Transfer Done' - ); - - const abiMethod = findMethod(token.abi, 'transfer', 'address,uint256,bytes'); - const transferData = ethjsABI.encodeMethod(abiMethod, - [token.contract.address, 100, extraData] - ); - await token.sendTransaction( - { from: accounts[0], data: transferData } - ).should.be.rejectedWith(EVMRevert); - }); - - it('should fail transferFrom (with data) when using token contract address as receiver', async function () { - const message = await Message.new(); - - const extraData = message.contract.showMessage.getData( - web3.toHex(123456), 666, 'Transfer Done' - ); - - await token.approve(accounts[1], 1, { from: accounts[0] }); - - const abiMethod = findMethod(token.abi, 'transferFrom', 'address,address,uint256,bytes'); - const transferFromData = ethjsABI.encodeMethod(abiMethod, - [accounts[0], token.contract.address, 1, extraData] - ); - await token.sendTransaction( - { from: accounts[1], data: transferFromData } - ).should.be.rejectedWith(EVMRevert); - }); - }); -});