From a98c5b8865ada33885212824d076711590ff5947 Mon Sep 17 00:00:00 2001 From: Makoto Inoue Date: Sat, 22 Oct 2016 17:27:46 +0100 Subject: [PATCH 1/7] Add bounty test to test against checkInvarient --- contracts/Bounty.sol | 4 ++++ test/Bounty.js | 14 ++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 test/Bounty.js diff --git a/contracts/Bounty.sol b/contracts/Bounty.sol index 3f8bf8d4a..d6945df65 100644 --- a/contracts/Bounty.sol +++ b/contracts/Bounty.sol @@ -23,6 +23,10 @@ contract Bounty is PullPayment { return target; } + function checkInvarient() returns(bool){ + return true; + } + function claim(SimpleToken target) { address researcher = researchers[target]; if (researcher == 0) throw; diff --git a/test/Bounty.js b/test/Bounty.js new file mode 100644 index 000000000..4cb3e0325 --- /dev/null +++ b/test/Bounty.js @@ -0,0 +1,14 @@ +contract('Bounty', function(accounts) { + it.only("create target", function(done){ + var bounty = Bounty.deployed(); + + bounty.createTarget(). + then(function() { + return bounty.checkInvarient.call() + }). + then(function(result) { + assert.isTrue(result); + }). + then(done); + }) +}); From 93454369577fcf513d4482b5612a297be6c4db39 Mon Sep 17 00:00:00 2001 From: Makoto Inoue Date: Sat, 22 Oct 2016 18:01:17 +0100 Subject: [PATCH 2/7] Swap SimpleToken with Target --- contracts/Bounty.sol | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/contracts/Bounty.sol b/contracts/Bounty.sol index d6945df65..6296b911b 100644 --- a/contracts/Bounty.sol +++ b/contracts/Bounty.sol @@ -1,15 +1,21 @@ pragma solidity ^0.4.0; import './PullPayment.sol'; -import './token/SimpleToken.sol'; /* * Bounty * This bounty will pay out if you can cause a SimpleToken's balance - * to be lower than its totalSupply, which would mean that it doesn't + * to be lower than its totalSupply, which would mean that it doesn't * have sufficient ether for everyone to withdraw. */ -contract Bounty is PullPayment { +contract Target { + function checkInvarient() returns(bool){ + return true; + } +} + +contract Bounty is PullPayment { + Target target; bool public claimed; mapping(address => address) public researchers; @@ -17,22 +23,22 @@ contract Bounty is PullPayment { if (claimed) throw; } - function createTarget() returns(SimpleToken) { - SimpleToken target = new SimpleToken(); + function createTarget() returns(Target) { + target = new Target(); researchers[target] = msg.sender; return target; } function checkInvarient() returns(bool){ - return true; + return target.checkInvarient(); } - function claim(SimpleToken target) { + function claim(Target target) { address researcher = researchers[target]; if (researcher == 0) throw; - // Check SimpleToken contract invariants + // Check Target contract invariants // Customize this to the specifics of your contract - if (target.totalSupply() == target.balance) { + if (!target.checkInvarient()) { throw; } asyncSend(researcher, this.balance); From 986509934b678188e1abec640dc30c69d00a2a3c Mon Sep 17 00:00:00 2001 From: Makoto Inoue Date: Sat, 22 Oct 2016 18:16:42 +0100 Subject: [PATCH 3/7] Swap target contract at test by using abstract interface --- contracts/Bounty.sol | 9 +++------ contracts/test-helpers/InsecureTargetMock.sol | 7 +++++++ contracts/test-helpers/SecureTargetMock.sol | 7 +++++++ migrations/2_deploy_contracts.js | 2 ++ test/Bounty.js | 19 ++++++++++++++++--- 5 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 contracts/test-helpers/InsecureTargetMock.sol create mode 100644 contracts/test-helpers/SecureTargetMock.sol diff --git a/contracts/Bounty.sol b/contracts/Bounty.sol index 6296b911b..71fb82838 100644 --- a/contracts/Bounty.sol +++ b/contracts/Bounty.sol @@ -9,9 +9,7 @@ import './PullPayment.sol'; */ contract Target { - function checkInvarient() returns(bool){ - return true; - } + function checkInvarient() returns(bool); } contract Bounty is PullPayment { @@ -23,8 +21,8 @@ contract Bounty is PullPayment { if (claimed) throw; } - function createTarget() returns(Target) { - target = new Target(); + function createTarget(address targetAddress) returns(Target) { + target = Target(targetAddress); researchers[target] = msg.sender; return target; } @@ -37,7 +35,6 @@ contract Bounty is PullPayment { address researcher = researchers[target]; if (researcher == 0) throw; // Check Target contract invariants - // Customize this to the specifics of your contract if (!target.checkInvarient()) { throw; } diff --git a/contracts/test-helpers/InsecureTargetMock.sol b/contracts/test-helpers/InsecureTargetMock.sol new file mode 100644 index 000000000..101d371e9 --- /dev/null +++ b/contracts/test-helpers/InsecureTargetMock.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.4.0; + +contract InsecureTargetMock { + function checkInvarient() returns(bool){ + return false; + } +} diff --git a/contracts/test-helpers/SecureTargetMock.sol b/contracts/test-helpers/SecureTargetMock.sol new file mode 100644 index 000000000..67e599018 --- /dev/null +++ b/contracts/test-helpers/SecureTargetMock.sol @@ -0,0 +1,7 @@ +pragma solidity ^0.4.0; + +contract SecureTargetMock { + function checkInvarient() returns(bool){ + return true; + } +} diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index b29a532cc..692a3013d 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -5,4 +5,6 @@ module.exports = function(deployer) { deployer.deploy(Bounty); deployer.deploy(Ownable); deployer.deploy(LimitFunds); + deployer.deploy(SecureTargetMock); + deployer.deploy(InsecureTargetMock); }; diff --git a/test/Bounty.js b/test/Bounty.js index 4cb3e0325..e214b9683 100644 --- a/test/Bounty.js +++ b/test/Bounty.js @@ -1,8 +1,8 @@ contract('Bounty', function(accounts) { - it.only("create target", function(done){ + it.only("can call checkInvarient for InsecureTargetMock", function(done){ var bounty = Bounty.deployed(); - - bounty.createTarget(). + var target = SecureTargetMock.deployed(); + bounty.createTarget(target.address). then(function() { return bounty.checkInvarient.call() }). @@ -11,4 +11,17 @@ contract('Bounty', function(accounts) { }). then(done); }) + + it("can call checkInvarient for InsecureTargetMock", function(done){ + var bounty = Bounty.deployed(); + var target = InsecureTargetMock.deployed(); + bounty.createTarget(target.address). + then(function() { + return bounty.checkInvarient.call() + }). + then(function(result) { + assert.isFalse(result); + }). + then(done); + }) }); From f19a69beb4926a77a8491d20adecbe159a32eb77 Mon Sep 17 00:00:00 2001 From: Makoto Inoue Date: Sat, 22 Oct 2016 18:18:02 +0100 Subject: [PATCH 4/7] Remove only --- test/Bounty.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Bounty.js b/test/Bounty.js index e214b9683..bb731b8ec 100644 --- a/test/Bounty.js +++ b/test/Bounty.js @@ -1,5 +1,5 @@ contract('Bounty', function(accounts) { - it.only("can call checkInvarient for InsecureTargetMock", function(done){ + it("can call checkInvarient for InsecureTargetMock", function(done){ var bounty = Bounty.deployed(); var target = SecureTargetMock.deployed(); bounty.createTarget(target.address). From bc3f2a66cc125cba21428cb0be6ec3f6b3236e57 Mon Sep 17 00:00:00 2001 From: Makoto Inoue Date: Sat, 22 Oct 2016 18:26:25 +0100 Subject: [PATCH 5/7] Deploy mock contracts only for test --- migrations/2_deploy_contracts.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index 692a3013d..09f969053 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -5,6 +5,8 @@ module.exports = function(deployer) { deployer.deploy(Bounty); deployer.deploy(Ownable); deployer.deploy(LimitFunds); - deployer.deploy(SecureTargetMock); - deployer.deploy(InsecureTargetMock); + if(deployer.network == 'test'){ + deployer.deploy(SecureTargetMock); + deployer.deploy(InsecureTargetMock); + }; }; From 334073a64fc976c38134a04a9b92f88518c8647f Mon Sep 17 00:00:00 2001 From: Makoto Inoue Date: Sat, 22 Oct 2016 18:29:07 +0100 Subject: [PATCH 6/7] Fix typo --- contracts/Bounty.sol | 8 ++++---- contracts/test-helpers/InsecureTargetMock.sol | 2 +- contracts/test-helpers/SecureTargetMock.sol | 2 +- test/Bounty.js | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/contracts/Bounty.sol b/contracts/Bounty.sol index 71fb82838..2bee51e98 100644 --- a/contracts/Bounty.sol +++ b/contracts/Bounty.sol @@ -9,7 +9,7 @@ import './PullPayment.sol'; */ contract Target { - function checkInvarient() returns(bool); + function checkInvariant() returns(bool); } contract Bounty is PullPayment { @@ -27,15 +27,15 @@ contract Bounty is PullPayment { return target; } - function checkInvarient() returns(bool){ - return target.checkInvarient(); + function checkInvariant() returns(bool){ + return target.checkInvariant(); } function claim(Target target) { address researcher = researchers[target]; if (researcher == 0) throw; // Check Target contract invariants - if (!target.checkInvarient()) { + if (!target.checkInvariant()) { throw; } asyncSend(researcher, this.balance); diff --git a/contracts/test-helpers/InsecureTargetMock.sol b/contracts/test-helpers/InsecureTargetMock.sol index 101d371e9..2918361a8 100644 --- a/contracts/test-helpers/InsecureTargetMock.sol +++ b/contracts/test-helpers/InsecureTargetMock.sol @@ -1,7 +1,7 @@ pragma solidity ^0.4.0; contract InsecureTargetMock { - function checkInvarient() returns(bool){ + function checkInvariant() returns(bool){ return false; } } diff --git a/contracts/test-helpers/SecureTargetMock.sol b/contracts/test-helpers/SecureTargetMock.sol index 67e599018..bd3a7dae2 100644 --- a/contracts/test-helpers/SecureTargetMock.sol +++ b/contracts/test-helpers/SecureTargetMock.sol @@ -1,7 +1,7 @@ pragma solidity ^0.4.0; contract SecureTargetMock { - function checkInvarient() returns(bool){ + function checkInvariant() returns(bool){ return true; } } diff --git a/test/Bounty.js b/test/Bounty.js index bb731b8ec..68b567a8d 100644 --- a/test/Bounty.js +++ b/test/Bounty.js @@ -1,10 +1,10 @@ contract('Bounty', function(accounts) { - it("can call checkInvarient for InsecureTargetMock", function(done){ + it("can call checkInvariant for InsecureTargetMock", function(done){ var bounty = Bounty.deployed(); var target = SecureTargetMock.deployed(); bounty.createTarget(target.address). then(function() { - return bounty.checkInvarient.call() + return bounty.checkInvariant.call() }). then(function(result) { assert.isTrue(result); @@ -12,12 +12,12 @@ contract('Bounty', function(accounts) { then(done); }) - it("can call checkInvarient for InsecureTargetMock", function(done){ + it("can call checkInvariant for InsecureTargetMock", function(done){ var bounty = Bounty.deployed(); var target = InsecureTargetMock.deployed(); bounty.createTarget(target.address). then(function() { - return bounty.checkInvarient.call() + return bounty.checkInvariant.call() }). then(function(result) { assert.isFalse(result); From 47b2c6d668a3255f5b2d274ab00a45c06b5f581b Mon Sep 17 00:00:00 2001 From: Makoto Inoue Date: Sat, 22 Oct 2016 23:29:13 +0100 Subject: [PATCH 7/7] WIP Target contract creation via factory pattern --- contracts/Bounty.sol | 8 ++++++-- contracts/test-helpers/InsecureTargetMock.sol | 6 ++++++ contracts/test-helpers/SecureTargetMock.sol | 6 ++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/contracts/Bounty.sol b/contracts/Bounty.sol index 2bee51e98..c3bde8cf4 100644 --- a/contracts/Bounty.sol +++ b/contracts/Bounty.sol @@ -8,6 +8,10 @@ import './PullPayment.sol'; * have sufficient ether for everyone to withdraw. */ +contract Factory { + function deployContract() returns (address); +} + contract Target { function checkInvariant() returns(bool); } @@ -21,8 +25,8 @@ contract Bounty is PullPayment { if (claimed) throw; } - function createTarget(address targetAddress) returns(Target) { - target = Target(targetAddress); + function createTarget(address factoryAddress) returns(Target) { + target = Target(Factory(factoryAddress).deployContract()); researchers[target] = msg.sender; return target; } diff --git a/contracts/test-helpers/InsecureTargetMock.sol b/contracts/test-helpers/InsecureTargetMock.sol index 2918361a8..8b85b6eb9 100644 --- a/contracts/test-helpers/InsecureTargetMock.sol +++ b/contracts/test-helpers/InsecureTargetMock.sol @@ -5,3 +5,9 @@ contract InsecureTargetMock { return false; } } + +contract Deployer { + function deployContract() returns (address) { + return new InsecureTargetMock(); + } +} diff --git a/contracts/test-helpers/SecureTargetMock.sol b/contracts/test-helpers/SecureTargetMock.sol index bd3a7dae2..382c4b53d 100644 --- a/contracts/test-helpers/SecureTargetMock.sol +++ b/contracts/test-helpers/SecureTargetMock.sol @@ -5,3 +5,9 @@ contract SecureTargetMock { return true; } } + +contract Deployer { + function deployContract() returns (address) { + return new SecureTargetMock(); + } +}