Transaction Hash:
Block:
4241000 at Sep-05-2017 12:26:29 PM +UTC
Transaction Fee:
0.0034936 ETH
$8.73
Gas Used:
69,872 Gas / 50 Gwei
Emitted Events:
20 |
AVTSale.0x0000000000000000000000000000000000000000000000000000000000000000( 0x0000000000000000000000000000000000000000000000000000000000000000, 0x00000000000000000000000009884af62d26d21442f130a1fca4915958d40e0f, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000003782dace9d900000, 0000000000000000000000000000000000000000000000000000000000000040, 0000000000000000000000000000000000000000000000000000000000000000 )
|
21 |
DSToken.0xa9059cbb00000000000000000000000000000000000000000000000000000000( 0xa9059cbb00000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000008b7b6c61238088593bf75eec8fbf58d0a615d30c, 0x00000000000000000000000009884af62d26d21442f130a1fca4915958d40e0f, 0x000000000000000000000000000000000000000000000013f306a2409fc00000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000004000000000, 00000000000000000000000000000000000000000000000000000044a9059cbb, 00000000000000000000000009884af62d26d21442f130a1fca4915958d40e0f, 000000000000000000000000000000000000000000000013f306a2409fc00000 )
|
22 |
DSToken.Transfer( from=[Receiver] AVTSale, to=[Sender] 0x09884af62d26d21442f130a1fca4915958d40e0f, value=368000000000000000000 )
|
23 |
MultiSigWallet.Deposit( sender=[Receiver] AVTSale, value=4000000000000000000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x035a4019...Ed036d680 | (Aventus: MultiSig) | 29,141.4025122297 Eth | 29,145.4025122297 Eth | 4 | |
0x09884aF6...958D40E0f |
4.03596845 Eth
Nonce: 7
|
0.03247485 Eth
Nonce: 8
| 4.0034936 | ||
0x0d88eD6E...5571e824F | |||||
0x8b7B6C61...0a615d30c | |||||
0xD284B7C8...a558d48Bd | |||||
0xEA674fdD...16B898ec8
Miner
| (Ethermine) | 548.555119535757593101 Eth | 548.558613135757593101 Eth | 0.0034936 |
Execution Trace
ETH 4
AVTSale.CALL( )
-
Whitelist.accepted( 0x09884aF62d26D21442f130a1fCa4915958D40E0f ) => ( 4000000000000000000 )
-
Whitelist.accept( a=0x09884aF62d26D21442f130a1fCa4915958D40E0f, amount=0 )
-
DSToken.transfer( dst=0x09884aF62d26D21442f130a1fCa4915958D40E0f, wad=368000000000000000000 ) => ( True )
- ETH 4
MultiSigWallet.CALL( )
[AVTSale (ln:500)]
getRateLimit[AVTSale (ln:501)]
time[AVTSale (ln:514)]
accepted[AVTSale (ln:522)]
accept[AVTSale (ln:526)]
mul[AVTSale (ln:503)]
add[AVTSale (ln:505)]
add[AVTSale (ln:507)]
transfer[AVTSale (ln:509)]
exec[AVTSale (ln:510)]
File 1 of 4: AVTSale
File 2 of 4: DSToken
File 3 of 4: MultiSigWallet
File 4 of 4: Whitelist
contract Whitelist { address public owner; address public sale; mapping (address => uint) public accepted; function Whitelist() { owner = msg.sender; } // Amount in WEI i.e. amount = 1 means 1 WEI function accept(address a, uint amount) { assert (msg.sender == owner || msg.sender == sale); accepted[a] = amount; } function setSale(address sale_) { assert (msg.sender == owner); sale = sale_; } } contract DSExec { function tryExec( address target, bytes calldata, uint value) internal returns (bool call_ret) { return target.call.value(value)(calldata); } function exec( address target, bytes calldata, uint value) internal { if(!tryExec(target, calldata, value)) { throw; } } // Convenience aliases function exec( address t, bytes c ) internal { exec(t, c, 0); } function exec( address t, uint256 v ) internal { bytes memory c; exec(t, c, v); } function tryExec( address t, bytes c ) internal returns (bool) { return tryExec(t, c, 0); } function tryExec( address t, uint256 v ) internal returns (bool) { bytes memory c; return tryExec(t, c, v); } } contract DSAuthority { function canCall( address src, address dst, bytes4 sig ) constant returns (bool); } contract DSAuthEvents { event LogSetAuthority (address indexed authority); event LogSetOwner (address indexed owner); } contract DSAuth is DSAuthEvents { DSAuthority public authority; address public owner; function DSAuth() { owner = msg.sender; LogSetOwner(msg.sender); } function setOwner(address owner_) auth { owner = owner_; LogSetOwner(owner); } function setAuthority(DSAuthority authority_) auth { authority = authority_; LogSetAuthority(authority); } modifier auth { assert(isAuthorized(msg.sender, msg.sig)); _; } function isAuthorized(address src, bytes4 sig) internal returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; } else if (authority == DSAuthority(0)) { return false; } else { return authority.canCall(src, this, sig); } } function assert(bool x) internal { if (!x) throw; } } contract DSNote { event LogNote( bytes4 indexed sig, address indexed guy, bytes32 indexed foo, bytes32 indexed bar, uint wad, bytes fax ) anonymous; modifier note { bytes32 foo; bytes32 bar; assembly { foo := calldataload(4) bar := calldataload(36) } LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data); _; } } contract DSMath { /* standard uint256 functions */ function add(uint256 x, uint256 y) constant internal returns (uint256 z) { assert((z = x + y) >= x); } function sub(uint256 x, uint256 y) constant internal returns (uint256 z) { assert((z = x - y) <= x); } function mul(uint256 x, uint256 y) constant internal returns (uint256 z) { z = x * y; assert(x == 0 || z / x == y); } function div(uint256 x, uint256 y) constant internal returns (uint256 z) { z = x / y; } function min(uint256 x, uint256 y) constant internal returns (uint256 z) { return x <= y ? x : y; } function max(uint256 x, uint256 y) constant internal returns (uint256 z) { return x >= y ? x : y; } /* uint128 functions (h is for half) */ function hadd(uint128 x, uint128 y) constant internal returns (uint128 z) { assert((z = x + y) >= x); } function hsub(uint128 x, uint128 y) constant internal returns (uint128 z) { assert((z = x - y) <= x); } function hmul(uint128 x, uint128 y) constant internal returns (uint128 z) { z = x * y; assert(x == 0 || z / x == y); } function hdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { z = x / y; } function hmin(uint128 x, uint128 y) constant internal returns (uint128 z) { return x <= y ? x : y; } function hmax(uint128 x, uint128 y) constant internal returns (uint128 z) { return x >= y ? x : y; } /* int256 functions */ function imin(int256 x, int256 y) constant internal returns (int256 z) { return x <= y ? x : y; } function imax(int256 x, int256 y) constant internal returns (int256 z) { return x >= y ? x : y; } /* WAD math */ uint128 constant WAD = 10 ** 18; function wadd(uint128 x, uint128 y) constant internal returns (uint128) { return hadd(x, y); } function wsub(uint128 x, uint128 y) constant internal returns (uint128) { return hsub(x, y); } function wmul(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * y + WAD / 2) / WAD); } function wdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * WAD + y / 2) / y); } function wmin(uint128 x, uint128 y) constant internal returns (uint128) { return hmin(x, y); } function wmax(uint128 x, uint128 y) constant internal returns (uint128) { return hmax(x, y); } /* RAY math */ uint128 constant RAY = 10 ** 27; function radd(uint128 x, uint128 y) constant internal returns (uint128) { return hadd(x, y); } function rsub(uint128 x, uint128 y) constant internal returns (uint128) { return hsub(x, y); } function rmul(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * y + RAY / 2) / RAY); } function rdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * RAY + y / 2) / y); } function rpow(uint128 x, uint64 n) constant internal returns (uint128 z) { // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } function rmin(uint128 x, uint128 y) constant internal returns (uint128) { return hmin(x, y); } function rmax(uint128 x, uint128 y) constant internal returns (uint128) { return hmax(x, y); } function cast(uint256 x) constant internal returns (uint128 z) { assert((z = uint128(x)) == x); } } contract DSStop is DSAuth, DSNote { bool public stopped; modifier stoppable { assert (!stopped); _; } function stop() auth note { stopped = true; } function start() auth note { stopped = false; } } contract ERC20 { function totalSupply() constant returns (uint supply); function balanceOf( address who ) constant returns (uint value); function allowance( address owner, address spender ) constant returns (uint _allowance); function transfer( address to, uint value) returns (bool ok); function transferFrom( address from, address to, uint value) returns (bool ok); function approve( address spender, uint value ) returns (bool ok); event Transfer( address indexed from, address indexed to, uint value); event Approval( address indexed owner, address indexed spender, uint value); } contract DSTokenBase is ERC20, DSMath { uint256 _supply; mapping (address => uint256) _balances; mapping (address => mapping (address => uint256)) _approvals; function DSTokenBase(uint256 supply) { _balances[msg.sender] = supply; _supply = supply; } function totalSupply() constant returns (uint256) { return _supply; } function balanceOf(address src) constant returns (uint256) { return _balances[src]; } function allowance(address src, address guy) constant returns (uint256) { return _approvals[src][guy]; } function transfer(address dst, uint wad) returns (bool) { assert(_balances[msg.sender] >= wad); _balances[msg.sender] = sub(_balances[msg.sender], wad); _balances[dst] = add(_balances[dst], wad); Transfer(msg.sender, dst, wad); return true; } function transferFrom(address src, address dst, uint wad) returns (bool) { assert(_balances[src] >= wad); assert(_approvals[src][msg.sender] >= wad); _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad); _balances[src] = sub(_balances[src], wad); _balances[dst] = add(_balances[dst], wad); Transfer(src, dst, wad); return true; } function approve(address guy, uint256 wad) returns (bool) { _approvals[msg.sender][guy] = wad; Approval(msg.sender, guy, wad); return true; } } contract DSToken is DSTokenBase(0), DSStop { bytes32 public symbol; uint256 public decimals = 18; // standard token precision. override to customize function DSToken(bytes32 symbol_) { symbol = symbol_; } function transfer(address dst, uint wad) stoppable note returns (bool) { return super.transfer(dst, wad); } function transferFrom( address src, address dst, uint wad ) stoppable note returns (bool) { return super.transferFrom(src, dst, wad); } function approve(address guy, uint wad) stoppable note returns (bool) { return super.approve(guy, wad); } function push(address dst, uint128 wad) returns (bool) { return transfer(dst, wad); } function pull(address src, uint128 wad) returns (bool) { return transferFrom(src, msg.sender, wad); } function mint(uint128 wad) auth stoppable note { _balances[msg.sender] = add(_balances[msg.sender], wad); _supply = add(_supply, wad); } function burn(uint128 wad) auth stoppable note { _balances[msg.sender] = sub(_balances[msg.sender], wad); _supply = sub(_supply, wad); } // Optional token name bytes32 public name = ""; function setName(bytes32 name_) auth { name = name_; } } contract AVTSale is DSMath, DSNote, DSExec { Whitelist public whitelist; DSToken public avt; // AVT PRICES (ETH/AVT) uint public constant PRIVATE_SALE_PRICE = 110; uint public constant WHITELIST_SALE_PRICE = 92; uint public constant PUBLIC_SALE_PRICE = 92; uint128 public constant CROWDSALE_SUPPLY = 10000000 ether; uint public constant LIQUID_TOKENS = 2500000 ether; uint public constant ILLIQUID_TOKENS = 1500000 ether; // PURCHASE LIMITS uint public constant PRIVATE_SALE_LIMIT = 3000000 ether; uint public constant WHITELIST_SALE_LIMIT = 5000000 ether; uint public constant PUBLIC_SALE_LIMIT = 6000000 ether; uint public privateStart; uint public whitelistStart; uint public publicStart; uint public publicEnd; address public aventus; address public privateBuyer; uint public sold; function AVTSale(uint privateStart_, address aventus_, address privateBuyer_, Whitelist whitelist_) { avt = new DSToken("AVT"); aventus = aventus_; privateBuyer = privateBuyer_; whitelist = whitelist_; privateStart = privateStart_; whitelistStart = privateStart + 2 days; publicStart = whitelistStart + 1 days; publicEnd = publicStart + 7 days; avt.mint(CROWDSALE_SUPPLY); avt.setOwner(aventus); avt.transfer(aventus, LIQUID_TOKENS); } // overrideable for easy testing function time() constant returns (uint) { return now; } function() payable note { var (rate, limit) = getRateLimit(); uint prize = mul(msg.value, rate); assert(add(sold, prize) <= limit); sold = add(sold, prize); avt.transfer(msg.sender, prize); exec(aventus, msg.value); // send the ETH to multisig } function getRateLimit() private constant returns (uint, uint) { uint t = time(); if (t >= privateStart && t < whitelistStart) { assert (msg.sender == privateBuyer); return (PRIVATE_SALE_PRICE, PRIVATE_SALE_LIMIT); } else if (t >= whitelistStart && t < publicStart) { uint allowance = whitelist.accepted(msg.sender); assert (allowance >= msg.value); whitelist.accept(msg.sender, allowance - msg.value); return (WHITELIST_SALE_PRICE, WHITELIST_SALE_LIMIT); } else if (t >= publicStart && t < publicEnd) return (PUBLIC_SALE_PRICE, PUBLIC_SALE_LIMIT); throw; } function claim() { assert(time() >= publicStart + 1 years); avt.transfer(aventus, ILLIQUID_TOKENS); } }
File 2 of 4: DSToken
contract DSAuthority { function canCall( address src, address dst, bytes4 sig ) constant returns (bool); } contract DSAuthEvents { event LogSetAuthority (address indexed authority); event LogSetOwner (address indexed owner); } contract DSAuth is DSAuthEvents { DSAuthority public authority; address public owner; function DSAuth() { owner = msg.sender; LogSetOwner(msg.sender); } function setOwner(address owner_) auth { owner = owner_; LogSetOwner(owner); } function setAuthority(DSAuthority authority_) auth { authority = authority_; LogSetAuthority(authority); } modifier auth { assert(isAuthorized(msg.sender, msg.sig)); _; } function isAuthorized(address src, bytes4 sig) internal returns (bool) { if (src == address(this)) { return true; } else if (src == owner) { return true; } else if (authority == DSAuthority(0)) { return false; } else { return authority.canCall(src, this, sig); } } function assert(bool x) internal { if (!x) throw; } } contract DSNote { event LogNote( bytes4 indexed sig, address indexed guy, bytes32 indexed foo, bytes32 indexed bar, uint wad, bytes fax ) anonymous; modifier note { bytes32 foo; bytes32 bar; assembly { foo := calldataload(4) bar := calldataload(36) } LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data); _; } } contract DSStop is DSAuth, DSNote { bool public stopped; modifier stoppable { assert (!stopped); _; } function stop() auth note { stopped = true; } function start() auth note { stopped = false; } } contract ERC20 { function totalSupply() constant returns (uint supply); function balanceOf( address who ) constant returns (uint value); function allowance( address owner, address spender ) constant returns (uint _allowance); function transfer( address to, uint value) returns (bool ok); function transferFrom( address from, address to, uint value) returns (bool ok); function approve( address spender, uint value ) returns (bool ok); event Transfer( address indexed from, address indexed to, uint value); event Approval( address indexed owner, address indexed spender, uint value); } contract DSMath { /* standard uint256 functions */ function add(uint256 x, uint256 y) constant internal returns (uint256 z) { assert((z = x + y) >= x); } function sub(uint256 x, uint256 y) constant internal returns (uint256 z) { assert((z = x - y) <= x); } function mul(uint256 x, uint256 y) constant internal returns (uint256 z) { z = x * y; assert(x == 0 || z / x == y); } function div(uint256 x, uint256 y) constant internal returns (uint256 z) { z = x / y; } function min(uint256 x, uint256 y) constant internal returns (uint256 z) { return x <= y ? x : y; } function max(uint256 x, uint256 y) constant internal returns (uint256 z) { return x >= y ? x : y; } /* uint128 functions (h is for half) */ function hadd(uint128 x, uint128 y) constant internal returns (uint128 z) { assert((z = x + y) >= x); } function hsub(uint128 x, uint128 y) constant internal returns (uint128 z) { assert((z = x - y) <= x); } function hmul(uint128 x, uint128 y) constant internal returns (uint128 z) { z = x * y; assert(x == 0 || z / x == y); } function hdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { z = x / y; } function hmin(uint128 x, uint128 y) constant internal returns (uint128 z) { return x <= y ? x : y; } function hmax(uint128 x, uint128 y) constant internal returns (uint128 z) { return x >= y ? x : y; } /* int256 functions */ function imin(int256 x, int256 y) constant internal returns (int256 z) { return x <= y ? x : y; } function imax(int256 x, int256 y) constant internal returns (int256 z) { return x >= y ? x : y; } /* WAD math */ uint128 constant WAD = 10 ** 18; function wadd(uint128 x, uint128 y) constant internal returns (uint128) { return hadd(x, y); } function wsub(uint128 x, uint128 y) constant internal returns (uint128) { return hsub(x, y); } function wmul(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * y + WAD / 2) / WAD); } function wdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * WAD + y / 2) / y); } function wmin(uint128 x, uint128 y) constant internal returns (uint128) { return hmin(x, y); } function wmax(uint128 x, uint128 y) constant internal returns (uint128) { return hmax(x, y); } /* RAY math */ uint128 constant RAY = 10 ** 27; function radd(uint128 x, uint128 y) constant internal returns (uint128) { return hadd(x, y); } function rsub(uint128 x, uint128 y) constant internal returns (uint128) { return hsub(x, y); } function rmul(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * y + RAY / 2) / RAY); } function rdiv(uint128 x, uint128 y) constant internal returns (uint128 z) { z = cast((uint256(x) * RAY + y / 2) / y); } function rpow(uint128 x, uint64 n) constant internal returns (uint128 z) { // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } function rmin(uint128 x, uint128 y) constant internal returns (uint128) { return hmin(x, y); } function rmax(uint128 x, uint128 y) constant internal returns (uint128) { return hmax(x, y); } function cast(uint256 x) constant internal returns (uint128 z) { assert((z = uint128(x)) == x); } } contract DSTokenBase is ERC20, DSMath { uint256 _supply; mapping (address => uint256) _balances; mapping (address => mapping (address => uint256)) _approvals; function DSTokenBase(uint256 supply) { _balances[msg.sender] = supply; _supply = supply; } function totalSupply() constant returns (uint256) { return _supply; } function balanceOf(address src) constant returns (uint256) { return _balances[src]; } function allowance(address src, address guy) constant returns (uint256) { return _approvals[src][guy]; } function transfer(address dst, uint wad) returns (bool) { assert(_balances[msg.sender] >= wad); _balances[msg.sender] = sub(_balances[msg.sender], wad); _balances[dst] = add(_balances[dst], wad); Transfer(msg.sender, dst, wad); return true; } function transferFrom(address src, address dst, uint wad) returns (bool) { assert(_balances[src] >= wad); assert(_approvals[src][msg.sender] >= wad); _approvals[src][msg.sender] = sub(_approvals[src][msg.sender], wad); _balances[src] = sub(_balances[src], wad); _balances[dst] = add(_balances[dst], wad); Transfer(src, dst, wad); return true; } function approve(address guy, uint256 wad) returns (bool) { _approvals[msg.sender][guy] = wad; Approval(msg.sender, guy, wad); return true; } } contract DSToken is DSTokenBase(0), DSStop { bytes32 public symbol; uint256 public decimals = 18; // standard token precision. override to customize function DSToken(bytes32 symbol_) { symbol = symbol_; } function transfer(address dst, uint wad) stoppable note returns (bool) { return super.transfer(dst, wad); } function transferFrom( address src, address dst, uint wad ) stoppable note returns (bool) { return super.transferFrom(src, dst, wad); } function approve(address guy, uint wad) stoppable note returns (bool) { return super.approve(guy, wad); } function push(address dst, uint128 wad) returns (bool) { return transfer(dst, wad); } function pull(address src, uint128 wad) returns (bool) { return transferFrom(src, msg.sender, wad); } function mint(uint128 wad) auth stoppable note { _balances[msg.sender] = add(_balances[msg.sender], wad); _supply = add(_supply, wad); } function burn(uint128 wad) auth stoppable note { _balances[msg.sender] = sub(_balances[msg.sender], wad); _supply = sub(_supply, wad); } // Optional token name bytes32 public name = ""; function setName(bytes32 name_) auth { name = name_; } }
File 3 of 4: MultiSigWallet
pragma solidity ^0.4.4; /// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution. /// @author Stefan George - <[email protected]> contract MultiSigWallet { uint constant public MAX_OWNER_COUNT = 50; event Confirmation(address indexed sender, uint indexed transactionId); event Revocation(address indexed sender, uint indexed transactionId); event Submission(uint indexed transactionId); event Execution(uint indexed transactionId); event ExecutionFailure(uint indexed transactionId); event Deposit(address indexed sender, uint value); event OwnerAddition(address indexed owner); event OwnerRemoval(address indexed owner); event RequirementChange(uint required); mapping (uint => Transaction) public transactions; mapping (uint => mapping (address => bool)) public confirmations; mapping (address => bool) public isOwner; address[] public owners; uint public required; uint public transactionCount; struct Transaction { address destination; uint value; bytes data; bool executed; } modifier onlyWallet() { if (msg.sender != address(this)) throw; _; } modifier ownerDoesNotExist(address owner) { if (isOwner[owner]) throw; _; } modifier ownerExists(address owner) { if (!isOwner[owner]) throw; _; } modifier transactionExists(uint transactionId) { if (transactions[transactionId].destination == 0) throw; _; } modifier confirmed(uint transactionId, address owner) { if (!confirmations[transactionId][owner]) throw; _; } modifier notConfirmed(uint transactionId, address owner) { if (confirmations[transactionId][owner]) throw; _; } modifier notExecuted(uint transactionId) { if (transactions[transactionId].executed) throw; _; } modifier notNull(address _address) { if (_address == 0) throw; _; } modifier validRequirement(uint ownerCount, uint _required) { if ( ownerCount > MAX_OWNER_COUNT || _required > ownerCount || _required == 0 || ownerCount == 0) throw; _; } /// @dev Fallback function allows to deposit ether. function() payable { if (msg.value > 0) Deposit(msg.sender, msg.value); } /* * Public functions */ /// @dev Contract constructor sets initial owners and required number of confirmations. /// @param _owners List of initial owners. /// @param _required Number of required confirmations. function MultiSigWallet(address[] _owners, uint _required) public validRequirement(_owners.length, _required) { for (uint i=0; i<_owners.length; i++) { if (isOwner[_owners[i]] || _owners[i] == 0) throw; isOwner[_owners[i]] = true; } owners = _owners; required = _required; } /// @dev Allows to add a new owner. Transaction has to be sent by wallet. /// @param owner Address of new owner. function addOwner(address owner) public onlyWallet ownerDoesNotExist(owner) notNull(owner) validRequirement(owners.length + 1, required) { isOwner[owner] = true; owners.push(owner); OwnerAddition(owner); } /// @dev Allows to remove an owner. Transaction has to be sent by wallet. /// @param owner Address of owner. function removeOwner(address owner) public onlyWallet ownerExists(owner) { isOwner[owner] = false; for (uint i=0; i<owners.length - 1; i++) if (owners[i] == owner) { owners[i] = owners[owners.length - 1]; break; } owners.length -= 1; if (required > owners.length) changeRequirement(owners.length); OwnerRemoval(owner); } /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet. /// @param owner Address of owner to be replaced. /// @param owner Address of new owner. function replaceOwner(address owner, address newOwner) public onlyWallet ownerExists(owner) ownerDoesNotExist(newOwner) { for (uint i=0; i<owners.length; i++) if (owners[i] == owner) { owners[i] = newOwner; break; } isOwner[owner] = false; isOwner[newOwner] = true; OwnerRemoval(owner); OwnerAddition(newOwner); } /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet. /// @param _required Number of required confirmations. function changeRequirement(uint _required) public onlyWallet validRequirement(owners.length, _required) { required = _required; RequirementChange(_required); } /// @dev Allows an owner to submit and confirm a transaction. /// @param destination Transaction target address. /// @param value Transaction ether value. /// @param data Transaction data payload. /// @return Returns transaction ID. function submitTransaction(address destination, uint value, bytes data) public returns (uint transactionId) { transactionId = addTransaction(destination, value, data); confirmTransaction(transactionId); } /// @dev Allows an owner to confirm a transaction. /// @param transactionId Transaction ID. function confirmTransaction(uint transactionId) public ownerExists(msg.sender) transactionExists(transactionId) notConfirmed(transactionId, msg.sender) { confirmations[transactionId][msg.sender] = true; Confirmation(msg.sender, transactionId); executeTransaction(transactionId); } /// @dev Allows an owner to revoke a confirmation for a transaction. /// @param transactionId Transaction ID. function revokeConfirmation(uint transactionId) public ownerExists(msg.sender) confirmed(transactionId, msg.sender) notExecuted(transactionId) { confirmations[transactionId][msg.sender] = false; Revocation(msg.sender, transactionId); } /// @dev Allows anyone to execute a confirmed transaction. /// @param transactionId Transaction ID. function executeTransaction(uint transactionId) public notExecuted(transactionId) { if (isConfirmed(transactionId)) { Transaction tx = transactions[transactionId]; tx.executed = true; if (tx.destination.call.value(tx.value)(tx.data)) Execution(transactionId); else { ExecutionFailure(transactionId); tx.executed = false; } } } /// @dev Returns the confirmation status of a transaction. /// @param transactionId Transaction ID. /// @return Confirmation status. function isConfirmed(uint transactionId) public constant returns (bool) { uint count = 0; for (uint i=0; i<owners.length; i++) { if (confirmations[transactionId][owners[i]]) count += 1; if (count == required) return true; } } /* * Internal functions */ /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet. /// @param destination Transaction target address. /// @param value Transaction ether value. /// @param data Transaction data payload. /// @return Returns transaction ID. function addTransaction(address destination, uint value, bytes data) internal notNull(destination) returns (uint transactionId) { transactionId = transactionCount; transactions[transactionId] = Transaction({ destination: destination, value: value, data: data, executed: false }); transactionCount += 1; Submission(transactionId); } /* * Web3 call functions */ /// @dev Returns number of confirmations of a transaction. /// @param transactionId Transaction ID. /// @return Number of confirmations. function getConfirmationCount(uint transactionId) public constant returns (uint count) { for (uint i=0; i<owners.length; i++) if (confirmations[transactionId][owners[i]]) count += 1; } /// @dev Returns total number of transactions after filers are applied. /// @param pending Include pending transactions. /// @param executed Include executed transactions. /// @return Total number of transactions after filters are applied. function getTransactionCount(bool pending, bool executed) public constant returns (uint count) { for (uint i=0; i<transactionCount; i++) if ( pending && !transactions[i].executed || executed && transactions[i].executed) count += 1; } /// @dev Returns list of owners. /// @return List of owner addresses. function getOwners() public constant returns (address[]) { return owners; } /// @dev Returns array with owner addresses, which confirmed transaction. /// @param transactionId Transaction ID. /// @return Returns array of owner addresses. function getConfirmations(uint transactionId) public constant returns (address[] _confirmations) { address[] memory confirmationsTemp = new address[](owners.length); uint count = 0; uint i; for (i=0; i<owners.length; i++) if (confirmations[transactionId][owners[i]]) { confirmationsTemp[count] = owners[i]; count += 1; } _confirmations = new address[](count); for (i=0; i<count; i++) _confirmations[i] = confirmationsTemp[i]; } /// @dev Returns list of transaction IDs in defined range. /// @param from Index start position of transaction array. /// @param to Index end position of transaction array. /// @param pending Include pending transactions. /// @param executed Include executed transactions. /// @return Returns array of transaction IDs. function getTransactionIds(uint from, uint to, bool pending, bool executed) public constant returns (uint[] _transactionIds) { uint[] memory transactionIdsTemp = new uint[](transactionCount); uint count = 0; uint i; for (i=0; i<transactionCount; i++) if ( pending && !transactions[i].executed || executed && transactions[i].executed) { transactionIdsTemp[count] = i; count += 1; } _transactionIds = new uint[](to - from); for (i=from; i<to; i++) _transactionIds[i - from] = transactionIdsTemp[i]; } }
File 4 of 4: Whitelist
contract Whitelist { address public owner; address public sale; mapping (address => uint) public accepted; function Whitelist() { owner = msg.sender; } // Amount in WEI i.e. amount = 1 means 1 WEI function accept(address a, uint amount) { assert (msg.sender == owner || msg.sender == sale); accepted[a] = amount; } function setSale(address sale_) { assert (msg.sender == owner); sale = sale_; } }