Add SB Curated (copied from the smartbugs repository).

This commit is contained in:
Joao F. Ferreira
2022-11-23 09:07:09 +00:00
parent 03da27c72a
commit 254a3b20c1
156 changed files with 17228 additions and 0 deletions

View File

@@ -0,0 +1,306 @@
/*
* @source: https://smartcontractsecurity.github.io/SWC-registry/docs/SWC-101#bectokensol
* @author: -
* @vulnerable_at_lines: 264
*/
pragma solidity ^0.4.16;
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
function mul(uint256 a, uint256 b) internal constant returns (uint256) {
uint256 c = a * b;
require(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal constant 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 constant returns (uint256) {
require(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal constant 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
*/
contract ERC20Basic {
uint256 public totalSupply;
function balanceOf(address who) public constant returns (uint256);
function transfer(address to, uint256 value) public 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 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);
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 An uint256 representing the amount owned by the passed address.
*/
function balanceOf(address _owner) public constant returns (uint256 balance) {
return balances[_owner];
}
}
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
*/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public constant returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public 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 returns (bool) {
require(_to != address(0));
require(_value > 0 && _value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
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 returns (bool) {
allowed[msg.sender][_spender] = _value;
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 A uint256 specifying the amount of tokens still available for the spender.
*/
function allowance(address _owner, address _spender) public constant 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.
*/
function Ownable() {
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));
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;
Pause();
}
/**
* @dev called by the owner to unpause, returns to normal state
*/
function unpause() onlyOwner whenPaused public {
paused = false;
Unpause();
}
}
/**
* @title Pausable token
*
* @dev StandardToken modified with pausable transfers.
**/
contract PausableToken is StandardToken, Pausable {
function transfer(address _to, uint256 _value) public whenNotPaused returns (bool) {
return super.transfer(_to, _value);
}
function transferFrom(address _from, address _to, uint256 _value) public whenNotPaused returns (bool) {
return super.transferFrom(_from, _to, _value);
}
function approve(address _spender, uint256 _value) public whenNotPaused returns (bool) {
return super.approve(_spender, _value);
}
function batchTransfer(address[] _receivers, uint256 _value) public whenNotPaused returns (bool) {
uint cnt = _receivers.length;
// <yes> <report> ARITHMETIC
uint256 amount = uint256(cnt) * _value;
require(cnt > 0 && cnt <= 20);
require(_value > 0 && balances[msg.sender] >= amount);
balances[msg.sender] = balances[msg.sender].sub(amount);
for (uint i = 0; i < cnt; i++) {
balances[_receivers[i]] = balances[_receivers[i]].add(_value);
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.
*/
function BecToken() {
totalSupply = 7000000000 * (10**(uint256(decimals)));
balances[msg.sender] = totalSupply; // Give the creator all initial tokens
}
function () {
//if ether is sent to this address, send it back.
revert();
}
}

43
dataset/arithmetic/README.md Executable file
View File

@@ -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/)

View File

@@ -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.4.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;
// <yes> <report> ARITHMETIC
balanceOf[_to] += _value;
}
}

View File

@@ -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.4.15;
contract Overflow {
uint private sellerBalance=0;
function add(uint value) returns (bool){
// <yes> <report> ARITHMETIC
sellerBalance += value; // possible overflow
// possible auditor assert
// assert(sellerBalance >= value);
}
// function safe_add(uint value) returns (bool){
// require(value + sellerBalance >= sellerBalance);
// sellerBalance += value;
// }
}

View File

@@ -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.4.19;
contract IntegerOverflowAdd {
uint public count = 1;
function run(uint256 input) public {
// <yes> <report> ARITHMETIC
count += input;
}
}

View File

@@ -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.4.19;
contract IntegerOverflowBenign1 {
uint public count = 1;
function run(uint256 input) public {
// <yes> <report> ARITHMETIC
uint res = count - input;
}
}

View File

@@ -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.4.11;
contract IntegerOverflowMappingSym1 {
mapping(uint256 => uint256) map;
function init(uint256 k, uint256 v) public {
// <yes> <report> ARITHMETIC
map[k] -= v;
}
}

View File

@@ -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.4.19;
contract IntegerOverflowMinimal {
uint public count = 1;
function run(uint256 input) public {
// <yes> <report> ARITHMETIC
count -= input;
}
}

View File

@@ -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.4.19;
contract IntegerOverflowMul {
uint public count = 2;
function run(uint256 input) public {
// <yes> <report> ARITHMETIC
count *= input;
}
}

View File

@@ -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.4.23;
contract IntegerOverflowMultiTxMultiFuncFeasible {
uint256 private initialized = 0;
uint256 public count = 1;
function init() public {
initialized = 1;
}
function run(uint256 input) {
if (initialized == 0) {
return;
}
// <yes> <report> ARITHMETIC
count -= input;
}
}

View File

@@ -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.4.23;
contract IntegerOverflowMultiTxOneFuncFeasible {
uint256 private initialized = 0;
uint256 public count = 1;
function run(uint256 input) public {
if (initialized == 0) {
initialized = 1;
return;
}
// <yes> <report> ARITHMETIC
count -= input;
}
}

View File

@@ -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.4.25;
contract Overflow_Add {
uint public balance = 1;
function add(uint256 deposit) public {
// <yes> <report> ARITHMETIC
balance += deposit;
}
}

View File

@@ -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.4.23;
contract IntegerOverflowSingleTransaction {
uint public count = 1;
// ADD overflow with result stored in state variable.
function overflowaddtostate(uint256 input) public {
// <yes> <report> ARITHMETIC
count += input;
}
// MUL overflow with result stored in state variable.
function overflowmultostate(uint256 input) public {
// <yes> <report> ARITHMETIC
count *= input;
}
// Underflow with result stored in state variable.
function underflowtostate(uint256 input) public {
// <yes> <report> ARITHMETIC
count -= input;
}
// ADD Overflow, no effect on state.
function overflowlocalonly(uint256 input) public {
// <yes> <report> ARITHMETIC
uint res = count + input;
}
// MUL Overflow, no effect on state.
function overflowmulocalonly(uint256 input) public {
// <yes> <report> ARITHMETIC
uint res = count * input;
}
// Underflow, no effect on state.
function underflowlocalonly(uint256 input) public {
// <yes> <report> ARITHMETIC
uint res = count - input;
}
}

View File

@@ -0,0 +1,32 @@
/*
* @source: https://github.com/sigp/solidity-security-blog
* @author: -
* @vulnerable_at_lines: 22
*/
//added pragma version
pragma solidity ^0.4.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] = now + 1 weeks;
}
function increaseLockTime(uint _secondsToIncrease) public {
// <yes> <report> ARITHMETIC
lockTime[msg.sender] += _secondsToIncrease;
}
function withdraw() public {
require(balances[msg.sender] > 0);
require(now > lockTime[msg.sender]);
uint transferValue = balances[msg.sender];
balances[msg.sender] = 0;
msg.sender.transfer(transferValue);
}
}

View File

@@ -0,0 +1,30 @@
/*
* @source: https://github.com/sigp/solidity-security-blog
* @author: Steve Marx
* @vulnerable_at_lines: 20,22
*/
pragma solidity ^0.4.18;
contract Token {
mapping(address => uint) balances;
uint public totalSupply;
function Token(uint _initialSupply) {
balances[msg.sender] = totalSupply = _initialSupply;
}
function transfer(address _to, uint _value) public returns (bool) {
// <yes> <report> ARITHMETIC
require(balances[msg.sender] - _value >= 0);
// <yes> <report> ARITHMETIC
balances[msg.sender] -= _value;
balances[_to] += _value;
return true;
}
function balanceOf(address _owner) public constant returns (uint balance) {
return balances[_owner];
}
}

View File

@@ -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.4.21;
contract TokenSaleChallenge {
mapping(address => uint256) public balanceOf;
uint256 constant PRICE_PER_TOKEN = 1 ether;
function TokenSaleChallenge(address _player) public payable {
require(msg.value == 1 ether);
}
function isComplete() public view returns (bool) {
return address(this).balance < 1 ether;
}
function buy(uint256 numTokens) public payable {
// <yes> <report> ARITHMETIC
require(msg.value == numTokens * PRICE_PER_TOKEN);
// <yes> <report> ARITHMETIC
balanceOf[msg.sender] += numTokens;
}
function sell(uint256 numTokens) public {
require(balanceOf[msg.sender] >= numTokens);
balanceOf[msg.sender] -= numTokens;
// <yes> <report> ARITHMETIC
msg.sender.transfer(numTokens * PRICE_PER_TOKEN);
}
}