mirror of https://github.com/ConsenSys/mythril
commit
479d3ccf42
@ -0,0 +1,68 @@ |
|||||||
|
--- |
||||||
|
name: Bug report |
||||||
|
about: Tell us about Mythril bugs to help us improve |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
_Note: did you notice that there is now a template for requesting new features?_ |
||||||
|
|
||||||
|
Please remove any of the optional sections if they are not applicable. |
||||||
|
|
||||||
|
## Description |
||||||
|
|
||||||
|
Replace this text with a clear and concise description of the bug. |
||||||
|
|
||||||
|
## How to Reproduce |
||||||
|
|
||||||
|
Please show both the input you gave and the |
||||||
|
output you got in describing how to reproduce the bug: |
||||||
|
|
||||||
|
1. Go to '...' |
||||||
|
2. Click on '....' |
||||||
|
3. Scroll down to '....' |
||||||
|
4. See error |
||||||
|
|
||||||
|
or give a complete console log with input and output |
||||||
|
|
||||||
|
```console |
||||||
|
$ myth <command-line-options> |
||||||
|
==== Exception state ==== |
||||||
|
Type: ... |
||||||
|
Contract: ... |
||||||
|
Function name: ... |
||||||
|
... |
||||||
|
$ |
||||||
|
``` |
||||||
|
|
||||||
|
If there is a Solidity source code, a truffle project, or bytecode |
||||||
|
that is involved, please provide that or links to it. |
||||||
|
|
||||||
|
## Expected behavior |
||||||
|
|
||||||
|
A clear and concise description of what you expected to happen. |
||||||
|
|
||||||
|
## Screenshots |
||||||
|
|
||||||
|
_This section is optional._ |
||||||
|
|
||||||
|
If applicable, add screenshots to help explain your problem. |
||||||
|
|
||||||
|
## Environment |
||||||
|
|
||||||
|
_This section sometimes is optional but helpful to us._ |
||||||
|
|
||||||
|
Please modify for your setup |
||||||
|
|
||||||
|
- Mythril version: output from `myth --version` or `pip show mythril` |
||||||
|
- Solidity compiler and version: `solc --version` |
||||||
|
- Python version: `python -V` |
||||||
|
- OS: [e.g. iOS] |
||||||
|
- OS Version [e.g. 22] |
||||||
|
|
||||||
|
## Additional Environment or Context |
||||||
|
|
||||||
|
_This section is optional._ |
||||||
|
|
||||||
|
Add any other context about the problem here or special environment setup |
||||||
|
|
||||||
|
Thanks for helping! |
@ -1,28 +0,0 @@ |
|||||||
--- |
|
||||||
name: Bug report |
|
||||||
about: Create a report to help us improve |
|
||||||
|
|
||||||
--- |
|
||||||
|
|
||||||
**Describe the bug** |
|
||||||
A clear and concise description of what the bug is. |
|
||||||
|
|
||||||
**To Reproduce** |
|
||||||
Steps to reproduce the behavior: |
|
||||||
1. Go to '...' |
|
||||||
2. Click on '....' |
|
||||||
3. Scroll down to '....' |
|
||||||
4. See error |
|
||||||
|
|
||||||
**Expected behavior** |
|
||||||
A clear and concise description of what you expected to happen. |
|
||||||
|
|
||||||
**Screenshots** |
|
||||||
If applicable, add screenshots to help explain your problem. |
|
||||||
|
|
||||||
**Desktop (please complete the following information):** |
|
||||||
- OS: [e.g. iOS] |
|
||||||
- Version [e.g. 22] |
|
||||||
|
|
||||||
**Additional context** |
|
||||||
Add any other context about the problem here. |
|
@ -0,0 +1,24 @@ |
|||||||
|
--- |
||||||
|
name: Feature Request |
||||||
|
about: Tell us about a new feature that would make Mythril better |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
|
## Description |
||||||
|
|
||||||
|
Replace this text with a short description of the feature. |
||||||
|
|
||||||
|
## Background |
||||||
|
|
||||||
|
Replace this text with any additional background for the |
||||||
|
feature, for example: user scenarios, or the value of the feature. |
||||||
|
|
||||||
|
## Tests |
||||||
|
_This section is optional._ |
||||||
|
|
||||||
|
Replace this text with suggestions on how to test the feature, |
||||||
|
if it is not obvious. This might require certain Solidity source, |
||||||
|
bytecode, or a Truffle project. You can also provide |
||||||
|
links to existing code. |
||||||
|
|
||||||
|
Thanks for helping! |
@ -0,0 +1,6 @@ |
|||||||
|
# We use RsT document formatting in docstring. For example :param to mark parameters. |
||||||
|
# See PEP 287 |
||||||
|
__docformat__ = 'restructuredtext' |
||||||
|
|
||||||
|
# Accept mythril.VERSION to get mythril's current version number |
||||||
|
from .version import VERSION # NOQA |
@ -0,0 +1,152 @@ |
|||||||
|
import logging |
||||||
|
from mythril import ether |
||||||
|
import time |
||||||
|
from ethereum.messages import Log |
||||||
|
import rlp |
||||||
|
from rlp.sedes import big_endian_int, binary |
||||||
|
from ethereum import utils |
||||||
|
from ethereum.utils import hash32, address, int256 |
||||||
|
|
||||||
|
BATCH_SIZE = 8 * 4096 |
||||||
|
|
||||||
|
|
||||||
|
class CountableList(object): |
||||||
|
"""A sedes for lists of arbitrary length. |
||||||
|
:param element_sedes: when (de-)serializing a list, this sedes will be |
||||||
|
applied to all of its elements |
||||||
|
""" |
||||||
|
|
||||||
|
def __init__(self, element_sedes): |
||||||
|
self.element_sedes = element_sedes |
||||||
|
|
||||||
|
def serialize(self, obj): |
||||||
|
return [self.element_sedes.serialize(e) for e in obj] |
||||||
|
|
||||||
|
def deserialize(self, serial): |
||||||
|
# needed for 2 reasons: |
||||||
|
# 1. empty lists are not zero elements |
||||||
|
# 2. underlying logs are stored as list - if empty will also except and receipts will be lost |
||||||
|
try: |
||||||
|
return [self.element_sedes.deserialize(e) for e in serial] |
||||||
|
except: |
||||||
|
return [] |
||||||
|
|
||||||
|
|
||||||
|
class ReceiptForStorage(rlp.Serializable): |
||||||
|
''' |
||||||
|
Receipt format stored in levelDB |
||||||
|
''' |
||||||
|
|
||||||
|
fields = [ |
||||||
|
('state_root', binary), |
||||||
|
('cumulative_gas_used', big_endian_int), |
||||||
|
('bloom', int256), |
||||||
|
('tx_hash', hash32), |
||||||
|
('contractAddress', address), |
||||||
|
('logs', CountableList(Log)), |
||||||
|
('gas_used', big_endian_int) |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
class AccountIndexer(object): |
||||||
|
''' |
||||||
|
Updates address index |
||||||
|
''' |
||||||
|
|
||||||
|
def __init__(self, ethDB): |
||||||
|
self.db = ethDB |
||||||
|
self.lastBlock = None |
||||||
|
self.lastProcessedBlock = None |
||||||
|
|
||||||
|
def get_contract_by_hash(self, contract_hash): |
||||||
|
''' |
||||||
|
get mapped address by its hash, if not found try indexing |
||||||
|
''' |
||||||
|
address = self.db.reader._get_address_by_hash(contract_hash) |
||||||
|
if address is not None: |
||||||
|
return address |
||||||
|
self.updateIfNeeded() |
||||||
|
return self.db.reader._get_address_by_hash(contract_hash) |
||||||
|
|
||||||
|
def _process(self, startblock): |
||||||
|
''' |
||||||
|
Processesing method |
||||||
|
''' |
||||||
|
logging.debug("Processing blocks %d to %d" % (startblock, startblock + BATCH_SIZE)) |
||||||
|
|
||||||
|
addresses = [] |
||||||
|
|
||||||
|
for blockNum in range(startblock, startblock + BATCH_SIZE): |
||||||
|
hash = self.db.reader._get_block_hash(blockNum) |
||||||
|
if hash is not None: |
||||||
|
receipts = self.db.reader._get_block_receipts(hash, blockNum) |
||||||
|
|
||||||
|
for receipt in receipts: |
||||||
|
if receipt.contractAddress is not None and not all(b == 0 for b in receipt.contractAddress): |
||||||
|
addresses.append(receipt.contractAddress) |
||||||
|
else: |
||||||
|
if len(addresses) == 0: |
||||||
|
raise Exception() |
||||||
|
|
||||||
|
return addresses |
||||||
|
|
||||||
|
def updateIfNeeded(self): |
||||||
|
''' |
||||||
|
update address index |
||||||
|
''' |
||||||
|
headBlock = self.db.reader._get_head_block() |
||||||
|
if headBlock is not None: |
||||||
|
# avoid restarting search if head block is same & we already initialized |
||||||
|
# this is required for fastSync handling |
||||||
|
if self.lastBlock is not None: |
||||||
|
self.lastBlock = max(self.lastBlock, headBlock.number) |
||||||
|
else: |
||||||
|
self.lastBlock = headBlock.number |
||||||
|
lastProcessed = self.db.reader._get_last_indexed_number() |
||||||
|
if lastProcessed is not None: |
||||||
|
self.lastProcessedBlock = utils.big_endian_to_int(lastProcessed) |
||||||
|
|
||||||
|
# in fast sync head block is at 0 (e.g. in fastSync), we can't use it to determine length |
||||||
|
if self.lastBlock is not None and self.lastBlock == 0: |
||||||
|
self.lastBlock = 2e+9 |
||||||
|
|
||||||
|
if self.lastBlock is None or (self.lastProcessedBlock is not None and self.lastBlock <= self.lastProcessedBlock): |
||||||
|
return |
||||||
|
|
||||||
|
blockNum = 0 |
||||||
|
if self.lastProcessedBlock is not None: |
||||||
|
blockNum = self.lastProcessedBlock + 1 |
||||||
|
print("Updating hash-to-address index from block " + str(self.lastProcessedBlock)) |
||||||
|
else: |
||||||
|
print("Starting hash-to-address index") |
||||||
|
|
||||||
|
count = 0 |
||||||
|
processed = 0 |
||||||
|
|
||||||
|
while (blockNum <= self.lastBlock): |
||||||
|
# leveldb cannot be accessed on multiple processes (not even readonly) |
||||||
|
# multithread version performs significantly worse than serial |
||||||
|
try: |
||||||
|
results = self._process(blockNum) |
||||||
|
except: |
||||||
|
break |
||||||
|
|
||||||
|
# store new mappings |
||||||
|
self.db.writer._start_writing() |
||||||
|
count += len(results) |
||||||
|
for addr in results: |
||||||
|
self.db.writer._store_account_address(addr) |
||||||
|
|
||||||
|
self.db.writer._commit_batch() |
||||||
|
|
||||||
|
processed += BATCH_SIZE |
||||||
|
blockNum = min(blockNum + BATCH_SIZE, self.lastBlock + 1) |
||||||
|
|
||||||
|
cost_time = time.time() - ether.start_time |
||||||
|
print("%d blocks processed (in %d seconds), %d unique addresses found, next block: %d" % (processed, cost_time, count, min(self.lastBlock, blockNum))) |
||||||
|
|
||||||
|
self.lastProcessedBlock = blockNum - 1 |
||||||
|
self.db.writer._set_last_indexed_number(self.lastProcessedBlock) |
||||||
|
|
||||||
|
print("Finished indexing") |
||||||
|
self.lastBlock = self.lastProcessedBlock |
@ -0,0 +1,3 @@ |
|||||||
|
# This file is suitable for sourcing inside POSIX shell, e.g. bash as |
||||||
|
# well as for importing into Python |
||||||
|
VERSION="v0.18.10" # NOQA |
@ -0,0 +1,299 @@ |
|||||||
|
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; |
||||||
|
assert(a == 0 || c / a == b); |
||||||
|
return c; |
||||||
|
} |
||||||
|
|
||||||
|
function div(uint256 a, uint256 b) internal constant returns (uint256) { |
||||||
|
// assert(b > 0); // Solidity automatically throws 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; |
||||||
|
} |
||||||
|
|
||||||
|
function sub(uint256 a, uint256 b) internal constant returns (uint256) { |
||||||
|
assert(b <= a); |
||||||
|
return a - b; |
||||||
|
} |
||||||
|
|
||||||
|
function add(uint256 a, uint256 b) internal constant returns (uint256) { |
||||||
|
uint256 c = a + b; |
||||||
|
assert(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; |
||||||
|
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(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,396 @@ |
|||||||
|
//sol Wallet |
||||||
|
// Multi-sig, daily-limited account proxy/wallet. |
||||||
|
// @authors: |
||||||
|
// Gav Wood <g@ethdev.com> |
||||||
|
// inheritable "property" contract that enables methods to be protected by requiring the acquiescence of either a |
||||||
|
// single, or, crucially, each of a number of, designated owners. |
||||||
|
// usage: |
||||||
|
// use modifiers onlyowner (just own owned) or onlymanyowners(hash), whereby the same hash must be provided by |
||||||
|
// some number (specified in constructor) of the set of owners (specified in the constructor, modifiable) before the |
||||||
|
// interior is executed. |
||||||
|
|
||||||
|
pragma solidity ^0.4.9; |
||||||
|
|
||||||
|
contract WalletEvents { |
||||||
|
// EVENTS |
||||||
|
|
||||||
|
// this contract only has six types of events: it can accept a confirmation, in which case |
||||||
|
// we record owner and operation (hash) alongside it. |
||||||
|
event Confirmation(address owner, bytes32 operation); |
||||||
|
event Revoke(address owner, bytes32 operation); |
||||||
|
|
||||||
|
// some others are in the case of an owner changing. |
||||||
|
event OwnerChanged(address oldOwner, address newOwner); |
||||||
|
event OwnerAdded(address newOwner); |
||||||
|
event OwnerRemoved(address oldOwner); |
||||||
|
|
||||||
|
// the last one is emitted if the required signatures change |
||||||
|
event RequirementChanged(uint newRequirement); |
||||||
|
|
||||||
|
// Funds has arrived into the wallet (record how much). |
||||||
|
event Deposit(address _from, uint value); |
||||||
|
// Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going). |
||||||
|
event SingleTransact(address owner, uint value, address to, bytes data, address created); |
||||||
|
// Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going). |
||||||
|
event MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data, address created); |
||||||
|
// Confirmation still needed for a transaction. |
||||||
|
event ConfirmationNeeded(bytes32 operation, address initiator, uint value, address to, bytes data); |
||||||
|
} |
||||||
|
|
||||||
|
contract WalletAbi { |
||||||
|
// Revokes a prior confirmation of the given operation |
||||||
|
function revoke(bytes32 _operation) external; |
||||||
|
|
||||||
|
// Replaces an owner `_from` with another `_to`. |
||||||
|
function changeOwner(address _from, address _to) external; |
||||||
|
|
||||||
|
function addOwner(address _owner) external; |
||||||
|
|
||||||
|
function removeOwner(address _owner) external; |
||||||
|
|
||||||
|
function changeRequirement(uint _newRequired) external; |
||||||
|
|
||||||
|
function isOwner(address _addr) constant returns (bool); |
||||||
|
|
||||||
|
function hasConfirmed(bytes32 _operation, address _owner) external constant returns (bool); |
||||||
|
|
||||||
|
// (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today. |
||||||
|
function setDailyLimit(uint _newLimit) external; |
||||||
|
|
||||||
|
function execute(address _to, uint _value, bytes _data) external returns (bytes32 o_hash); |
||||||
|
function confirm(bytes32 _h) returns (bool o_success); |
||||||
|
} |
||||||
|
|
||||||
|
contract WalletLibrary is WalletEvents { |
||||||
|
// TYPES |
||||||
|
|
||||||
|
// struct for the status of a pending operation. |
||||||
|
struct PendingState { |
||||||
|
uint yetNeeded; |
||||||
|
uint ownersDone; |
||||||
|
uint index; |
||||||
|
} |
||||||
|
|
||||||
|
// Transaction structure to remember details of transaction lest it need be saved for a later call. |
||||||
|
struct Transaction { |
||||||
|
address to; |
||||||
|
uint value; |
||||||
|
bytes data; |
||||||
|
} |
||||||
|
|
||||||
|
// MODIFIERS |
||||||
|
|
||||||
|
// simple single-sig function modifier. |
||||||
|
modifier onlyowner { |
||||||
|
if (isOwner(msg.sender)) |
||||||
|
_; |
||||||
|
} |
||||||
|
// multi-sig function modifier: the operation must have an intrinsic hash in order |
||||||
|
// that later attempts can be realised as the same underlying operation and |
||||||
|
// thus count as confirmations. |
||||||
|
modifier onlymanyowners(bytes32 _operation) { |
||||||
|
if (confirmAndCheck(_operation)) |
||||||
|
_; |
||||||
|
} |
||||||
|
|
||||||
|
// METHODS |
||||||
|
|
||||||
|
// gets called when no other function matches |
||||||
|
function() payable { |
||||||
|
// just being sent some cash? |
||||||
|
if (msg.value > 0) |
||||||
|
Deposit(msg.sender, msg.value); |
||||||
|
} |
||||||
|
|
||||||
|
// constructor is given number of sigs required to do protected "onlymanyowners" transactions |
||||||
|
// as well as the selection of addresses capable of confirming them. |
||||||
|
function initMultiowned(address[] _owners, uint _required) only_uninitialized { |
||||||
|
m_numOwners = _owners.length + 1; |
||||||
|
m_owners[1] = uint(msg.sender); |
||||||
|
m_ownerIndex[uint(msg.sender)] = 1; |
||||||
|
for (uint i = 0; i < _owners.length; ++i) |
||||||
|
{ |
||||||
|
m_owners[2 + i] = uint(_owners[i]); |
||||||
|
m_ownerIndex[uint(_owners[i])] = 2 + i; |
||||||
|
} |
||||||
|
m_required = _required; |
||||||
|
} |
||||||
|
|
||||||
|
// Revokes a prior confirmation of the given operation |
||||||
|
function revoke(bytes32 _operation) external { |
||||||
|
uint ownerIndex = m_ownerIndex[uint(msg.sender)]; |
||||||
|
// make sure they're an owner |
||||||
|
if (ownerIndex == 0) return; |
||||||
|
uint ownerIndexBit = 2**ownerIndex; |
||||||
|
var pending = m_pending[_operation]; |
||||||
|
if (pending.ownersDone & ownerIndexBit > 0) { |
||||||
|
pending.yetNeeded++; |
||||||
|
pending.ownersDone -= ownerIndexBit; |
||||||
|
Revoke(msg.sender, _operation); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Replaces an owner `_from` with another `_to`. |
||||||
|
function changeOwner(address _from, address _to) onlymanyowners(sha3(msg.data)) external { |
||||||
|
if (isOwner(_to)) return; |
||||||
|
uint ownerIndex = m_ownerIndex[uint(_from)]; |
||||||
|
if (ownerIndex == 0) return; |
||||||
|
|
||||||
|
clearPending(); |
||||||
|
m_owners[ownerIndex] = uint(_to); |
||||||
|
m_ownerIndex[uint(_from)] = 0; |
||||||
|
m_ownerIndex[uint(_to)] = ownerIndex; |
||||||
|
OwnerChanged(_from, _to); |
||||||
|
} |
||||||
|
|
||||||
|
function addOwner(address _owner) onlymanyowners(sha3(msg.data)) external { |
||||||
|
if (isOwner(_owner)) return; |
||||||
|
|
||||||
|
clearPending(); |
||||||
|
if (m_numOwners >= c_maxOwners) |
||||||
|
reorganizeOwners(); |
||||||
|
if (m_numOwners >= c_maxOwners) |
||||||
|
return; |
||||||
|
m_numOwners++; |
||||||
|
m_owners[m_numOwners] = uint(_owner); |
||||||
|
m_ownerIndex[uint(_owner)] = m_numOwners; |
||||||
|
OwnerAdded(_owner); |
||||||
|
} |
||||||
|
|
||||||
|
function removeOwner(address _owner) onlymanyowners(sha3(msg.data)) external { |
||||||
|
uint ownerIndex = m_ownerIndex[uint(_owner)]; |
||||||
|
if (ownerIndex == 0) return; |
||||||
|
if (m_required > m_numOwners - 1) return; |
||||||
|
|
||||||
|
m_owners[ownerIndex] = 0; |
||||||
|
m_ownerIndex[uint(_owner)] = 0; |
||||||
|
clearPending(); |
||||||
|
reorganizeOwners(); //make sure m_numOwner is equal to the number of owners and always points to the optimal free slot |
||||||
|
OwnerRemoved(_owner); |
||||||
|
} |
||||||
|
|
||||||
|
function changeRequirement(uint _newRequired) onlymanyowners(sha3(msg.data)) external { |
||||||
|
if (_newRequired > m_numOwners) return; |
||||||
|
m_required = _newRequired; |
||||||
|
clearPending(); |
||||||
|
RequirementChanged(_newRequired); |
||||||
|
} |
||||||
|
|
||||||
|
// Gets an owner by 0-indexed position (using numOwners as the count) |
||||||
|
function getOwner(uint ownerIndex) external constant returns (address) { |
||||||
|
return address(m_owners[ownerIndex + 1]); |
||||||
|
} |
||||||
|
|
||||||
|
function isOwner(address _addr) constant returns (bool) { |
||||||
|
return m_ownerIndex[uint(_addr)] > 0; |
||||||
|
} |
||||||
|
|
||||||
|
function hasConfirmed(bytes32 _operation, address _owner) external constant returns (bool) { |
||||||
|
var pending = m_pending[_operation]; |
||||||
|
uint ownerIndex = m_ownerIndex[uint(_owner)]; |
||||||
|
|
||||||
|
// make sure they're an owner |
||||||
|
if (ownerIndex == 0) return false; |
||||||
|
|
||||||
|
// determine the bit to set for this owner. |
||||||
|
uint ownerIndexBit = 2**ownerIndex; |
||||||
|
return !(pending.ownersDone & ownerIndexBit == 0); |
||||||
|
} |
||||||
|
|
||||||
|
// constructor - stores initial daily limit and records the present day's index. |
||||||
|
function initDaylimit(uint _limit) only_uninitialized { |
||||||
|
m_dailyLimit = _limit; |
||||||
|
m_lastDay = today(); |
||||||
|
} |
||||||
|
// (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today. |
||||||
|
function setDailyLimit(uint _newLimit) onlymanyowners(sha3(msg.data)) external { |
||||||
|
m_dailyLimit = _newLimit; |
||||||
|
} |
||||||
|
// resets the amount already spent today. needs many of the owners to confirm. |
||||||
|
function resetSpentToday() onlymanyowners(sha3(msg.data)) external { |
||||||
|
m_spentToday = 0; |
||||||
|
} |
||||||
|
|
||||||
|
// throw unless the contract is not yet initialized. |
||||||
|
modifier only_uninitialized { if (m_numOwners > 0) throw; _; } |
||||||
|
|
||||||
|
// constructor - just pass on the owner array to the multiowned and |
||||||
|
// the limit to daylimit |
||||||
|
function initWallet(address[] _owners, uint _required, uint _daylimit) only_uninitialized { |
||||||
|
initDaylimit(_daylimit); |
||||||
|
initMultiowned(_owners, _required); |
||||||
|
} |
||||||
|
|
||||||
|
// kills the contract sending everything to `_to`. |
||||||
|
function kill(address _to) onlymanyowners(sha3(msg.data)) external { |
||||||
|
suicide(_to); |
||||||
|
} |
||||||
|
|
||||||
|
// Outside-visible transact entry point. Executes transaction immediately if below daily spend limit. |
||||||
|
// If not, goes into multisig process. We provide a hash on return to allow the sender to provide |
||||||
|
// shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value |
||||||
|
// and _data arguments). They still get the option of using them if they want, anyways. |
||||||
|
function execute(address _to, uint _value, bytes _data) external onlyowner returns (bytes32 o_hash) { |
||||||
|
// first, take the opportunity to check that we're under the daily limit. |
||||||
|
if ((_data.length == 0 && underLimit(_value)) || m_required == 1) { |
||||||
|
// yes - just execute the call. |
||||||
|
address created; |
||||||
|
if (_to == 0) { |
||||||
|
created = create(_value, _data); |
||||||
|
} else { |
||||||
|
if (!_to.call.value(_value)(_data)) |
||||||
|
throw; |
||||||
|
} |
||||||
|
SingleTransact(msg.sender, _value, _to, _data, created); |
||||||
|
} else { |
||||||
|
// determine our operation hash. |
||||||
|
o_hash = sha3(msg.data, block.number); |
||||||
|
// store if it's new |
||||||
|
if (m_txs[o_hash].to == 0 && m_txs[o_hash].value == 0 && m_txs[o_hash].data.length == 0) { |
||||||
|
m_txs[o_hash].to = _to; |
||||||
|
m_txs[o_hash].value = _value; |
||||||
|
m_txs[o_hash].data = _data; |
||||||
|
} |
||||||
|
if (!confirm(o_hash)) { |
||||||
|
ConfirmationNeeded(o_hash, msg.sender, _value, _to, _data); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function create(uint _value, bytes _code) internal returns (address o_addr) { |
||||||
|
assembly { |
||||||
|
o_addr := create(_value, add(_code, 0x20), mload(_code)) |
||||||
|
jumpi(0xdeadbeef, iszero(extcodesize(o_addr))) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// confirm a transaction through just the hash. we use the previous transactions map, m_txs, in order |
||||||
|
// to determine the body of the transaction from the hash provided. |
||||||
|
function confirm(bytes32 _h) onlymanyowners(_h) returns (bool o_success) { |
||||||
|
if (m_txs[_h].to != 0 || m_txs[_h].value != 0 || m_txs[_h].data.length != 0) { |
||||||
|
address created; |
||||||
|
if (m_txs[_h].to == 0) { |
||||||
|
created = create(m_txs[_h].value, m_txs[_h].data); |
||||||
|
} else { |
||||||
|
if (!m_txs[_h].to.call.value(m_txs[_h].value)(m_txs[_h].data)) |
||||||
|
throw; |
||||||
|
} |
||||||
|
|
||||||
|
MultiTransact(msg.sender, _h, m_txs[_h].value, m_txs[_h].to, m_txs[_h].data, created); |
||||||
|
delete m_txs[_h]; |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// INTERNAL METHODS |
||||||
|
|
||||||
|
function confirmAndCheck(bytes32 _operation) internal returns (bool) { |
||||||
|
// determine what index the present sender is: |
||||||
|
uint ownerIndex = m_ownerIndex[uint(msg.sender)]; |
||||||
|
// make sure they're an owner |
||||||
|
if (ownerIndex == 0) return; |
||||||
|
|
||||||
|
var pending = m_pending[_operation]; |
||||||
|
// if we're not yet working on this operation, switch over and reset the confirmation status. |
||||||
|
if (pending.yetNeeded == 0) { |
||||||
|
// reset count of confirmations needed. |
||||||
|
pending.yetNeeded = m_required; |
||||||
|
// reset which owners have confirmed (none) - set our bitmap to 0. |
||||||
|
pending.ownersDone = 0; |
||||||
|
pending.index = m_pendingIndex.length++; |
||||||
|
m_pendingIndex[pending.index] = _operation; |
||||||
|
} |
||||||
|
// determine the bit to set for this owner. |
||||||
|
uint ownerIndexBit = 2**ownerIndex; |
||||||
|
// make sure we (the message sender) haven't confirmed this operation previously. |
||||||
|
if (pending.ownersDone & ownerIndexBit == 0) { |
||||||
|
Confirmation(msg.sender, _operation); |
||||||
|
// ok - check if count is enough to go ahead. |
||||||
|
if (pending.yetNeeded <= 1) { |
||||||
|
// enough confirmations: reset and run interior. |
||||||
|
delete m_pendingIndex[m_pending[_operation].index]; |
||||||
|
delete m_pending[_operation]; |
||||||
|
return true; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
// not enough: record that this owner in particular confirmed. |
||||||
|
pending.yetNeeded--; |
||||||
|
pending.ownersDone |= ownerIndexBit; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function reorganizeOwners() private { |
||||||
|
uint free = 1; |
||||||
|
while (free < m_numOwners) |
||||||
|
{ |
||||||
|
while (free < m_numOwners && m_owners[free] != 0) free++; |
||||||
|
while (m_numOwners > 1 && m_owners[m_numOwners] == 0) m_numOwners--; |
||||||
|
if (free < m_numOwners && m_owners[m_numOwners] != 0 && m_owners[free] == 0) |
||||||
|
{ |
||||||
|
m_owners[free] = m_owners[m_numOwners]; |
||||||
|
m_ownerIndex[m_owners[free]] = free; |
||||||
|
m_owners[m_numOwners] = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// checks to see if there is at least `_value` left from the daily limit today. if there is, subtracts it and |
||||||
|
// returns true. otherwise just returns false. |
||||||
|
function underLimit(uint _value) internal onlyowner returns (bool) { |
||||||
|
// reset the spend limit if we're on a different day to last time. |
||||||
|
if (today() > m_lastDay) { |
||||||
|
m_spentToday = 0; |
||||||
|
m_lastDay = today(); |
||||||
|
} |
||||||
|
// check to see if there's enough left - if so, subtract and return true. |
||||||
|
// overflow protection // dailyLimit check |
||||||
|
if (m_spentToday + _value >= m_spentToday && m_spentToday + _value <= m_dailyLimit) { |
||||||
|
m_spentToday += _value; |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
// determines today's index. |
||||||
|
function today() private constant returns (uint) { return now / 1 days; } |
||||||
|
|
||||||
|
function clearPending() internal { |
||||||
|
uint length = m_pendingIndex.length; |
||||||
|
|
||||||
|
for (uint i = 0; i < length; ++i) { |
||||||
|
delete m_txs[m_pendingIndex[i]]; |
||||||
|
|
||||||
|
if (m_pendingIndex[i] != 0) |
||||||
|
delete m_pending[m_pendingIndex[i]]; |
||||||
|
} |
||||||
|
|
||||||
|
delete m_pendingIndex; |
||||||
|
} |
||||||
|
|
||||||
|
// FIELDS |
||||||
|
address constant _walletLibrary = 0xcafecafecafecafecafecafecafecafecafecafe; |
||||||
|
|
||||||
|
// the number of owners that must confirm the same operation before it is run. |
||||||
|
uint public m_required; |
||||||
|
// pointer used to find a free slot in m_owners |
||||||
|
uint public m_numOwners; |
||||||
|
|
||||||
|
uint public m_dailyLimit; |
||||||
|
uint public m_spentToday; |
||||||
|
uint public m_lastDay; |
||||||
|
|
||||||
|
// list of owners |
||||||
|
uint[256] m_owners; |
||||||
|
|
||||||
|
uint constant c_maxOwners = 250; |
||||||
|
// index on the list of owners to allow reverse lookup |
||||||
|
mapping(uint => uint) m_ownerIndex; |
||||||
|
// the ongoing operations. |
||||||
|
mapping(bytes32 => PendingState) m_pending; |
||||||
|
bytes32[] m_pendingIndex; |
||||||
|
|
||||||
|
// pending transactions we have at present. |
||||||
|
mapping (bytes32 => Transaction) m_txs; |
||||||
|
} |
@ -1,31 +0,0 @@ |
|||||||
contract Crowdfunding { |
|
||||||
|
|
||||||
mapping(address => uint) public balances; |
|
||||||
address public owner; |
|
||||||
uint256 INVEST_MIN = 1 ether; |
|
||||||
uint256 INVEST_MAX = 10 ether; |
|
||||||
|
|
||||||
modifier onlyOwner() { |
|
||||||
require(msg.sender == owner); |
|
||||||
_; |
|
||||||
} |
|
||||||
|
|
||||||
function crowdfunding() { |
|
||||||
owner = msg.sender; |
|
||||||
} |
|
||||||
|
|
||||||
function withdrawfunds() onlyOwner { |
|
||||||
msg.sender.transfer(this.balance); |
|
||||||
} |
|
||||||
|
|
||||||
function invest() public payable { |
|
||||||
require(msg.value > INVEST_MIN && msg.value < INVEST_MAX); |
|
||||||
|
|
||||||
balances[msg.sender] += msg.value; |
|
||||||
} |
|
||||||
|
|
||||||
function getBalance() public constant returns (uint) { |
|
||||||
return balances[msg.sender]; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,21 @@ |
|||||||
|
contract EtherStore { |
||||||
|
|
||||||
|
uint256 public withdrawalLimit = 1 ether; |
||||||
|
mapping(address => uint256) public lastWithdrawTime; |
||||||
|
mapping(address => uint256) public balances; |
||||||
|
|
||||||
|
function depositFunds() public payable { |
||||||
|
balances[msg.sender] += msg.value; |
||||||
|
} |
||||||
|
|
||||||
|
function withdrawFunds (uint256 _weiToWithdraw) public { |
||||||
|
require(balances[msg.sender] >= _weiToWithdraw); |
||||||
|
// limit the withdrawal |
||||||
|
require(_weiToWithdraw <= withdrawalLimit); |
||||||
|
// limit the time allowed to withdraw |
||||||
|
require(now >= lastWithdrawTime[msg.sender] + 1 weeks); |
||||||
|
require(msg.sender.call.value(_weiToWithdraw)()); |
||||||
|
balances[msg.sender] -= _weiToWithdraw; |
||||||
|
lastWithdrawTime[msg.sender] = now; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
contract HashForEther { |
||||||
|
|
||||||
|
function withdrawWinnings() { |
||||||
|
// Winner if the last 8 hex characters of the address are 0. |
||||||
|
require(uint32(msg.sender) == 0); |
||||||
|
_sendWinnings(); |
||||||
|
} |
||||||
|
|
||||||
|
function _sendWinnings() { |
||||||
|
msg.sender.transfer(this.balance); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
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 { |
||||||
|
lockTime[msg.sender] += _secondsToIncrease; |
||||||
|
} |
||||||
|
|
||||||
|
function withdraw() public { |
||||||
|
require(balances[msg.sender] > 0); |
||||||
|
require(now > lockTime[msg.sender]); |
||||||
|
balances[msg.sender] = 0; |
||||||
|
msg.sender.transfer(balances[msg.sender]); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
pragma solidity ^0.4.16; |
||||||
|
|
||||||
|
|
||||||
|
contract IntegerOverflow2 { |
||||||
|
uint256 public count = 7; |
||||||
|
mapping(address => uint256) balances; |
||||||
|
|
||||||
|
function batchTransfer(address[] _receivers, uint256 _value) public returns(bool){ |
||||||
|
uint cnt = _receivers.length; |
||||||
|
uint256 amount = uint256(cnt) * _value; |
||||||
|
|
||||||
|
require(cnt > 0 && cnt <= 20); |
||||||
|
|
||||||
|
balances[msg.sender] -=amount; |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1 @@ |
|||||||
|
60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306661abd1461005157806383f12fec1461007c575b600080fd5b34801561005d57600080fd5b50610066610104565b6040518082815260200191505060405180910390f35b34801561008857600080fd5b506100ea600480360381019080803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091929192908035906020019092919050505061010a565b604051808215151515815260200191505060405180910390f35b60005481565b6000806000845191508382029050600082118015610129575060148211155b151561013457600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540392505081905550600192505050929150505600a165627a7a7230582016b81221eb990028632ba9b34d3c01599d24acdb5b81dd6789845696f5db257c0029 |
@ -0,0 +1,259 @@ |
|||||||
|
0 PUSH1 0x80 |
||||||
|
2 PUSH1 0x40 |
||||||
|
4 MSTORE |
||||||
|
5 PUSH1 0x04 |
||||||
|
7 CALLDATASIZE |
||||||
|
8 LT |
||||||
|
9 PUSH2 0x004c |
||||||
|
12 JUMPI |
||||||
|
13 PUSH1 0x00 |
||||||
|
15 CALLDATALOAD |
||||||
|
16 PUSH29 0x0100000000000000000000000000000000000000000000000000000000 |
||||||
|
46 SWAP1 |
||||||
|
47 DIV |
||||||
|
48 PUSH4 0xffffffff |
||||||
|
53 AND |
||||||
|
54 DUP1 |
||||||
|
55 PUSH4 0x06661abd |
||||||
|
60 EQ |
||||||
|
61 PUSH2 0x0051 |
||||||
|
64 JUMPI |
||||||
|
65 DUP1 |
||||||
|
66 PUSH4 0x83f12fec |
||||||
|
71 EQ |
||||||
|
72 PUSH2 0x007c |
||||||
|
75 JUMPI |
||||||
|
76 JUMPDEST |
||||||
|
77 PUSH1 0x00 |
||||||
|
79 DUP1 |
||||||
|
80 REVERT |
||||||
|
81 JUMPDEST |
||||||
|
82 CALLVALUE |
||||||
|
83 DUP1 |
||||||
|
84 ISZERO |
||||||
|
85 PUSH2 0x005d |
||||||
|
88 JUMPI |
||||||
|
89 PUSH1 0x00 |
||||||
|
91 DUP1 |
||||||
|
92 REVERT |
||||||
|
93 JUMPDEST |
||||||
|
94 POP |
||||||
|
95 PUSH2 0x0066 |
||||||
|
98 PUSH2 0x0104 |
||||||
|
101 JUMP |
||||||
|
102 JUMPDEST |
||||||
|
103 PUSH1 0x40 |
||||||
|
105 MLOAD |
||||||
|
106 DUP1 |
||||||
|
107 DUP3 |
||||||
|
108 DUP2 |
||||||
|
109 MSTORE |
||||||
|
110 PUSH1 0x20 |
||||||
|
112 ADD |
||||||
|
113 SWAP2 |
||||||
|
114 POP |
||||||
|
115 POP |
||||||
|
116 PUSH1 0x40 |
||||||
|
118 MLOAD |
||||||
|
119 DUP1 |
||||||
|
120 SWAP2 |
||||||
|
121 SUB |
||||||
|
122 SWAP1 |
||||||
|
123 RETURN |
||||||
|
124 JUMPDEST |
||||||
|
125 CALLVALUE |
||||||
|
126 DUP1 |
||||||
|
127 ISZERO |
||||||
|
128 PUSH2 0x0088 |
||||||
|
131 JUMPI |
||||||
|
132 PUSH1 0x00 |
||||||
|
134 DUP1 |
||||||
|
135 REVERT |
||||||
|
136 JUMPDEST |
||||||
|
137 POP |
||||||
|
138 PUSH2 0x00ea |
||||||
|
141 PUSH1 0x04 |
||||||
|
143 DUP1 |
||||||
|
144 CALLDATASIZE |
||||||
|
145 SUB |
||||||
|
146 DUP2 |
||||||
|
147 ADD |
||||||
|
148 SWAP1 |
||||||
|
149 DUP1 |
||||||
|
150 DUP1 |
||||||
|
151 CALLDATALOAD |
||||||
|
152 SWAP1 |
||||||
|
153 PUSH1 0x20 |
||||||
|
155 ADD |
||||||
|
156 SWAP1 |
||||||
|
157 DUP3 |
||||||
|
158 ADD |
||||||
|
159 DUP1 |
||||||
|
160 CALLDATALOAD |
||||||
|
161 SWAP1 |
||||||
|
162 PUSH1 0x20 |
||||||
|
164 ADD |
||||||
|
165 SWAP1 |
||||||
|
166 DUP1 |
||||||
|
167 DUP1 |
||||||
|
168 PUSH1 0x20 |
||||||
|
170 MUL |
||||||
|
171 PUSH1 0x20 |
||||||
|
173 ADD |
||||||
|
174 PUSH1 0x40 |
||||||
|
176 MLOAD |
||||||
|
177 SWAP1 |
||||||
|
178 DUP2 |
||||||
|
179 ADD |
||||||
|
180 PUSH1 0x40 |
||||||
|
182 MSTORE |
||||||
|
183 DUP1 |
||||||
|
184 SWAP4 |
||||||
|
185 SWAP3 |
||||||
|
186 SWAP2 |
||||||
|
187 SWAP1 |
||||||
|
188 DUP2 |
||||||
|
189 DUP2 |
||||||
|
190 MSTORE |
||||||
|
191 PUSH1 0x20 |
||||||
|
193 ADD |
||||||
|
194 DUP4 |
||||||
|
195 DUP4 |
||||||
|
196 PUSH1 0x20 |
||||||
|
198 MUL |
||||||
|
199 DUP1 |
||||||
|
200 DUP3 |
||||||
|
201 DUP5 |
||||||
|
202 CALLDATACOPY |
||||||
|
203 DUP3 |
||||||
|
204 ADD |
||||||
|
205 SWAP2 |
||||||
|
206 POP |
||||||
|
207 POP |
||||||
|
208 POP |
||||||
|
209 POP |
||||||
|
210 POP |
||||||
|
211 POP |
||||||
|
212 SWAP2 |
||||||
|
213 SWAP3 |
||||||
|
214 SWAP2 |
||||||
|
215 SWAP3 |
||||||
|
216 SWAP1 |
||||||
|
217 DUP1 |
||||||
|
218 CALLDATALOAD |
||||||
|
219 SWAP1 |
||||||
|
220 PUSH1 0x20 |
||||||
|
222 ADD |
||||||
|
223 SWAP1 |
||||||
|
224 SWAP3 |
||||||
|
225 SWAP2 |
||||||
|
226 SWAP1 |
||||||
|
227 POP |
||||||
|
228 POP |
||||||
|
229 POP |
||||||
|
230 PUSH2 0x010a |
||||||
|
233 JUMP |
||||||
|
234 JUMPDEST |
||||||
|
235 PUSH1 0x40 |
||||||
|
237 MLOAD |
||||||
|
238 DUP1 |
||||||
|
239 DUP3 |
||||||
|
240 ISZERO |
||||||
|
241 ISZERO |
||||||
|
242 ISZERO |
||||||
|
243 ISZERO |
||||||
|
244 DUP2 |
||||||
|
245 MSTORE |
||||||
|
246 PUSH1 0x20 |
||||||
|
248 ADD |
||||||
|
249 SWAP2 |
||||||
|
250 POP |
||||||
|
251 POP |
||||||
|
252 PUSH1 0x40 |
||||||
|
254 MLOAD |
||||||
|
255 DUP1 |
||||||
|
256 SWAP2 |
||||||
|
257 SUB |
||||||
|
258 SWAP1 |
||||||
|
259 RETURN |
||||||
|
260 JUMPDEST |
||||||
|
261 PUSH1 0x00 |
||||||
|
263 SLOAD |
||||||
|
264 DUP2 |
||||||
|
265 JUMP |
||||||
|
266 JUMPDEST |
||||||
|
267 PUSH1 0x00 |
||||||
|
269 DUP1 |
||||||
|
270 PUSH1 0x00 |
||||||
|
272 DUP5 |
||||||
|
273 MLOAD |
||||||
|
274 SWAP2 |
||||||
|
275 POP |
||||||
|
276 DUP4 |
||||||
|
277 DUP3 |
||||||
|
278 MUL |
||||||
|
279 SWAP1 |
||||||
|
280 POP |
||||||
|
281 PUSH1 0x00 |
||||||
|
283 DUP3 |
||||||
|
284 GT |
||||||
|
285 DUP1 |
||||||
|
286 ISZERO |
||||||
|
287 PUSH2 0x0129 |
||||||
|
290 JUMPI |
||||||
|
291 POP |
||||||
|
292 PUSH1 0x14 |
||||||
|
294 DUP3 |
||||||
|
295 GT |
||||||
|
296 ISZERO |
||||||
|
297 JUMPDEST |
||||||
|
298 ISZERO |
||||||
|
299 ISZERO |
||||||
|
300 PUSH2 0x0134 |
||||||
|
303 JUMPI |
||||||
|
304 PUSH1 0x00 |
||||||
|
306 DUP1 |
||||||
|
307 REVERT |
||||||
|
308 JUMPDEST |
||||||
|
309 DUP1 |
||||||
|
310 PUSH1 0x01 |
||||||
|
312 PUSH1 0x00 |
||||||
|
314 CALLER |
||||||
|
315 PUSH20 0xffffffffffffffffffffffffffffffffffffffff |
||||||
|
336 AND |
||||||
|
337 PUSH20 0xffffffffffffffffffffffffffffffffffffffff |
||||||
|
358 AND |
||||||
|
359 DUP2 |
||||||
|
360 MSTORE |
||||||
|
361 PUSH1 0x20 |
||||||
|
363 ADD |
||||||
|
364 SWAP1 |
||||||
|
365 DUP2 |
||||||
|
366 MSTORE |
||||||
|
367 PUSH1 0x20 |
||||||
|
369 ADD |
||||||
|
370 PUSH1 0x00 |
||||||
|
372 SHA3 |
||||||
|
373 PUSH1 0x00 |
||||||
|
375 DUP3 |
||||||
|
376 DUP3 |
||||||
|
377 SLOAD |
||||||
|
378 SUB |
||||||
|
379 SWAP3 |
||||||
|
380 POP |
||||||
|
381 POP |
||||||
|
382 DUP2 |
||||||
|
383 SWAP1 |
||||||
|
384 SSTORE |
||||||
|
385 POP |
||||||
|
386 PUSH1 0x01 |
||||||
|
388 SWAP3 |
||||||
|
389 POP |
||||||
|
390 POP |
||||||
|
391 POP |
||||||
|
392 SWAP3 |
||||||
|
393 SWAP2 |
||||||
|
394 POP |
||||||
|
395 POP |
||||||
|
396 JUMP |
||||||
|
397 STOP |
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@ |
|||||||
|
{"error": null, "issues": [{"address": 158, "contract": "Unknown", "debug": "<DEBUG-DATA>", "description": "A possible integer overflow exists in the function `_function_0x83f12fec`.\nThe addition or multiplication may result in a value higher than the maximum representable integer.", "function": "_function_0x83f12fec", "title": "Integer Overflow", "type": "Warning"}, {"address": 278, "contract": "Unknown", "debug": "<DEBUG-DATA>", "description": "A possible integer overflow exists in the function `_function_0x83f12fec`.\nThe addition or multiplication may result in a value higher than the maximum representable integer.", "function": "_function_0x83f12fec", "title": "Integer Overflow", "type": "Warning"}, {"address": 378, "contract": "Unknown", "debug": "<DEBUG-DATA>", "description": "A possible integer underflow exists in the function `_function_0x83f12fec`.\nThe subtraction may result in a value < 0.", "function": "_function_0x83f12fec", "title": "Integer Underflow", "type": "Warning"}], "success": true} |
@ -0,0 +1,37 @@ |
|||||||
|
# Analysis results for test-filename.sol |
||||||
|
|
||||||
|
## Integer Overflow |
||||||
|
|
||||||
|
- Type: Warning |
||||||
|
- Contract: Unknown |
||||||
|
- Function name: `_function_0x83f12fec` |
||||||
|
- PC address: 158 |
||||||
|
|
||||||
|
### Description |
||||||
|
|
||||||
|
A possible integer overflow exists in the function `_function_0x83f12fec`. |
||||||
|
The addition or multiplication may result in a value higher than the maximum representable integer. |
||||||
|
|
||||||
|
## Integer Overflow |
||||||
|
|
||||||
|
- Type: Warning |
||||||
|
- Contract: Unknown |
||||||
|
- Function name: `_function_0x83f12fec` |
||||||
|
- PC address: 278 |
||||||
|
|
||||||
|
### Description |
||||||
|
|
||||||
|
A possible integer overflow exists in the function `_function_0x83f12fec`. |
||||||
|
The addition or multiplication may result in a value higher than the maximum representable integer. |
||||||
|
|
||||||
|
## Integer Underflow |
||||||
|
|
||||||
|
- Type: Warning |
||||||
|
- Contract: Unknown |
||||||
|
- Function name: `_function_0x83f12fec` |
||||||
|
- PC address: 378 |
||||||
|
|
||||||
|
### Description |
||||||
|
|
||||||
|
A possible integer underflow exists in the function `_function_0x83f12fec`. |
||||||
|
The subtraction may result in a value < 0. |
@ -0,0 +1,27 @@ |
|||||||
|
==== Integer Overflow ==== |
||||||
|
Type: Warning |
||||||
|
Contract: Unknown |
||||||
|
Function name: _function_0x83f12fec |
||||||
|
PC address: 158 |
||||||
|
A possible integer overflow exists in the function `_function_0x83f12fec`. |
||||||
|
The addition or multiplication may result in a value higher than the maximum representable integer. |
||||||
|
-------------------- |
||||||
|
|
||||||
|
==== Integer Overflow ==== |
||||||
|
Type: Warning |
||||||
|
Contract: Unknown |
||||||
|
Function name: _function_0x83f12fec |
||||||
|
PC address: 278 |
||||||
|
A possible integer overflow exists in the function `_function_0x83f12fec`. |
||||||
|
The addition or multiplication may result in a value higher than the maximum representable integer. |
||||||
|
-------------------- |
||||||
|
|
||||||
|
==== Integer Underflow ==== |
||||||
|
Type: Warning |
||||||
|
Contract: Unknown |
||||||
|
Function name: _function_0x83f12fec |
||||||
|
PC address: 378 |
||||||
|
A possible integer underflow exists in the function `_function_0x83f12fec`. |
||||||
|
The subtraction may result in a value < 0. |
||||||
|
-------------------- |
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue