ETH Price: $2,065.97 (+2.13%)

Transaction Decoder

Block:
5535933 at May-01-2018 04:34:21 AM +UTC
Transaction Fee:
0.001155105 ETH $2.39
Gas Used:
33,003 Gas / 35 Gwei

Emitted Events:

5 MultiSigWallet.Deposit( sender=[Receiver] DAOstackPreSale, value=1500000000000000000 )
6 DAOstackPreSale.LogFundsReceived( _sender=[Sender] 0xe29968a79a4e8c2195a100b7bdcd52dd18f59f56, _amount=1500000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0xd3BA32dd...5423D8A6f 2,860.326708331181940327 Eth2,861.826708331181940327 Eth1.5
0xe29968a7...D18F59f56
2.123966277110453337 Eth
Nonce: 24
0.622811172110453337 Eth
Nonce: 25
1.501155105
(Ethermine)
690.266258244659805807 Eth690.267413349659805807 Eth0.001155105

Execution Trace

ETH 1.5 DAOstackPreSale.CALL( )
  • ETH 1.5 MultiSigWallet.CALL( )
    File 1 of 2: DAOstackPreSale
    pragma solidity ^0.4.21;
    
    
    /**
     * @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() public {
        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) public onlyOwner {
        require(newOwner != address(0));
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
      }
    
    }
    
    /**
     * @title Whitelist
     * @dev The Whitelist contract has a whitelist of addresses, and provides basic authorization control functions.
     * @dev This simplifies the implementation of "user permissions".
     */
    contract Whitelist is Ownable {
      mapping(address => bool) public whitelist;
    
      event WhitelistedAddressAdded(address addr);
      event WhitelistedAddressRemoved(address addr);
    
      /**
       * @dev Throws if called by any account that's not whitelisted.
       */
      modifier onlyWhitelisted() {
        require(whitelist[msg.sender]);
        _;
      }
    
      /**
       * @dev add an address to the whitelist
       * @param addr address
       * @return true if the address was added to the whitelist, false if the address was already in the whitelist
       */
      function addAddressToWhitelist(address addr) onlyOwner public returns(bool success) {
        if (!whitelist[addr]) {
          whitelist[addr] = true;
          emit WhitelistedAddressAdded(addr);
          success = true;
        }
      }
    
      /**
       * @dev add addresses to the whitelist
       * @param addrs addresses
       * @return true if at least one address was added to the whitelist,
       * false if all addresses were already in the whitelist
       */
      function addAddressesToWhitelist(address[] addrs) onlyOwner public returns(bool success) {
        for (uint256 i = 0; i < addrs.length; i++) {
          if (addAddressToWhitelist(addrs[i])) {
            success = true;
          }
        }
      }
    
      /**
       * @dev remove an address from the whitelist
       * @param addr address
       * @return true if the address was removed from the whitelist,
       * false if the address wasn't in the whitelist in the first place
       */
      function removeAddressFromWhitelist(address addr) onlyOwner public returns(bool success) {
        if (whitelist[addr]) {
          whitelist[addr] = false;
          emit WhitelistedAddressRemoved(addr);
          success = true;
        }
      }
    
      /**
       * @dev remove addresses from the whitelist
       * @param addrs addresses
       * @return true if at least one address was removed from the whitelist,
       * false if all addresses weren't in the whitelist in the first place
       */
      function removeAddressesFromWhitelist(address[] addrs) onlyOwner public returns(bool success) {
        for (uint256 i = 0; i < addrs.length; i++) {
          if (removeAddressFromWhitelist(addrs[i])) {
            success = true;
          }
        }
      }
    
    }
    
    
    /**
     * @title Pausable
     * @dev Base contract which allows children to implement an emergency stop mechanism.
     */
    contract Pausable is Ownable {
      event Pause();
      event Unpause();
    
      bool public paused = false;
    
    
      /**
       * @dev Modifier to make a function callable only when the contract is not paused.
       */
      modifier whenNotPaused() {
        require(!paused);
        _;
      }
    
      /**
       * @dev Modifier to make a function callable only when the contract is paused.
       */
      modifier whenPaused() {
        require(paused);
        _;
      }
    
      /**
       * @dev called by the owner to pause, triggers stopped state
       */
      function pause() onlyOwner whenNotPaused public {
        paused = true;
        emit Pause();
      }
    
      /**
       * @dev called by the owner to unpause, returns to normal state
       */
      function unpause() onlyOwner whenPaused public {
        paused = false;
        emit Unpause();
      }
    }
    
    contract BuyLimits {
        event LogLimitsChanged(uint _minBuy, uint _maxBuy);
    
        // Variables holding the min and max payment in wei
        uint public minBuy; // min buy in wei
        uint public maxBuy; // max buy in wei, 0 means no maximum
    
        /*
        ** Modifier, reverting if not within limits.
        */
        modifier isWithinLimits(uint _amount) {
            require(withinLimits(_amount));
            _;
        }
    
        /*
        ** @dev Constructor, define variable:
        */
        function BuyLimits(uint _min, uint  _max) public {
            _setLimits(_min, _max);
        }
    
        /*
        ** @dev Check TXs value is within limits:
        */
        function withinLimits(uint _value) public view returns(bool) {
            if (maxBuy != 0) {
                return (_value >= minBuy && _value <= maxBuy);
            }
            return (_value >= minBuy);
        }
    
        /*
        ** @dev set limits logic:
        ** @param _min set the minimum buy in wei
        ** @param _max set the maximum buy in wei, 0 indeicates no maximum
        */
        function _setLimits(uint _min, uint _max) internal {
            if (_max != 0) {
                require (_min <= _max); // Sanity Check
            }
            minBuy = _min;
            maxBuy = _max;
            emit LogLimitsChanged(_min, _max);
        }
    }
    
    
    /**
     * @title DAOstackPresale
     * @dev A contract to allow only whitelisted followers to participate in presale.
     */
    contract DAOstackPreSale is Pausable,BuyLimits,Whitelist {
        event LogFundsReceived(address indexed _sender, uint _amount);
    
        address public wallet;
    
        /**
        * @dev Constructor.
        * @param _wallet Address where the funds are transfered to
        * @param _minBuy Address where the funds are transfered to
        * @param _maxBuy Address where the funds are transfered to
        */
        function DAOstackPreSale(address _wallet, uint _minBuy, uint _maxBuy)
        public
        BuyLimits(_minBuy, _maxBuy)
        {
            // Set wallet:
            require(_wallet != address(0));
            wallet = _wallet;
        }
    
        /**
        * @dev Fallback, funds coming in are transfered to wallet
        */
        function () payable whenNotPaused onlyWhitelisted isWithinLimits(msg.value) external {
            wallet.transfer(msg.value);
            emit LogFundsReceived(msg.sender, msg.value);
        }
    
        /*
        ** @dev Drain function, in case of failure. Contract should not hold eth anyhow.
        */
        function drain() external {
            wallet.transfer((address(this)).balance);
        }
    
    }

    File 2 of 2: MultiSigWallet
    pragma solidity 0.4.4;
    
    
    /// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.
    /// @author Stefan George - <stefan.george@consensys.net>
    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];
        }
    }