Merge with master
This commit is contained in:
@ -31,7 +31,7 @@ contract('Bounty', function(accounts) {
|
||||
assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber());
|
||||
});
|
||||
|
||||
it('empties itself when killed', async function(){
|
||||
it('empties itself when destroyed', async function(){
|
||||
let owner = accounts[0];
|
||||
let reward = web3.toWei(1, 'ether');
|
||||
let bounty = await SecureTargetBounty.new();
|
||||
@ -39,7 +39,7 @@ contract('Bounty', function(accounts) {
|
||||
|
||||
assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber());
|
||||
|
||||
await bounty.kill();
|
||||
await bounty.destroy();
|
||||
assert.equal(0, web3.eth.getBalance(bounty.address).toNumber());
|
||||
});
|
||||
|
||||
@ -52,7 +52,7 @@ contract('Bounty', function(accounts) {
|
||||
let bounty = await SecureTargetBounty.new();
|
||||
let event = bounty.TargetCreated({});
|
||||
|
||||
event.watch(async function(err, result) {
|
||||
let watcher = async function(err, result) {
|
||||
event.stopWatching();
|
||||
if (err) { throw err; }
|
||||
|
||||
@ -66,8 +66,8 @@ contract('Bounty', function(accounts) {
|
||||
await bounty.claim(targetAddress, {from:researcher});
|
||||
assert.isTrue(false); // should never reach here
|
||||
} catch(error) {
|
||||
let reClaimedBounty = await bounty.claimed.call();
|
||||
assert.isFalse(reClaimedBounty);
|
||||
let reClaimedBounty = await bounty.claimed.call();
|
||||
assert.isFalse(reClaimedBounty);
|
||||
|
||||
}
|
||||
try {
|
||||
@ -77,8 +77,9 @@ contract('Bounty', function(accounts) {
|
||||
assert.equal(reward,
|
||||
web3.eth.getBalance(bounty.address).toNumber());
|
||||
}
|
||||
});
|
||||
};
|
||||
bounty.createTarget({from:researcher});
|
||||
await awaitEvent(event, watcher);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
26
test/Destructible.js
Normal file
26
test/Destructible.js
Normal file
@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
var Destructible = artifacts.require('../contracts/lifecycle/Destructible.sol');
|
||||
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));
|
||||
});
|
||||
|
||||
});
|
||||
35
test/HasNoContracts.js
Normal file
35
test/HasNoContracts.js
Normal file
@ -0,0 +1,35 @@
|
||||
'use strict';
|
||||
import expectThrow from './helpers/expectThrow';
|
||||
import toPromise from './helpers/toPromise';
|
||||
const Ownable = artifacts.require('../contracts/ownership/Ownable.sol');
|
||||
const HasNoContracts = artifacts.require(
|
||||
'../contracts/ownership/HasNoContracts.sol',
|
||||
);
|
||||
|
||||
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]}),
|
||||
);
|
||||
});
|
||||
});
|
||||
63
test/HasNoEther.js
Normal file
63
test/HasNoEther.js
Normal file
@ -0,0 +1,63 @@
|
||||
'use strict';
|
||||
import expectThrow from './helpers/expectThrow';
|
||||
import toPromise from './helpers/toPromise';
|
||||
const HasNoEther = artifacts.require('../contracts/lifecycle/HasNoEther.sol');
|
||||
const HasNoEtherTest = artifacts.require('../helpers/HasNoEtherTest.sol');
|
||||
const ForceEther = artifacts.require('../helpers/ForceEther.sol');
|
||||
|
||||
contract('HasNoEther', function(accounts) {
|
||||
const amount = web3.toWei('1', 'ether');
|
||||
|
||||
it('should be constructorable', async function() {
|
||||
let hasNoEther = 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
|
||||
await ForceEther.new(hasNoEther.address, {value: amount});
|
||||
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
|
||||
await ForceEther.new(hasNoEther.address, {value: amount});
|
||||
const forcedBalance = await web3.eth.getBalance(hasNoEther.address);
|
||||
assert.equal(forcedBalance, amount);
|
||||
|
||||
// Reclaim
|
||||
await expectThrow(hasNoEther.reclaimEther({from: accounts[1]}));
|
||||
});
|
||||
});
|
||||
40
test/HasNoTokens.js
Normal file
40
test/HasNoTokens.js
Normal file
@ -0,0 +1,40 @@
|
||||
'use strict';
|
||||
import expectThrow from './helpers/expectThrow';
|
||||
import toPromise from './helpers/toPromise';
|
||||
const HasNoTokens = artifacts.require('../contracts/lifecycle/HasNoTokens.sol');
|
||||
const ERC23TokenMock = artifacts.require('./helpers/ERC23TokenMock.sol');
|
||||
|
||||
contract('HasNoTokens', function(accounts) {
|
||||
let hasNoTokens = null;
|
||||
let token = null;
|
||||
|
||||
beforeEach(async () => {
|
||||
// Create contract and token
|
||||
hasNoTokens = await HasNoTokens.new();
|
||||
token = await ERC23TokenMock.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 ERC23 tokens', async function() {
|
||||
await expectThrow(token.transferERC23(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]}),
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,18 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var Killable = artifacts.require('../contracts/lifecycle/Killable.sol');
|
||||
require('./helpers/transactionMined.js');
|
||||
|
||||
contract('Killable', function(accounts) {
|
||||
|
||||
it('should send balance to owner after death', async function() {
|
||||
let killable = await Killable.new({from: accounts[0], value: web3.toWei('10','ether')});
|
||||
let owner = await killable.owner();
|
||||
let initBalance = web3.eth.getBalance(owner);
|
||||
await killable.kill({from: owner});
|
||||
let newBalance = web3.eth.getBalance(owner);
|
||||
|
||||
assert.isTrue(newBalance > initBalance);
|
||||
});
|
||||
|
||||
});
|
||||
35
test/MintableToken.js
Normal file
35
test/MintableToken.js
Normal file
@ -0,0 +1,35 @@
|
||||
'use strict';
|
||||
|
||||
const assertJump = require('./helpers/assertJump');
|
||||
var MintableToken = artifacts.require('../contracts/Tokens/MintableToken.sol');
|
||||
|
||||
contract('Mintable', function(accounts) {
|
||||
let token;
|
||||
|
||||
beforeEach(async function() {
|
||||
token = await MintableToken.new();
|
||||
});
|
||||
|
||||
it('should start with a totalSupply of 0', async function() {
|
||||
let totalSupply = await token.totalSupply();
|
||||
|
||||
assert.equal(totalSupply, 0);
|
||||
});
|
||||
|
||||
it('should return mintingFinished false after construction', async function() {
|
||||
let mintingFinished = await token.mintingFinished();
|
||||
|
||||
assert.equal(mintingFinished, false);
|
||||
});
|
||||
|
||||
it('should mint a given amount of tokens to a given address', async function() {
|
||||
await token.mint(accounts[0], 100);
|
||||
|
||||
let balance0 = await token.balanceOf(accounts[0]);
|
||||
assert(balance0, 100);
|
||||
|
||||
let totalSupply = await token.totalSupply();
|
||||
assert(totalSupply, 100);
|
||||
})
|
||||
|
||||
});
|
||||
@ -22,11 +22,11 @@ contract('MultisigWallet', function(accounts) {
|
||||
let walletBalance = web3.eth.getBalance(wallet.address);
|
||||
let hash = 1234;
|
||||
|
||||
//Call kill function from two different owner accounts, satisfying owners required
|
||||
await wallet.kill(accounts[0], {data: hash});
|
||||
let txnHash = await wallet.kill(accounts[0], {from: accounts[1], data: hash});
|
||||
//Call destroy function from two different owner accounts, satisfying owners required
|
||||
await wallet.destroy(accounts[0], {data: hash});
|
||||
let txnHash = await wallet.destroy(accounts[0], {from: accounts[1], data: hash});
|
||||
|
||||
//Get balances of owner and wallet after kill function is complete, compare with previous values
|
||||
//Get balances of owner and wallet after destroy function is complete, compare with previous values
|
||||
let newOwnerBalance = web3.eth.getBalance(accounts[0]);
|
||||
let newWalletBalance = web3.eth.getBalance(wallet.address);
|
||||
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
var PausableMock = artifacts.require('helpers/PausableMock.sol');
|
||||
const assertJump = require('./helpers/assertJump');
|
||||
const PausableMock = artifacts.require('helpers/PausableMock.sol');
|
||||
|
||||
contract('Pausable', function(accounts) {
|
||||
|
||||
it('can perform normal process in non-emergency', async function() {
|
||||
it('can perform normal process in non-pause', async function() {
|
||||
let Pausable = await PausableMock.new();
|
||||
let count0 = await Pausable.count();
|
||||
assert.equal(count0, 0);
|
||||
@ -14,39 +15,47 @@ contract('Pausable', function(accounts) {
|
||||
assert.equal(count1, 1);
|
||||
});
|
||||
|
||||
it('can not perform normal process in emergency', async function() {
|
||||
it('can not perform normal process in pause', async function() {
|
||||
let Pausable = await PausableMock.new();
|
||||
await Pausable.emergencyStop();
|
||||
await Pausable.pause();
|
||||
let count0 = await Pausable.count();
|
||||
assert.equal(count0, 0);
|
||||
|
||||
await Pausable.normalProcess();
|
||||
try {
|
||||
await Pausable.normalProcess();
|
||||
} catch(error) {
|
||||
assertJump(error);
|
||||
}
|
||||
let count1 = await Pausable.count();
|
||||
assert.equal(count1, 0);
|
||||
});
|
||||
|
||||
|
||||
it('can not take drastic measure in non-emergency', async function() {
|
||||
it('can not take drastic measure in non-pause', async function() {
|
||||
let Pausable = await PausableMock.new();
|
||||
await Pausable.drasticMeasure();
|
||||
let drasticMeasureTaken = await Pausable.drasticMeasureTaken();
|
||||
try {
|
||||
await Pausable.drasticMeasure();
|
||||
} catch(error) {
|
||||
assertJump(error);
|
||||
}
|
||||
|
||||
const drasticMeasureTaken = await Pausable.drasticMeasureTaken();
|
||||
assert.isFalse(drasticMeasureTaken);
|
||||
});
|
||||
|
||||
it('can take a drastic measure in an emergency', async function() {
|
||||
it('can take a drastic measure in a pause', async function() {
|
||||
let Pausable = await PausableMock.new();
|
||||
await Pausable.emergencyStop();
|
||||
await Pausable.pause();
|
||||
await Pausable.drasticMeasure();
|
||||
let drasticMeasureTaken = await Pausable.drasticMeasureTaken();
|
||||
|
||||
assert.isTrue(drasticMeasureTaken);
|
||||
});
|
||||
|
||||
it('should resume allowing normal process after emergency is over', async function() {
|
||||
it('should resume allowing normal process after pause is over', async function() {
|
||||
let Pausable = await PausableMock.new();
|
||||
await Pausable.emergencyStop();
|
||||
await Pausable.release();
|
||||
await Pausable.pause();
|
||||
await Pausable.unpause();
|
||||
await Pausable.normalProcess();
|
||||
let count0 = await Pausable.count();
|
||||
|
||||
|
||||
73
test/PausableToken.js
Normal file
73
test/PausableToken.js
Normal file
@ -0,0 +1,73 @@
|
||||
'user strict';
|
||||
|
||||
const assertJump = require('./helpers/assertJump');
|
||||
var PausableTokenMock = artifacts.require('./helpers/PausableTokenMock.sol');
|
||||
|
||||
contract('PausableToken', function(accounts) {
|
||||
let token;
|
||||
|
||||
beforeEach(async function() {
|
||||
token = await PausableTokenMock.new(accounts[0], 100);
|
||||
});
|
||||
|
||||
it('should return paused false after construction', async function() {
|
||||
let paused = await token.paused();
|
||||
|
||||
assert.equal(paused, false);
|
||||
});
|
||||
|
||||
it('should return paused true after pause', async function() {
|
||||
await token.pause();
|
||||
let paused = await token.paused();
|
||||
|
||||
assert.equal(paused, true);
|
||||
});
|
||||
|
||||
it('should return paused false after pause and unpause', async function() {
|
||||
await token.pause();
|
||||
await token.unpause();
|
||||
let paused = await token.paused();
|
||||
|
||||
assert.equal(paused, false);
|
||||
});
|
||||
|
||||
it('should be able to transfer if transfers are unpaused', 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 be able to transfer after transfers are paused and unpaused', async function() {
|
||||
await token.pause();
|
||||
await token.unpause();
|
||||
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 trying to transfer while transactions are paused', async function() {
|
||||
await token.pause();
|
||||
try {
|
||||
await token.transfer(accounts[1], 100);
|
||||
} catch (error) {
|
||||
return assertJump(error);
|
||||
}
|
||||
assert.fail('should have thrown before');
|
||||
});
|
||||
|
||||
it('should throw an error trying to transfer from another account while transactions are paused', async function() {
|
||||
await token.pause();
|
||||
try {
|
||||
await token.transferFrom(accounts[0], accounts[1], 100);
|
||||
} catch (error) {
|
||||
return assertJump(error);
|
||||
}
|
||||
assert.fail('should have thrown before');
|
||||
});
|
||||
})
|
||||
@ -12,7 +12,9 @@ contract('PullPayment', function(accounts) {
|
||||
let ppce = await PullPaymentMock.new();
|
||||
let callSend = 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);
|
||||
});
|
||||
|
||||
@ -21,7 +23,9 @@ contract('PullPayment', function(accounts) {
|
||||
let call1 = await ppce.callSend(accounts[0], 200);
|
||||
let call2 = 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);
|
||||
});
|
||||
|
||||
@ -35,6 +39,9 @@ contract('PullPayment', function(accounts) {
|
||||
|
||||
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() {
|
||||
@ -48,10 +55,16 @@ contract('PullPayment', function(accounts) {
|
||||
let payment1 = await ppce.payments(payee);
|
||||
assert.equal(payment1, AMOUNT);
|
||||
|
||||
let totalPayments = await ppce.totalPayments();
|
||||
assert.equal(totalPayments, AMOUNT);
|
||||
|
||||
let withdraw = 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);
|
||||
});
|
||||
|
||||
31
test/ReentrancyGuard.js
Normal file
31
test/ReentrancyGuard.js
Normal file
@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
import expectThrow from './helpers/expectThrow';
|
||||
const ReentrancyMock = artifacts.require('./helper/ReentrancyMock.sol');
|
||||
const ReentrancyAttack = artifacts.require('./helper/ReentrancyAttack.sol');
|
||||
|
||||
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 that 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));
|
||||
});
|
||||
});
|
||||
@ -1,26 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
const assertJump = require('./helpers/assertJump');
|
||||
var StandardTokenMock = artifacts.require("./helpers/StandardTokenMock.sol");
|
||||
var StandardTokenMock = artifacts.require('./helpers/StandardTokenMock.sol');
|
||||
|
||||
contract('StandardToken', function(accounts) {
|
||||
|
||||
it("should return the correct totalSupply after construction", async function() {
|
||||
it('should return the correct totalSupply after construction', async function() {
|
||||
let token = await StandardTokenMock.new(accounts[0], 100);
|
||||
let totalSupply = await token.totalSupply();
|
||||
|
||||
assert.equal(totalSupply, 100);
|
||||
})
|
||||
});
|
||||
|
||||
it("should return the correct allowance amount after approval", async function() {
|
||||
it('should return the correct allowance amount after approval', async function() {
|
||||
let token = await StandardTokenMock.new();
|
||||
let approve = await token.approve(accounts[1], 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() {
|
||||
it('should return correct balances after transfer', async function() {
|
||||
let token = await StandardTokenMock.new(accounts[0], 100);
|
||||
let transfer = await token.transfer(accounts[1], 100);
|
||||
await token.transfer(accounts[1], 100);
|
||||
let balance0 = await token.balanceOf(accounts[0]);
|
||||
assert.equal(balance0, 0);
|
||||
|
||||
@ -28,20 +30,20 @@ contract('StandardToken', function(accounts) {
|
||||
assert.equal(balance1, 100);
|
||||
});
|
||||
|
||||
it("should throw an error when trying to transfer more than balance", async function() {
|
||||
it('should throw an error when trying to transfer more than balance', async function() {
|
||||
let token = await StandardTokenMock.new(accounts[0], 100);
|
||||
try {
|
||||
let transfer = await token.transfer(accounts[1], 101);
|
||||
await token.transfer(accounts[1], 101);
|
||||
} catch(error) {
|
||||
return assertJump(error);
|
||||
}
|
||||
assert.fail('should have thrown before');
|
||||
});
|
||||
|
||||
it("should return correct balances after transfering from another account", async function() {
|
||||
it('should return correct balances after transfering from another account', async function() {
|
||||
let token = await StandardTokenMock.new(accounts[0], 100);
|
||||
let approve = await token.approve(accounts[1], 100);
|
||||
let transferFrom = await token.transferFrom(accounts[0], accounts[2], 100, {from: accounts[1]});
|
||||
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);
|
||||
@ -53,11 +55,11 @@ contract('StandardToken', function(accounts) {
|
||||
assert.equal(balance2, 0);
|
||||
});
|
||||
|
||||
it("should throw an error when trying to transfer more than allowed", async function() {
|
||||
it('should throw an error when trying to transfer more than allowed', async function() {
|
||||
let token = await StandardTokenMock.new();
|
||||
let approve = await token.approve(accounts[1], 99);
|
||||
await token.approve(accounts[1], 99);
|
||||
try {
|
||||
let transfer = await token.transferFrom(accounts[0], accounts[2], 100, {from: accounts[1]});
|
||||
await token.transferFrom(accounts[0], accounts[2], 100, {from: accounts[1]});
|
||||
} catch (error) {
|
||||
return assertJump(error);
|
||||
}
|
||||
|
||||
32
test/TokenDestructible.js
Normal file
32
test/TokenDestructible.js
Normal file
@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
var TokenDestructible = artifacts.require('../contracts/lifecycle/TokenDestructible.sol');
|
||||
var StandardTokenMock = artifacts.require("./helpers/StandardTokenMock.sol");
|
||||
require('./helpers/transactionMined.js');
|
||||
|
||||
contract('TokenDestructible', function(accounts) {
|
||||
|
||||
it('should send balance to owner after destruction', async function() {
|
||||
let destructible = await TokenDestructible.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 tokens to owner after destruction', async function() {
|
||||
let destructible = await TokenDestructible.new({from: accounts[0], value: web3.toWei('10','ether')});
|
||||
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);
|
||||
});
|
||||
});
|
||||
@ -40,7 +40,7 @@ contract('VestedToken', function(accounts) {
|
||||
})
|
||||
|
||||
it('all tokens are transferable after vesting', async () => {
|
||||
assert.equal(await token.transferableTokens(receiver, now + vesting + 1), tokenAmount);
|
||||
assert.equal(await token.transferableTokens(receiver, now + vesting), tokenAmount);
|
||||
})
|
||||
|
||||
it('throws when trying to transfer non vested tokens', async () => {
|
||||
@ -84,13 +84,13 @@ contract('VestedToken', function(accounts) {
|
||||
})
|
||||
|
||||
it('can transfer all tokens after vesting ends', async () => {
|
||||
await timer(vesting + 1);
|
||||
await timer(vesting);
|
||||
await token.transfer(accounts[7], tokenAmount, { from: receiver })
|
||||
assert.equal(await token.balanceOf(accounts[7]), tokenAmount);
|
||||
})
|
||||
|
||||
it('can approve and transferFrom all tokens after vesting ends', async () => {
|
||||
await timer(vesting + 1);
|
||||
await timer(vesting);
|
||||
await token.approve(accounts[7], tokenAmount, { from: receiver })
|
||||
await token.transferFrom(receiver, accounts[7], tokenAmount, { from: accounts[7] })
|
||||
assert.equal(await token.balanceOf(accounts[7]), tokenAmount);
|
||||
@ -104,6 +104,7 @@ contract('VestedToken', function(accounts) {
|
||||
let newNow = web3.eth.getBlock(web3.eth.blockNumber).timestamp
|
||||
|
||||
await token.grantVestedTokens(receiver, tokenAmount, newNow, newNow + cliff, newNow + vesting, false, false, { from: granter })
|
||||
|
||||
await token.transfer(accounts[7], 13, { from: receiver })
|
||||
assert.equal(await token.balanceOf(accounts[7]), tokenAmount / 2);
|
||||
|
||||
|
||||
33
test/helpers/ERC23TokenMock.sol
Normal file
33
test/helpers/ERC23TokenMock.sol
Normal file
@ -0,0 +1,33 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
|
||||
import '../../contracts/token/BasicToken.sol';
|
||||
|
||||
|
||||
contract ERC23ContractInterface {
|
||||
function tokenFallback(address _from, uint _value, bytes _data) external;
|
||||
}
|
||||
|
||||
contract ERC23TokenMock is BasicToken {
|
||||
|
||||
function ERC23TokenMock(address initialAccount, uint initialBalance) {
|
||||
balances[initialAccount] = initialBalance;
|
||||
totalSupply = initialBalance;
|
||||
}
|
||||
|
||||
// ERC23 compatible transfer function (except the name)
|
||||
function transferERC23(address _to, uint _value, bytes _data)
|
||||
returns (bool success)
|
||||
{
|
||||
transfer(_to, _value);
|
||||
bool is_contract = false;
|
||||
assembly {
|
||||
is_contract := not(iszero(extcodesize(_to)))
|
||||
}
|
||||
if(is_contract) {
|
||||
ERC23ContractInterface receiver = ERC23ContractInterface(_to);
|
||||
receiver.tokenFallback(msg.sender, _value, _data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
13
test/helpers/ForceEther.sol
Normal file
13
test/helpers/ForceEther.sol
Normal file
@ -0,0 +1,13 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
// @title Force Ether into a contract.
|
||||
// @notice even
|
||||
// if the contract is not payable.
|
||||
// @notice To use, construct the contract with the target as argument.
|
||||
// @author Remco Bloemen <remco@neufund.org>
|
||||
contract ForceEther {
|
||||
function ForceEther(address target) payable {
|
||||
// Selfdestruct transfers all Ether to the arget address
|
||||
selfdestruct(target);
|
||||
}
|
||||
}
|
||||
11
test/helpers/HasNoEtherTest.sol
Normal file
11
test/helpers/HasNoEtherTest.sol
Normal file
@ -0,0 +1,11 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
import "../../contracts/ownership/HasNoEther.sol";
|
||||
|
||||
contract HasNoEtherTest is HasNoEther {
|
||||
|
||||
// Constructor with explicit payable — should still fail
|
||||
function HasNoEtherTest() payable {
|
||||
}
|
||||
|
||||
}
|
||||
@ -14,11 +14,11 @@ contract PausableMock is Pausable {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
function normalProcess() external stopInEmergency {
|
||||
function normalProcess() external whenNotPaused {
|
||||
count++;
|
||||
}
|
||||
|
||||
function drasticMeasure() external onlyInEmergency {
|
||||
function drasticMeasure() external whenPaused {
|
||||
drasticMeasureTaken = true;
|
||||
}
|
||||
|
||||
|
||||
12
test/helpers/PausableTokenMock.sol
Normal file
12
test/helpers/PausableTokenMock.sol
Normal file
@ -0,0 +1,12 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
import '../../contracts/token/PausableToken.sol';
|
||||
|
||||
// mock class using PausableToken
|
||||
contract PausableTokenMock is PausableToken {
|
||||
|
||||
function PausableTokenMock(address initialAccount, uint initialBalance) {
|
||||
balances[initialAccount] = initialBalance;
|
||||
}
|
||||
|
||||
}
|
||||
11
test/helpers/ReentrancyAttack.sol
Normal file
11
test/helpers/ReentrancyAttack.sol
Normal file
@ -0,0 +1,11 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
contract ReentrancyAttack {
|
||||
|
||||
function callSender(bytes4 data) {
|
||||
if(!msg.sender.call(data)) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
46
test/helpers/ReentrancyMock.sol
Normal file
46
test/helpers/ReentrancyMock.sol
Normal file
@ -0,0 +1,46 @@
|
||||
pragma solidity ^0.4.8;
|
||||
|
||||
import '../../contracts/ReentrancyGuard.sol';
|
||||
import './ReentrancyAttack.sol';
|
||||
|
||||
contract ReentrancyMock is ReentrancyGuard {
|
||||
|
||||
uint256 public counter;
|
||||
|
||||
function ReentrancyMock() {
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
function count() private {
|
||||
counter += 1;
|
||||
}
|
||||
|
||||
function countLocalRecursive(uint 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();
|
||||
bool result = this.call(func, n - 1);
|
||||
if(result != true) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function countAndCall(ReentrancyAttack attacker) public nonReentrant {
|
||||
count();
|
||||
bytes4 func = bytes4(keccak256("callback()"));
|
||||
attacker.callSender(func);
|
||||
}
|
||||
|
||||
function callback() external nonReentrant {
|
||||
count();
|
||||
}
|
||||
|
||||
}
|
||||
@ -4,18 +4,18 @@ pragma solidity ^0.4.8;
|
||||
import '../../contracts/SafeMath.sol';
|
||||
|
||||
|
||||
contract SafeMathMock is SafeMath {
|
||||
contract SafeMathMock {
|
||||
uint public result;
|
||||
|
||||
function multiply(uint a, uint b) {
|
||||
result = safeMul(a, b);
|
||||
result = SafeMath.mul(a, b);
|
||||
}
|
||||
|
||||
function subtract(uint a, uint b) {
|
||||
result = safeSub(a, b);
|
||||
result = SafeMath.sub(a, b);
|
||||
}
|
||||
|
||||
function add(uint a, uint b) {
|
||||
result = safeAdd(a, b);
|
||||
result = SafeMath.add(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
20
test/helpers/expectThrow.js
Normal file
20
test/helpers/expectThrow.js
Normal file
@ -0,0 +1,20 @@
|
||||
export default async promise => {
|
||||
try {
|
||||
await promise;
|
||||
} catch (error) {
|
||||
// TODO: Check jump destination to destinguish between a throw
|
||||
// and an actual invalid jump.
|
||||
const invalidJump = error.message.search('invalid JUMP') >= 0;
|
||||
// TODO: When we contract A calls contract B, and B throws, instead
|
||||
// of an 'invalid jump', we get an 'out of gas' error. How do
|
||||
// we distinguish this from an actual out of gas event? (The
|
||||
// testrpc log actually show an 'invalid jump' event.)
|
||||
const outOfGas = error.message.search('out of gas') >= 0;
|
||||
assert(
|
||||
invalidJump || outOfGas,
|
||||
"Expected throw, got '" + error + "' instead",
|
||||
);
|
||||
return;
|
||||
}
|
||||
assert.fail('Expected throw not received');
|
||||
};
|
||||
4
test/helpers/toPromise.js
Normal file
4
test/helpers/toPromise.js
Normal file
@ -0,0 +1,4 @@
|
||||
export default func =>
|
||||
(...args) =>
|
||||
new Promise((accept, reject) =>
|
||||
func(...args, (error, data) => error ? reject(error) : accept(data)));
|
||||
Reference in New Issue
Block a user