diff --git a/.travis.yml b/.travis.yml index a8f72598e..5523f1ae1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ language: node_js node_js: - "6" before_install: - - npm install truffle@3.1.9 -g + - npm install truffle@3.2.2 -g - npm i -g ethereumjs-testrpc script: - testrpc > /dev/null & diff --git a/audit/ZeppelinAudit.md b/audit/ZeppelinAudit.md index 4590a33a7..2291749f6 100644 --- a/audit/ZeppelinAudit.md +++ b/audit/ZeppelinAudit.md @@ -48,7 +48,7 @@ We think much more could be done here, and recommend the OpenZeppelin team keep ## Solidity Version Updates Recommended -Most of the code uses Solidity 0.4.8, but some files under `Ownership` are marked 0.4.0. These should be updated. +Most of the code uses Solidity 0.4.11, but some files under `Ownership` are marked 0.4.0. These should be updated. Solidity 0.4.10 will add several features which could be useful in these contracts: diff --git a/contracts/Bounty.sol b/contracts/Bounty.sol index e6c2efc32..4425b7a54 100644 --- a/contracts/Bounty.sol +++ b/contracts/Bounty.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import './payment/PullPayment.sol'; diff --git a/contracts/DayLimit.sol b/contracts/DayLimit.sol index 66fb72782..c76a955a7 100644 --- a/contracts/DayLimit.sol +++ b/contracts/DayLimit.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; /** * @title DayLimit diff --git a/contracts/LimitBalance.sol b/contracts/LimitBalance.sol index a5a77ccf3..4071edbea 100644 --- a/contracts/LimitBalance.sol +++ b/contracts/LimitBalance.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; /** diff --git a/contracts/MultisigWallet.sol b/contracts/MultisigWallet.sol index 9d5e3fccc..fc6fe37f8 100644 --- a/contracts/MultisigWallet.sol +++ b/contracts/MultisigWallet.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "./ownership/Multisig.sol"; @@ -93,7 +93,7 @@ contract MultisigWallet is Multisig, Shareable, DayLimit { /** * @dev Updates the daily limit value. - * @param _newLimit + * @param _newLimit Uint to represent the new limit. */ function setDailyLimit(uint _newLimit) onlymanyowners(keccak256(msg.data)) external { _setDailyLimit(_newLimit); diff --git a/contracts/ReentrancyGuard.sol b/contracts/ReentrancyGuard.sol index 3492d7bdf..ca8b643bc 100644 --- a/contracts/ReentrancyGuard.sol +++ b/contracts/ReentrancyGuard.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; /** * @title Helps contracts guard agains rentrancy attacks. diff --git a/contracts/SafeMath.sol b/contracts/SafeMath.sol index cf4091220..02718a372 100644 --- a/contracts/SafeMath.sol +++ b/contracts/SafeMath.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; /** diff --git a/contracts/lifecycle/Destructible.sol b/contracts/lifecycle/Destructible.sol index 005c6b8c1..3561e3b74 100644 --- a/contracts/lifecycle/Destructible.sol +++ b/contracts/lifecycle/Destructible.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "../ownership/Ownable.sol"; @@ -10,6 +10,8 @@ import "../ownership/Ownable.sol"; */ contract Destructible is Ownable { + function Destructible() payable { } + /** * @dev Transfers the current balance to the owner and terminates the contract. */ diff --git a/contracts/lifecycle/Migrations.sol b/contracts/lifecycle/Migrations.sol index 8cc949ae0..42ce534ad 100644 --- a/contracts/lifecycle/Migrations.sol +++ b/contracts/lifecycle/Migrations.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../ownership/Ownable.sol'; diff --git a/contracts/lifecycle/Pausable.sol b/contracts/lifecycle/Pausable.sol index 8960ec135..b14f87678 100644 --- a/contracts/lifecycle/Pausable.sol +++ b/contracts/lifecycle/Pausable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "../ownership/Ownable.sol"; diff --git a/contracts/lifecycle/TokenDestructible.sol b/contracts/lifecycle/TokenDestructible.sol index de9fa50d4..46a729519 100644 --- a/contracts/lifecycle/TokenDestructible.sol +++ b/contracts/lifecycle/TokenDestructible.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "../ownership/Ownable.sol"; @@ -12,6 +12,8 @@ import "../token/ERC20Basic.sol"; */ contract TokenDestructible is Ownable { + function TokenDestructible() payable { } + /** * @notice Terminate contract and refund to owner * @param tokens List of addresses of ERC20 or ERC20Basic token contracts to diff --git a/contracts/ownership/Claimable.sol b/contracts/ownership/Claimable.sol index 42997cf48..d063502d1 100644 --- a/contracts/ownership/Claimable.sol +++ b/contracts/ownership/Claimable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import './Ownable.sol'; diff --git a/contracts/ownership/Contactable.sol b/contracts/ownership/Contactable.sol index ca81c76cd..0db3ee07c 100644 --- a/contracts/ownership/Contactable.sol +++ b/contracts/ownership/Contactable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import './Ownable.sol'; diff --git a/contracts/ownership/DelayedClaimable.sol b/contracts/ownership/DelayedClaimable.sol index fb1a47c73..9360931b0 100644 --- a/contracts/ownership/DelayedClaimable.sol +++ b/contracts/ownership/DelayedClaimable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import './Claimable.sol'; diff --git a/contracts/ownership/HasNoContracts.sol b/contracts/ownership/HasNoContracts.sol index cd650499c..b5bd649d7 100644 --- a/contracts/ownership/HasNoContracts.sol +++ b/contracts/ownership/HasNoContracts.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "./Ownable.sol"; diff --git a/contracts/ownership/HasNoEther.sol b/contracts/ownership/HasNoEther.sol index 0fd4305da..2bcaf1b83 100644 --- a/contracts/ownership/HasNoEther.sol +++ b/contracts/ownership/HasNoEther.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "./Ownable.sol"; diff --git a/contracts/ownership/HasNoTokens.sol b/contracts/ownership/HasNoTokens.sol index 3a69673f8..46cea2936 100644 --- a/contracts/ownership/HasNoTokens.sol +++ b/contracts/ownership/HasNoTokens.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "./Ownable.sol"; import "../token/ERC20Basic.sol"; diff --git a/contracts/ownership/Multisig.sol b/contracts/ownership/Multisig.sol index ffb379ff5..a9a03ef4f 100644 --- a/contracts/ownership/Multisig.sol +++ b/contracts/ownership/Multisig.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; /** diff --git a/contracts/ownership/NoOwner.sol b/contracts/ownership/NoOwner.sol index 4979c2b38..7215abf3a 100644 --- a/contracts/ownership/NoOwner.sol +++ b/contracts/ownership/NoOwner.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "./HasNoEther.sol"; import "./HasNoTokens.sol"; diff --git a/contracts/ownership/Ownable.sol b/contracts/ownership/Ownable.sol index 77496627f..f16284540 100644 --- a/contracts/ownership/Ownable.sol +++ b/contracts/ownership/Ownable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; /** diff --git a/contracts/ownership/Shareable.sol b/contracts/ownership/Shareable.sol index 9cdfa791f..cd2e8422e 100644 --- a/contracts/ownership/Shareable.sol +++ b/contracts/ownership/Shareable.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; /** diff --git a/contracts/payment/PullPayment.sol b/contracts/payment/PullPayment.sol index eadc93b40..1c59a390d 100644 --- a/contracts/payment/PullPayment.sol +++ b/contracts/payment/PullPayment.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../SafeMath.sol'; diff --git a/contracts/token/BasicToken.sol b/contracts/token/BasicToken.sol index c560d0ab5..b0f06923f 100644 --- a/contracts/token/BasicToken.sol +++ b/contracts/token/BasicToken.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import './ERC20Basic.sol'; diff --git a/contracts/token/CrowdsaleToken.sol b/contracts/token/CrowdsaleToken.sol index 1cdbdc1c1..0f5bca546 100644 --- a/contracts/token/CrowdsaleToken.sol +++ b/contracts/token/CrowdsaleToken.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "./StandardToken.sol"; diff --git a/contracts/token/ERC20.sol b/contracts/token/ERC20.sol index 57b213edf..34de0fc98 100644 --- a/contracts/token/ERC20.sol +++ b/contracts/token/ERC20.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import './ERC20Basic.sol'; diff --git a/contracts/token/ERC20Basic.sol b/contracts/token/ERC20Basic.sol index 11185765b..4f8d38f03 100644 --- a/contracts/token/ERC20Basic.sol +++ b/contracts/token/ERC20Basic.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; /** diff --git a/contracts/token/LimitedTransferToken.sol b/contracts/token/LimitedTransferToken.sol index 4adf81cc0..a353eac95 100644 --- a/contracts/token/LimitedTransferToken.sol +++ b/contracts/token/LimitedTransferToken.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "./ERC20.sol"; diff --git a/contracts/token/MintableToken.sol b/contracts/token/MintableToken.sol index 211b440e4..8f6dc751b 100644 --- a/contracts/token/MintableToken.sol +++ b/contracts/token/MintableToken.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import './StandardToken.sol'; diff --git a/contracts/token/PausableToken.sol b/contracts/token/PausableToken.sol index 76ff7cd15..aeddfe3d9 100644 --- a/contracts/token/PausableToken.sol +++ b/contracts/token/PausableToken.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import './StandardToken.sol'; import '../lifecycle/Pausable.sol'; diff --git a/contracts/token/SimpleToken.sol b/contracts/token/SimpleToken.sol index fa2241fcb..63c6210cd 100644 --- a/contracts/token/SimpleToken.sol +++ b/contracts/token/SimpleToken.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "./StandardToken.sol"; diff --git a/contracts/token/StandardToken.sol b/contracts/token/StandardToken.sol index 676356d2d..1093800c6 100644 --- a/contracts/token/StandardToken.sol +++ b/contracts/token/StandardToken.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import './BasicToken.sol'; diff --git a/contracts/token/VestedToken.sol b/contracts/token/VestedToken.sol index 8adfb691d..ff2e6caa6 100644 --- a/contracts/token/VestedToken.sol +++ b/contracts/token/VestedToken.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "./StandardToken.sol"; import "./LimitedTransferToken.sol"; diff --git a/package.json b/package.json index 093cb01f2..fdb7d65ef 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,6 @@ "ethereumjs-testrpc": "^3.0.2", "mocha-lcov-reporter": "^1.3.0", "solidity-coverage": "^0.1.0", - "truffle": "https://github.com/ConsenSys/truffle.git#3.1.9" + "truffle": "3.2.2" } } diff --git a/test/DelayedClaimble.js b/test/DelayedClaimble.js index 5c5ab1fa9..516b3059e 100644 --- a/test/DelayedClaimble.js +++ b/test/DelayedClaimble.js @@ -49,7 +49,7 @@ contract('DelayedClaimable', function(accounts) { } catch (error) { err = error; } - assert.isFalse(err.message.search('invalid JUMP') === -1); + assert.isFalse(err.message.search('invalid opcode') === -1); let owner = await delayedClaimable.owner(); assert.isTrue(owner !== accounts[1]); }); @@ -62,7 +62,7 @@ contract('DelayedClaimable', function(accounts) { } catch (error) { err = error; } - assert.isFalse(err.message.search('invalid JUMP') === -1); + assert.isFalse(err.message.search('invalid opcode') === -1); }); }); diff --git a/test/HasNoEther.js b/test/HasNoEther.js index ac19634b3..573de1d21 100644 --- a/test/HasNoEther.js +++ b/test/HasNoEther.js @@ -35,7 +35,8 @@ contract('HasNoEther', function(accounts) { assert.equal(startBalance, 0); // Force ether into it - await ForceEther.new(hasNoEther.address, {value: amount}); + let forceEther = await ForceEther.new({value: amount}); + await forceEther.destroyAndSend(hasNoEther.address); const forcedBalance = await web3.eth.getBalance(hasNoEther.address); assert.equal(forcedBalance, amount); @@ -53,7 +54,8 @@ contract('HasNoEther', function(accounts) { let hasNoEther = await HasNoEtherTest.new({from: accounts[0]}); // Force ether into it - await ForceEther.new(hasNoEther.address, {value: amount}); + let forceEther = await ForceEther.new({value: amount}); + await forceEther.destroyAndSend(hasNoEther.address); const forcedBalance = await web3.eth.getBalance(hasNoEther.address); assert.equal(forcedBalance, amount); diff --git a/test/helpers/BasicTokenMock.sol b/test/helpers/BasicTokenMock.sol index 566dc330e..3e7f63569 100644 --- a/test/helpers/BasicTokenMock.sol +++ b/test/helpers/BasicTokenMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../../contracts/token/BasicToken.sol'; diff --git a/test/helpers/DayLimitMock.sol b/test/helpers/DayLimitMock.sol index c65396da6..c047e7b0f 100644 --- a/test/helpers/DayLimitMock.sol +++ b/test/helpers/DayLimitMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "../../contracts/DayLimit.sol"; contract DayLimitMock is DayLimit { diff --git a/test/helpers/ERC23TokenMock.sol b/test/helpers/ERC23TokenMock.sol index 417c2494b..2d0504ea4 100644 --- a/test/helpers/ERC23TokenMock.sol +++ b/test/helpers/ERC23TokenMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../../contracts/token/BasicToken.sol'; diff --git a/test/helpers/ForceEther.sol b/test/helpers/ForceEther.sol index cb73b6349..4d25ac4a2 100644 --- a/test/helpers/ForceEther.sol +++ b/test/helpers/ForceEther.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; // @title Force Ether into a contract. // @notice even @@ -6,8 +6,10 @@ pragma solidity ^0.4.8; // @notice To use, construct the contract with the target as argument. // @author Remco Bloemen contract ForceEther { - function ForceEther(address target) payable { - // Selfdestruct transfers all Ether to the arget address - selfdestruct(target); + + function ForceEther() payable { } + + function destroyAndSend(address _recipient) { + selfdestruct(_recipient); } } diff --git a/test/helpers/HasNoEtherTest.sol b/test/helpers/HasNoEtherTest.sol index 6b29e325d..9f320c06f 100644 --- a/test/helpers/HasNoEtherTest.sol +++ b/test/helpers/HasNoEtherTest.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "../../contracts/ownership/HasNoEther.sol"; diff --git a/test/helpers/InsecureTargetBounty.sol b/test/helpers/InsecureTargetBounty.sol index cfce6b099..3ac46a24e 100644 --- a/test/helpers/InsecureTargetBounty.sol +++ b/test/helpers/InsecureTargetBounty.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import {Bounty, Target} from "../../contracts/Bounty.sol"; diff --git a/test/helpers/LimitBalanceMock.sol b/test/helpers/LimitBalanceMock.sol index d2032d238..d38914ecd 100644 --- a/test/helpers/LimitBalanceMock.sol +++ b/test/helpers/LimitBalanceMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../../contracts/LimitBalance.sol'; diff --git a/test/helpers/MultisigWalletMock.sol b/test/helpers/MultisigWalletMock.sol index ae908de46..139d4187d 100644 --- a/test/helpers/MultisigWalletMock.sol +++ b/test/helpers/MultisigWalletMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "../../contracts/MultisigWallet.sol"; contract MultisigWalletMock is MultisigWallet { diff --git a/test/helpers/PausableMock.sol b/test/helpers/PausableMock.sol index 80fcb7d2d..4367f4a5c 100644 --- a/test/helpers/PausableMock.sol +++ b/test/helpers/PausableMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../../contracts/lifecycle/Pausable.sol'; diff --git a/test/helpers/PausableTokenMock.sol b/test/helpers/PausableTokenMock.sol index 569590d9b..360402151 100644 --- a/test/helpers/PausableTokenMock.sol +++ b/test/helpers/PausableTokenMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../../contracts/token/PausableToken.sol'; diff --git a/test/helpers/PullPaymentMock.sol b/test/helpers/PullPaymentMock.sol index 7c4bdb913..83a1d2a53 100644 --- a/test/helpers/PullPaymentMock.sol +++ b/test/helpers/PullPaymentMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../../contracts/payment/PullPayment.sol'; diff --git a/test/helpers/ReentrancyAttack.sol b/test/helpers/ReentrancyAttack.sol index ce67683a6..7eac47820 100644 --- a/test/helpers/ReentrancyAttack.sol +++ b/test/helpers/ReentrancyAttack.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; contract ReentrancyAttack { diff --git a/test/helpers/ReentrancyMock.sol b/test/helpers/ReentrancyMock.sol index dbfb41209..4b8cca94c 100644 --- a/test/helpers/ReentrancyMock.sol +++ b/test/helpers/ReentrancyMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../../contracts/ReentrancyGuard.sol'; import './ReentrancyAttack.sol'; diff --git a/test/helpers/SafeMathMock.sol b/test/helpers/SafeMathMock.sol index f4c6e90f6..f2b6d81e9 100644 --- a/test/helpers/SafeMathMock.sol +++ b/test/helpers/SafeMathMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../../contracts/SafeMath.sol'; diff --git a/test/helpers/SecureTargetBounty.sol b/test/helpers/SecureTargetBounty.sol index 2a46e3145..1f370246f 100644 --- a/test/helpers/SecureTargetBounty.sol +++ b/test/helpers/SecureTargetBounty.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import {Bounty, Target} from "../../contracts/Bounty.sol"; diff --git a/test/helpers/ShareableMock.sol b/test/helpers/ShareableMock.sol index 8a2ab990e..031e37ae2 100644 --- a/test/helpers/ShareableMock.sol +++ b/test/helpers/ShareableMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import "../../contracts/ownership/Shareable.sol"; contract ShareableMock is Shareable { diff --git a/test/helpers/StandardTokenMock.sol b/test/helpers/StandardTokenMock.sol index 602aac0bc..d96626965 100644 --- a/test/helpers/StandardTokenMock.sol +++ b/test/helpers/StandardTokenMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../../contracts/token/StandardToken.sol'; diff --git a/test/helpers/VestedTokenMock.sol b/test/helpers/VestedTokenMock.sol index 311692e72..a3aa4a0e8 100644 --- a/test/helpers/VestedTokenMock.sol +++ b/test/helpers/VestedTokenMock.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.4.8; +pragma solidity ^0.4.11; import '../../contracts/token/VestedToken.sol'; diff --git a/test/helpers/assertJump.js b/test/helpers/assertJump.js index c13654d27..63b50f5ad 100644 --- a/test/helpers/assertJump.js +++ b/test/helpers/assertJump.js @@ -1,3 +1,3 @@ module.exports = function(error) { - assert.isAbove(error.message.search('invalid JUMP'), -1, 'Invalid JUMP error must be returned'); + assert.isAbove(error.message.search('invalid opcode'), -1, 'Invalid opcode error must be returned'); } diff --git a/test/helpers/expectThrow.js b/test/helpers/expectThrow.js index 45bdcfdb0..6aeab6064 100644 --- a/test/helpers/expectThrow.js +++ b/test/helpers/expectThrow.js @@ -4,14 +4,14 @@ export default async promise => { } catch (error) { // TODO: Check jump destination to destinguish between a throw // and an actual invalid jump. - const invalidJump = error.message.search('invalid JUMP') >= 0; + const invalidOpcode = error.message.search('invalid opcode') >= 0; // TODO: When we contract A calls contract B, and B throws, instead // of an 'invalid jump', we get an 'out of gas' error. How do // we distinguish this from an actual out of gas event? (The // testrpc log actually show an 'invalid jump' event.) const outOfGas = error.message.search('out of gas') >= 0; assert( - invalidJump || outOfGas, + invalidOpcode || outOfGas, "Expected throw, got '" + error + "' instead", ); return;