From f2142545c7096aae0f55d163bc2d06888e5e7f48 Mon Sep 17 00:00:00 2001 From: Angello Pozo Date: Sun, 27 Nov 2016 12:09:48 -0800 Subject: [PATCH 01/18] modified test to use async await pattern. --- .babelrc | 3 + package.json | 3 + test/BasicToken.js | 60 +++++--------- test/Bounty.js | 188 +++++++++++++++++------------------------- test/Claimable.js | 71 ++++++---------- test/Killable.js | 38 +++------ test/LimitBalance.js | 85 +++++++++---------- test/Ownable.js | 65 +++++---------- test/PullPayment.js | 126 +++++++++------------------- test/SafeMath.js | 109 +++++++++++------------- test/StandardToken.js | 139 +++++++++++-------------------- test/Stoppable.js | 127 ++++++++-------------------- 12 files changed, 360 insertions(+), 654 deletions(-) create mode 100644 .babelrc diff --git a/.babelrc b/.babelrc new file mode 100644 index 000000000..ce6eb60be --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015", "stage-2", "stage-3"] +} diff --git a/package.json b/package.json index 7c0969247..efc6234bd 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,9 @@ "description": "Secure Smart Contract library for Solidity", "main": "truffle.js", "devDependencies": { + "babel-preset-es2015": "^6.18.0", + "babel-preset-stage-2": "^6.18.0", + "babel-preset-stage-3": "^6.17.0", "ethereumjs-testrpc": "^3.0.2", "truffle": "^2.1.1" }, diff --git a/test/BasicToken.js b/test/BasicToken.js index 12b411c41..fbf39001e 100644 --- a/test/BasicToken.js +++ b/test/BasicToken.js @@ -1,49 +1,29 @@ contract('BasicToken', function(accounts) { - it("should return the correct totalSupply after construction", function(done) { - return BasicTokenMock.new(accounts[0], 100) - .then(function(token) { - return token.totalSupply(); - }) - .then(function(totalSupply) { - assert.equal(totalSupply, 100); - }) - .then(done); + it("should return the correct totalSupply after construction", async function() { + let token = await BasicTokenMock.new(accounts[0], 100); + let totalSupply = await token.totalSupply(); + assert.equal(totalSupply, 100); }) - it("should return correct balances after transfer", function(done) { - var token; - return BasicTokenMock.new(accounts[0], 100) - .then(function(_token) { - token = _token; - return token.transfer(accounts[1], 100); - }) - .then(function() { - return token.balanceOf(accounts[0]); - }) - .then(function(balance) { - assert.equal(balance, 0); - }) - .then(function() { - return token.balanceOf(accounts[1]); - }) - .then(function(balance) { - assert.equal(balance, 100); - }) - .then(done); + it("should return correct balances after transfer", async function(){ + let token = await BasicTokenMock.new(accounts[0], 100); + let transfer = await token.transfer(accounts[1], 100); + let firstAccountBalance = await token.balanceOf(accounts[0]); + assert.equal(firstAccountBalance, 0); + let secondAccountBalance = await token.balanceOf(accounts[1]); + assert.equal(secondAccountBalance, 100); }); - it("should throw an error when trying to transfer more than balance", function(done) { - var token; - return BasicTokenMock.new(accounts[0], 100) - .then(function(_token) { - token = _token; - return token.transfer(accounts[1], 101); - }) - .catch(function(error) { - if (error.message.search('invalid JUMP') == -1) throw error - }) - .then(done); + it("should throw an error when trying to transfer more than balance", async function() { + + let token = await BasicTokenMock.new(accounts[0], 100); + try { + let transfer = await token.transfer(accounts[1], 101); + } catch(error) { + if (error.message.search('invalid JUMP') === -1) throw error + assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + } }); }); diff --git a/test/Bounty.js b/test/Bounty.js index 17eb80a66..31efc43f7 100644 --- a/test/Bounty.js +++ b/test/Bounty.js @@ -1,4 +1,4 @@ -var sendReward = function(sender, receiver, value){ +let sendReward = function(sender, receiver, value){ web3.eth.sendTransaction({ from:sender, to:receiver, @@ -8,134 +8,100 @@ var sendReward = function(sender, receiver, value){ contract('Bounty', function(accounts) { - it("sets reward", function(done){ - var owner = accounts[0]; - var reward = web3.toWei(1, "ether"); + it("sets reward", async function(){ + let owner = accounts[0]; + let reward = web3.toWei(1, "ether"); - SecureTargetBounty.new(). - then(function(bounty){ - sendReward(owner, bounty.address, reward); - assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()) - }). - then(done); + let bounty = await SecureTargetBounty.new(); + sendReward(owner, bounty.address, reward); + assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()) }) - it("empties itself when killed", function(done){ - var owner = accounts[0]; - var reward = web3.toWei(1, "ether"); - var bounty; + it("empties itself when killed", async function(){ + let owner = accounts[0]; + let reward = web3.toWei(1, "ether"); - SecureTargetBounty.new(). - then(function(_bounty){ - bounty = _bounty; - sendReward(owner, bounty.address, reward); - assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()) - return bounty.kill() - }). - then(function(){ - assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()) - }). - then(done); + let bounty = await SecureTargetBounty.new(); + sendReward(owner, bounty.address, reward); + assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()) + await bounty.kill(); + assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()) }) describe("Against secure contract", function(){ - it("checkInvariant returns true", function(done){ - var bounty; + it("checkInvariant returns true", async function(){ - SecureTargetBounty.new(). - then(function(_bounty) { - bounty = _bounty; - return bounty.createTarget(); - }). - then(function() { - return bounty.checkInvariant.call() - }). - then(function(result) { - assert.isTrue(result); - }). - then(done); + let bounty = await SecureTargetBounty.new(); + let target = await bounty.createTarget(); + let check = await bounty.checkInvariant.call(); + assert.isTrue(check); }) - it("cannot claim reward", function(done){ - var owner = accounts[0]; - var researcher = accounts[1]; - var reward = web3.toWei(1, "ether"); + it("cannot claim reward", async function(done){ + let owner = accounts[0]; + let researcher = accounts[1]; + let reward = web3.toWei(1, "ether"); - SecureTargetBounty.new(). - then(function(bounty) { - var event = bounty.TargetCreated({}); - event.watch(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()) - bounty.claim(targetAddress, {from:researcher}). - then(function(){ throw("should not come here")}). - catch(function() { - return bounty.claimed.call(); - }). - then(function(result) { - assert.isFalse(result); - bounty.withdrawPayments({from:researcher}). - then(function(){ throw("should not come here")}). - catch(function() { - assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()) - done(); - }) - }) - }) - bounty.createTarget({from:researcher}); - }) + let bounty = await SecureTargetBounty.new(); + let event = bounty.TargetCreated({}); + + event.watch(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 { + let tmpClain = await bounty.claim(targetAddress, {from:researcher}); + done("should not come here"); + } catch(error) { + let reClaimedBounty = await bounty.claimed.call(); + assert.isFalse(reClaimedBounty); + try { + let withdraw = await bounty.withdrawPayments({from:researcher}); + done("should not come here") + } catch (err) { + assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()) + } + done(); + }//end of first try catch + }); + bounty.createTarget({from:researcher}); }) }) describe("Against broken contract", function(){ - it("checkInvariant returns false", function(done){ - var bounty; - - InsecureTargetBounty.new(). - then(function(_bounty) { - bounty = _bounty; - return bounty.createTarget(); - }). - then(function() { - return bounty.checkInvariant.call() - }). - then(function(result) { - assert.isFalse(result); - }). - then(done); + it("checkInvariant returns false", async function(){ + let bounty = await InsecureTargetBounty.new(); + let target = await bounty.createTarget(); + let invarriantCall = await bounty.checkInvariant.call(); + assert.isFalse(invarriantCall); }) - it("claims reward", function(done){ - var owner = accounts[0]; - var researcher = accounts[1]; - var reward = web3.toWei(1, "ether"); + it("claims reward", async function(){ + let owner = accounts[0]; + let researcher = accounts[1]; + let reward = web3.toWei(1, "ether"); - InsecureTargetBounty.new(). - then(function(bounty) { - var event = bounty.TargetCreated({}); - event.watch(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()) - bounty.claim(targetAddress, {from:researcher}). - then(function() { - return bounty.claimed.call(); - }). - then(function(result) { - assert.isTrue(result); - return bounty.withdrawPayments({from:researcher}) - }). - then(function() { - assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()) - }).then(done); - }) - bounty.createTarget({from:researcher}); - }) + let bounty = await InsecureTargetBounty.new(); + + let event = bounty.TargetCreated({}); + + event.watch(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()); + + let bountyClaim = await bounty.claim(targetAddress, {from:researcher}); + let claim = await bounty.claimed.call(); + assert.isTrue(claim); + let payment = await bounty.withdrawPayments({from:researcher}); + assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()); + }) + bounty.createTarget({from:researcher}); }) }) }); diff --git a/test/Claimable.js b/test/Claimable.js index 464b7406e..926783900 100644 --- a/test/Claimable.js +++ b/test/Claimable.js @@ -1,71 +1,46 @@ contract('Claimable', function(accounts) { var claimable; - beforeEach(function() { - return Claimable.new().then(function(deployed) { - claimable = deployed; - }); + beforeEach(async function() { + claimable = await Claimable.new(); }); - it("should have an owner", function(done) { - return claimable.owner() - .then(function(owner) { - assert.isTrue(owner != 0); - }) - .then(done) + it("should have an owner", async function() { + let owner = await claimable.owner(); + assert.isTrue(owner != 0); }); - it("changes pendingOwner after transfer", function(done) { - var newOwner = accounts[1]; - return claimable.transfer(newOwner) - .then(function() { - return claimable.pendingOwner(); - }) - .then(function(pendingOwner) { - assert.isTrue(pendingOwner === newOwner); - }) - .then(done) + it("changes pendingOwner after transfer", async function() { + let newOwner = accounts[1]; + let transfer = await claimable.transfer(newOwner); + let pendingOwner = await claimable.pendingOwner(); + assert.isTrue(pendingOwner === newOwner); }); - it("should prevent to claimOwnership from no pendingOwner", function(done) { - return claimable.claimOwnership({from: accounts[2]}) - .then(function() { - return claimable.owner(); - }) - .then(function(owner) { - assert.isTrue(owner != accounts[2]); - }) - .then(done) + it("should prevent to claimOwnership from no pendingOwner", async function() { + let claimedOwner = await claimable.claimOwnership({from: accounts[2]}); + let owner = await claimable.owner(); + assert.isTrue(owner != accounts[2]); }); - it("should prevent non-owners from transfering" ,function(done) { - return claimable.transfer(accounts[2], {from: accounts[2]}) - .then(function() { - return claimable.pendingOwner(); - }) - .then(function(pendingOwner) { - assert.isFalse(pendingOwner === accounts[2]); - }) - .then(done) + it("should prevent non-owners from transfering", async function() { + let transfer = await claimable.transfer(accounts[2], {from: accounts[2]}); + let pendingOwner = await claimable.pendingOwner(); + assert.isFalse(pendingOwner === accounts[2]); }); describe("after initiating a transfer", function () { - var newOwner; + let newOwner; beforeEach(function () { newOwner = accounts[1]; return claimable.transfer(newOwner); }); - it("changes allow pending owner to claim ownership", function(done) { - return claimable.claimOwnership({from: newOwner}) - .then(function() { - return claimable.owner(); - }) - .then(function(owner) { - assert.isTrue(owner === newOwner); - }) - .then(done) + it("changes allow pending owner to claim ownership", async function() { + let claimedOwner = await claimable.claimOwnership({from: newOwner}) + let owner = await claimable.owner(); + assert.isTrue(owner === newOwner); }); }); }); diff --git a/test/Killable.js b/test/Killable.js index 13b695324..9c55e0099 100644 --- a/test/Killable.js +++ b/test/Killable.js @@ -32,38 +32,24 @@ contract('Killable', function(accounts) { } }; - it("should send balance to owner after death", function(done) { - var initBalance, newBalance, owner, address, killable, kBalance; + it("should send balance to owner after death", async function() { + let initBalance, newBalance, owner, address, killable, kBalance, txnHash, receiptMined; web3.eth.sendTransaction({from: web3.eth.coinbase, to: accounts[0], value: web3.toWei('50','ether')}, function(err, result) { if(err) console.log("ERROR:" + err); else { console.log(result); } - }) - return Killable.new({from: accounts[0], value: web3.toWei('10','ether')}) - .then(function(_killable) { - killable = _killable; - return killable.owner(); - }) - .then(function(_owner) { - owner = _owner; - initBalance = web3.eth.getBalance(owner); - kBalance = web3.eth.getBalance(killable.address); - }) - .then(function() { - return killable.kill({from: owner}); - }) - .then(function (txnHash) { - return web3.eth.getTransactionReceiptMined(txnHash); - }) - .then(function() { - newBalance = web3.eth.getBalance(owner); - }) - .then(function() { - assert.isTrue(newBalance > initBalance); - }) - .then(done); + }); + + killable = await Killable.new({from: accounts[0], value: web3.toWei('10','ether')}); + owner = await killable.owner(); + initBalance = web3.eth.getBalance(owner); + kBalance = web3.eth.getBalance(killable.address); + txnHash = await killable.kill({from: owner}); + receiptMined = await web3.eth.getTransactionReceiptMined(txnHash); + newBalance = web3.eth.getBalance(owner); + assert.isTrue(newBalance > initBalance); }); }); diff --git a/test/LimitBalance.js b/test/LimitBalance.js index ce75821a0..3732639ae 100644 --- a/test/LimitBalance.js +++ b/test/LimitBalance.js @@ -1,64 +1,55 @@ contract('LimitBalance', function(accounts) { var lb; - beforeEach(function() { - return LimitBalanceMock.new().then(function(deployed) { - lb = deployed; - }); + beforeEach(async function() { + lb = await LimitBalanceMock.new(); }); - var LIMIT = 1000; + let LIMIT = 1000; - it("should expose limit", function(done) { - return lb.limit() - .then(function(limit) { - assert.equal(limit, LIMIT); - }) - .then(done) + it("should expose limit", async function() { + let limit = await lb.limit(); + assert.equal(limit, LIMIT); }); - it("should allow sending below limit", function(done) { - var amount = 1; - return lb.limitedDeposit({value: amount}) - .then(function() { - assert.equal(web3.eth.getBalance(lb.address), amount); - }) - .then(done) + it("should allow sending below limit", async function() { + let amount = 1; + let limDeposit = await lb.limitedDeposit({value: amount}); + assert.equal(web3.eth.getBalance(lb.address), amount); }); - it("shouldnt allow sending above limit", function(done) { - var amount = 1100; - return lb.limitedDeposit({value: amount}) - .catch(function(error) { - if (error.message.search('invalid JUMP') == -1) throw error - }) - .then(done) + it("shouldnt allow sending above limit", async function() { + + let amount = 1110; + try { + let limDeposit = await lb.limitedDeposit({value: amount}); + } catch(error) { + if (error.message.search('invalid JUMP') == -1) throw error + assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + } }); - it("should allow multiple sends below limit", function(done) { - var amount = 500; - return lb.limitedDeposit({value: amount}) - .then(function() { - assert.equal(web3.eth.getBalance(lb.address), amount); - return lb.limitedDeposit({value: amount}) - }) - .then(function() { - assert.equal(web3.eth.getBalance(lb.address), amount*2); - }) - .then(done) + it("should allow multiple sends below limit", async function() { + let amount = 500; + + let limDeposit = await lb.limitedDeposit({value: amount}); + assert.equal(web3.eth.getBalance(lb.address), amount); + let limDeposit2 = await lb.limitedDeposit({value: amount}); + assert.equal(web3.eth.getBalance(lb.address), amount*2); }); - it("shouldnt allow multiple sends above limit", function(done) { - var amount = 500; - return lb.limitedDeposit({value: amount}) - .then(function() { - assert.equal(web3.eth.getBalance(lb.address), amount); - return lb.limitedDeposit({value: amount+1}) - }) - .catch(function(error) { - if (error.message.search('invalid JUMP') == -1) throw error; - }) - .then(done) + it("shouldnt allow multiple sends above limit", async function() { + let amount = 500; + + + let limDeposit = await lb.limitedDeposit({value: amount}); + assert.equal(web3.eth.getBalance(lb.address), amount); + try { + lb.limitedDeposit({value: amount+1}) + } catch(error) { + if (error.message.search('invalid JUMP') == -1) throw error + assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + } }); }); diff --git a/test/Ownable.js b/test/Ownable.js index 2e9f59c55..424e03bf5 100644 --- a/test/Ownable.js +++ b/test/Ownable.js @@ -1,58 +1,35 @@ contract('Ownable', function(accounts) { var ownable; - beforeEach(function() { - return Ownable.new().then(function(deployed) { - ownable = deployed; - }); + beforeEach(async function() { + ownable = await Ownable.new(); }); - it("should have an owner", function(done) { - return ownable.owner() - .then(function(owner) { - assert.isTrue(owner != 0); - }) - .then(done) + it("should have an owner", async function() { + let owner = await ownable.owner(); + assert.isTrue(owner != 0); }); - it("changes owner after transfer", function(done) { - var other = accounts[1]; - return ownable.transfer(other) - .then(function() { - return ownable.owner(); - }) - .then(function(owner) { - assert.isTrue(owner === other); - }) - .then(done) + it("changes owner after transfer", async function() { + let other = accounts[1]; + let transfer = await ownable.transfer(other); + let owner = await ownable.owner(); + assert.isTrue(owner === other); }); - it("should prevent non-owners from transfering" ,function(done) { - var other = accounts[2]; - return ownable.transfer(other, {from: accounts[2]}) - .then(function() { - return ownable.owner(); - }) - .then(function(owner) { - assert.isFalse(owner === other); - }) - .then(done) + it("should prevent non-owners from transfering", async function() { + let other = accounts[2]; + let transfer = await ownable.transfer(other, {from: accounts[2]}); + let owner = await ownable.owner(); + assert.isFalse(owner === other); }); - it("should guard ownership against stuck state" ,function(done) { - var ownable = Ownable.deployed(); - - return ownable.owner() - .then(function (originalOwner) { - return ownable.transfer(null, {from: originalOwner}) - .then(function() { - return ownable.owner(); - }) - .then(function(newOwner) { - assert.equal(originalOwner, newOwner); - }) - .then(done); - }); + it("should guard ownership against stuck state", async function() { + let ownable = Ownable.deployed(); + let originalOwner = await ownable.owner(); + let transfer = await ownable.transfer(null, {from: originalOwner}); + let newOwner = await ownable.owner(); + assert.equal(originalOwner, newOwner); }); }); diff --git a/test/PullPayment.js b/test/PullPayment.js index 8da3bf2ff..93734103a 100644 --- a/test/PullPayment.js +++ b/test/PullPayment.js @@ -1,102 +1,50 @@ contract('PullPayment', function(accounts) { - it("can't call asyncSend externally", function(done) { - return PullPaymentMock.new() - .then(function(ppc) { - assert.isUndefined(ppc.asyncSend); - }) - .then(done); + it("can't call asyncSend externally", async function() { + let ppc = await PullPaymentMock.new(); + assert.isUndefined(ppc.asyncSend); }); - it("can record an async payment correctly", function(done) { - var ppce; - var AMOUNT = 100; - return PullPaymentMock.new() - .then(function(_ppce) { - ppce = _ppce; - ppce.callSend(accounts[0], AMOUNT) - }) - .then(function() { - return ppce.payments(accounts[0]); - }) - .then(function(paymentsToAccount0) { - assert.equal(paymentsToAccount0, AMOUNT); - }) - .then(done); + it("can record an async payment correctly", async function() { + let AMOUNT = 100; + let ppce = await PullPaymentMock.new(); + let callSend = await ppce.callSend(accounts[0], AMOUNT); + let paymentsToAccount0 = await ppce.payments(accounts[0]); + assert.equal(paymentsToAccount0, AMOUNT); }); - it("can add multiple balances on one account", function(done) { - var ppce; - return PullPaymentMock.new() - .then(function(_ppce) { - ppce = _ppce; - return ppce.callSend(accounts[0], 200) - }) - .then(function() { - return ppce.callSend(accounts[0], 300) - }) - .then(function() { - return ppce.payments(accounts[0]); - }) - .then(function(paymentsToAccount0) { - assert.equal(paymentsToAccount0, 500); - }) - .then(done); + it("can add multiple balances on one account", async function() { + let ppce = await PullPaymentMock.new(); + let call1 = await ppce.callSend(accounts[0], 200); + let call2 = await ppce.callSend(accounts[0], 300) + let paymentsToAccount0 = await ppce.payments(accounts[0]); + assert.equal(paymentsToAccount0, 500); }); - it("can add balances on multiple accounts", function(done) { - var ppce; - return PullPaymentMock.new() - .then(function(_ppce) { - ppce = _ppce; - return ppce.callSend(accounts[0], 200) - }) - .then(function() { - return ppce.callSend(accounts[1], 300) - }) - .then(function() { - return ppce.payments(accounts[0]); - }) - .then(function(paymentsToAccount0) { - assert.equal(paymentsToAccount0, 200); - }) - .then(function() { - return ppce.payments(accounts[1]); - }) - .then(function(paymentsToAccount0) { - assert.equal(paymentsToAccount0, 300); - }) - .then(done); + it("can add balances on multiple accounts", async function() { + let ppce = await PullPaymentMock.new(); + let call1 = await ppce.callSend(accounts[0], 200); + let call2 = 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); }); - it("can withdraw payment", function(done) { - var ppce; - var AMOUNT = 17*1e18; - var payee = accounts[1]; - var initialBalance = web3.eth.getBalance(payee); - return PullPaymentMock.new({value: AMOUNT}) - .then(function(_ppce) { - ppce = _ppce; - return ppce.callSend(payee, AMOUNT); - }) - .then(function() { - return ppce.payments(payee); - }) - .then(function(paymentsToAccount0) { - assert.equal(paymentsToAccount0, AMOUNT); - }) - .then(function() { - return ppce.withdrawPayments({from: payee}); - }) - .then(function() { - return ppce.payments(payee); - }) - .then(function(paymentsToAccount0) { - assert.equal(paymentsToAccount0, 0); - var balance = web3.eth.getBalance(payee); - assert(Math.abs(balance-initialBalance-AMOUNT) < 1e16); - }) - .then(done); + it("can withdraw payment", async function() { + let AMOUNT = 17*1e18; + let payee = accounts[1]; + let initialBalance = web3.eth.getBalance(payee); + + let ppce = await PullPaymentMock.new({value: AMOUNT}); + let call1 = await ppce.callSend(payee, AMOUNT); + let payment1 = await ppce.payments(payee); + assert.equal(payment1, AMOUNT); + let withdraw = await ppce.withdrawPayments({from: payee}); + let payment2 = await ppce.payments(payee); + assert.equal(payment2, 0); + let balance = web3.eth.getBalance(payee); + assert(Math.abs(balance-initialBalance-AMOUNT) < 1e16); }); }); diff --git a/test/SafeMath.js b/test/SafeMath.js index 251c0d139..ab7af6e56 100644 --- a/test/SafeMath.js +++ b/test/SafeMath.js @@ -3,80 +3,65 @@ contract('SafeMath', function(accounts) { var safeMath; - before(function() { - return SafeMathMock.new() - .then(function(_safeMath) { - safeMath = _safeMath; - }); + before(async function() { + safeMath = await SafeMathMock.new(); }); - it("multiplies correctly", function(done) { - var a = 5678; - var b = 1234; - return safeMath.multiply(a, b) - .then(function() { - return safeMath.result(); - }) - .then(function(result) { - assert.equal(result, a*b); - }) - .then(done); + it("multiplies correctly", async function() { + let a = 5678; + let b = 1234; + let mult = await safeMath.multiply(a, b); + let result = await safeMath.result(); + assert.equal(result, a*b); }); - it("adds correctly", function(done) { - var a = 5678; - var b = 1234; - return safeMath.add(a, b) - .then(function() { - return safeMath.result(); - }) - .then(function(result) { - assert.equal(result, a+b); - }) - .then(done); + it("adds correctly", async function() { + let a = 5678; + let b = 1234; + let add = await safeMath.add(a, b); + let result = await safeMath.result(); + assert.equal(result, a+b); }); - it("subtracts correctly", function(done) { - var a = 5678; - var b = 1234; - return safeMath.subtract(a, b) - .then(function() { - return safeMath.result(); - }) - .then(function(result) { - assert.equal(result, a-b); - }) - .then(done); + it("subtracts correctly", async function() { + let a = 5678; + let b = 1234; + let subtract = await safeMath.subtract(a, b); + let result = await safeMath.result(); + assert.equal(result, a-b); }); - it("should throw an error if subtraction result would be negative", function (done) { - var a = 1234; - var b = 5678; - return safeMath.subtract(a, b) - .catch(function(error) { - if (error.message.search('invalid JUMP') == -1) throw error - }) - .then(done); + it("should throw an error if subtraction result would be negative", async function () { + let a = 1234; + let b = 5678; + try { + let subtract = await safeMath.subtract(a, b); + } catch(error) { + if (error.message.search('invalid JUMP') == -1) throw error + assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + } }); - it("should throw an error on addition overflow", function(done) { - var a = 115792089237316195423570985008687907853269984665640564039457584007913129639935; - var b = 1; - return safeMath.add(a, b) - .catch(function(error) { - if (error.message.search('invalid JUMP') == -1) throw error - }) - .then(done); + it("should throw an error on addition overflow", async function() { + let a = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + let b = 1; + try { + let add = await safeMath.add(a, b); + } catch(error) { + if (error.message.search('invalid JUMP') == -1) throw error + assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + } }); - it("should throw an error on multiplication overflow", function(done) { - var a = 115792089237316195423570985008687907853269984665640564039457584007913129639933; - var b = 2; - return safeMath.multiply(a, b) - .catch(function(error) { - if (error.message.search('invalid JUMP') == -1) throw error - }) - .then(done); + it("should throw an error on multiplication overflow", async function() { + let a = 115792089237316195423570985008687907853269984665640564039457584007913129639933; + let b = 2; + try { + let multiply = await safeMath.multiply(a, b); + } catch(error) { + if (error.message.search('invalid JUMP') == -1) throw error + assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + } }); }); diff --git a/test/StandardToken.js b/test/StandardToken.js index ec2f158cd..cac3e8633 100644 --- a/test/StandardToken.js +++ b/test/StandardToken.js @@ -1,108 +1,61 @@ contract('StandardToken', function(accounts) { - it("should return the correct totalSupply after construction", function(done) { - return StandardTokenMock.new(accounts[0], 100) - .then(function(token) { - return token.totalSupply(); - }) - .then(function(totalSupply) { - assert.equal(totalSupply, 100); - }) - .then(done); + 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", function(done) { - var token; - return StandardTokenMock.new() - .then(function(_token) { - token = _token; - return token.approve(accounts[1], 100); - }) - .then(function() { - return token.allowance(accounts[0], accounts[1]); - }) - .then(function(allowance) { - assert.equal(allowance, 100); - }) - .then(done); + it("should return the correct allowance amount after approval", async function() { + let token = await StandardTokenMock.new(); + let approve = 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", function(done) { - var token; - return StandardTokenMock.new(accounts[0], 100) - .then(function(_token) { - token = _token; - return token.transfer(accounts[1], 100); - }) - .then(function() { - return token.balanceOf(accounts[0]); - }) - .then(function(balance) { - assert.equal(balance, 0); - }) - .then(function() { - return token.balanceOf(accounts[1]); - }) - .then(function(balance) { - assert.equal(balance, 100); - }) - .then(done); + 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); + 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", function(done) { - var token; - return StandardTokenMock.new(accounts[0], 100) - .then(function(_token) { - token = _token; - return token.transfer(accounts[1], 101); - }) - .catch(function(error) { - if (error.message.search('invalid JUMP') == -1) throw error - }) - .then(done); + 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); + } catch(error) { + if (error.message.search('invalid JUMP') == -1) throw error + assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + } }); - it("should return correct balances after transfering from another account", function(done) { - var token; - return StandardTokenMock.new(accounts[0], 100) - .then(function(_token) { - token = _token; - return token.approve(accounts[1], 100); - }) - .then(function() { - return token.transferFrom(accounts[0], accounts[2], 100, {from: accounts[1]}); - }) - .then(function() { - return token.balanceOf(accounts[0]); - }) - .then(function(balance) { - assert.equal(balance, 0); - return token.balanceOf(accounts[2]); - }) - .then(function(balance) { - assert.equal(balance, 100) - return token.balanceOf(accounts[1]); - }) - .then(function(balance) { - assert.equal(balance, 0); - }) - .then(done); + 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]}); + + 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", function(done) { - var token; - return StandardTokenMock.new(accounts[0], 100) - .then(function(_token) { - token = _token; - return token.approve(accounts[1], 99); - }) - .then(function() { - return token.transferFrom(accounts[0], accounts[2], 100, {from: accounts[1]}); - }) - .catch(function(error) { - if (error.message.search('invalid JUMP') == -1) throw error - }) - .then(done); + 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); + try { + let transfer = await token.transferFrom(accounts[0], accounts[2], 100, {from: accounts[1]}); + } catch (error) { + if (error.message.search('invalid JUMP') == -1) throw error + assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + } }); }); diff --git a/test/Stoppable.js b/test/Stoppable.js index 3fa4f3ad2..b347bac16 100644 --- a/test/Stoppable.js +++ b/test/Stoppable.js @@ -1,108 +1,47 @@ contract('Stoppable', function(accounts) { - it("can perform normal process in non-emergency", function(done) { - var stoppable; - return StoppableMock.new() - .then(function(_stoppable) { - stoppable = _stoppable; - return stoppable.count(); - }) - .then(function(count) { - assert.equal(count, 0); - }) - .then(function () { - return stoppable.normalProcess(); - }) - .then(function() { - return stoppable.count(); - }) - .then(function(count) { - assert.equal(count, 1); - }) - .then(done); + it("can perform normal process in non-emergency", async function() { + let stoppable = await StoppableMock.new(); + let count0 = await stoppable.count(); + assert.equal(count0, 0); + let normalProcess = await stoppable.normalProcess(); + let count1 = await stoppable.count(); + assert.equal(count1, 1); }); - it("can not perform normal process in emergency", function(done) { - var stoppable; - return StoppableMock.new() - .then(function(_stoppable) { - stoppable = _stoppable; - return stoppable.emergencyStop(); - }) - .then(function () { - return stoppable.count(); - }) - .then(function(count) { - assert.equal(count, 0); - }) - .then(function () { - return stoppable.normalProcess(); - }) - .then(function() { - return stoppable.count(); - }) - .then(function(count) { - assert.equal(count, 0); - }) - .then(done); + it("can not perform normal process in emergency", async function() { + let stoppable = await StoppableMock.new(); + let emergencyStop = await stoppable.emergencyStop(); + let count0 = await stoppable.count(); + assert.equal(count0, 0); + let normalProcess = await stoppable.normalProcess(); + let count1 = await stoppable.count(); + assert.equal(count1, 0); }); - it("can not take drastic measure in non-emergency", function(done) { - var stoppable; - return StoppableMock.new() - .then(function(_stoppable) { - stoppable = _stoppable; - return stoppable.drasticMeasure(); - }) - .then(function() { - return stoppable.drasticMeasureTaken(); - }) - .then(function(taken) { - assert.isFalse(taken); - }) - .then(done); + it("can not take drastic measure in non-emergency", async function() { + let stoppable = await StoppableMock.new(); + let drasticMeasure = await stoppable.drasticMeasure(); + let drasticMeasureTaken = await stoppable.drasticMeasureTaken(); + assert.isFalse(drasticMeasureTaken); }); - it("can take a drastic measure in an emergency", function(done) { - var stoppable; - return StoppableMock.new() - .then(function(_stoppable) { - stoppable = _stoppable; - return stoppable.emergencyStop(); - }) - .then(function() { - return stoppable.drasticMeasure(); - }) - .then(function() { - return stoppable.drasticMeasureTaken(); - }) - .then(function(taken) { - assert.isTrue(taken); - }) - .then(done); + it("can take a drastic measure in an emergency", async function() { + let stoppable = await StoppableMock.new(); + let emergencyStop = await stoppable.emergencyStop(); + let drasticMeasure = await stoppable.drasticMeasure(); + let drasticMeasureTaken = await stoppable.drasticMeasureTaken(); + assert.isTrue(drasticMeasureTaken); }); - it("should resume allowing normal process after emergency is over", function(done) { - var stoppable; - return StoppableMock.new() - .then(function(_stoppable) { - stoppable = _stoppable; - return stoppable.emergencyStop(); - }) - .then(function () { - return stoppable.release(); - }) - .then(function() { - return stoppable.normalProcess(); - }) - .then(function() { - return stoppable.count(); - }) - .then(function(count) { - assert.equal(count, 1); - }) - .then(done); + it("should resume allowing normal process after emergency is over", async function() { + let stoppable = await StoppableMock.new(); + let emergencyStop = await stoppable.emergencyStop(); + let release = await stoppable.release(); + let normalProcess = await stoppable.normalProcess(); + let count0 = await stoppable.count(); + assert.equal(count0, 1); }); }); From 688106e9c3bdcf01d170a59ac9427b38e388e9b9 Mon Sep 17 00:00:00 2001 From: Angello Pozo Date: Wed, 30 Nov 2016 13:24:02 -0800 Subject: [PATCH 02/18] fix: made all the tests consistent. now with done. --- test/BasicToken.js | 9 ++++++--- test/Bounty.js | 19 ++++++++++++------- test/Claimable.js | 25 ++++++++++++++++--------- test/Killable.js | 3 ++- test/LimitBalance.js | 23 ++++++++++++++--------- test/Ownable.js | 17 +++++++++++------ test/PullPayment.js | 15 ++++++++++----- test/SafeMath.js | 23 +++++++++++++++-------- test/StandardToken.js | 18 ++++++++++++------ test/Stoppable.js | 15 ++++++++++----- 10 files changed, 108 insertions(+), 59 deletions(-) diff --git a/test/BasicToken.js b/test/BasicToken.js index fbf39001e..3e3600576 100644 --- a/test/BasicToken.js +++ b/test/BasicToken.js @@ -1,21 +1,23 @@ contract('BasicToken', function(accounts) { - it("should return the correct totalSupply after construction", async function() { + it("should return the correct totalSupply after construction", async function(done) { let token = await BasicTokenMock.new(accounts[0], 100); let totalSupply = await token.totalSupply(); assert.equal(totalSupply, 100); + done(); }) - it("should return correct balances after transfer", async function(){ + it("should return correct balances after transfer", async function(done){ let token = await BasicTokenMock.new(accounts[0], 100); let transfer = await token.transfer(accounts[1], 100); let firstAccountBalance = await token.balanceOf(accounts[0]); assert.equal(firstAccountBalance, 0); let secondAccountBalance = await token.balanceOf(accounts[1]); assert.equal(secondAccountBalance, 100); + done(); }); - 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(done) { let token = await BasicTokenMock.new(accounts[0], 100); try { @@ -23,6 +25,7 @@ contract('BasicToken', function(accounts) { } catch(error) { if (error.message.search('invalid JUMP') === -1) throw error assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + done(); } }); diff --git a/test/Bounty.js b/test/Bounty.js index 31efc43f7..2e4ea06c3 100644 --- a/test/Bounty.js +++ b/test/Bounty.js @@ -8,16 +8,17 @@ let sendReward = function(sender, receiver, value){ contract('Bounty', function(accounts) { - it("sets reward", async function(){ + it("sets reward", async function(done){ 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()) + assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()); + done(); }) - it("empties itself when killed", async function(){ + it("empties itself when killed", async function(done){ let owner = accounts[0]; let reward = web3.toWei(1, "ether"); @@ -25,16 +26,18 @@ contract('Bounty', function(accounts) { sendReward(owner, bounty.address, reward); assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()) await bounty.kill(); - assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()) + assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()); + done(); }) describe("Against secure contract", function(){ - it("checkInvariant returns true", async function(){ + it("checkInvariant returns true", async function(done){ let bounty = await SecureTargetBounty.new(); let target = await bounty.createTarget(); let check = await bounty.checkInvariant.call(); assert.isTrue(check); + done(); }) it("cannot claim reward", async function(done){ @@ -72,14 +75,15 @@ contract('Bounty', function(accounts) { }) describe("Against broken contract", function(){ - it("checkInvariant returns false", async function(){ + it("checkInvariant returns false", async function(done){ let bounty = await InsecureTargetBounty.new(); let target = await bounty.createTarget(); let invarriantCall = await bounty.checkInvariant.call(); assert.isFalse(invarriantCall); + done(); }) - it("claims reward", async function(){ + it("claims reward", async function(done){ let owner = accounts[0]; let researcher = accounts[1]; let reward = web3.toWei(1, "ether"); @@ -100,6 +104,7 @@ contract('Bounty', function(accounts) { assert.isTrue(claim); let payment = await bounty.withdrawPayments({from:researcher}); assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()); + done(); }) bounty.createTarget({from:researcher}); }) diff --git a/test/Claimable.js b/test/Claimable.js index 926783900..ea0e6c385 100644 --- a/test/Claimable.js +++ b/test/Claimable.js @@ -1,46 +1,53 @@ contract('Claimable', function(accounts) { - var claimable; + let claimable; - beforeEach(async function() { + beforeEach(async function(done) { claimable = await Claimable.new(); + done(); }); - it("should have an owner", async function() { + it("should have an owner", async function(done) { let owner = await claimable.owner(); assert.isTrue(owner != 0); + done(); }); - it("changes pendingOwner after transfer", async function() { + it("changes pendingOwner after transfer", async function(done) { let newOwner = accounts[1]; let transfer = await claimable.transfer(newOwner); let pendingOwner = await claimable.pendingOwner(); assert.isTrue(pendingOwner === newOwner); + done(); }); - it("should prevent to claimOwnership from no pendingOwner", async function() { + it("should prevent to claimOwnership from no pendingOwner", async function(done) { let claimedOwner = await claimable.claimOwnership({from: accounts[2]}); let owner = await claimable.owner(); assert.isTrue(owner != accounts[2]); + done(); }); - it("should prevent non-owners from transfering", async function() { + it("should prevent non-owners from transfering", async function(done) { let transfer = await claimable.transfer(accounts[2], {from: accounts[2]}); let pendingOwner = await claimable.pendingOwner(); assert.isFalse(pendingOwner === accounts[2]); + done(); }); describe("after initiating a transfer", function () { let newOwner; - beforeEach(function () { + beforeEach(async function (done) { newOwner = accounts[1]; - return claimable.transfer(newOwner); + await claimable.transfer(newOwner); + done(); }); - it("changes allow pending owner to claim ownership", async function() { + it("changes allow pending owner to claim ownership", async function(done) { let claimedOwner = await claimable.claimOwnership({from: newOwner}) let owner = await claimable.owner(); assert.isTrue(owner === newOwner); + done(); }); }); }); diff --git a/test/Killable.js b/test/Killable.js index 9c55e0099..4cb4de152 100644 --- a/test/Killable.js +++ b/test/Killable.js @@ -32,7 +32,7 @@ contract('Killable', function(accounts) { } }; - it("should send balance to owner after death", async function() { + it("should send balance to owner after death", async function(done) { let initBalance, newBalance, owner, address, killable, kBalance, txnHash, receiptMined; web3.eth.sendTransaction({from: web3.eth.coinbase, to: accounts[0], value: web3.toWei('50','ether')}, function(err, result) { if(err) @@ -50,6 +50,7 @@ contract('Killable', function(accounts) { receiptMined = await web3.eth.getTransactionReceiptMined(txnHash); newBalance = web3.eth.getBalance(owner); assert.isTrue(newBalance > initBalance); + done(); }); }); diff --git a/test/LimitBalance.js b/test/LimitBalance.js index 3732639ae..1e2156b8c 100644 --- a/test/LimitBalance.js +++ b/test/LimitBalance.js @@ -1,24 +1,27 @@ contract('LimitBalance', function(accounts) { - var lb; + let lb; - beforeEach(async function() { + beforeEach(async function(done) { lb = await LimitBalanceMock.new(); + done(); }); let LIMIT = 1000; - it("should expose limit", async function() { + it("should expose limit", async function(done) { let limit = await lb.limit(); assert.equal(limit, LIMIT); + done(); }); - it("should allow sending below limit", async function() { + it("should allow sending below limit", async function(done) { let amount = 1; let limDeposit = await lb.limitedDeposit({value: amount}); assert.equal(web3.eth.getBalance(lb.address), amount); + done(); }); - it("shouldnt allow sending above limit", async function() { + it("shouldnt allow sending above limit", async function(done) { let amount = 1110; try { @@ -26,29 +29,31 @@ contract('LimitBalance', function(accounts) { } catch(error) { if (error.message.search('invalid JUMP') == -1) throw error assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + done(); } }); - it("should allow multiple sends below limit", async function() { + it("should allow multiple sends below limit", async function(done) { let amount = 500; let limDeposit = await lb.limitedDeposit({value: amount}); assert.equal(web3.eth.getBalance(lb.address), amount); let limDeposit2 = await lb.limitedDeposit({value: amount}); assert.equal(web3.eth.getBalance(lb.address), amount*2); + done(); }); - it("shouldnt allow multiple sends above limit", async function() { + it("shouldnt allow multiple sends above limit", async function(done) { let amount = 500; - let limDeposit = await lb.limitedDeposit({value: amount}); assert.equal(web3.eth.getBalance(lb.address), amount); try { - lb.limitedDeposit({value: amount+1}) + await lb.limitedDeposit({value: amount+1}) } catch(error) { if (error.message.search('invalid JUMP') == -1) throw error assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + done(); } }); diff --git a/test/Ownable.js b/test/Ownable.js index 424e03bf5..c25c27e3d 100644 --- a/test/Ownable.js +++ b/test/Ownable.js @@ -1,35 +1,40 @@ contract('Ownable', function(accounts) { - var ownable; + let ownable; - beforeEach(async function() { + beforeEach(async function(done) { ownable = await Ownable.new(); + done(); }); - it("should have an owner", async function() { + it("should have an owner", async function(done) { let owner = await ownable.owner(); assert.isTrue(owner != 0); + done(); }); - it("changes owner after transfer", async function() { + it("changes owner after transfer", async function(done) { let other = accounts[1]; let transfer = await ownable.transfer(other); let owner = await ownable.owner(); assert.isTrue(owner === other); + done(); }); - it("should prevent non-owners from transfering", async function() { + it("should prevent non-owners from transfering", async function(done) { let other = accounts[2]; let transfer = await ownable.transfer(other, {from: accounts[2]}); let owner = await ownable.owner(); assert.isFalse(owner === other); + done(); }); - it("should guard ownership against stuck state", async function() { + it("should guard ownership against stuck state", async function(done) { let ownable = Ownable.deployed(); let originalOwner = await ownable.owner(); let transfer = await ownable.transfer(null, {from: originalOwner}); let newOwner = await ownable.owner(); assert.equal(originalOwner, newOwner); + done(); }); }); diff --git a/test/PullPayment.js b/test/PullPayment.js index 93734103a..65b3f247c 100644 --- a/test/PullPayment.js +++ b/test/PullPayment.js @@ -1,27 +1,30 @@ contract('PullPayment', function(accounts) { - it("can't call asyncSend externally", async function() { + it("can't call asyncSend externally", async function(done) { let ppc = await PullPaymentMock.new(); assert.isUndefined(ppc.asyncSend); + done(); }); - it("can record an async payment correctly", async function() { + it("can record an async payment correctly", async function(done) { let AMOUNT = 100; let ppce = await PullPaymentMock.new(); let callSend = await ppce.callSend(accounts[0], AMOUNT); let paymentsToAccount0 = await ppce.payments(accounts[0]); assert.equal(paymentsToAccount0, AMOUNT); + done(); }); - it("can add multiple balances on one account", async function() { + it("can add multiple balances on one account", async function(done) { let ppce = await PullPaymentMock.new(); let call1 = await ppce.callSend(accounts[0], 200); let call2 = await ppce.callSend(accounts[0], 300) let paymentsToAccount0 = await ppce.payments(accounts[0]); assert.equal(paymentsToAccount0, 500); + done(); }); - it("can add balances on multiple accounts", async function() { + it("can add balances on multiple accounts", async function(done) { let ppce = await PullPaymentMock.new(); let call1 = await ppce.callSend(accounts[0], 200); let call2 = await ppce.callSend(accounts[1], 300); @@ -29,9 +32,10 @@ contract('PullPayment', function(accounts) { assert.equal(paymentsToAccount0, 200); let paymentsToAccount1 = await ppce.payments(accounts[1]); assert.equal(paymentsToAccount1, 300); + done(); }); - it("can withdraw payment", async function() { + it("can withdraw payment", async function(done) { let AMOUNT = 17*1e18; let payee = accounts[1]; let initialBalance = web3.eth.getBalance(payee); @@ -45,6 +49,7 @@ contract('PullPayment', function(accounts) { assert.equal(payment2, 0); let balance = web3.eth.getBalance(payee); assert(Math.abs(balance-initialBalance-AMOUNT) < 1e16); + done(); }); }); diff --git a/test/SafeMath.js b/test/SafeMath.js index ab7af6e56..fd1765b9e 100644 --- a/test/SafeMath.js +++ b/test/SafeMath.js @@ -1,37 +1,41 @@ contract('SafeMath', function(accounts) { - var safeMath; + let safeMath; - before(async function() { + before(async function(done) { safeMath = await SafeMathMock.new(); + done(); }); - it("multiplies correctly", async function() { + it("multiplies correctly", async function(done) { let a = 5678; let b = 1234; let mult = await safeMath.multiply(a, b); let result = await safeMath.result(); assert.equal(result, a*b); + done(); }); - it("adds correctly", async function() { + it("adds correctly", async function(done) { let a = 5678; let b = 1234; let add = await safeMath.add(a, b); let result = await safeMath.result(); assert.equal(result, a+b); + done(); }); - it("subtracts correctly", async function() { + it("subtracts correctly", async function(done) { let a = 5678; let b = 1234; let subtract = await safeMath.subtract(a, b); let result = await safeMath.result(); assert.equal(result, a-b); + done(); }); - it("should throw an error if subtraction result would be negative", async function () { + it("should throw an error if subtraction result would be negative", async function (done) { let a = 1234; let b = 5678; try { @@ -39,10 +43,11 @@ contract('SafeMath', function(accounts) { } catch(error) { if (error.message.search('invalid JUMP') == -1) throw error assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + done(); } }); - it("should throw an error on addition overflow", async function() { + it("should throw an error on addition overflow", async function(done) { let a = 115792089237316195423570985008687907853269984665640564039457584007913129639935; let b = 1; try { @@ -50,10 +55,11 @@ contract('SafeMath', function(accounts) { } catch(error) { if (error.message.search('invalid JUMP') == -1) throw error assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + done(); } }); - it("should throw an error on multiplication overflow", async function() { + it("should throw an error on multiplication overflow", async function(done) { let a = 115792089237316195423570985008687907853269984665640564039457584007913129639933; let b = 2; try { @@ -61,6 +67,7 @@ contract('SafeMath', function(accounts) { } catch(error) { if (error.message.search('invalid JUMP') == -1) throw error assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + done(); } }); diff --git a/test/StandardToken.js b/test/StandardToken.js index cac3e8633..186c1951e 100644 --- a/test/StandardToken.js +++ b/test/StandardToken.js @@ -1,38 +1,42 @@ contract('StandardToken', function(accounts) { - it("should return the correct totalSupply after construction", async function() { + it("should return the correct totalSupply after construction", async function(done) { let token = await StandardTokenMock.new(accounts[0], 100); let totalSupply = await token.totalSupply(); assert.equal(totalSupply, 100); + done(); }) - it("should return the correct allowance amount after approval", async function() { + it("should return the correct allowance amount after approval", async function(done) { let token = await StandardTokenMock.new(); let approve = await token.approve(accounts[1], 100); let allowance = await token.allowance(accounts[0], accounts[1]); assert.equal(allowance, 100); + done(); }); - it("should return correct balances after transfer", async function() { + it("should return correct balances after transfer", async function(done) { let token = await StandardTokenMock.new(accounts[0], 100); let transfer = 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); + done(); }); - 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(done) { let token = await StandardTokenMock.new(accounts[0], 100); try { let transfer = await token.transfer(accounts[1], 101); } catch(error) { if (error.message.search('invalid JUMP') == -1) throw error assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + done(); } }); - it("should return correct balances after transfering from another account", async function() { + it("should return correct balances after transfering from another account", async function(done) { 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]}); @@ -45,9 +49,10 @@ contract('StandardToken', function(accounts) { let balance2 = await token.balanceOf(accounts[1]); assert.equal(balance2, 0); + done(); }); - 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(done) { let token = await StandardTokenMock.new(); let approve = await token.approve(accounts[1], 99); try { @@ -55,6 +60,7 @@ contract('StandardToken', function(accounts) { } catch (error) { if (error.message.search('invalid JUMP') == -1) throw error assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + done(); } }); diff --git a/test/Stoppable.js b/test/Stoppable.js index b347bac16..e4699fbd0 100644 --- a/test/Stoppable.js +++ b/test/Stoppable.js @@ -1,15 +1,16 @@ contract('Stoppable', function(accounts) { - it("can perform normal process in non-emergency", async function() { + it("can perform normal process in non-emergency", async function(done) { let stoppable = await StoppableMock.new(); let count0 = await stoppable.count(); assert.equal(count0, 0); let normalProcess = await stoppable.normalProcess(); let count1 = await stoppable.count(); assert.equal(count1, 1); + done(); }); - it("can not perform normal process in emergency", async function() { + it("can not perform normal process in emergency", async function(done) { let stoppable = await StoppableMock.new(); let emergencyStop = await stoppable.emergencyStop(); let count0 = await stoppable.count(); @@ -17,31 +18,35 @@ contract('Stoppable', function(accounts) { let normalProcess = await stoppable.normalProcess(); let count1 = await stoppable.count(); assert.equal(count1, 0); + done(); }); - it("can not take drastic measure in non-emergency", async function() { + it("can not take drastic measure in non-emergency", async function(done) { let stoppable = await StoppableMock.new(); let drasticMeasure = await stoppable.drasticMeasure(); let drasticMeasureTaken = await stoppable.drasticMeasureTaken(); assert.isFalse(drasticMeasureTaken); + done(); }); - it("can take a drastic measure in an emergency", async function() { + it("can take a drastic measure in an emergency", async function(done) { let stoppable = await StoppableMock.new(); let emergencyStop = await stoppable.emergencyStop(); let drasticMeasure = await stoppable.drasticMeasure(); let drasticMeasureTaken = await stoppable.drasticMeasureTaken(); assert.isTrue(drasticMeasureTaken); + done(); }); - it("should resume allowing normal process after emergency is over", async function() { + it("should resume allowing normal process after emergency is over", async function(done) { let stoppable = await StoppableMock.new(); let emergencyStop = await stoppable.emergencyStop(); let release = await stoppable.release(); let normalProcess = await stoppable.normalProcess(); let count0 = await stoppable.count(); assert.equal(count0, 1); + done(); }); }); From eb41a81faac5fcf865608cd549d7e19579ec601a Mon Sep 17 00:00:00 2001 From: Angello Pozo Date: Thu, 1 Dec 2016 08:42:05 -0800 Subject: [PATCH 03/18] fix: made code cleaner. added helper. removed done from most tests. --- test/BasicToken.js | 18 +++++++++--------- test/Bounty.js | 35 +++++++++++++++++++---------------- test/Claimable.js | 25 +++++++++++-------------- test/Killable.js | 4 ++-- test/LimitBalance.js | 34 +++++++++++++++------------------- test/Ownable.js | 18 ++++++++---------- test/PullPayment.js | 24 +++++++++++++----------- test/SafeMath.js | 33 +++++++++++++-------------------- test/StandardToken.js | 29 +++++++++++++---------------- test/Stoppable.js | 20 ++++++++++---------- test/helpers/assertJump.js | 3 +++ 11 files changed, 116 insertions(+), 127 deletions(-) create mode 100644 test/helpers/assertJump.js diff --git a/test/BasicToken.js b/test/BasicToken.js index 3e3600576..b899fb026 100644 --- a/test/BasicToken.js +++ b/test/BasicToken.js @@ -1,31 +1,31 @@ +const assertJump = require('./helpers/assertJump'); + contract('BasicToken', function(accounts) { - it("should return the correct totalSupply after construction", async function(done) { + it("should return the correct totalSupply after construction", async function() { let token = await BasicTokenMock.new(accounts[0], 100); let totalSupply = await token.totalSupply(); + assert.equal(totalSupply, 100); - done(); }) - it("should return correct balances after transfer", async function(done){ + it("should return correct balances after transfer", async function(){ let token = await BasicTokenMock.new(accounts[0], 100); let transfer = await token.transfer(accounts[1], 100); + let firstAccountBalance = await token.balanceOf(accounts[0]); assert.equal(firstAccountBalance, 0); + let secondAccountBalance = await token.balanceOf(accounts[1]); assert.equal(secondAccountBalance, 100); - done(); }); - it("should throw an error when trying to transfer more than balance", async function(done) { - + it("should throw an error when trying to transfer more than balance", async function() { let token = await BasicTokenMock.new(accounts[0], 100); try { let transfer = await token.transfer(accounts[1], 101); } catch(error) { - if (error.message.search('invalid JUMP') === -1) throw error - assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); - done(); + assertJump(error); } }); diff --git a/test/Bounty.js b/test/Bounty.js index 2e4ea06c3..60eba99a0 100644 --- a/test/Bounty.js +++ b/test/Bounty.js @@ -8,51 +8,51 @@ let sendReward = function(sender, receiver, value){ contract('Bounty', function(accounts) { - it("sets reward", async function(done){ + 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()); - done(); }) - it("empties itself when killed", async function(done){ + it("empties itself when killed", 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()) + + assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()); + await bounty.kill(); assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()); - done(); }) describe("Against secure contract", function(){ - it("checkInvariant returns true", async function(done){ + it("checkInvariant returns true", async function(){ let bounty = await SecureTargetBounty.new(); let target = await bounty.createTarget(); let check = await bounty.checkInvariant.call(); + assert.isTrue(check); - done(); }) it("cannot claim reward", async function(done){ let owner = accounts[0]; let researcher = accounts[1]; let reward = web3.toWei(1, "ether"); - let bounty = await SecureTargetBounty.new(); let event = bounty.TargetCreated({}); event.watch(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 { @@ -61,13 +61,14 @@ contract('Bounty', function(accounts) { } catch(error) { let reClaimedBounty = await bounty.claimed.call(); assert.isFalse(reClaimedBounty); + try { let withdraw = await bounty.withdrawPayments({from:researcher}); done("should not come here") } catch (err) { - assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()) + assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()); + done(); } - done(); }//end of first try catch }); bounty.createTarget({from:researcher}); @@ -75,21 +76,19 @@ contract('Bounty', function(accounts) { }) describe("Against broken contract", function(){ - it("checkInvariant returns false", async function(done){ + it("checkInvariant returns false", async function(){ let bounty = await InsecureTargetBounty.new(); let target = await bounty.createTarget(); let invarriantCall = await bounty.checkInvariant.call(); + assert.isFalse(invarriantCall); - done(); }) it("claims reward", async function(done){ let owner = accounts[0]; let researcher = accounts[1]; let reward = web3.toWei(1, "ether"); - let bounty = await InsecureTargetBounty.new(); - let event = bounty.TargetCreated({}); event.watch(async function(err, result) { @@ -97,12 +96,16 @@ contract('Bounty', function(accounts) { if (err) { throw err } let targetAddress = result.args.createdAddress; sendReward(owner, bounty.address, reward); + assert.equal(reward, web3.eth.getBalance(bounty.address).toNumber()); let bountyClaim = await bounty.claim(targetAddress, {from:researcher}); let claim = await bounty.claimed.call(); + assert.isTrue(claim); + let payment = await bounty.withdrawPayments({from:researcher}); + assert.equal(0, web3.eth.getBalance(bounty.address).toNumber()); done(); }) diff --git a/test/Claimable.js b/test/Claimable.js index ea0e6c385..b30b31d2d 100644 --- a/test/Claimable.js +++ b/test/Claimable.js @@ -1,53 +1,50 @@ contract('Claimable', function(accounts) { let claimable; - beforeEach(async function(done) { + beforeEach(async function() { claimable = await Claimable.new(); - done(); }); - it("should have an owner", async function(done) { + it("should have an owner", async function() { let owner = await claimable.owner(); assert.isTrue(owner != 0); - done(); }); - it("changes pendingOwner after transfer", async function(done) { + it("changes pendingOwner after transfer", async function() { let newOwner = accounts[1]; let transfer = await claimable.transfer(newOwner); let pendingOwner = await claimable.pendingOwner(); + assert.isTrue(pendingOwner === newOwner); - done(); }); - it("should prevent to claimOwnership from no pendingOwner", async function(done) { + it("should prevent to claimOwnership from no pendingOwner", async function() { let claimedOwner = await claimable.claimOwnership({from: accounts[2]}); let owner = await claimable.owner(); + assert.isTrue(owner != accounts[2]); - done(); }); - it("should prevent non-owners from transfering", async function(done) { + it("should prevent non-owners from transfering", async function() { let transfer = await claimable.transfer(accounts[2], {from: accounts[2]}); let pendingOwner = await claimable.pendingOwner(); + assert.isFalse(pendingOwner === accounts[2]); - done(); }); describe("after initiating a transfer", function () { let newOwner; - beforeEach(async function (done) { + beforeEach(async function () { newOwner = accounts[1]; await claimable.transfer(newOwner); - done(); }); - it("changes allow pending owner to claim ownership", async function(done) { + it("changes allow pending owner to claim ownership", async function() { let claimedOwner = await claimable.claimOwnership({from: newOwner}) let owner = await claimable.owner(); + assert.isTrue(owner === newOwner); - done(); }); }); }); diff --git a/test/Killable.js b/test/Killable.js index 4cb4de152..73bc8067b 100644 --- a/test/Killable.js +++ b/test/Killable.js @@ -32,7 +32,7 @@ contract('Killable', function(accounts) { } }; - it("should send balance to owner after death", async function(done) { + it("should send balance to owner after death", async function() { let initBalance, newBalance, owner, address, killable, kBalance, txnHash, receiptMined; web3.eth.sendTransaction({from: web3.eth.coinbase, to: accounts[0], value: web3.toWei('50','ether')}, function(err, result) { if(err) @@ -49,8 +49,8 @@ contract('Killable', function(accounts) { txnHash = await killable.kill({from: owner}); receiptMined = await web3.eth.getTransactionReceiptMined(txnHash); newBalance = web3.eth.getBalance(owner); + assert.isTrue(newBalance > initBalance); - done(); }); }); diff --git a/test/LimitBalance.js b/test/LimitBalance.js index 1e2156b8c..2ada59445 100644 --- a/test/LimitBalance.js +++ b/test/LimitBalance.js @@ -1,59 +1,55 @@ +const assertJump = require('./helpers/assertJump'); + contract('LimitBalance', function(accounts) { let lb; - beforeEach(async function(done) { + beforeEach(async function() { lb = await LimitBalanceMock.new(); - done(); }); let LIMIT = 1000; - it("should expose limit", async function(done) { + it("should expose limit", async function() { let limit = await lb.limit(); assert.equal(limit, LIMIT); - done(); }); - it("should allow sending below limit", async function(done) { + it("should allow sending below limit", async function() { let amount = 1; let limDeposit = await lb.limitedDeposit({value: amount}); + assert.equal(web3.eth.getBalance(lb.address), amount); - done(); }); - it("shouldnt allow sending above limit", async function(done) { - + it("shouldnt allow sending above limit", async function() { let amount = 1110; try { let limDeposit = await lb.limitedDeposit({value: amount}); } catch(error) { - if (error.message.search('invalid JUMP') == -1) throw error - assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); - done(); + assertJump(error); } }); - it("should allow multiple sends below limit", async function(done) { + it("should allow multiple sends below limit", async function() { let amount = 500; - let limDeposit = await lb.limitedDeposit({value: amount}); + assert.equal(web3.eth.getBalance(lb.address), amount); + let limDeposit2 = await lb.limitedDeposit({value: amount}); assert.equal(web3.eth.getBalance(lb.address), amount*2); - done(); }); - it("shouldnt allow multiple sends above limit", async function(done) { + it("shouldnt allow multiple sends above limit", async function() { let amount = 500; - let limDeposit = await lb.limitedDeposit({value: amount}); + assert.equal(web3.eth.getBalance(lb.address), amount); + try { await lb.limitedDeposit({value: amount+1}) } catch(error) { - if (error.message.search('invalid JUMP') == -1) throw error - assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); - done(); + assertJump(error); } }); diff --git a/test/Ownable.js b/test/Ownable.js index c25c27e3d..abf8a9272 100644 --- a/test/Ownable.js +++ b/test/Ownable.js @@ -1,40 +1,38 @@ contract('Ownable', function(accounts) { let ownable; - beforeEach(async function(done) { + beforeEach(async function() { ownable = await Ownable.new(); - done(); }); - it("should have an owner", async function(done) { + it("should have an owner", async function() { let owner = await ownable.owner(); assert.isTrue(owner != 0); - done(); }); - it("changes owner after transfer", async function(done) { + it("changes owner after transfer", async function() { let other = accounts[1]; let transfer = await ownable.transfer(other); let owner = await ownable.owner(); + assert.isTrue(owner === other); - done(); }); - it("should prevent non-owners from transfering", async function(done) { + it("should prevent non-owners from transfering", async function() { let other = accounts[2]; let transfer = await ownable.transfer(other, {from: accounts[2]}); let owner = await ownable.owner(); + assert.isFalse(owner === other); - done(); }); - it("should guard ownership against stuck state", async function(done) { + it("should guard ownership against stuck state", async function() { let ownable = Ownable.deployed(); let originalOwner = await ownable.owner(); let transfer = await ownable.transfer(null, {from: originalOwner}); let newOwner = await ownable.owner(); + assert.equal(originalOwner, newOwner); - done(); }); }); diff --git a/test/PullPayment.js b/test/PullPayment.js index 65b3f247c..0aa86b4e9 100644 --- a/test/PullPayment.js +++ b/test/PullPayment.js @@ -1,55 +1,57 @@ contract('PullPayment', function(accounts) { - it("can't call asyncSend externally", async function(done) { + it("can't call asyncSend externally", async function() { let ppc = await PullPaymentMock.new(); assert.isUndefined(ppc.asyncSend); - done(); }); - it("can record an async payment correctly", async function(done) { + it("can record an async payment correctly", async function() { let AMOUNT = 100; let ppce = await PullPaymentMock.new(); let callSend = await ppce.callSend(accounts[0], AMOUNT); let paymentsToAccount0 = await ppce.payments(accounts[0]); + assert.equal(paymentsToAccount0, AMOUNT); - done(); }); - it("can add multiple balances on one account", async function(done) { + it("can add multiple balances on one account", async function() { let ppce = await PullPaymentMock.new(); let call1 = await ppce.callSend(accounts[0], 200); - let call2 = await ppce.callSend(accounts[0], 300) + let call2 = await ppce.callSend(accounts[0], 300); let paymentsToAccount0 = await ppce.payments(accounts[0]); + assert.equal(paymentsToAccount0, 500); - done(); }); - it("can add balances on multiple accounts", async function(done) { + it("can add balances on multiple accounts", async function() { let ppce = await PullPaymentMock.new(); let call1 = await ppce.callSend(accounts[0], 200); let call2 = 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); - done(); }); - it("can withdraw payment", async function(done) { + it("can withdraw payment", async function() { let AMOUNT = 17*1e18; let payee = accounts[1]; let initialBalance = web3.eth.getBalance(payee); let ppce = await PullPaymentMock.new({value: AMOUNT}); let call1 = await ppce.callSend(payee, AMOUNT); + let payment1 = await ppce.payments(payee); assert.equal(payment1, AMOUNT); + let withdraw = await ppce.withdrawPayments({from: payee}); let payment2 = await ppce.payments(payee); assert.equal(payment2, 0); + let balance = web3.eth.getBalance(payee); assert(Math.abs(balance-initialBalance-AMOUNT) < 1e16); - done(); }); }); diff --git a/test/SafeMath.js b/test/SafeMath.js index fd1765b9e..d65b0acc7 100644 --- a/test/SafeMath.js +++ b/test/SafeMath.js @@ -1,73 +1,66 @@ +const assertJump = require('./helpers/assertJump'); contract('SafeMath', function(accounts) { let safeMath; - before(async function(done) { + before(async function() { safeMath = await SafeMathMock.new(); - done(); }); - it("multiplies correctly", async function(done) { + it("multiplies correctly", async function() { let a = 5678; let b = 1234; let mult = await safeMath.multiply(a, b); let result = await safeMath.result(); assert.equal(result, a*b); - done(); }); - it("adds correctly", async function(done) { + it("adds correctly", async function() { let a = 5678; let b = 1234; let add = await safeMath.add(a, b); let result = await safeMath.result(); + assert.equal(result, a+b); - done(); }); - it("subtracts correctly", async function(done) { + it("subtracts correctly", async function() { let a = 5678; let b = 1234; let subtract = await safeMath.subtract(a, b); let result = await safeMath.result(); + assert.equal(result, a-b); - done(); }); - it("should throw an error if subtraction result would be negative", async function (done) { + it("should throw an error if subtraction result would be negative", async function () { let a = 1234; let b = 5678; try { let subtract = await safeMath.subtract(a, b); } catch(error) { - if (error.message.search('invalid JUMP') == -1) throw error - assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); - done(); + assertJump(error); } }); - it("should throw an error on addition overflow", async function(done) { + it("should throw an error on addition overflow", async function() { let a = 115792089237316195423570985008687907853269984665640564039457584007913129639935; let b = 1; try { let add = await safeMath.add(a, b); } catch(error) { - if (error.message.search('invalid JUMP') == -1) throw error - assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); - done(); + assertJump(error); } }); - it("should throw an error on multiplication overflow", async function(done) { + it("should throw an error on multiplication overflow", async function() { let a = 115792089237316195423570985008687907853269984665640564039457584007913129639933; let b = 2; try { let multiply = await safeMath.multiply(a, b); } catch(error) { - if (error.message.search('invalid JUMP') == -1) throw error - assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); - done(); + assertJump(error); } }); diff --git a/test/StandardToken.js b/test/StandardToken.js index 186c1951e..293810ee3 100644 --- a/test/StandardToken.js +++ b/test/StandardToken.js @@ -1,42 +1,42 @@ +const assertJump = require('./helpers/assertJump'); + contract('StandardToken', function(accounts) { - it("should return the correct totalSupply after construction", async function(done) { + 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); - done(); }) - it("should return the correct allowance amount after approval", async function(done) { + it("should return the correct allowance amount after approval", async function() { let token = await StandardTokenMock.new(); let approve = await token.approve(accounts[1], 100); let allowance = await token.allowance(accounts[0], accounts[1]); + assert.equal(allowance, 100); - done(); }); - it("should return correct balances after transfer", async function(done) { + 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); let balance0 = await token.balanceOf(accounts[0]); assert.equal(balance0, 0); + let balance1 = await token.balanceOf(accounts[1]); assert.equal(balance1, 100); - done(); }); - it("should throw an error when trying to transfer more than balance", async function(done) { + 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); } catch(error) { - if (error.message.search('invalid JUMP') == -1) throw error - assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); - done(); + assertJump(error); } }); - it("should return correct balances after transfering from another account", async function(done) { + 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]}); @@ -49,18 +49,15 @@ contract('StandardToken', function(accounts) { let balance2 = await token.balanceOf(accounts[1]); assert.equal(balance2, 0); - done(); }); - it("should throw an error when trying to transfer more than allowed", async function(done) { + 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); try { let transfer = await token.transferFrom(accounts[0], accounts[2], 100, {from: accounts[1]}); } catch (error) { - if (error.message.search('invalid JUMP') == -1) throw error - assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); - done(); + assertJump(error); } }); diff --git a/test/Stoppable.js b/test/Stoppable.js index e4699fbd0..e8e6e2e80 100644 --- a/test/Stoppable.js +++ b/test/Stoppable.js @@ -1,52 +1,52 @@ contract('Stoppable', function(accounts) { - it("can perform normal process in non-emergency", async function(done) { + it("can perform normal process in non-emergency", async function() { let stoppable = await StoppableMock.new(); let count0 = await stoppable.count(); assert.equal(count0, 0); + let normalProcess = await stoppable.normalProcess(); let count1 = await stoppable.count(); assert.equal(count1, 1); - done(); }); - it("can not perform normal process in emergency", async function(done) { + it("can not perform normal process in emergency", async function() { let stoppable = await StoppableMock.new(); let emergencyStop = await stoppable.emergencyStop(); let count0 = await stoppable.count(); assert.equal(count0, 0); + let normalProcess = await stoppable.normalProcess(); let count1 = await stoppable.count(); assert.equal(count1, 0); - done(); }); - it("can not take drastic measure in non-emergency", async function(done) { + it("can not take drastic measure in non-emergency", async function() { let stoppable = await StoppableMock.new(); let drasticMeasure = await stoppable.drasticMeasure(); let drasticMeasureTaken = await stoppable.drasticMeasureTaken(); + assert.isFalse(drasticMeasureTaken); - done(); }); - it("can take a drastic measure in an emergency", async function(done) { + it("can take a drastic measure in an emergency", async function() { let stoppable = await StoppableMock.new(); let emergencyStop = await stoppable.emergencyStop(); let drasticMeasure = await stoppable.drasticMeasure(); let drasticMeasureTaken = await stoppable.drasticMeasureTaken(); + assert.isTrue(drasticMeasureTaken); - done(); }); - it("should resume allowing normal process after emergency is over", async function(done) { + it("should resume allowing normal process after emergency is over", async function() { let stoppable = await StoppableMock.new(); let emergencyStop = await stoppable.emergencyStop(); let release = await stoppable.release(); let normalProcess = await stoppable.normalProcess(); let count0 = await stoppable.count(); + assert.equal(count0, 1); - done(); }); }); diff --git a/test/helpers/assertJump.js b/test/helpers/assertJump.js new file mode 100644 index 000000000..c13654d27 --- /dev/null +++ b/test/helpers/assertJump.js @@ -0,0 +1,3 @@ +module.exports = function(error) { + assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); +} From 38545eb6484d44c652d92cdb0dd2edac96d035cf Mon Sep 17 00:00:00 2001 From: Angello Pozo Date: Thu, 1 Dec 2016 20:20:44 -0800 Subject: [PATCH 04/18] fix: spelling in a test --- test/Bounty.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Bounty.js b/test/Bounty.js index 60eba99a0..582b2fe8c 100644 --- a/test/Bounty.js +++ b/test/Bounty.js @@ -79,9 +79,9 @@ contract('Bounty', function(accounts) { it("checkInvariant returns false", async function(){ let bounty = await InsecureTargetBounty.new(); let target = await bounty.createTarget(); - let invarriantCall = await bounty.checkInvariant.call(); + let invariantCall = await bounty.checkInvariant.call(); - assert.isFalse(invarriantCall); + assert.isFalse(invariantCall); }) it("claims reward", async function(done){ From 0e58f7b992794cf18d2d4d481a3fbad82e2106ca Mon Sep 17 00:00:00 2001 From: qdeswaef Date: Tue, 13 Dec 2016 11:53:16 +0100 Subject: [PATCH 05/18] fixes gh-99 PullPaymentMock needed a payable constructor --- contracts/test-helpers/PullPaymentMock.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contracts/test-helpers/PullPaymentMock.sol b/contracts/test-helpers/PullPaymentMock.sol index 0c8c3d943..a50c8187c 100644 --- a/contracts/test-helpers/PullPaymentMock.sol +++ b/contracts/test-helpers/PullPaymentMock.sol @@ -4,6 +4,9 @@ import '../PullPayment.sol'; // mock class using PullPayment contract PullPaymentMock is PullPayment { // test helper function to call asyncSend + + function PullPaymentMock() payable { } + function callSend(address dest, uint amount) { asyncSend(dest, amount); } From c15fa95beaca6bf3fb68ded144e25edc8ad0bc9c Mon Sep 17 00:00:00 2001 From: qdeswaef Date: Tue, 13 Dec 2016 11:53:16 +0100 Subject: [PATCH 06/18] fixes gh-99 PullPaymentMock needed a payable constructor --- contracts/test-helpers/PullPaymentMock.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contracts/test-helpers/PullPaymentMock.sol b/contracts/test-helpers/PullPaymentMock.sol index 0c8c3d943..1dac2ce53 100644 --- a/contracts/test-helpers/PullPaymentMock.sol +++ b/contracts/test-helpers/PullPaymentMock.sol @@ -3,6 +3,9 @@ import '../PullPayment.sol'; // mock class using PullPayment contract PullPaymentMock is PullPayment { + + function PullPaymentMock() payable { } + // test helper function to call asyncSend function callSend(address dest, uint amount) { asyncSend(dest, amount); From 9d56414b758b1bc6a5950fa6a747efbfd6aedc33 Mon Sep 17 00:00:00 2001 From: qdeswaef Date: Tue, 13 Dec 2016 12:00:48 +0100 Subject: [PATCH 07/18] fixed the code --- contracts/test-helpers/PullPaymentMock.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/contracts/test-helpers/PullPaymentMock.sol b/contracts/test-helpers/PullPaymentMock.sol index 773f6b148..1dac2ce53 100644 --- a/contracts/test-helpers/PullPaymentMock.sol +++ b/contracts/test-helpers/PullPaymentMock.sol @@ -7,9 +7,6 @@ contract PullPaymentMock is PullPayment { function PullPaymentMock() payable { } // test helper function to call asyncSend - - function PullPaymentMock() payable { } - function callSend(address dest, uint amount) { asyncSend(dest, amount); } From 41fdd5d4c6d52aa723348d4891b88c06a4d46efa Mon Sep 17 00:00:00 2001 From: qdeswaef Date: Thu, 15 Dec 2016 15:32:08 +0100 Subject: [PATCH 08/18] fixes gh-109: resolve conflict between Ownable and ERC20 token. --- contracts/Ownable.sol | 4 ++-- test/Ownable.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/Ownable.sol b/contracts/Ownable.sol index 40fc08146..705f081bc 100644 --- a/contracts/Ownable.sol +++ b/contracts/Ownable.sol @@ -14,12 +14,12 @@ contract Ownable { owner = msg.sender; } - modifier onlyOwner() { + modifier onlyOwner() { if (msg.sender == owner) _; } - function transfer(address newOwner) onlyOwner { + function transferOwnership(address newOwner) onlyOwner { if (newOwner != address(0)) owner = newOwner; } diff --git a/test/Ownable.js b/test/Ownable.js index abf8a9272..24a2d239c 100644 --- a/test/Ownable.js +++ b/test/Ownable.js @@ -12,7 +12,7 @@ contract('Ownable', function(accounts) { it("changes owner after transfer", async function() { let other = accounts[1]; - let transfer = await ownable.transfer(other); + let transfer = await ownable.transferOwnership(other); let owner = await ownable.owner(); assert.isTrue(owner === other); @@ -20,7 +20,7 @@ contract('Ownable', function(accounts) { it("should prevent non-owners from transfering", async function() { let other = accounts[2]; - let transfer = await ownable.transfer(other, {from: accounts[2]}); + let transfer = await ownable.transferOwnership(other, {from: accounts[2]}); let owner = await ownable.owner(); assert.isFalse(owner === other); @@ -29,9 +29,9 @@ contract('Ownable', function(accounts) { it("should guard ownership against stuck state", async function() { let ownable = Ownable.deployed(); let originalOwner = await ownable.owner(); - let transfer = await ownable.transfer(null, {from: originalOwner}); + let transfer = await ownable.transferOwnership(null, {from: originalOwner}); let newOwner = await ownable.owner(); - + assert.equal(originalOwner, newOwner); }); From 77e732218e911b4a6c1a99b25e3c99e1ea2924ef Mon Sep 17 00:00:00 2001 From: qdeswaef Date: Thu, 15 Dec 2016 15:59:25 +0100 Subject: [PATCH 09/18] Also change claimable to avoid conflicts with ERC20 tokens --- contracts/Claimable.sol | 6 +++--- test/Claimable.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/Claimable.sol b/contracts/Claimable.sol index d51d34f01..e7490e05d 100644 --- a/contracts/Claimable.sol +++ b/contracts/Claimable.sol @@ -7,8 +7,8 @@ import './Ownable.sol'; /* * Claimable - * - * Extension for the Ownable contract, where the ownership needs to be claimed. This allows the new owner to accept the transfer. + * + * 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; @@ -18,7 +18,7 @@ contract Claimable is Ownable { _; } - function transfer(address newOwner) onlyOwner { + function transferOwnership(address newOwner) onlyOwner { pendingOwner = newOwner; } diff --git a/test/Claimable.js b/test/Claimable.js index b30b31d2d..ae3acc5cc 100644 --- a/test/Claimable.js +++ b/test/Claimable.js @@ -12,7 +12,7 @@ contract('Claimable', function(accounts) { it("changes pendingOwner after transfer", async function() { let newOwner = accounts[1]; - let transfer = await claimable.transfer(newOwner); + let transfer = await claimable.transferOwnership(newOwner); let pendingOwner = await claimable.pendingOwner(); assert.isTrue(pendingOwner === newOwner); @@ -21,12 +21,12 @@ contract('Claimable', function(accounts) { it("should prevent to claimOwnership from no pendingOwner", async function() { let claimedOwner = await claimable.claimOwnership({from: accounts[2]}); let owner = await claimable.owner(); - + assert.isTrue(owner != accounts[2]); }); it("should prevent non-owners from transfering", async function() { - let transfer = await claimable.transfer(accounts[2], {from: accounts[2]}); + let transfer = await claimable.transferOwnership(accounts[2], {from: accounts[2]}); let pendingOwner = await claimable.pendingOwner(); assert.isFalse(pendingOwner === accounts[2]); @@ -37,7 +37,7 @@ contract('Claimable', function(accounts) { beforeEach(async function () { newOwner = accounts[1]; - await claimable.transfer(newOwner); + await claimable.transferOwnership(newOwner); }); it("changes allow pending owner to claim ownership", async function() { From ed6df57f88b4f019ccc3fdf43e6baef84001843d Mon Sep 17 00:00:00 2001 From: qdeswaef Date: Fri, 16 Dec 2016 10:15:08 +0100 Subject: [PATCH 10/18] updated documentation for claimable and ownable interfaces --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 598347dd6..6a9274583 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Sets the address of the creator of the contract as the owner. #### modifier onlyOwner( ) Prevents function from running if it is called by anyone other than the owner. -#### transfer(address newOwner) onlyOwner +#### transferOwnership(address newOwner) onlyOwner Transfers ownership of the contract to the passed address. --- @@ -97,7 +97,7 @@ ___ ### Claimable Extension for the Ownable contract, where the ownership needs to be claimed -#### transfer(address newOwner) onlyOwner +#### transferOwnership(address newOwner) onlyOwner Sets the passed address as the pending owner. #### modifier onlyPendingOwner From 8ba40d066fec61d64047a2fde20697052c81000e Mon Sep 17 00:00:00 2001 From: Demian Elias Brener Date: Tue, 13 Dec 2016 19:30:41 -0300 Subject: [PATCH 11/18] building docs --- docs/.DS_Store | Bin 0 -> 6148 bytes docs/Makefile | 20 +++++ docs/make.bat | 36 ++++++++ docs/source/.DS_Store | Bin 0 -> 6148 bytes docs/source/conf.py | 160 ++++++++++++++++++++++++++++++++++ docs/source/index.rst | 184 ++++++++++++++++++++++++++++++++++++++++ docs/source/license.rst | 150 ++++++++++++++++++++++++++++++++ 7 files changed, 550 insertions(+) create mode 100644 docs/.DS_Store create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/.DS_Store create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst create mode 100644 docs/source/license.rst diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c3b68036b4c9a7012d8613fd0a10449b9dc6cd82 GIT binary patch literal 6148 zcmeHK!EO^V5FNK^aX?jbKx&V^AaRILTAKENkXE4_dZ>gH1P4IvZg<t62mKVjfX{)M@qji7aH)h)bkBfiVDT8B`@x_R27;ACzB;hsCjept-7IKREu=om(8$T7!CwNNUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/source/.DS_Store b/docs/source/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ae8289a52d722ead7b0b698adee50cef7cf30097 GIT binary patch literal 6148 zcmeH~&u-H|5XNWQK%62(4oK~BFGw6Blorw+5R#R)hu)Ba-~cGKV?!;u-Y9kmB~9fE z4?*9ckHQo1IPlHx5;acf5uvgp&3^l5X083n-t`iZ=#Hapq9ze}aMs!eiWSD=>`S(0 zdw5XjISNW>aFnV+m@Y-T4oAQd_}2*Vw_B$^)=-A+*W)m7h8c?rvWL-=mR|g#@Hgnl~ampYt;Z`75JfFrO-VBIvE zeEuK)`ToC{e09;0j0JuM+qL0vgU> literal 0 HcmV?d00001 diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 000000000..2a17842e5 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# +# zeppelin-solidity documentation build configuration file, created by +# sphinx-quickstart on Tue Dec 13 11:35:05 2016. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'zeppelin-solidity' +copyright = u'2016, Smart Contract Solutions, Inc' +author = u'Smart Contract Solutions, Inc' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = u'1.0.0' +# The full version, including alpha/beta/rc tags. +release = u'1.0.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +import sphinx_rtd_theme + +html_theme = "sphinx_rtd_theme" + +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + + +# -- Options for HTMLHelp output ------------------------------------------ + +# Output file base name for HTML help builder. +htmlhelp_basename = 'zeppelin-soliditydoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'zeppelin-solidity.tex', u'zeppelin-solidity Documentation', + u'Zeppelin', 'manual'), +] + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'zeppelin-solidity', u'zeppelin-solidity Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'zeppelin-solidity', u'zeppelin-solidity Documentation', + author, 'zeppelin-solidity', 'One line description of project.', + 'Miscellaneous'), +] + + + diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 000000000..be70ad8dc --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,184 @@ +.. zeppelin-solidity documentation master file, created by + sphinx-quickstart on Tue Dec 13 11:35:05 2016. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Documentation +============================================= + +**Welcome to Zeppelin-Solidity!** Get familiar with the Zeppelin Smart Contracts. + +Documentation +^^^^^^^^^^^^^^ + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + license + hola + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + +Smart Contracts +^^^^^^^^^^^^^^^ + +Ownable +-------- +Base contract with an owner. + +**Ownable( )** +++++++++++++++++ +Sets the address of the creator of the contract as the owner. + +modifier onlyOwner( ) +++++++++++++++++++++++++ +Prevents function from running if it is called by anyone other than the owner. + +**transfer(address newOwner) onlyOwner** +>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +Transfers ownership of the contract to the passed address. + +--- +### Stoppable +Base contract that provides an emergency stop mechanism. + +Inherits from contract Ownable. + +#### emergencyStop( ) external onlyOwner +Triggers the stop mechanism on the contract. After this function is called (by the owner of the contract), any function with modifier stopInEmergency will not run. + +#### modifier stopInEmergency +Prevents function from running if stop mechanism is activated. + +#### modifier onlyInEmergency +Only runs if stop mechanism is activated. + +#### release( ) external onlyOwner onlyInEmergency +Deactivates the stop mechanism. + +--- +### Killable +Base contract that can be killed by owner. + +Inherits from contract Ownable. + +#### kill( ) onlyOwner +Destroys the contract and sends funds back to the owner. +___ +### Claimable +Extension for the Ownable contract, where the ownership needs to be claimed + +#### transfer(address newOwner) onlyOwner +Sets the passed address as the pending owner. + +#### modifier onlyPendingOwner +Function only runs if called by pending owner. + +#### claimOwnership( ) onlyPendingOwner +Completes transfer of ownership by setting pending owner as the new owner. +___ +### Migrations +Base contract that allows for a new instance of itself to be created at a different address. + +Inherits from contract Ownable. + +#### upgrade(address new_address) onlyOwner +Creates a new instance of the contract at the passed address. + +#### setCompleted(uint completed) onlyOwner +Sets the last time that a migration was completed. + +___ +### SafeMath +Provides functions of mathematical operations with safety checks. + +#### assert(bool assertion) internal +Throws an error if the passed result is false. Used in this contract by checking mathematical expressions. + +#### safeMul(uint a, uint b) internal returns (uint) +Multiplies two unisgned integers. Asserts that dividing the product by the non-zero multiplicand results in the multiplier. + +#### safeSub(uint a, unit b) internal returns (uint) +Checks that b is not greater than a before subtracting. + +#### safeAdd(unit a, unit b) internal returns (uint) +Checks that the result is greater than both a and b. + +___ +### LimitBalance + +Base contract that provides mechanism for limiting the amount of funds a contract can hold. + +#### LimitBalance(unit _limit) +Constructor takes an unisgned integer and sets it as the limit of funds this contract can hold. + +#### modifier limitedPayable() +Throws an error if this contract's balance is already above the limit. + +___ +### PullPayment +Base contract supporting async send for pull payments. +Inherit from this contract and use asyncSend instead of send. + +#### asyncSend(address dest, uint amount) internal +Adds sent amount to available balance that payee can pull from this contract, called by payer. + +#### withdrawPayments( ) +Sends designated balance to payee calling the contract. Throws error if designated balance is 0, if contract does not hold enough funds ot pay the payee, or if the send transaction is not successful. + +___ +### StandardToken +Based on code by FirstBlood: [FirstBloodToken.sol] + +Inherits from contract SafeMath. Implementation of abstract contract ERC20 (see https://github.com/ethereum/EIPs/issues/20) + +[FirstBloodToken.sol]: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol + +#### approve(address _spender, uint _value) returns (bool success) +Sets the amount of the sender's token balance that the passed address is approved to use. + +###allowance(address _owner, address _spender) constant returns (uint remaining) +Returns the approved amount of the owner's balance that the spender can use. + +###balanceOf(address _owner) constant returns (uint balance) +Returns the token balance of the passed address. + +###transferFrom(address _from, address _to, uint _value) returns (bool success) +Transfers tokens from an account that the sender is approved to transfer from. Amount must not be greater than the approved amount or the account's balance. + +###function transfer(address _to, uint _value) returns (bool success) +Transfers tokens from sender's account. Amount must not be greater than sender's balance. + +___ +### BasicToken +Simpler version of StandardToken, with no allowances + +#### balanceOf(address _owner) constant returns (uint balance) +Returns the token balance of the passed address. + +###function transfer(address _to, uint _value) returns (bool success) +Transfers tokens from sender's account. Amount must not be greater than sender's balance. + +___ +### CrowdsaleToken +Simple ERC20 Token example, with crowdsale token creation. + +Inherits from contract StandardToken. + +#### createTokens(address recipient) payable +Creates tokens based on message value and credits to the recipient. + +#### getPrice() constant returns (uint result) +Returns the amount of tokens per 1 ether. + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` \ No newline at end of file diff --git a/docs/source/license.rst b/docs/source/license.rst new file mode 100644 index 000000000..737abba96 --- /dev/null +++ b/docs/source/license.rst @@ -0,0 +1,150 @@ +LICENSE +============================================= + +**Welcome to Zeppelin-Solidity!** Get familiar with the Zeppelin Smart Contracts. + +Documentation +^^^^^^^^^^^^^^ +Smart Contr + +--- +### Stoppable +Base contract that provides an emergency stop mechanism. + +Inherits from contract Ownable. + +#### emergencyStop( ) external onlyOwner +Triggers the stop mechanism on the contract. After this function is called (by the owner of the contract), any function with modifier stopInEmergency will not run. + +#### modifier stopInEmergency +Prevents function from running if stop mechanism is activated. + +#### modifier onlyInEmergency +Only runs if stop mechanism is activated. + +#### release( ) external onlyOwner onlyInEmergency +Deactivates the stop mechanism. + +--- +### Killable +Base contract that can be killed by owner. + +Inherits from contract Ownable. + +#### kill( ) onlyOwner +Destroys the contract and sends funds back to the owner. +___ +### Claimable +Extension for the Ownable contract, where the ownership needs to be claimed + +#### transfer(address newOwner) onlyOwner +Sets the passed address as the pending owner. + +#### modifier onlyPendingOwner +Function only runs if called by pending owner. + +#### claimOwnership( ) onlyPendingOwner +Completes transfer of ownership by setting pending owner as the new owner. +___ +### Migrations +Base contract that allows for a new instance of itself to be created at a different address. + +Inherits from contract Ownable. + +#### upgrade(address new_address) onlyOwner +Creates a new instance of the contract at the passed address. + +#### setCompleted(uint completed) onlyOwner +Sets the last time that a migration was completed. + +___ +### SafeMath +Provides functions of mathematical operations with safety checks. + +#### assert(bool assertion) internal +Throws an error if the passed result is false. Used in this contract by checking mathematical expressions. + +#### safeMul(uint a, uint b) internal returns (uint) +Multiplies two unisgned integers. Asserts that dividing the product by the non-zero multiplicand results in the multiplier. + +#### safeSub(uint a, unit b) internal returns (uint) +Checks that b is not greater than a before subtracting. + +#### safeAdd(unit a, unit b) internal returns (uint) +Checks that the result is greater than both a and b. + +___ +### LimitBalance + +Base contract that provides mechanism for limiting the amount of funds a contract can hold. + +#### LimitBalance(unit _limit) +Constructor takes an unisgned integer and sets it as the limit of funds this contract can hold. + +#### modifier limitedPayable() +Throws an error if this contract's balance is already above the limit. + +___ +### PullPayment +Base contract supporting async send for pull payments. +Inherit from this contract and use asyncSend instead of send. + +#### asyncSend(address dest, uint amount) internal +Adds sent amount to available balance that payee can pull from this contract, called by payer. + +#### withdrawPayments( ) +Sends designated balance to payee calling the contract. Throws error if designated balance is 0, if contract does not hold enough funds ot pay the payee, or if the send transaction is not successful. + +___ +### StandardToken +Based on code by FirstBlood: [FirstBloodToken.sol] + +Inherits from contract SafeMath. Implementation of abstract contract ERC20 (see https://github.com/ethereum/EIPs/issues/20) + +[FirstBloodToken.sol]: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol + +#### approve(address _spender, uint _value) returns (bool success) +Sets the amount of the sender's token balance that the passed address is approved to use. + +###allowance(address _owner, address _spender) constant returns (uint remaining) +Returns the approved amount of the owner's balance that the spender can use. + +###balanceOf(address _owner) constant returns (uint balance) +Returns the token balance of the passed address. + +###transferFrom(address _from, address _to, uint _value) returns (bool success) +Transfers tokens from an account that the sender is approved to transfer from. Amount must not be greater than the approved amount or the account's balance. + +###function transfer(address _to, uint _value) returns (bool success) +Transfers tokens from sender's account. Amount must not be greater than sender's balance. + +___ +### BasicToken +Simpler version of StandardToken, with no allowances + +#### balanceOf(address _owner) constant returns (uint balance) +Returns the token balance of the passed address. + +###function transfer(address _to, uint _value) returns (bool success) +Transfers tokens from sender's account. Amount must not be greater than sender's balance. + +___ +### CrowdsaleToken +Simple ERC20 Token example, with crowdsale token creation. + +Inherits from contract StandardToken. + +#### createTokens(address recipient) payable +Creates tokens based on message value and credits to the recipient. + +#### getPrice() constant returns (uint result) +Returns the amount of tokens per 1 ether. + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` \ No newline at end of file From ec07dce76f9ed07a99c46b7e16593763c73b1b0d Mon Sep 17 00:00:00 2001 From: Demian Elias Brener Date: Sun, 18 Dec 2016 19:52:20 -0300 Subject: [PATCH 12/18] writing docs --- docs/.DS_Store | Bin 6148 -> 8196 bytes docs/source/.DS_Store | Bin 6148 -> 8196 bytes docs/source/basictoken.rst | 12 ++ docs/source/bounty.rst | 60 +++++++ docs/source/claimable.rst | 20 +++ docs/source/contract-security-patterns.rst | 4 + docs/source/crowdsaletoken.rst | 14 ++ docs/source/developer-resources.rst | 12 ++ docs/source/getting-started.rst | 36 ++++ docs/source/index.rst | 195 +++------------------ docs/source/killable.rst | 11 ++ docs/source/license.rst | 163 ++--------------- docs/source/limitbalance.rst | 12 ++ docs/source/migrations.rst | 16 ++ docs/source/ownable.rst | 16 ++ docs/source/pullpayment.rst | 12 ++ docs/source/safemath.rst | 24 +++ docs/source/standardtoken.rst | 26 +++ docs/source/stoppable.rst | 26 +++ 19 files changed, 345 insertions(+), 314 deletions(-) create mode 100644 docs/source/basictoken.rst create mode 100644 docs/source/bounty.rst create mode 100644 docs/source/claimable.rst create mode 100644 docs/source/contract-security-patterns.rst create mode 100644 docs/source/crowdsaletoken.rst create mode 100644 docs/source/developer-resources.rst create mode 100644 docs/source/getting-started.rst create mode 100644 docs/source/killable.rst create mode 100644 docs/source/limitbalance.rst create mode 100644 docs/source/migrations.rst create mode 100644 docs/source/ownable.rst create mode 100644 docs/source/pullpayment.rst create mode 100644 docs/source/safemath.rst create mode 100644 docs/source/standardtoken.rst create mode 100644 docs/source/stoppable.rst diff --git a/docs/.DS_Store b/docs/.DS_Store index c3b68036b4c9a7012d8613fd0a10449b9dc6cd82..0a18ce9b1057c123a53faee76eba4e6b93163f52 100644 GIT binary patch delta 630 zcmZXSPiqrF7{=c>8Q2Po=9O?{w=*p%kt!95|uEUY$sATZ)}#YUYmYNYSXu=#j#_KJi}#% zNc(7buHy&Q>Ni!zgp@p!O3TVZCcAhxr{;+JnEaJ_i*lbBLO)PcxQP>`+FD zqEu?lxGTd3+=hp+4SO&?f(g8acW?rq;VXQHUzo;Kyo4Kg9dF?l-p5DS!VdQEG49L* z5*P delta 116 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{Mvv5r;6q~50$jGrVU^g=($7UXZV5Z4e1Ux1$ z7vi1VC&Ih2$c=F^I|qj#Gf*`U2yg=lSCGbyh2NPc^UHXGjA3Ac7zwh4VRJms9A*I1 Cv=kEn diff --git a/docs/source/.DS_Store b/docs/source/.DS_Store index ae8289a52d722ead7b0b698adee50cef7cf30097..841b9aa3c0ffa7e15f91ea805461619a16b864e7 100644 GIT binary patch literal 8196 zcmeHM&2G~`5T2!lI{ghlQhW3Ti9P!V zcmp1VC*VPN0QhEiiPnh|PN1snR=eY$`F3W$9eXn_5s7-cxkH>z6#`n38 zwJZ9{Dx?6OD5sE)_M_y;kH)m^1DCv$;7F_I-8Nj+Oz-z<CcI7S^HF|L+1EeA?UDCShvgV0c+OAMjlxbLz$WKGL~ zk_t{j!AWS#LRTn4S_jUR>LhAP+R-v#85n1PYxg-ipbWLUXV&kDk30M@Jw(6rQ#Krp zY5Se5aE8~oO@v$q=x#d7h&8?I`yO-H#0fUQ!hUORvJ2}uJw9b+uQ5z*7i<+ z-R_Z503aiy5cN?&QPBP1@959%`hW&|=5dJ95hx<@HzW06ep z5xhG_7S02kP#gL=b;~iFx#HZwEWr*hR)}TufRA9W+!{X>pA6(2kO^$Pfqsj+Bfhb= zxzIPDokG7uO+?~JJAaDr$4Gpuzy@@N9$}^yWJ-6@k!CXP6gK#HqW^`+Z_+WebNq#f z;utfj=RL)h0G7&UVa`qdDiY0poliy-m{`P`hKPV!pTalsqhj*C00d_R=R=0E)IUZQ z{HsdTDUi9$EVdfUS<3O8A7)N1BQHX*lLE&~@rqAk7~G6_%y_@o>st(xp!*Q+06W!u42api#$FvW|NcEZYJ_WT7yS^O z8|w{}ln@NE9EX(UIOOmjhB$Vi%9xs#10`_G#Yzn)Y-Tx>3`nLPO%+<>@ F`~pU2By0cx delta 113 zcmZp1XfcprU|?W$DortDU=RQ@Ie-{Mvv5r;6q~50$jGrVU^g=($7UXZYNpAC!g`a< zMT|CAizzTJX6N7#WCkh)0s(Fy;R@2VvG6kQoe25c5D*Fl>(JnZpbKGSU(8 diff --git a/docs/source/basictoken.rst b/docs/source/basictoken.rst new file mode 100644 index 000000000..2903c10a5 --- /dev/null +++ b/docs/source/basictoken.rst @@ -0,0 +1,12 @@ +BasicToken +============================================= + +Simpler version of StandardToken, with no allowances + +balanceOf(address _owner) constant returns (uint balance) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Returns the token balance of the passed address. + +function transfer(address _to, uint _value) returns (bool success) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Transfers tokens from sender's account. Amount must not be greater than sender's balance. \ No newline at end of file diff --git a/docs/source/bounty.rst b/docs/source/bounty.rst new file mode 100644 index 000000000..1bc2173fc --- /dev/null +++ b/docs/source/bounty.rst @@ -0,0 +1,60 @@ +Bounty +============================================= + +To create a bounty for your contract, inherit from the base `Bounty` contract and provide an implementation for ```deployContract()``` returning the new contract address.:: + + import {Bounty, Target} from "./zeppelin/Bounty.sol"; + import "./YourContract.sol"; + + contract YourBounty is Bounty { + function deployContract() internal returns(address) { + return new YourContract() + } + } + + +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. + +At contracts/YourContract.sol:: + + + import {Bounty, Target} from "./zeppelin/Bounty.sol"; + contract YourContract is Target { + function checkInvariant() returns(bool) { + // Implement your logic to make sure that none of the invariants are broken. + } + } + +Next, deploy your bounty contract along with your main contract to the network. + +At ```migrations/2_deploy_contracts.js```:: + + module.exports = function(deployer) { + deployer.deploy(YourContract); + deployer.deploy(YourBounty); + }; + +Next, add a reward to the bounty contract + +After deploying the contract, send reward funds into the bounty contract. + +From ```truffle console```:: + + bounty = YourBounty.deployed(); + address = 0xb9f68f96cde3b895cc9f6b14b856081b41cb96f1; // your account address + reward = 5; // reward to pay to a researcher who breaks your contract + + web3.eth.sendTransaction({ + from: address, + to: bounty.address, + value: web3.toWei(reward, "ether") + }) + +If researchers break the contract, they can claim their reward. + +For each researcher who wants to hack the contract and claims the reward, refer to our `Test `_ for the detail. + +Finally, if you manage to protect your contract from security researchers, you can reclaim the bounty funds. To end the bounty, kill the contract so that all the rewards go back to the owner.:: + + bounty.kill(); diff --git a/docs/source/claimable.rst b/docs/source/claimable.rst new file mode 100644 index 000000000..47efcc247 --- /dev/null +++ b/docs/source/claimable.rst @@ -0,0 +1,20 @@ +Claimable +============================================= + +Extension for the Ownable contract, where the ownership needs to be claimed + +transfer(address newOwner) onlyOwner +"""""""""""""""""""""""""""""""""""""" + +Sets the passed address as the pending owner. + +modifier onlyPendingOwner +"""""""""""""""""""""""""""""""""""""" + +Function only runs if called by pending owner. + +claimOwnership( ) onlyPendingOwner +"""""""""""""""""""""""""""""""""""""" + +Completes transfer of ownership by setting pending owner as the new owner. + diff --git a/docs/source/contract-security-patterns.rst b/docs/source/contract-security-patterns.rst new file mode 100644 index 000000000..f2d91a8e4 --- /dev/null +++ b/docs/source/contract-security-patterns.rst @@ -0,0 +1,4 @@ +Common Contract Security Patterns +============================================= + +Zeppelin smart contracts are developed using common contract security patterns. To learn more, please see `Onward with Ethereum Smart Contract Security `_ diff --git a/docs/source/crowdsaletoken.rst b/docs/source/crowdsaletoken.rst new file mode 100644 index 000000000..98a06f190 --- /dev/null +++ b/docs/source/crowdsaletoken.rst @@ -0,0 +1,14 @@ +CrowdsaleToken +============================================= + +Simple ERC20 Token example, with crowdsale token creation. + +Inherits from contract StandardToken. + +createTokens(address recipient) payable +""""""""""""""""""""""""""""""""""""""""" +Creates tokens based on message value and credits to the recipient. + +getPrice() constant returns (uint result) +""""""""""""""""""""""""""""""""""""""""" +Returns the amount of tokens per 1 ether. \ No newline at end of file diff --git a/docs/source/developer-resources.rst b/docs/source/developer-resources.rst new file mode 100644 index 000000000..b015dfce3 --- /dev/null +++ b/docs/source/developer-resources.rst @@ -0,0 +1,12 @@ +Developer Resources +============================================= + +Building a distributed application, protocol or organization with Zeppelin? + +Ask for help and follow progress at: https://zeppelin-slackin.herokuapp.com/ + +Interested in contributing to Zeppelin? + +* Framework proposal and roadmap: https://medium.com/zeppelin-blog/zeppelin-framework-proposal-and-development-roadmap-fdfa9a3a32ab#.iain47pak +* Issue tracker: https://github.com/OpenZeppelin/zeppelin-solidity/issues +* Contribution guidelines: https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/CONTRIBUTING.md \ No newline at end of file diff --git a/docs/source/getting-started.rst b/docs/source/getting-started.rst new file mode 100644 index 000000000..4419fa34b --- /dev/null +++ b/docs/source/getting-started.rst @@ -0,0 +1,36 @@ +Getting Started +============================================= + +Zeppelin integrates with `Truffle `_, an Ethereum development environment. Please install Truffle and initialize your project with ``truffle init``:: + + npm install -g truffle + mkdir myproject && cd myproject + truffle init + +To install the Zeppelin library, run:: + + npm i zeppelin-solidity + +After that, you'll get all the library's contracts in the contracts/zeppelin folder. You can use the contracts in the library like so:: + + import "./zeppelin/Ownable.sol"; + + contract MyContract is Ownable { + ... + } + +.. epigraph:: + + NOTE: The current distribution channel is npm, which is not ideal. `We're looking into providing a better tool for code distribution `_ , and ideas are welcome. + +Truffle Beta Support +"""""""""""""""""""""""" +We also support Truffle Beta npm integration. If you're using Truffle Beta, the contracts in ``node_modules`` will be enough, so feel free to delete the copies at your ``contracts`` folder. If you're using Truffle Beta, you can use Zeppelin contracts like so:: + + import "zeppelin-solidity/contracts/Ownable.sol"; + + contract MyContract is Ownable { + ... + } + +For more info see the `Truffle Beta package management tutorial `_. diff --git a/docs/source/index.rst b/docs/source/index.rst index be70ad8dc..828f0b9df 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,182 +3,39 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Documentation +Welcome to Zeppelin-Solidity ============================================= -**Welcome to Zeppelin-Solidity!** Get familiar with the Zeppelin Smart Contracts. +Zeppelin is a library for writing secure Smart Contracts on Ethereum. Get familiar with the Zeppelin Smart Contracts. -Documentation -^^^^^^^^^^^^^^ +The code is open-source, and `available on github `_. .. toctree:: :maxdepth: 2 - :caption: Contents: + + getting-started + +.. toctree:: + :maxdepth: 2 + :caption: Smart Contracts - license - hola - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -Smart Contracts -^^^^^^^^^^^^^^^ - -Ownable --------- -Base contract with an owner. - -**Ownable( )** -++++++++++++++++ -Sets the address of the creator of the contract as the owner. - -modifier onlyOwner( ) -++++++++++++++++++++++++ -Prevents function from running if it is called by anyone other than the owner. - -**transfer(address newOwner) onlyOwner** ->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -Transfers ownership of the contract to the passed address. - ---- -### Stoppable -Base contract that provides an emergency stop mechanism. - -Inherits from contract Ownable. - -#### emergencyStop( ) external onlyOwner -Triggers the stop mechanism on the contract. After this function is called (by the owner of the contract), any function with modifier stopInEmergency will not run. - -#### modifier stopInEmergency -Prevents function from running if stop mechanism is activated. - -#### modifier onlyInEmergency -Only runs if stop mechanism is activated. - -#### release( ) external onlyOwner onlyInEmergency -Deactivates the stop mechanism. - ---- -### Killable -Base contract that can be killed by owner. - -Inherits from contract Ownable. - -#### kill( ) onlyOwner -Destroys the contract and sends funds back to the owner. -___ -### Claimable -Extension for the Ownable contract, where the ownership needs to be claimed - -#### transfer(address newOwner) onlyOwner -Sets the passed address as the pending owner. - -#### modifier onlyPendingOwner -Function only runs if called by pending owner. - -#### claimOwnership( ) onlyPendingOwner -Completes transfer of ownership by setting pending owner as the new owner. -___ -### Migrations -Base contract that allows for a new instance of itself to be created at a different address. - -Inherits from contract Ownable. - -#### upgrade(address new_address) onlyOwner -Creates a new instance of the contract at the passed address. - -#### setCompleted(uint completed) onlyOwner -Sets the last time that a migration was completed. - -___ -### SafeMath -Provides functions of mathematical operations with safety checks. - -#### assert(bool assertion) internal -Throws an error if the passed result is false. Used in this contract by checking mathematical expressions. - -#### safeMul(uint a, uint b) internal returns (uint) -Multiplies two unisgned integers. Asserts that dividing the product by the non-zero multiplicand results in the multiplier. - -#### safeSub(uint a, unit b) internal returns (uint) -Checks that b is not greater than a before subtracting. - -#### safeAdd(unit a, unit b) internal returns (uint) -Checks that the result is greater than both a and b. - -___ -### LimitBalance - -Base contract that provides mechanism for limiting the amount of funds a contract can hold. - -#### LimitBalance(unit _limit) -Constructor takes an unisgned integer and sets it as the limit of funds this contract can hold. - -#### modifier limitedPayable() -Throws an error if this contract's balance is already above the limit. - -___ -### PullPayment -Base contract supporting async send for pull payments. -Inherit from this contract and use asyncSend instead of send. - -#### asyncSend(address dest, uint amount) internal -Adds sent amount to available balance that payee can pull from this contract, called by payer. - -#### withdrawPayments( ) -Sends designated balance to payee calling the contract. Throws error if designated balance is 0, if contract does not hold enough funds ot pay the payee, or if the send transaction is not successful. - -___ -### StandardToken -Based on code by FirstBlood: [FirstBloodToken.sol] - -Inherits from contract SafeMath. Implementation of abstract contract ERC20 (see https://github.com/ethereum/EIPs/issues/20) - -[FirstBloodToken.sol]: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol - -#### approve(address _spender, uint _value) returns (bool success) -Sets the amount of the sender's token balance that the passed address is approved to use. - -###allowance(address _owner, address _spender) constant returns (uint remaining) -Returns the approved amount of the owner's balance that the spender can use. - -###balanceOf(address _owner) constant returns (uint balance) -Returns the token balance of the passed address. - -###transferFrom(address _from, address _to, uint _value) returns (bool success) -Transfers tokens from an account that the sender is approved to transfer from. Amount must not be greater than the approved amount or the account's balance. - -###function transfer(address _to, uint _value) returns (bool success) -Transfers tokens from sender's account. Amount must not be greater than sender's balance. - -___ -### BasicToken -Simpler version of StandardToken, with no allowances - -#### balanceOf(address _owner) constant returns (uint balance) -Returns the token balance of the passed address. - -###function transfer(address _to, uint _value) returns (bool success) -Transfers tokens from sender's account. Amount must not be greater than sender's balance. - -___ -### CrowdsaleToken -Simple ERC20 Token example, with crowdsale token creation. - -Inherits from contract StandardToken. - -#### createTokens(address recipient) payable -Creates tokens based on message value and credits to the recipient. - -#### getPrice() constant returns (uint result) -Returns the amount of tokens per 1 ether. - + ownable + stoppable + killable + claimable + migrations + safemath + limitbalance + pullpayment + standardtoken + basictoken + crowdsaletoken + bounty .. toctree:: :maxdepth: 2 - :caption: Contents: - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` \ No newline at end of file + :caption: Developer Resources + + contract-security-patterns + developer-resources + license \ No newline at end of file diff --git a/docs/source/killable.rst b/docs/source/killable.rst new file mode 100644 index 000000000..d07c2f7f9 --- /dev/null +++ b/docs/source/killable.rst @@ -0,0 +1,11 @@ +Killable +============================================= + +Base contract that can be killed by owner. + +Inherits from contract Ownable. + +kill( ) onlyOwner +""""""""""""""""""" + +Destroys the contract and sends funds back to the owner. \ No newline at end of file diff --git a/docs/source/license.rst b/docs/source/license.rst index 737abba96..877cc423b 100644 --- a/docs/source/license.rst +++ b/docs/source/license.rst @@ -1,150 +1,23 @@ -LICENSE +The MIT License (MIT) ============================================= -**Welcome to Zeppelin-Solidity!** Get familiar with the Zeppelin Smart Contracts. +Copyright (c) 2016 Smart Contract Solutions, Inc. -Documentation -^^^^^^^^^^^^^^ -Smart Contr +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: ---- -### Stoppable -Base contract that provides an emergency stop mechanism. +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. -Inherits from contract Ownable. - -#### emergencyStop( ) external onlyOwner -Triggers the stop mechanism on the contract. After this function is called (by the owner of the contract), any function with modifier stopInEmergency will not run. - -#### modifier stopInEmergency -Prevents function from running if stop mechanism is activated. - -#### modifier onlyInEmergency -Only runs if stop mechanism is activated. - -#### release( ) external onlyOwner onlyInEmergency -Deactivates the stop mechanism. - ---- -### Killable -Base contract that can be killed by owner. - -Inherits from contract Ownable. - -#### kill( ) onlyOwner -Destroys the contract and sends funds back to the owner. -___ -### Claimable -Extension for the Ownable contract, where the ownership needs to be claimed - -#### transfer(address newOwner) onlyOwner -Sets the passed address as the pending owner. - -#### modifier onlyPendingOwner -Function only runs if called by pending owner. - -#### claimOwnership( ) onlyPendingOwner -Completes transfer of ownership by setting pending owner as the new owner. -___ -### Migrations -Base contract that allows for a new instance of itself to be created at a different address. - -Inherits from contract Ownable. - -#### upgrade(address new_address) onlyOwner -Creates a new instance of the contract at the passed address. - -#### setCompleted(uint completed) onlyOwner -Sets the last time that a migration was completed. - -___ -### SafeMath -Provides functions of mathematical operations with safety checks. - -#### assert(bool assertion) internal -Throws an error if the passed result is false. Used in this contract by checking mathematical expressions. - -#### safeMul(uint a, uint b) internal returns (uint) -Multiplies two unisgned integers. Asserts that dividing the product by the non-zero multiplicand results in the multiplier. - -#### safeSub(uint a, unit b) internal returns (uint) -Checks that b is not greater than a before subtracting. - -#### safeAdd(unit a, unit b) internal returns (uint) -Checks that the result is greater than both a and b. - -___ -### LimitBalance - -Base contract that provides mechanism for limiting the amount of funds a contract can hold. - -#### LimitBalance(unit _limit) -Constructor takes an unisgned integer and sets it as the limit of funds this contract can hold. - -#### modifier limitedPayable() -Throws an error if this contract's balance is already above the limit. - -___ -### PullPayment -Base contract supporting async send for pull payments. -Inherit from this contract and use asyncSend instead of send. - -#### asyncSend(address dest, uint amount) internal -Adds sent amount to available balance that payee can pull from this contract, called by payer. - -#### withdrawPayments( ) -Sends designated balance to payee calling the contract. Throws error if designated balance is 0, if contract does not hold enough funds ot pay the payee, or if the send transaction is not successful. - -___ -### StandardToken -Based on code by FirstBlood: [FirstBloodToken.sol] - -Inherits from contract SafeMath. Implementation of abstract contract ERC20 (see https://github.com/ethereum/EIPs/issues/20) - -[FirstBloodToken.sol]: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol - -#### approve(address _spender, uint _value) returns (bool success) -Sets the amount of the sender's token balance that the passed address is approved to use. - -###allowance(address _owner, address _spender) constant returns (uint remaining) -Returns the approved amount of the owner's balance that the spender can use. - -###balanceOf(address _owner) constant returns (uint balance) -Returns the token balance of the passed address. - -###transferFrom(address _from, address _to, uint _value) returns (bool success) -Transfers tokens from an account that the sender is approved to transfer from. Amount must not be greater than the approved amount or the account's balance. - -###function transfer(address _to, uint _value) returns (bool success) -Transfers tokens from sender's account. Amount must not be greater than sender's balance. - -___ -### BasicToken -Simpler version of StandardToken, with no allowances - -#### balanceOf(address _owner) constant returns (uint balance) -Returns the token balance of the passed address. - -###function transfer(address _to, uint _value) returns (bool success) -Transfers tokens from sender's account. Amount must not be greater than sender's balance. - -___ -### CrowdsaleToken -Simple ERC20 Token example, with crowdsale token creation. - -Inherits from contract StandardToken. - -#### createTokens(address recipient) payable -Creates tokens based on message value and credits to the recipient. - -#### getPrice() constant returns (uint result) -Returns the amount of tokens per 1 ether. - - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/docs/source/limitbalance.rst b/docs/source/limitbalance.rst new file mode 100644 index 000000000..ba50cefa9 --- /dev/null +++ b/docs/source/limitbalance.rst @@ -0,0 +1,12 @@ +LimitBalance +============================================= + +Base contract that provides mechanism for limiting the amount of funds a contract can hold. + +LimitBalance(unit _limit) +"""""""""""""""""""""""""""" +Constructor takes an unisgned integer and sets it as the limit of funds this contract can hold. + +modifier limitedPayable() +"""""""""""""""""""""""""""" +Throws an error if this contract's balance is already above the limit. \ No newline at end of file diff --git a/docs/source/migrations.rst b/docs/source/migrations.rst new file mode 100644 index 000000000..0f2cd5a3f --- /dev/null +++ b/docs/source/migrations.rst @@ -0,0 +1,16 @@ +Migrations +============================================= + +Base contract that allows for a new instance of itself to be created at a different address. + +Inherits from contract Ownable. + +upgrade(address new_address) onlyOwner +"""""""""""""""""""""""""""""""""""""""" + +Creates a new instance of the contract at the passed address. + +setCompleted(uint completed) onlyOwner** +"""""""""""""""""""""""""""""""""""""""" + +Sets the last time that a migration was completed. \ No newline at end of file diff --git a/docs/source/ownable.rst b/docs/source/ownable.rst new file mode 100644 index 000000000..43a088517 --- /dev/null +++ b/docs/source/ownable.rst @@ -0,0 +1,16 @@ +Ownable +============================================= + +Base contract with an owner. + +Ownable( ) +"""""""""""""""""""""""""""""""""""""" +Sets the address of the creator of the contract as the owner. + +modifier onlyOwner( ) +"""""""""""""""""""""""""""""""""""""" +Prevents function from running if it is called by anyone other than the owner. + +transfer(address newOwner) onlyOwner +"""""""""""""""""""""""""""""""""""""" +Transfers ownership of the contract to the passed address. \ No newline at end of file diff --git a/docs/source/pullpayment.rst b/docs/source/pullpayment.rst new file mode 100644 index 000000000..fa2932428 --- /dev/null +++ b/docs/source/pullpayment.rst @@ -0,0 +1,12 @@ +PullPayment +============================================= + +Base contract supporting async send for pull payments. Inherit from this contract and use asyncSend instead of send. + +asyncSend(address dest, uint amount) internal +""""""""""""""""""""""""""""""""""""""""""""""" +Adds sent amount to available balance that payee can pull from this contract, called by payer. + +withdrawPayments( ) +""""""""""""""""""""""""""""""""""""""""""""""" +Sends designated balance to payee calling the contract. Throws error if designated balance is 0, if contract does not hold enough funds ot pay the payee, or if the send transaction is not successful. \ No newline at end of file diff --git a/docs/source/safemath.rst b/docs/source/safemath.rst new file mode 100644 index 000000000..fcb21e467 --- /dev/null +++ b/docs/source/safemath.rst @@ -0,0 +1,24 @@ +SafeMath +============================================= + +Provides functions of mathematical operations with safety checks. + +assert(bool assertion) internal +""""""""""""""""""""""""""""""""""""""""""""""""" + +Throws an error if the passed result is false. Used in this contract by checking mathematical expressions. + +safeMul(uint a, uint b) internal returns (uint) +""""""""""""""""""""""""""""""""""""""""""""""""" + +Multiplies two unisgned integers. Asserts that dividing the product by the non-zero multiplicand results in the multiplier. + +safeSub(uint a, unit b) internal returns (uint) +""""""""""""""""""""""""""""""""""""""""""""""""" + +Checks that b is not greater than a before subtracting. + +safeAdd(unit a, unit b) internal returns (uint) +""""""""""""""""""""""""""""""""""""""""""""""""" + +Checks that the result is greater than both a and b. \ No newline at end of file diff --git a/docs/source/standardtoken.rst b/docs/source/standardtoken.rst new file mode 100644 index 000000000..4c842c8c1 --- /dev/null +++ b/docs/source/standardtoken.rst @@ -0,0 +1,26 @@ +StandardToken +============================================= + +Based on code by FirstBlood: `Link FirstBloodToken.sol `_ + +Inherits from contract SafeMath. Implementation of abstract contract ERC20 (see https://github.com/ethereum/EIPs/issues/20) + +approve(address _spender, uint _value) returns (bool success) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Sets the amount of the sender's token balance that the passed address is approved to use. + +allowance(address _owner, address _spender) constant returns (uint remaining) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Returns the approved amount of the owner's balance that the spender can use. + +balanceOf(address _owner) constant returns (uint balance) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Returns the token balance of the passed address. + +transferFrom(address _from, address _to, uint _value) returns (bool success) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Transfers tokens from an account that the sender is approved to transfer from. Amount must not be greater than the approved amount or the account's balance. + +function transfer(address _to, uint _value) returns (bool success) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +Transfers tokens from sender's account. Amount must not be greater than sender's balance. \ No newline at end of file diff --git a/docs/source/stoppable.rst b/docs/source/stoppable.rst new file mode 100644 index 000000000..3ad04d7a1 --- /dev/null +++ b/docs/source/stoppable.rst @@ -0,0 +1,26 @@ +Stoppable +============================================= + +Base contract that provides an emergency stop mechanism. + +Inherits from contract Ownable. + +emergencyStop( ) external onlyOwner +""""""""""""""""""""""""""""""""""""" + +Triggers the stop mechanism on the contract. After this function is called (by the owner of the contract), any function with modifier stopInEmergency will not run. + +modifier stopInEmergency +""""""""""""""""""""""""""""""""""""" + +Prevents function from running if stop mechanism is activated. + +modifier onlyInEmergency +""""""""""""""""""""""""""""""""""""" + +Only runs if stop mechanism is activated. + +release( ) external onlyOwner onlyInEmergency +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Deactivates the stop mechanism. \ No newline at end of file From 31a01ebde1f3c85714539654fd81a995b79b2b43 Mon Sep 17 00:00:00 2001 From: Demian Elias Brener Date: Mon, 19 Dec 2016 08:57:20 -0300 Subject: [PATCH 13/18] developer resources update --- docs/.DS_Store | Bin 8196 -> 8196 bytes docs/source/.DS_Store | Bin 8196 -> 8196 bytes docs/source/contract-security-patterns.rst | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/.DS_Store b/docs/.DS_Store index 0a18ce9b1057c123a53faee76eba4e6b93163f52..cc0f307c95ef010813210d503110bba59bf97370 100644 GIT binary patch delta 161 zcmZp1XmQx^NQhHRR9r$-Qc7BC@@t_Y*?0l|;^d?oF{JhBM^rFlZ|FpE? z)RM_n!oJcGnaTNi!I@R5Af*}k<(@!pKv8O0W@`E5N5U2^$_@bxV8F@1!Jy6H$l%Km z#*ocW#W0a!F2j0;-3%uf?lQb*_{qr5D8Q)1sLg1?Xv=8N=)oAs7{nOD7|9sLn7lbo HWEnRA(V{I& delta 161 zcmZp1XmQx^NQhHZOk6@#Qc6l@@@t_Y+3575%oP8$wBpo~$an$%;^d?oF z{JhCk!oJcV(Tx0Z&*c2PfTGm0%+&ITOdvZrvnqA+BVh{{PGyGx1_N z$Y!Wwn8+}fVI{+Eh7$~T8QwGeWMpTQWK?3*W;9{6WwdAXU<_moVhmx7WQ<~r-W(^g Gj2i&abuC8# diff --git a/docs/source/.DS_Store b/docs/source/.DS_Store index 841b9aa3c0ffa7e15f91ea805461619a16b864e7..2c3bc9e934c14539b75fd3a09a9801b3019b6e59 100644 GIT binary patch delta 98 zcmZp1XmOa}&nU4mU^hRb#AY6WU}jS}hGd3(hCGH6h9ZVUAiIP?m!X&;704Xwgh={X(W?*2f*c>7p&a#V!Z diff --git a/docs/source/contract-security-patterns.rst b/docs/source/contract-security-patterns.rst index f2d91a8e4..74dacfc45 100644 --- a/docs/source/contract-security-patterns.rst +++ b/docs/source/contract-security-patterns.rst @@ -1,4 +1,4 @@ Common Contract Security Patterns ============================================= -Zeppelin smart contracts are developed using common contract security patterns. To learn more, please see `Onward with Ethereum Smart Contract Security `_ +Zeppelin smart contracts are developed using industry standard contract security patterns and best practices. To learn more, please see `Onward with Ethereum Smart Contract Security `_. From 2299cd1c395c9c15d82b134894d0628cc108052e Mon Sep 17 00:00:00 2001 From: Demian Elias Brener Date: Mon, 19 Dec 2016 12:10:00 -0300 Subject: [PATCH 14/18] remove unneeded files --- .gitignore | 1 + docs/.DS_Store | Bin 8196 -> 0 bytes docs/make.bat | 36 ------------------------------------ docs/source/.DS_Store | Bin 8196 -> 0 bytes 4 files changed, 1 insertion(+), 36 deletions(-) delete mode 100644 docs/.DS_Store delete mode 100644 docs/make.bat delete mode 100644 docs/source/.DS_Store diff --git a/.gitignore b/.gitignore index 672444ec6..97b040664 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.swo node_modules/ build/ +.DS_Store/ diff --git a/docs/.DS_Store b/docs/.DS_Store deleted file mode 100644 index cc0f307c95ef010813210d503110bba59bf97370..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHM-A)rh6h6a`Y(-@G6U3NoBqk&f1IW*XA=H9VVhoiMYy~X4?NByscbeTT2#D#8 z58$OHK7dy~fQj)^pTH~QBj~MHdS+%@+9KW?lAV z0BBe_>aE!PqVREEkCcY6CxS@O9w0mKu#Dv}>xi!EPz)#r6a$I@#eibqbTEK-HZR&S z_r4retztki@Lw{(-wy^>j?oZH62+?n8<7GaHet6YC}SQVY>W`2A(kWxQ}ijb2NIf+ zFvTF!9LEi=ju;KGBvG0Jk>)_cnMs(T5HUO28A2UMRHAAX1B!v84Dj5&87wG*4Ngt| z&JWTJtb;#95vEm|){b8YGyRWN!Lj{dWaJZRXl!ae)1pNpTBJ=|OKh^8L|_I*KW2I> z;>pfZE0mWQb1JfFE!%V_t#{8dH!y9NdR6MH4{SHfc4DmPW_{r&ZU&oZD<(?oef#@k z6BEP6*u><)u(3ZiH8O0BU!OcU(6rvGqto;2`Q5$!CkIboh#vtYe1|~0e6F-FQL6fh z+X>Hgn4801ZlOUQOxOYn*N`w1f~t=loUGSatI5*fUZ}qz$fdRVq_7KT&nBrT3^#AEr)DU84w!?TM@5=G^Mb|44ceeFh+xd3AqqD1{yQAkqPj6q( z#r{kEX}!xbGg~>2$IdKsm=|-3bS3B6*+jw2*lsQv(8oc--lJ)~vrcu9W*;4PE$tRi zr~9x&xV!C9>I#1g8yh|il4-r&&v?vn;>@=Lo4Ki~(bTGsXJS5}`FVGP;f&iD^$P{A z<}XvvM?7MmOqrf%x;Yx#U2{x}Ity-$1p&(^?F@6}%G-roe2jaPyBwJLh7p5hAbPhf z3`#+V0V(jo#rHzibh6|!mqrGnaXA>la36x37{bdK@_XOC&`el8kiFP(Ear<#V|uS(Ivaw&s|r`@c+-LdC$zGSDd9_woGy z*74u}Pj(T?yJA2w@J|^aO>>F47%riFW!JBU=h_C=b*#K_y^=&>f{jSW5k)$VSoy;c bWdl{YO*F)kMC`$$J_HCFRHGR9s|@@Ebt6X= diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index fef370f59..000000000 --- a/docs/make.bat +++ /dev/null @@ -1,36 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build -set SPHINXPROJ=zeppelin-solidity - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd diff --git a/docs/source/.DS_Store b/docs/source/.DS_Store deleted file mode 100644 index 2c3bc9e934c14539b75fd3a09a9801b3019b6e59..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHM&2G~`5T0!db^05Ar1pe-LE_M&w$S!~kfKlyy&(m`0Z?n#rnPYG$ab2B5R?n= z0K5T@!V~ZyJOF$%Hj$IqLA@ZLyVCA#?D=MAz8U|lLqw|HayE%piO4`_S)IpF(D*#} zu{M<*VXy+8C?SuI_Wkh4_Q$mK0nLDBKr^5j&{sso{%;sj4JonSHdejVP1}-H7 ze19;}S=KVyPo>;CFvu1Fat4Q`VUB%(V9ZR`GTBe1Kw&f8J*W(-vMq*6;W%%yI%F-A z{ZyuKQYoBNwzA50C`wib&J=Z0wN&a+GoTq5XMp$avvfc)_U=}G{~p>n!xz&7^gBPK zVK%01x8tVmi}qK$>3eaqvGGk!P0w7pI%`xaMrF}>)i?>;jl@b?aovhu$S==v?QH%u z4E@2}vY&Zw`=EOBQ5Yna7r0SQ{pE8naKd&yYz0m%cAi+t39z!zL3Op;-P+z>Gq<*P zdTVBPcXwmWynk<}*E5Wj+nW#f4^KO9yYG7MKS>~@vU>?Fr@sf|=kYMl8d2bf!7%ABH)Zp$R+V*n9t=r5L|IwYn+wBC>b^6UsX`2KqgYPylNm;it$`~ zdCr$ma~{~?ieRR=n#vdkHzOW%zJtkeDr9+xpJimWCH!!ub+A51oJ@!}@9zSyUP3j z$K~JuFJMutY6dg|{~7~oX0NeVhu6Q}here8y|#&dh|Z1m`l%EM2HB27%61%b@P{Gh iCR7 Date: Mon, 19 Dec 2016 12:59:36 -0300 Subject: [PATCH 15/18] improve docs --- docs/.DS_Store | Bin 0 -> 8196 bytes docs/source/index.rst | 10 ++++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 docs/.DS_Store diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e70324420bb07e279324b4d5bcf46951a22fb749 GIT binary patch literal 8196 zcmeHM-A)rh6h6a`Y(-@Gvp_W2NK8l|29(H!A=H9VVhl(dECQC@b|@Q`oo06nLdEpP z2k=fWd;qU}028ly1Fwv}f!=zhXMTXTh<6yGbCQ|w?94f5y5FAJ$=Lz`NtW`X0KEWU zVB=`EV)q;2^Sm9C1~n2xBpm{3@eC|oh7tR9GRC91?A z(jDh5ZjP8xSdl2*fk<~CYGtA-6e3nfKTDVcNl4VaW|DH-iHuaKWpo-}y$m zjcxF!5aC*7>1>BZRq5|LMb8bRk&#cNp|Pp?T#FHl8L>8FCAH4BQ;{8&!lWH6i7Pix z9i^uk^A2^}S#arg*6f~Qeq_5o4XVtSAG>~@Z6{gD&xaz;oE@#BuUIH+#>?gLv0>}R z*y!G{RURK78Mel5-rCzUjQF+DiJ8^So!#>Dy%(>=JpfU!5NMazhy5GWs_t+r75E4A=x4Hh{u)RSir>K(Rft_*mn?AHXhwAP-)>+H`#2n?S?06D0)efcNb zfAmSz@ZsjRRJM_i2if+;G!OIbeCvg_i|uAdXIDpeN6)36cyCW%fB)sI+2z=|jY7aP zXNq|&NO~o@R0!OBs%Yn2zmSROvnb{6(yZB8XF5;wPmhMuJ4LkVJ{l0=?gfp9?6DlyOn#_cAc~9TNs+Ao1Wp8I+0%15&}s$*)p1 zOp^AQPh+ux#GINnUQ5^)4Y Pe+UpX=uR{6R~h&P3DQPx literal 0 HcmV?d00001 diff --git a/docs/source/index.rst b/docs/source/index.rst index 828f0b9df..8ea157a6c 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -6,15 +6,21 @@ Welcome to Zeppelin-Solidity ============================================= -Zeppelin is a library for writing secure Smart Contracts on Ethereum. Get familiar with the Zeppelin Smart Contracts. +Zeppelin is a library for writing secure Smart Contracts on Ethereum. -The code is open-source, and `available on github `_. +With Zeppelin, you can build distributed applications, protocols and organizations: + +* using :doc:`contract-security-patterns` +* in the `Solidity language `_. + +The code is open-source, and `available on github `_. .. toctree:: :maxdepth: 2 getting-started + .. toctree:: :maxdepth: 2 :caption: Smart Contracts From b1b66ce16565b5ca5d1667bcbf1225ffad0c562c Mon Sep 17 00:00:00 2001 From: Demian Elias Brener Date: Mon, 19 Dec 2016 14:29:48 -0300 Subject: [PATCH 16/18] remove DS_Store --- docs/.DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 docs/.DS_Store diff --git a/docs/.DS_Store b/docs/.DS_Store deleted file mode 100644 index e70324420bb07e279324b4d5bcf46951a22fb749..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHM-A)rh6h6a`Y(-@Gvp_W2NK8l|29(H!A=H9VVhl(dECQC@b|@Q`oo06nLdEpP z2k=fWd;qU}028ly1Fwv}f!=zhXMTXTh<6yGbCQ|w?94f5y5FAJ$=Lz`NtW`X0KEWU zVB=`EV)q;2^Sm9C1~n2xBpm{3@eC|oh7tR9GRC91?A z(jDh5ZjP8xSdl2*fk<~CYGtA-6e3nfKTDVcNl4VaW|DH-iHuaKWpo-}y$m zjcxF!5aC*7>1>BZRq5|LMb8bRk&#cNp|Pp?T#FHl8L>8FCAH4BQ;{8&!lWH6i7Pix z9i^uk^A2^}S#arg*6f~Qeq_5o4XVtSAG>~@Z6{gD&xaz;oE@#BuUIH+#>?gLv0>}R z*y!G{RURK78Mel5-rCzUjQF+DiJ8^So!#>Dy%(>=JpfU!5NMazhy5GWs_t+r75E4A=x4Hh{u)RSir>K(Rft_*mn?AHXhwAP-)>+H`#2n?S?06D0)efcNb zfAmSz@ZsjRRJM_i2if+;G!OIbeCvg_i|uAdXIDpeN6)36cyCW%fB)sI+2z=|jY7aP zXNq|&NO~o@R0!OBs%Yn2zmSROvnb{6(yZB8XF5;wPmhMuJ4LkVJ{l0=?gfp9?6DlyOn#_cAc~9TNs+Ao1Wp8I+0%15&}s$*)p1 zOp^AQPh+ux#GINnUQ5^)4Y Pe+UpX=uR{6R~h&P3DQPx From 2ddfb80a5ef69a69da23147dcd05a566c3fdb2d1 Mon Sep 17 00:00:00 2001 From: Demian Elias Brener Date: Mon, 19 Dec 2016 16:29:02 -0300 Subject: [PATCH 17/18] update readme --- README.md | 226 ++---------------------------------------------------- 1 file changed, 5 insertions(+), 221 deletions(-) diff --git a/README.md b/README.md index 6a9274583..dbdb39f8c 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ [![NPM Package](https://img.shields.io/npm/v/zeppelin-solidity.svg?style=flat-square)](https://www.npmjs.org/package/zeppelin-solidity) [![Build Status](https://img.shields.io/travis/OpenZeppelin/zeppelin-solidity.svg?branch=master&style=flat-square)](https://travis-ci.org/OpenZeppelin/zeppelin-solidity) -Zeppelin is a library for writing secure Smart Contracts on Ethereum. +Zeppelin is a library for writing secure [Smart Contracts](https://en.wikipedia.org/wiki/Smart_contract) on Ethereum. With Zeppelin, you can build distributed applications, protocols and organizations: - using common contract security patterns (See [Onward with Ethereum Smart Contract Security](https://medium.com/bitcorps-blog/onward-with-ethereum-smart-contract-security-97a827e47702#.y3kvdetbz)) -- in the Solidity language. +- in the [Solidity language](http://solidity.readthedocs.io/en/develop/). ## Getting Started @@ -53,228 +53,12 @@ Zeppelin is meant to provide secure, tested and community-audited code, but plea If you find a security issue, please email [security@openzeppelin.org](mailto:security@openzeppelin.org). -## Contracts - -### Ownable -Base contract with an owner. - -#### Ownable( ) -Sets the address of the creator of the contract as the owner. - -#### modifier onlyOwner( ) -Prevents function from running if it is called by anyone other than the owner. - -#### transferOwnership(address newOwner) onlyOwner -Transfers ownership of the contract to the passed address. - ---- -### Stoppable -Base contract that provides an emergency stop mechanism. - -Inherits from contract Ownable. - -#### emergencyStop( ) external onlyOwner -Triggers the stop mechanism on the contract. After this function is called (by the owner of the contract), any function with modifier stopInEmergency will not run. - -#### modifier stopInEmergency -Prevents function from running if stop mechanism is activated. - -#### modifier onlyInEmergency -Only runs if stop mechanism is activated. - -#### release( ) external onlyOwner onlyInEmergency -Deactivates the stop mechanism. - ---- -### Killable -Base contract that can be killed by owner. - -Inherits from contract Ownable. - -#### kill( ) onlyOwner -Destroys the contract and sends funds back to the owner. -___ -### Claimable -Extension for the Ownable contract, where the ownership needs to be claimed - -#### transferOwnership(address newOwner) onlyOwner -Sets the passed address as the pending owner. - -#### modifier onlyPendingOwner -Function only runs if called by pending owner. - -#### claimOwnership( ) onlyPendingOwner -Completes transfer of ownership by setting pending owner as the new owner. -___ -### Migrations -Base contract that allows for a new instance of itself to be created at a different address. - -Inherits from contract Ownable. - -#### upgrade(address new_address) onlyOwner -Creates a new instance of the contract at the passed address. - -#### setCompleted(uint completed) onlyOwner -Sets the last time that a migration was completed. - -___ -### SafeMath -Provides functions of mathematical operations with safety checks. - -#### assert(bool assertion) internal -Throws an error if the passed result is false. Used in this contract by checking mathematical expressions. - -#### safeMul(uint a, uint b) internal returns (uint) -Multiplies two unisgned integers. Asserts that dividing the product by the non-zero multiplicand results in the multiplier. - -#### safeSub(uint a, unit b) internal returns (uint) -Checks that b is not greater than a before subtracting. - -#### safeAdd(unit a, unit b) internal returns (uint) -Checks that the result is greater than both a and b. - -___ -### LimitBalance - -Base contract that provides mechanism for limiting the amount of funds a contract can hold. - -#### LimitBalance(unit _limit) -Constructor takes an unisgned integer and sets it as the limit of funds this contract can hold. - -#### modifier limitedPayable() -Throws an error if this contract's balance is already above the limit. - -___ -### PullPayment -Base contract supporting async send for pull payments. -Inherit from this contract and use asyncSend instead of send. - -#### asyncSend(address dest, uint amount) internal -Adds sent amount to available balance that payee can pull from this contract, called by payer. - -#### withdrawPayments( ) -Sends designated balance to payee calling the contract. Throws error if designated balance is 0, if contract does not hold enough funds ot pay the payee, or if the send transaction is not successful. - -___ -### StandardToken -Based on code by FirstBlood: [FirstBloodToken.sol] - -Inherits from contract SafeMath. Implementation of abstract contract ERC20 (see https://github.com/ethereum/EIPs/issues/20) - -[FirstBloodToken.sol]: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol - -#### approve(address _spender, uint _value) returns (bool success) -Sets the amount of the sender's token balance that the passed address is approved to use. - -###allowance(address _owner, address _spender) constant returns (uint remaining) -Returns the approved amount of the owner's balance that the spender can use. - -###balanceOf(address _owner) constant returns (uint balance) -Returns the token balance of the passed address. - -###transferFrom(address _from, address _to, uint _value) returns (bool success) -Transfers tokens from an account that the sender is approved to transfer from. Amount must not be greater than the approved amount or the account's balance. - -###function transfer(address _to, uint _value) returns (bool success) -Transfers tokens from sender's account. Amount must not be greater than sender's balance. - -___ -### BasicToken -Simpler version of StandardToken, with no allowances - -#### balanceOf(address _owner) constant returns (uint balance) -Returns the token balance of the passed address. - -###function transfer(address _to, uint _value) returns (bool success) -Transfers tokens from sender's account. Amount must not be greater than sender's balance. - -___ -### CrowdsaleToken -Simple ERC20 Token example, with crowdsale token creation. - -Inherits from contract StandardToken. - -#### createTokens(address recipient) payable -Creates tokens based on message value and credits to the recipient. - -#### getPrice() constant returns (uint result) -Returns the amount of tokens per 1 ether. - - -___ -### Bounty -To create a bounty for your contract, inherit from the base `Bounty` contract and provide an implementation for `deployContract()` returning the new contract address. - -``` -import {Bounty, Target} from "./zeppelin/Bounty.sol"; -import "./YourContract.sol"; - -contract YourBounty is Bounty { - function deployContract() internal returns(address) { - return new YourContract() - } -} -``` - -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. - -At contracts/YourContract.sol - -``` -import {Bounty, Target} from "./zeppelin/Bounty.sol"; -contract YourContract is Target { - function checkInvariant() returns(bool) { - // Implement your logic to make sure that none of the invariants are broken. - } -} -``` - -Next, deploy your bounty contract along with your main contract to the network. - -At `migrations/2_deploy_contracts.js` - -``` -module.exports = function(deployer) { - deployer.deploy(YourContract); - deployer.deploy(YourBounty); -}; -``` - -Next, add a reward to the bounty contract - -After deploying the contract, send reward funds into the bounty contract. - -From `truffle console` - -``` -bounty = YourBounty.deployed(); -address = 0xb9f68f96cde3b895cc9f6b14b856081b41cb96f1; // your account address -reward = 5; // reward to pay to a researcher who breaks your contract - -web3.eth.sendTransaction({ - from: address, - to: bounty.address, - value: web3.toWei(reward, "ether") -}) - -``` - -If researchers break the contract, they can claim their reward. - -For each researcher who wants to hack the contract and claims the reward, refer to our [test](./test/Bounty.js) for the detail. - -Finally, if you manage to protect your contract from security researchers, you can reclaim the bounty funds. To end the bounty, kill the contract so that all the rewards go back to the owner. - -``` -bounty.kill(); -``` - - -## More Developer Resources +## Developer Resources Building a distributed application, protocol or organization with Zeppelin? +- Read documentation: http://zeppelin-solidity.readthedocs.io/en/latest/ + - Ask for help and follow progress at: https://zeppelin-slackin.herokuapp.com/ Interested in contributing to Zeppelin? From f79ad4e2f6f9ef9161561b1473a4e97f7e9a3c94 Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Mon, 19 Dec 2016 17:43:02 -0300 Subject: [PATCH 18/18] add 2 lines between top level definitions --- contracts/Claimable.sol | 1 - contracts/LimitBalance.sol | 9 +++++++++ contracts/Migrations.sol | 3 +++ contracts/examples/BadArrayUse.sol | 4 +++- contracts/examples/BadFailEarly.sol | 3 ++- contracts/examples/BadPushPayments.sol | 3 ++- contracts/examples/GoodArrayUse.sol | 3 +++ contracts/examples/GoodFailEarly.sol | 1 + contracts/examples/GoodPullPayments.sol | 2 ++ contracts/examples/ProofOfExistence.sol | 1 + contracts/examples/PullPaymentBid.sol | 2 ++ contracts/examples/StoppableBid.sol | 2 ++ contracts/test-helpers/BasicTokenMock.sol | 3 +++ contracts/test-helpers/LimitBalanceMock.sol | 3 +++ contracts/test-helpers/PullPaymentMock.sol | 3 +++ contracts/test-helpers/SafeMathMock.sol | 3 +++ contracts/test-helpers/StandardTokenMock.sol | 3 +++ contracts/test-helpers/StoppableMock.sol | 3 +++ contracts/token/StandardToken.sol | 4 +++- 19 files changed, 51 insertions(+), 5 deletions(-) diff --git a/contracts/Claimable.sol b/contracts/Claimable.sol index e7490e05d..89a375d7f 100644 --- a/contracts/Claimable.sol +++ b/contracts/Claimable.sol @@ -1,7 +1,6 @@ pragma solidity ^0.4.0; - import './Ownable.sol'; diff --git a/contracts/LimitBalance.sol b/contracts/LimitBalance.sol index d8c29baec..c03cb03e0 100644 --- a/contracts/LimitBalance.sol +++ b/contracts/LimitBalance.sol @@ -1,4 +1,13 @@ pragma solidity ^0.4.4; + + +/** + * LimitBalance + * Simple contract to limit the balance of child contract. + * Note this doesn't prevent other contracts to send funds + * by using selfdestruct(address); + * See: https://github.com/ConsenSys/smart-contract-best-practices#remember-that-ether-can-be-forcibly-sent-to-an-account + */ contract LimitBalance { uint public limit; diff --git a/contracts/Migrations.sol b/contracts/Migrations.sol index c8d890bef..010f551fc 100644 --- a/contracts/Migrations.sol +++ b/contracts/Migrations.sol @@ -1,6 +1,9 @@ pragma solidity ^0.4.4; + + import './Ownable.sol'; + contract Migrations is Ownable { uint public lastCompletedMigration; diff --git a/contracts/examples/BadArrayUse.sol b/contracts/examples/BadArrayUse.sol index d5c1c7b7b..dd8a65344 100644 --- a/contracts/examples/BadArrayUse.sol +++ b/contracts/examples/BadArrayUse.sol @@ -1,8 +1,10 @@ pragma solidity ^0.4.4; + + import '../PullPayment.sol'; -// UNSAFE CODE, DO NOT USE! +// UNSAFE CODE, DO NOT USE! contract BadArrayUse is PullPayment { address[] employees; diff --git a/contracts/examples/BadFailEarly.sol b/contracts/examples/BadFailEarly.sol index 0ad95a92e..ee26bdd1d 100644 --- a/contracts/examples/BadFailEarly.sol +++ b/contracts/examples/BadFailEarly.sol @@ -1,6 +1,7 @@ pragma solidity ^0.4.4; -// UNSAFE CODE, DO NOT USE! + +// UNSAFE CODE, DO NOT USE! contract BadFailEarly { uint constant DEFAULT_SALARY = 50000; diff --git a/contracts/examples/BadPushPayments.sol b/contracts/examples/BadPushPayments.sol index 510b39473..2d85ffeec 100644 --- a/contracts/examples/BadPushPayments.sol +++ b/contracts/examples/BadPushPayments.sol @@ -1,6 +1,7 @@ pragma solidity ^0.4.4; -// UNSAFE CODE, DO NOT USE! + +// UNSAFE CODE, DO NOT USE! contract BadPushPayments { address highestBidder; diff --git a/contracts/examples/GoodArrayUse.sol b/contracts/examples/GoodArrayUse.sol index ce450293e..8995702a8 100644 --- a/contracts/examples/GoodArrayUse.sol +++ b/contracts/examples/GoodArrayUse.sol @@ -1,6 +1,9 @@ pragma solidity ^0.4.4; + + import '../PullPayment.sol'; + contract GoodArrayUse is PullPayment { address[] employees; mapping(address => uint) bonuses; diff --git a/contracts/examples/GoodFailEarly.sol b/contracts/examples/GoodFailEarly.sol index 7a3ec9e60..dce0eac44 100644 --- a/contracts/examples/GoodFailEarly.sol +++ b/contracts/examples/GoodFailEarly.sol @@ -1,5 +1,6 @@ pragma solidity ^0.4.4; + contract GoodFailEarly { uint constant DEFAULT_SALARY = 50000; diff --git a/contracts/examples/GoodPullPayments.sol b/contracts/examples/GoodPullPayments.sol index 9236d0a4f..1469eb57f 100644 --- a/contracts/examples/GoodPullPayments.sol +++ b/contracts/examples/GoodPullPayments.sol @@ -1,4 +1,6 @@ pragma solidity ^0.4.4; + + contract GoodPullPayments { address highestBidder; uint highestBid; diff --git a/contracts/examples/ProofOfExistence.sol b/contracts/examples/ProofOfExistence.sol index a4ec0d45f..0bf7ca220 100644 --- a/contracts/examples/ProofOfExistence.sol +++ b/contracts/examples/ProofOfExistence.sol @@ -1,5 +1,6 @@ pragma solidity ^0.4.4; + /* * Proof of Existence example contract * see https://medium.com/zeppelin-blog/the-hitchhikers-guide-to-smart-contracts-in-ethereum-848f08001f05 diff --git a/contracts/examples/PullPaymentBid.sol b/contracts/examples/PullPaymentBid.sol index 01c91c991..ad4b612b5 100644 --- a/contracts/examples/PullPaymentBid.sol +++ b/contracts/examples/PullPaymentBid.sol @@ -1,7 +1,9 @@ pragma solidity ^0.4.4; + import '../PullPayment.sol'; + contract PullPaymentBid is PullPayment { address public highestBidder; uint public highestBid; diff --git a/contracts/examples/StoppableBid.sol b/contracts/examples/StoppableBid.sol index 0edbd8b3e..61b9d43aa 100644 --- a/contracts/examples/StoppableBid.sol +++ b/contracts/examples/StoppableBid.sol @@ -1,8 +1,10 @@ pragma solidity ^0.4.4; + import '../PullPayment.sol'; import '../Stoppable.sol'; + contract StoppableBid is Stoppable, PullPayment { address public highestBidder; uint public highestBid; diff --git a/contracts/test-helpers/BasicTokenMock.sol b/contracts/test-helpers/BasicTokenMock.sol index 9f19e47ea..5b6447c8a 100644 --- a/contracts/test-helpers/BasicTokenMock.sol +++ b/contracts/test-helpers/BasicTokenMock.sol @@ -1,6 +1,9 @@ pragma solidity ^0.4.4; + + import '../token/BasicToken.sol'; + // mock class using BasicToken contract BasicTokenMock is BasicToken { diff --git a/contracts/test-helpers/LimitBalanceMock.sol b/contracts/test-helpers/LimitBalanceMock.sol index c0f05ba8b..bcb862ef9 100644 --- a/contracts/test-helpers/LimitBalanceMock.sol +++ b/contracts/test-helpers/LimitBalanceMock.sol @@ -1,6 +1,9 @@ pragma solidity ^0.4.4; + + import '../LimitBalance.sol'; + // mock class using LimitBalance contract LimitBalanceMock is LimitBalance(1000) { diff --git a/contracts/test-helpers/PullPaymentMock.sol b/contracts/test-helpers/PullPaymentMock.sol index 1dac2ce53..2d6ca1e2f 100644 --- a/contracts/test-helpers/PullPaymentMock.sol +++ b/contracts/test-helpers/PullPaymentMock.sol @@ -1,6 +1,9 @@ pragma solidity ^0.4.4; + + import '../PullPayment.sol'; + // mock class using PullPayment contract PullPaymentMock is PullPayment { diff --git a/contracts/test-helpers/SafeMathMock.sol b/contracts/test-helpers/SafeMathMock.sol index 9cd618214..430343b81 100644 --- a/contracts/test-helpers/SafeMathMock.sol +++ b/contracts/test-helpers/SafeMathMock.sol @@ -1,6 +1,9 @@ pragma solidity ^0.4.4; + + import '../SafeMath.sol'; + contract SafeMathMock is SafeMath { uint public result; diff --git a/contracts/test-helpers/StandardTokenMock.sol b/contracts/test-helpers/StandardTokenMock.sol index 5b222be9a..1e6741f24 100644 --- a/contracts/test-helpers/StandardTokenMock.sol +++ b/contracts/test-helpers/StandardTokenMock.sol @@ -1,6 +1,9 @@ pragma solidity ^0.4.4; + + import '../token/StandardToken.sol'; + // mock class using StandardToken contract StandardTokenMock is StandardToken { diff --git a/contracts/test-helpers/StoppableMock.sol b/contracts/test-helpers/StoppableMock.sol index 6d3464bdf..44c12bbcf 100644 --- a/contracts/test-helpers/StoppableMock.sol +++ b/contracts/test-helpers/StoppableMock.sol @@ -1,6 +1,9 @@ pragma solidity ^0.4.4; + + import '../Stoppable.sol'; + // mock class using Stoppable contract StoppableMock is Stoppable { bool public drasticMeasureTaken; diff --git a/contracts/token/StandardToken.sol b/contracts/token/StandardToken.sol index 2f3e301d6..b457808ee 100644 --- a/contracts/token/StandardToken.sol +++ b/contracts/token/StandardToken.sol @@ -1,10 +1,12 @@ pragma solidity ^0.4.4; + import './ERC20.sol'; import '../SafeMath.sol'; + /** - * ERC20 token + * Standard ERC20 token * * https://github.com/ethereum/EIPs/issues/20 * Based on code by FirstBlood: