Add SB Curated (copied from the smartbugs repository).
This commit is contained in:
129
dataset/front_running/ERC20.sol
Normal file
129
dataset/front_running/ERC20.sol
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* @source: https://github.com/SmartContractSecurity/SWC-registry/blob/master/test_cases/transaction_order_dependence/ERC20.sol
|
||||
* @author: -
|
||||
* @vulnerable_at_lines: 110,113
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.24;
|
||||
|
||||
/** Taken from the OpenZeppelin github
|
||||
* @title SafeMath
|
||||
* @dev Math operations with safety checks that revert on error
|
||||
*/
|
||||
library SafeMath {
|
||||
|
||||
/**
|
||||
* @dev Multiplies two numbers, reverts on overflow.
|
||||
*/
|
||||
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
|
||||
// benefit is lost if 'b' is also tested.
|
||||
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
|
||||
if (a == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint256 c = a * b;
|
||||
require(c / a == b);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
|
||||
*/
|
||||
function div(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b > 0); // Solidity only automatically asserts when dividing by 0
|
||||
uint256 c = a / b;
|
||||
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
|
||||
*/
|
||||
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b <= a);
|
||||
uint256 c = a - b;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Adds two numbers, reverts on overflow.
|
||||
*/
|
||||
function add(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
uint256 c = a + b;
|
||||
require(c >= a);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Divides two numbers and returns the remainder (unsigned integer modulo),
|
||||
* reverts when dividing by zero.
|
||||
*/
|
||||
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
require(b != 0);
|
||||
return a % b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
contract ERC20 {
|
||||
|
||||
event Transfer( address indexed from, address indexed to, uint256 value );
|
||||
event Approval( address indexed owner, address indexed spender, uint256 value);
|
||||
using SafeMath for *;
|
||||
|
||||
mapping (address => uint256) private _balances;
|
||||
|
||||
mapping (address => mapping (address => uint256)) private _allowed;
|
||||
|
||||
uint256 private _totalSupply;
|
||||
|
||||
constructor(uint totalSupply){
|
||||
_balances[msg.sender] = totalSupply;
|
||||
}
|
||||
|
||||
function balanceOf(address owner) public view returns (uint256) {
|
||||
return _balances[owner];
|
||||
}
|
||||
|
||||
|
||||
function allowance(address owner, address spender) public view returns (uint256)
|
||||
{
|
||||
return _allowed[owner][spender];
|
||||
}
|
||||
|
||||
function transfer(address to, uint256 value) public returns (bool) {
|
||||
require(value <= _balances[msg.sender]);
|
||||
require(to != address(0));
|
||||
|
||||
_balances[msg.sender] = _balances[msg.sender].sub(value);
|
||||
_balances[to] = _balances[to].add(value);
|
||||
emit Transfer(msg.sender, to, value);
|
||||
return true;
|
||||
}
|
||||
// <yes> <report> FRONT_RUNNING
|
||||
function approve(address spender, uint256 value) public returns (bool) {
|
||||
require(spender != address(0));
|
||||
// <yes> <report> FRONT_RUNNING
|
||||
_allowed[msg.sender][spender] = value;
|
||||
emit Approval(msg.sender, spender, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
function transferFrom(address from, address to, uint256 value) public returns (bool) {
|
||||
require(value <= _balances[from]);
|
||||
require(value <= _allowed[from][msg.sender]);
|
||||
require(to != address(0));
|
||||
|
||||
_balances[from] = _balances[from].sub(value);
|
||||
_balances[to] = _balances[to].add(value);
|
||||
_allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);
|
||||
emit Transfer(from, to, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
20
dataset/front_running/FindThisHash.sol
Normal file
20
dataset/front_running/FindThisHash.sol
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* @source: https://github.com/sigp/solidity-security-blog
|
||||
* @author: -
|
||||
* @vulnerable_at_lines: 17
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.22;
|
||||
|
||||
contract FindThisHash {
|
||||
bytes32 constant public hash = 0xb5b5b97fafd9855eec9b41f74dfb6c38f5951141f9a3ecd7f44d5479b630ee0a;
|
||||
|
||||
constructor() public payable {} // load with ether
|
||||
|
||||
function solve(string solution) public {
|
||||
// If you can find the pre image of the hash, receive 1000 ether
|
||||
// <yes> <report> FRONT_RUNNING
|
||||
require(hash == sha3(solution));
|
||||
msg.sender.transfer(1000 ether);
|
||||
}
|
||||
}
|
||||
14
dataset/front_running/README.md
Executable file
14
dataset/front_running/README.md
Executable file
@@ -0,0 +1,14 @@
|
||||
# Front Running
|
||||
Also known as time-of-check vs time-of-use (TOCTOU), race condition, transaction ordering dependence (TOD).
|
||||
|
||||
Since miners always get rewarded via gas fees for running code on behalf of externally owned addresses (EOA), users can specify higher fees to have their transactions mined more quickly. Since the Ethereum blockchain is public, everyone can see the contents of others' pending transactions. This means if a given user is revealing the solution to a puzzle or other valuable secret, a malicious user can steal the solution and copy their transaction with higher fees to preempt the original solution. If developers of smart contracts are not careful, this situation can lead to practical and devastating front-running attacks.
|
||||
|
||||
## Attack Scenario
|
||||
A smart contract publishes an RSA number (N = prime1 x prime2).
|
||||
A call to its submitSolution() public function with the right prime1 and prime2 rewards the caller.
|
||||
Alice successfuly factors the RSA number and submits a solution.
|
||||
Someone on the network sees Alice's transaction (containing the solution) waiting to be mined and submits it with a higher gas price.
|
||||
The second transaction gets picked up first by miners due to the higher paid fee. The attacker wins the prize.
|
||||
|
||||
## References
|
||||
Taken from [DASP TOP10](https://dasp.co/)
|
||||
34
dataset/front_running/eth_tx_order_dependence_minimal.sol
Normal file
34
dataset/front_running/eth_tx_order_dependence_minimal.sol
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* @source: https://github.com/ConsenSys/evm-analyzer-benchmark-suite
|
||||
* @author: Suhabe Bugrara
|
||||
* @vulnerable_at_lines: 23,31
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.16;
|
||||
|
||||
contract EthTxOrderDependenceMinimal {
|
||||
address public owner;
|
||||
bool public claimed;
|
||||
uint public reward;
|
||||
|
||||
function EthTxOrderDependenceMinimal() public {
|
||||
owner = msg.sender;
|
||||
}
|
||||
|
||||
function setReward() public payable {
|
||||
require (!claimed);
|
||||
|
||||
require(msg.sender == owner);
|
||||
// <yes> <report> FRONT_RUNNING
|
||||
owner.transfer(reward);
|
||||
reward = msg.value;
|
||||
}
|
||||
|
||||
function claimReward(uint256 submission) {
|
||||
require (!claimed);
|
||||
require(submission < 10);
|
||||
// <yes> <report> FRONT_RUNNING
|
||||
msg.sender.transfer(reward);
|
||||
claimed = true;
|
||||
}
|
||||
}
|
||||
53
dataset/front_running/odds_and_evens.sol
Normal file
53
dataset/front_running/odds_and_evens.sol
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* @source: http://blockchain.unica.it/projects/ethereum-survey/attacks.html#oddsandevens
|
||||
* @author: -
|
||||
* @vulnerable_at_lines: 25,28
|
||||
*/
|
||||
|
||||
pragma solidity ^0.4.2;
|
||||
|
||||
contract OddsAndEvens{
|
||||
|
||||
struct Player {
|
||||
address addr;
|
||||
uint number;
|
||||
}
|
||||
|
||||
Player[2] public players; //public only for debug purpose
|
||||
|
||||
uint8 tot;
|
||||
address owner;
|
||||
|
||||
function OddsAndEvens() {
|
||||
owner = msg.sender;
|
||||
}
|
||||
// <yes> <report> FRONT_RUNNING
|
||||
function play(uint number) payable{
|
||||
if (msg.value != 1 ether) throw;
|
||||
// <yes> <report> FRONT_RUNNING
|
||||
players[tot] = Player(msg.sender, number);
|
||||
tot++;
|
||||
|
||||
if (tot==2) andTheWinnerIs();
|
||||
}
|
||||
|
||||
function andTheWinnerIs() private {
|
||||
bool res ;
|
||||
uint n = players[0].number+players[1].number;
|
||||
if (n%2==0) {
|
||||
res = players[0].addr.send(1800 finney);
|
||||
}
|
||||
else {
|
||||
res = players[1].addr.send(1800 finney);
|
||||
}
|
||||
|
||||
delete players;
|
||||
tot=0;
|
||||
}
|
||||
|
||||
function getProfit() {
|
||||
if(msg.sender!=owner) throw;
|
||||
bool res = msg.sender.send(this.balance);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user