Unverified Commit 689e18aa by Alejandro Santander Committed by GitHub

Merge branch 'master' into fix/docs

parents 2cb2799a 7a19bcf6
...@@ -15,3 +15,9 @@ matrix: ...@@ -15,3 +15,9 @@ matrix:
- env: SOLIDITY_COVERAGE=true - env: SOLIDITY_COVERAGE=true
script: script:
- yarn test - yarn test
notifications:
slack:
rooms:
- secure: uEhwUkuwJp5pBNh+VTEytPHz3FDKsnPrKO+8MTAKv5hKi4PCRoVhLv6pklr82HUpL6pvSvJbUPA0HVebOXA+MMSxdny/BHZTh2mtw5Y78l2Ad0svDTWuV2Lus2pmhYigRhT0Wo00/SRX9+pxm0kg4EIFJSTS+uR9G76x0l9NljpEGXrqxlDxjxoHBgk8Ciru2LHaLzX/utE3jlABts4Sb1F3wc2BwFkjd6BDCRTGAPhVJwwFk41ZfnmLVbgSNUyk46Cb38oG5oXHb0FI3d3jV/k1OUhRyFfmA2fLXRk0wavibW8TG1gGJJWZ7xTCKzw/Cvup6mpehSAeQef8eekMdjpWEhF9hYRq1BvOs0384UU8NQ0O+BtdXU+X3Nyr84TMJN/iIfgN7gYX7AsvXH3jC0JfNUcIkWlJvyXdE6l2GV1hMmhL09GFEBbSpuSXRIWlOXTcYBlp5NbvE8xO8PUW+T6N5RG2XXjv1g8wCpr6Wwk1+LmRkX5trv8MFBZ2pM8p4H5da5++Ov8egLonNGK2jbx6aBLBX3tPf+g70LZEkiQ4eBfZw8VIgXIvKreisicppNuCD27gNmSEPNt0NkwiEBcTCJ9GSVAO0CU2g4ggvHDX2A+RW5XPET9bGkBXKLfFyV7Qe+MSQjXkCnW3bIRh7Wo1V31XiUiYOLuZPIiH3EQ=
on_success: change
on_failure: always
...@@ -44,7 +44,7 @@ contract Crowdsale { ...@@ -44,7 +44,7 @@ contract Crowdsale {
require(_startTime >= now); require(_startTime >= now);
require(_endTime >= _startTime); require(_endTime >= _startTime);
require(_rate > 0); require(_rate > 0);
require(_wallet != 0x0); require(_wallet != address(0));
token = createTokenContract(); token = createTokenContract();
startTime = _startTime; startTime = _startTime;
...@@ -67,7 +67,7 @@ contract Crowdsale { ...@@ -67,7 +67,7 @@ contract Crowdsale {
// low level token purchase function // low level token purchase function
function buyTokens(address beneficiary) public payable { function buyTokens(address beneficiary) public payable {
require(beneficiary != 0x0); require(beneficiary != address(0));
require(validPurchase()); require(validPurchase());
uint256 weiAmount = msg.value; uint256 weiAmount = msg.value;
......
...@@ -23,7 +23,7 @@ contract RefundVault is Ownable { ...@@ -23,7 +23,7 @@ contract RefundVault is Ownable {
event Refunded(address indexed beneficiary, uint256 weiAmount); event Refunded(address indexed beneficiary, uint256 weiAmount);
function RefundVault(address _wallet) { function RefundVault(address _wallet) {
require(_wallet != 0x0); require(_wallet != address(0));
wallet = _wallet; wallet = _wallet;
state = State.Active; state = State.Active;
} }
......
...@@ -7,8 +7,11 @@ pragma solidity ^0.4.11; ...@@ -7,8 +7,11 @@ pragma solidity ^0.4.11;
*/ */
library SafeMath { library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) { function mul(uint256 a, uint256 b) internal constant returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b; uint256 c = a * b;
assert(a == 0 || c / a == b); assert(c / a == b);
return c; return c;
} }
......
...@@ -34,6 +34,6 @@ contract Claimable is Ownable { ...@@ -34,6 +34,6 @@ contract Claimable is Ownable {
function claimOwnership() onlyPendingOwner public { function claimOwnership() onlyPendingOwner public {
OwnershipTransferred(owner, pendingOwner); OwnershipTransferred(owner, pendingOwner);
owner = pendingOwner; owner = pendingOwner;
pendingOwner = 0x0; pendingOwner = address(0);
} }
} }
...@@ -35,7 +35,7 @@ contract DelayedClaimable is Claimable { ...@@ -35,7 +35,7 @@ contract DelayedClaimable is Claimable {
require((block.number <= end) && (block.number >= start)); require((block.number <= end) && (block.number >= start));
OwnershipTransferred(owner, pendingOwner); OwnershipTransferred(owner, pendingOwner);
owner = pendingOwner; owner = pendingOwner;
pendingOwner = 0x0; pendingOwner = address(0);
end = 0; end = 0;
} }
......
pragma solidity ^0.4.11;
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) {
require(_payees.length == _shares.length);
for (uint256 i = 0; i < _payees.length; i++) {
addPayee(_payees[i], _shares[i]);
}
}
/**
* @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);
}
/**
* @dev Claim your share of the balance.
*/
function claim() public {
address payee = msg.sender;
require(shares[payee] > 0);
uint256 totalReceived = this.balance.add(totalReleased);
uint256 payment = totalReceived.mul(shares[payee]).div(totalShares).sub(released[payee]);
require(payment != 0);
require(this.balance >= payment);
released[payee] = released[payee].add(payment);
totalReleased = totalReleased.add(payment);
payee.transfer(payment);
}
}
pragma solidity ^0.4.11;
import './ERC20.sol';
contract DetailedERC20 is ERC20 {
string public name;
string public symbol;
uint8 public decimals;
function DetailedERC20(string _name, string _symbol, uint8 _decimals) {
name = _name;
symbol = _symbol;
decimals = _decimals;
}
}
...@@ -35,7 +35,7 @@ contract MintableToken is StandardToken, Ownable { ...@@ -35,7 +35,7 @@ contract MintableToken is StandardToken, Ownable {
totalSupply = totalSupply.add(_amount); totalSupply = totalSupply.add(_amount);
balances[_to] = balances[_to].add(_amount); balances[_to] = balances[_to].add(_amount);
Mint(_to, _amount); Mint(_to, _amount);
Transfer(0x0, _to, _amount); Transfer(address(0), _to, _amount);
return true; return true;
} }
...@@ -43,7 +43,7 @@ contract MintableToken is StandardToken, Ownable { ...@@ -43,7 +43,7 @@ contract MintableToken is StandardToken, Ownable {
* @dev Function to stop minting new tokens. * @dev Function to stop minting new tokens.
* @return True if the operation was successful. * @return True if the operation was successful.
*/ */
function finishMinting() onlyOwner public returns (bool) { function finishMinting() onlyOwner canMint public returns (bool) {
mintingFinished = true; mintingFinished = true;
MintFinished(); MintFinished();
return true; return true;
......
...@@ -30,15 +30,6 @@ contract TokenTimelock { ...@@ -30,15 +30,6 @@ contract TokenTimelock {
/** /**
* @notice Transfers tokens held by timelock to beneficiary. * @notice Transfers tokens held by timelock to beneficiary.
* Deprecated: please use TokenTimelock#release instead.
*/
function claim() public {
require(msg.sender == beneficiary);
release();
}
/**
* @notice Transfers tokens held by timelock to beneficiary.
*/ */
function release() public { function release() public {
require(now >= releaseTime); require(now >= releaseTime);
......
pragma solidity ^0.4.11; pragma solidity ^0.4.11;
import './ERC20Basic.sol'; import './ERC20Basic.sol';
import './SafeERC20.sol';
import '../ownership/Ownable.sol'; import '../ownership/Ownable.sol';
import '../math/Math.sol';
import '../math/SafeMath.sol'; import '../math/SafeMath.sol';
/** /**
...@@ -13,20 +13,22 @@ import '../math/SafeMath.sol'; ...@@ -13,20 +13,22 @@ import '../math/SafeMath.sol';
*/ */
contract TokenVesting is Ownable { contract TokenVesting is Ownable {
using SafeMath for uint256; using SafeMath for uint256;
using SafeERC20 for ERC20Basic;
event Released(uint256 amount); event Released(uint256 amount);
event Revoked(); event Revoked();
// beneficiary of tokens after they are released // beneficiary of tokens after they are released
address beneficiary; address public beneficiary;
uint256 cliff; uint256 public cliff;
uint256 start; uint256 public start;
uint256 duration; uint256 public duration;
bool revocable; bool public revocable;
mapping (address => uint256) released; mapping (address => uint256) public released;
mapping (address => bool) public revoked;
/** /**
* @dev Creates a vesting contract that vests its balance of any ERC20 token to the * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
...@@ -38,13 +40,13 @@ contract TokenVesting is Ownable { ...@@ -38,13 +40,13 @@ contract TokenVesting is Ownable {
* @param _revocable whether the vesting is revocable or not * @param _revocable whether the vesting is revocable or not
*/ */
function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) { function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) {
require(_beneficiary != 0x0); require(_beneficiary != address(0));
require(_cliff <= _duration); require(_cliff <= _duration);
beneficiary = _beneficiary; beneficiary = _beneficiary;
revocable = _revocable; revocable = _revocable;
duration = _duration; duration = _duration;
cliff = _start + _cliff; cliff = _start.add(_cliff);
start = _start; start = _start;
} }
...@@ -52,30 +54,35 @@ contract TokenVesting is Ownable { ...@@ -52,30 +54,35 @@ contract TokenVesting is Ownable {
* @notice Transfers vested tokens to beneficiary. * @notice Transfers vested tokens to beneficiary.
* @param token ERC20 token which is being vested * @param token ERC20 token which is being vested
*/ */
function release(ERC20Basic token) { function release(ERC20Basic token) public {
uint256 vested = vestedAmount(token); uint256 unreleased = releasableAmount(token);
require(vested > 0); require(unreleased > 0);
token.transfer(beneficiary, vested); released[token] = released[token].add(unreleased);
released[token] = released[token].add(vested); token.safeTransfer(beneficiary, unreleased);
Released(vested); Released(unreleased);
} }
/** /**
* @notice Allows the owner to revoke the vesting. Tokens already vested remain in the contract. * @notice Allows the owner to revoke the vesting. Tokens already vested
* remain in the contract, the rest are returned to the owner.
* @param token ERC20 token which is being vested * @param token ERC20 token which is being vested
*/ */
function revoke(ERC20Basic token) onlyOwner { function revoke(ERC20Basic token) public onlyOwner {
require(revocable); require(revocable);
require(!revoked[token]);
uint256 balance = token.balanceOf(this); uint256 balance = token.balanceOf(this);
uint256 vested = vestedAmount(token); uint256 unreleased = releasableAmount(token);
uint256 refund = balance.sub(unreleased);
token.transfer(owner, balance - vested); revoked[token] = true;
token.safeTransfer(owner, refund);
Revoked(); Revoked();
} }
...@@ -84,20 +91,24 @@ contract TokenVesting is Ownable { ...@@ -84,20 +91,24 @@ contract TokenVesting is Ownable {
* @dev Calculates the amount that has already vested but hasn't been released yet. * @dev Calculates the amount that has already vested but hasn't been released yet.
* @param token ERC20 token which is being vested * @param token ERC20 token which is being vested
*/ */
function vestedAmount(ERC20Basic token) constant returns (uint256) { function releasableAmount(ERC20Basic token) public constant returns (uint256) {
if (now < cliff) { return vestedAmount(token).sub(released[token]);
return 0; }
} else if (now >= start + duration) {
return token.balanceOf(this); /**
} else { * @dev Calculates the amount that has already vested.
* @param token ERC20 token which is being vested
*/
function vestedAmount(ERC20Basic token) public constant returns (uint256) {
uint256 currentBalance = token.balanceOf(this); uint256 currentBalance = token.balanceOf(this);
uint256 totalBalance = currentBalance.add(released[token]); uint256 totalBalance = currentBalance.add(released[token]);
uint256 vested = totalBalance.mul(now - start).div(duration); if (now < cliff) {
uint256 unreleased = vested.sub(released[token]); return 0;
} else if (now >= start.add(duration) || revoked[token]) {
// currentBalance can be 0 in case of vesting being revoked earlier. return totalBalance;
return Math.min256(currentBalance, unreleased); } else {
return totalBalance.mul(now.sub(start)).div(duration);
} }
} }
} }
...@@ -14,7 +14,7 @@ To create a bounty for your contract, inherit from the base `Bounty` contract an ...@@ -14,7 +14,7 @@ To create a bounty for your contract, inherit from the base `Bounty` contract an
Next, implement invariant logic into your smart contract. Next, implement invariant logic into your smart contract.
Your main contract should inherit from the Target class and implement the checkInvariant method. This is a function that should check everything your contract assumes to be true all the time. If this function returns false, it means your contract was broken in some way and is in an inconsistent state. This is what security researchers will try to acomplish when trying to get the bounty. Your main contract should inherit from the `Target` class and implement the ```checkInvariant()``` method. This is a function that should check everything your contract assumes to be true all the time. If this function returns false, it means your contract was broken in some way and is in an inconsistent state. This is what security researchers will try to acomplish when trying to get the bounty.
At contracts/YourContract.sol:: At contracts/YourContract.sol::
...@@ -35,7 +35,7 @@ At ```migrations/2_deploy_contracts.js```:: ...@@ -35,7 +35,7 @@ At ```migrations/2_deploy_contracts.js```::
deployer.deploy(YourBounty); deployer.deploy(YourBounty);
}; };
Next, add a reward to the bounty contract Next, add a reward to the bounty contract.
After deploying the contract, send reward funds into the bounty contract. After deploying the contract, send reward funds into the bounty contract.
......
ECReovery ECRecovery
============================================= =============================================
Returns the signer of the the hash using the signature divided in v, r, and s values. Returns the signer of the hash using the signature divided in v, r, and s values.
recover(bytes32 hash, bytes sig) internal returns (address) recover(bytes32 hash, bytes sig) internal returns (address)
""""""""""""""""""""""""""""""""""""""""""""""""" """""""""""""""""""""""""""""""""""""""""""""""""
......
...@@ -9,6 +9,7 @@ OpenZeppelin integrates with `Truffle <https://github.com/ConsenSys/truffle/>`_, ...@@ -9,6 +9,7 @@ OpenZeppelin integrates with `Truffle <https://github.com/ConsenSys/truffle/>`_,
To install the OpenZeppelin library, run:: To install the OpenZeppelin library, run::
npm init # follow instructions
npm install zeppelin-solidity npm install zeppelin-solidity
# If you are using yarn, add dependency like this - # If you are using yarn, add dependency like this -
......
{ {
"name": "zeppelin-solidity", "name": "zeppelin-solidity",
"version": "1.2.0", "version": "1.3.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
...@@ -5084,15 +5084,6 @@ ...@@ -5084,15 +5084,6 @@
"xtend": "4.0.1" "xtend": "4.0.1"
} }
}, },
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"dev": true,
"requires": {
"safe-buffer": "5.1.1"
}
},
"string-width": { "string-width": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
...@@ -5115,6 +5106,15 @@ ...@@ -5115,6 +5106,15 @@
"function-bind": "1.1.0" "function-bind": "1.1.0"
} }
}, },
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"dev": true,
"requires": {
"safe-buffer": "5.1.1"
}
},
"stringstream": { "stringstream": {
"version": "0.0.5", "version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
......
'use strict'; 'use strict';
const assertJump = require('./helpers/assertJump'); const assertJump = require('./helpers/assertJump');
const timer = require('./helpers/timer'); import latestTime from './helpers/latestTime'
import {increaseTimeTo, duration} from './helpers/increaseTime'
var DayLimitMock = artifacts.require('./helpers/DayLimitMock.sol'); var DayLimitMock = artifacts.require('./helpers/DayLimitMock.sol');
contract('DayLimit', function(accounts) { contract('DayLimit', function(accounts) {
const day = 60 * 60 * 24;
let dayLimit; let dayLimit;
let initLimit = 10; let initLimit = 10;
beforeEach( async function() { beforeEach( async function() {
this.startTime = latestTime();
dayLimit = await DayLimitMock.new(initLimit); dayLimit = await DayLimitMock.new(initLimit);
}); });
...@@ -99,7 +100,7 @@ contract('DayLimit', function(accounts) { ...@@ -99,7 +100,7 @@ contract('DayLimit', function(accounts) {
spentToday = await dayLimit.spentToday(); spentToday = await dayLimit.spentToday();
assert.equal(spentToday, 8); assert.equal(spentToday, 8);
await timer(day); await increaseTimeTo(this.startTime + duration.days(1));
await dayLimit.attemptSpend(3); await dayLimit.attemptSpend(3);
spentToday = await dayLimit.spentToday(); spentToday = await dayLimit.spentToday();
......
const BigNumber = web3.BigNumber;
require('chai')
.use(require('chai-as-promised'))
.use(require('chai-bignumber')(BigNumber))
.should();
const DetailedERC20Mock = artifacts.require('./helpers/DetailedERC20Mock.sol');
contract('DetailedERC20', accounts => {
let detailedERC20 = null;
const _name = "My Detailed ERC20";
const _symbol = "MDT";
const _decimals = 18;
beforeEach(async function() {
detailedERC20 = await DetailedERC20Mock.new(_name, _symbol, _decimals);
});
it('has a name', async function () {
const name = await detailedERC20.name();
name.should.be.equal(_name);
});
it('has a symbol', async function () {
const symbol = await detailedERC20.symbol();
symbol.should.be.equal(_symbol);
});
it('has an amount of decimals', async function () {
const decimals = await detailedERC20.decimals();
decimals.should.be.bignumber.equal(_decimals)
});
});
const BigNumber = web3.BigNumber
const should = require('chai')
.use(require('chai-as-promised'))
.use(require('chai-bignumber')(BigNumber))
.should()
const EVMThrow = require('./helpers/EVMThrow.js')
const SplitPaymentMock = artifacts.require('./helpers/SplitPaymentMock.sol')
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 SplitPaymentMock.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)
})
})
...@@ -80,28 +80,36 @@ contract('TokenVesting', function ([_, owner, beneficiary]) { ...@@ -80,28 +80,36 @@ contract('TokenVesting', function ([_, owner, beneficiary]) {
}); });
it('should return the non-vested tokens when revoked by owner', async function () { it('should return the non-vested tokens when revoked by owner', async function () {
await increaseTimeTo(this.start + this.cliff + duration.weeks(1)); await increaseTimeTo(this.start + this.cliff + duration.weeks(12));
await this.vesting.release(this.token.address);
const vested = await this.vesting.vestedAmount(this.token.address); const vested = await this.vesting.vestedAmount(this.token.address);
const balance = await this.token.balanceOf(this.vesting.address);
await this.vesting.revoke(this.token.address, { from: owner }); await this.vesting.revoke(this.token.address, { from: owner });
const ownerBalance = await this.token.balanceOf(owner); const ownerBalance = await this.token.balanceOf(owner);
ownerBalance.should.bignumber.equal(balance.sub(vested)); ownerBalance.should.bignumber.equal(amount.sub(vested));
}); });
it('should keep the vested tokens when revoked by owner', async function () { it('should keep the vested tokens when revoked by owner', async function () {
await increaseTimeTo(this.start + this.cliff + duration.weeks(1)); await increaseTimeTo(this.start + this.cliff + duration.weeks(12));
await this.vesting.release(this.token.address);
const vestedPre = await this.vesting.vestedAmount(this.token.address);
await this.vesting.revoke(this.token.address, { from: owner });
const vestedPost = await this.vesting.vestedAmount(this.token.address);
vestedPre.should.bignumber.equal(vestedPost);
});
it('should fail to be revoked a second time', async function () {
await increaseTimeTo(this.start + this.cliff + duration.weeks(12));
const vested = await this.vesting.vestedAmount(this.token.address); const vested = await this.vesting.vestedAmount(this.token.address);
await this.vesting.revoke(this.token.address, { from: owner }); await this.vesting.revoke(this.token.address, { from: owner });
const balance = await this.token.balanceOf(this.vesting.address); await this.vesting.revoke(this.token.address, { from: owner }).should.be.rejectedWith(EVMThrow);
balance.should.bignumber.equal(vested);
}); });
}); });
pragma solidity ^0.4.11;
import '../../contracts/token/StandardToken.sol';
import '../../contracts/token/DetailedERC20.sol';
contract DetailedERC20Mock is StandardToken, DetailedERC20 {
function DetailedERC20Mock(string _name, string _symbol, uint8 _decimals) DetailedERC20(_name, _symbol, _decimals) {}
}
pragma solidity ^0.4.11;
import '../../contracts/payment/SplitPayment.sol';
// mock class using SplitPayment
contract SplitPaymentMock is SplitPayment {
function SplitPaymentMock(address[] _payees, uint256[] _shares)
SplitPayment(_payees, _shares) payable {}
function () payable {}
}
...@@ -10,8 +10,9 @@ export default async promise => { ...@@ -10,8 +10,9 @@ export default async promise => {
// we distinguish this from an actual out of gas event? (The // we distinguish this from an actual out of gas event? (The
// testrpc log actually show an 'invalid jump' event.) // testrpc log actually show an 'invalid jump' event.)
const outOfGas = error.message.search('out of gas') >= 0; const outOfGas = error.message.search('out of gas') >= 0;
const revert = error.message.search('revert') >= 0;
assert( assert(
invalidOpcode || outOfGas, invalidOpcode || outOfGas || revert,
"Expected throw, got '" + error + "' instead", "Expected throw, got '" + error + "' instead",
); );
return; return;
......
// timer for tests specific to testrpc
module.exports = s => {
return new Promise((resolve, reject) => {
web3.currentProvider.sendAsync({
jsonrpc: '2.0',
method: 'evm_increaseTime',
params: [s], // 60 seaconds, may need to be hex, I forget
id: new Date().getTime() // Id of the request; anything works, really
}, function(err) {
if (err) return reject(err);
resolve();
});
//setTimeout(() => resolve(), s * 1000 + 600) // 600ms breathing room for testrpc to sync
});
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment