ETH Price: $2,127.20 (+3.46%)

Transaction Decoder

Block:
4739380 at Dec-15-2017 10:44:51 PM +UTC
Transaction Fee:
0.00239496 ETH $5.09
Gas Used:
46,960 Gas / 51 Gwei

Account State Difference:

  Address   Before After State Difference Code
(F2Pool Old)
5,674.700110508897768187 Eth5,674.702505468897768187 Eth0.00239496
0xcbCC0F03...A7487b908
0xFBb1b73C...f520fBB98
(Bittrex)
720,064.018316997817134644 Eth
Nonce: 3284746
720,064.015922037817134644 Eth
Nonce: 3284747
0.00239496

Execution Trace

0xd1f8b47a4bba9d02589267aff5b2eba7b7042ef2.6ea056a9( )
  • Controller.sweeperOf( _token=0xcbCC0F036ED4788F63FC0fEE32873d6A7487b908 ) => ( 0xb2233FCEC42c588Ee71A594d9A25AA695345426c )
  • DefaultSweeper.sweep( _token=0xcbCC0F036ED4788F63FC0fEE32873d6A7487b908, _amount=382725655249 ) => ( True )
    • Controller.CALL( )
    • Controller.CALL( )
    • Controller.CALL( )
    • Controller.CALL( )
    • HumaniqToken.balanceOf( _owner=0xD1F8B47a4BBa9d02589267Aff5b2eBa7B7042Ef2 ) => ( balance=382725655249 )
    • HumaniqToken.transfer( _to=0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98, _value=382725655249 ) => ( success=True )
    • Controller.logSweep( from=0xD1F8B47a4BBa9d02589267Aff5b2eBa7B7042Ef2, to=0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98, token=0xcbCC0F036ED4788F63FC0fEE32873d6A7487b908, amount=382725655249 )
      File 1 of 3: HumaniqToken
      pragma solidity ^0.4.6;
      
      
      /**
       * Math operations with safety checks
       */
      contract SafeMath {
        function mul(uint a, uint b) internal returns (uint) {
          uint c = a * b;
          assert(a == 0 || c / a == b);
          return c;
        }
      
        function div(uint a, uint b) internal returns (uint) {
          assert(b > 0);
          uint c = a / b;
          assert(a == b * c + a % b);
          return c;
        }
      
        function sub(uint a, uint b) internal returns (uint) {
          assert(b <= a);
          return a - b;
        }
      
        function add(uint a, uint b) internal returns (uint) {
          uint c = a + b;
          assert(c >= a);
          return c;
        }
      
        function assert(bool assertion) internal {
          if (!assertion) {
            throw;
          }
        }
      }
      
      
      /// Implements ERC 20 Token standard: https://github.com/ethereum/EIPs/issues/20
      /// @title Abstract token contract - Functions to be implemented by token contracts.
      contract AbstractToken {
          // This is not an abstract function, because solc won't recognize generated getter functions for public variables as functions
          function totalSupply() constant returns (uint256 supply) {}
          function balanceOf(address owner) constant returns (uint256 balance);
          function transfer(address to, uint256 value) returns (bool success);
          function transferFrom(address from, address to, uint256 value) returns (bool success);
          function approve(address spender, uint256 value) returns (bool success);
          function allowance(address owner, address spender) constant returns (uint256 remaining);
      
          event Transfer(address indexed from, address indexed to, uint256 value);
          event Approval(address indexed owner, address indexed spender, uint256 value);
          event Issuance(address indexed to, uint256 value);
      }
      
      
      contract StandardToken is AbstractToken {
      
          /*
           *  Data structures
           */
          mapping (address => uint256) balances;
          mapping (address => mapping (address => uint256)) allowed;
          uint256 public totalSupply;
      
          /*
           *  Read and write storage functions
           */
          /// @dev Transfers sender's tokens to a given address. Returns success.
          /// @param _to Address of token receiver.
          /// @param _value Number of tokens to transfer.
          function transfer(address _to, uint256 _value) returns (bool success) {
              if (balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
                  balances[msg.sender] -= _value;
                  balances[_to] += _value;
                  Transfer(msg.sender, _to, _value);
                  return true;
              }
              else {
                  return false;
              }
          }
      
          /// @dev Allows allowed third party to transfer tokens from one address to another. Returns success.
          /// @param _from Address from where tokens are withdrawn.
          /// @param _to Address to where tokens are sent.
          /// @param _value Number of tokens to transfer.
          function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
            if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
                  balances[_to] += _value;
                  balances[_from] -= _value;
                  allowed[_from][msg.sender] -= _value;
                  Transfer(_from, _to, _value);
                  return true;
              }
              else {
                  return false;
              }
          }
      
          /// @dev Returns number of tokens owned by given address.
          /// @param _owner Address of token owner.
          function balanceOf(address _owner) constant returns (uint256 balance) {
              return balances[_owner];
          }
      
          /// @dev Sets approved amount of tokens for spender. Returns success.
          /// @param _spender Address of allowed account.
          /// @param _value Number of approved tokens.
          function approve(address _spender, uint256 _value) returns (bool success) {
              allowed[msg.sender][_spender] = _value;
              Approval(msg.sender, _spender, _value);
              return true;
          }
      
          /*
           * Read storage functions
           */
          /// @dev Returns number of allowed tokens for given address.
          /// @param _owner Address of token owner.
          /// @param _spender Address of token spender.
          function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
            return allowed[_owner][_spender];
          }
      
      }
      
      
      /// @title Token contract - Implements Standard Token Interface with HumaniQ features.
      /// @author Evgeny Yurtaev - <evgeny@etherionlab.com>
      /// @author Alexey Bashlykov - <alexey@etherionlab.com>
      contract HumaniqToken is StandardToken, SafeMath {
      
          /*
           * External contracts
           */
          address public minter;
      
          /*
           * Token meta data
           */
          string constant public name = "Humaniq";
          string constant public symbol = "HMQ";
          uint8 constant public decimals = 8;
      
          // Address of the founder of Humaniq.
          address public founder = 0xc890b1f532e674977dfdb791cafaee898dfa9671;
      
          // Multisig address of the founders
          address public multisig = 0xa2c9a7578e2172f32a36c5c0e49d64776f9e7883;
      
          // Address where all tokens created during ICO stage initially allocated
          address constant public allocationAddressICO = 0x1111111111111111111111111111111111111111;
      
          // Address where all tokens created during preICO stage initially allocated
          address constant public allocationAddressPreICO = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
      
          // 31 820 314 tokens were minted during preICO
          uint constant public preICOSupply = mul(31820314, 100000000);
      
          // 131 038 286 tokens were minted during ICO
          uint constant public ICOSupply = mul(131038286, 100000000);
      
          // Max number of tokens that can be minted
          uint public maxTotalSupply;
      
          /*
           * Modifiers
           */
          modifier onlyFounder() {
              // Only founder is allowed to do this action.
              if (msg.sender != founder) {
                  throw;
              }
              _;
          }
      
          modifier onlyMinter() {
              // Only minter is allowed to proceed.
              if (msg.sender != minter) {
                  throw;
              }
              _;
          }
      
          /*
           * Contract functions
           */
      
          /// @dev Crowdfunding contract issues new tokens for address. Returns success.
          /// @param _for Address of receiver.
          /// @param tokenCount Number of tokens to issue.
          function issueTokens(address _for, uint tokenCount)
              external
              payable
              onlyMinter
              returns (bool)
          {
              if (tokenCount == 0) {
                  return false;
              }
      
              if (add(totalSupply, tokenCount) > maxTotalSupply) {
                  throw;
              }
      
              totalSupply = add(totalSupply, tokenCount);
              balances[_for] = add(balances[_for], tokenCount);
              Issuance(_for, tokenCount);
              return true;
          }
      
          /// @dev Function to change address that is allowed to do emission.
          /// @param newAddress Address of new emission contract.
          function changeMinter(address newAddress)
              public
              onlyFounder
              returns (bool)
          {   
              // Forbid previous emission contract to distribute tokens minted during ICO stage
              delete allowed[allocationAddressICO][minter];
      
              minter = newAddress;
      
              // Allow emission contract to distribute tokens minted during ICO stage
              allowed[allocationAddressICO][minter] = balanceOf(allocationAddressICO);
          }
      
          /// @dev Function to change founder address.
          /// @param newAddress Address of new founder.
          function changeFounder(address newAddress)
              public
              onlyFounder
              returns (bool)
          {   
              founder = newAddress;
          }
      
          /// @dev Function to change multisig address.
          /// @param newAddress Address of new multisig.
          function changeMultisig(address newAddress)
              public
              onlyFounder
              returns (bool)
          {
              multisig = newAddress;
          }
      
          /// @dev Contract constructor function sets initial token balances.
          function HumaniqToken(address founderAddress)
          {   
              // Set founder address
              founder = founderAddress;
      
              // Allocate all created tokens during ICO stage to allocationAddressICO.
              balances[allocationAddressICO] = ICOSupply;
      
              // Allocate all created tokens during preICO stage to allocationAddressPreICO.
              balances[allocationAddressPreICO] = preICOSupply;
      
              // Allow founder to distribute tokens minted during preICO stage
              allowed[allocationAddressPreICO][founder] = preICOSupply;
      
              // Give 14 percent of all tokens to founders.
              balances[multisig] = div(mul(ICOSupply, 14), 86);
      
              // Set correct totalSupply and limit maximum total supply.
              totalSupply = add(ICOSupply, balances[multisig]);
              totalSupply = add(totalSupply, preICOSupply);
              maxTotalSupply = mul(totalSupply, 5);
          }
      }

      File 2 of 3: Controller
      pragma solidity ^0.4.10;
      
      // Copyright 2017 Bittrex
      
      contract AbstractSweeper {
          function sweep(address token, uint amount) returns (bool);
      
          function () { throw; }
      
          Controller controller;
      
          function AbstractSweeper(address _controller) {
              controller = Controller(_controller);
          }
      
          modifier canSweep() {
              if (msg.sender != controller.authorizedCaller() && msg.sender != controller.owner()) throw;
              if (controller.halted()) throw;
              _;
          }
      }
      
      contract Token {
          function balanceOf(address a) returns (uint) {
              (a);
              return 0;
          }
      
          function transfer(address a, uint val) returns (bool) {
              (a);
              (val);
              return false;
          }
      }
      
      contract DefaultSweeper is AbstractSweeper {
          function DefaultSweeper(address controller)
                   AbstractSweeper(controller) {}
      
          function sweep(address _token, uint _amount)
          canSweep
          returns (bool) {
              bool success = false;
              address destination = controller.destination();
      
              if (_token != address(0)) {
                  Token token = Token(_token);
                  uint amount = _amount;
                  if (amount > token.balanceOf(this)) {
                      return false;
                  }
      
                  success = token.transfer(destination, amount);
              }
              else {
                  uint amountInWei = _amount;
                  if (amountInWei > this.balance) {
                      return false;
                  }
      
                  success = destination.send(amountInWei);
              }
      
              if (success) {
                  controller.logSweep(this, destination, _token, _amount);
              }
              return success;
          }
      }
      
      contract UserWallet {
          AbstractSweeperList sweeperList;
          function UserWallet(address _sweeperlist) {
              sweeperList = AbstractSweeperList(_sweeperlist);
          }
      
          function () public payable { }
      
          function tokenFallback(address _from, uint _value, bytes _data) {
              (_from);
              (_value);
              (_data);
           }
      
          function sweep(address _token, uint _amount)
          returns (bool) {
              (_amount);
              return sweeperList.sweeperOf(_token).delegatecall(msg.data);
          }
      }
      
      contract AbstractSweeperList {
          function sweeperOf(address _token) returns (address);
      }
      
      contract Controller is AbstractSweeperList {
          address public owner;
          address public authorizedCaller;
      
          address public destination;
      
          bool public halted;
      
          event LogNewWallet(address receiver);
          event LogSweep(address indexed from, address indexed to, address indexed token, uint amount);
          
          modifier onlyOwner() {
              if (msg.sender != owner) throw; 
              _;
          }
      
          modifier onlyAuthorizedCaller() {
              if (msg.sender != authorizedCaller) throw; 
              _;
          }
      
          modifier onlyAdmins() {
              if (msg.sender != authorizedCaller && msg.sender != owner) throw; 
              _;
          }
      
          function Controller() 
          {
              owner = msg.sender;
              destination = msg.sender;
              authorizedCaller = msg.sender;
          }
      
          function changeAuthorizedCaller(address _newCaller) onlyOwner {
              authorizedCaller = _newCaller;
          }
      
          function changeDestination(address _dest) onlyOwner {
              destination = _dest;
          }
      
          function changeOwner(address _owner) onlyOwner {
              owner = _owner;
          }
      
          function makeWallet() onlyAdmins returns (address wallet)  {
              wallet = address(new UserWallet(this));
              LogNewWallet(wallet);
          }
      
          function halt() onlyAdmins {
              halted = true;
          }
      
          function start() onlyOwner {
              halted = false;
          }
      
          address public defaultSweeper = address(new DefaultSweeper(this));
          mapping (address => address) sweepers;
      
          function addSweeper(address _token, address _sweeper) onlyOwner {
              sweepers[_token] = _sweeper;
          }
      
          function sweeperOf(address _token) returns (address) {
              address sweeper = sweepers[_token];
              if (sweeper == 0) sweeper = defaultSweeper;
              return sweeper;
          }
      
          function logSweep(address from, address to, address token, uint amount) {
              LogSweep(from, to, token, amount);
          }
      }

      File 3 of 3: DefaultSweeper
      pragma solidity ^0.4.10;
      
      // Copyright 2017 Bittrex
      
      contract AbstractSweeper {
          function sweep(address token, uint amount) returns (bool);
      
          function () { throw; }
      
          Controller controller;
      
          function AbstractSweeper(address _controller) {
              controller = Controller(_controller);
          }
      
          modifier canSweep() {
              if (msg.sender != controller.authorizedCaller() && msg.sender != controller.owner()) throw;
              if (controller.halted()) throw;
              _;
          }
      }
      
      contract Token {
          function balanceOf(address a) returns (uint) {
              (a);
              return 0;
          }
      
          function transfer(address a, uint val) returns (bool) {
              (a);
              (val);
              return false;
          }
      }
      
      contract DefaultSweeper is AbstractSweeper {
          function DefaultSweeper(address controller)
                   AbstractSweeper(controller) {}
      
          function sweep(address _token, uint _amount)
          canSweep
          returns (bool) {
              bool success = false;
              address destination = controller.destination();
      
              if (_token != address(0)) {
                  Token token = Token(_token);
                  uint amount = _amount;
                  if (amount > token.balanceOf(this)) {
                      return false;
                  }
      
                  success = token.transfer(destination, amount);
              }
              else {
                  uint amountInWei = _amount;
                  if (amountInWei > this.balance) {
                      return false;
                  }
      
                  success = destination.send(amountInWei);
              }
      
              if (success) {
                  controller.logSweep(this, destination, _token, _amount);
              }
              return success;
          }
      }
      
      contract UserWallet {
          AbstractSweeperList sweeperList;
          function UserWallet(address _sweeperlist) {
              sweeperList = AbstractSweeperList(_sweeperlist);
          }
      
          function () public payable { }
      
          function tokenFallback(address _from, uint _value, bytes _data) {
              (_from);
              (_value);
              (_data);
           }
      
          function sweep(address _token, uint _amount)
          returns (bool) {
              (_amount);
              return sweeperList.sweeperOf(_token).delegatecall(msg.data);
          }
      }
      
      contract AbstractSweeperList {
          function sweeperOf(address _token) returns (address);
      }
      
      contract Controller is AbstractSweeperList {
          address public owner;
          address public authorizedCaller;
      
          address public destination;
      
          bool public halted;
      
          event LogNewWallet(address receiver);
          event LogSweep(address indexed from, address indexed to, address indexed token, uint amount);
          
          modifier onlyOwner() {
              if (msg.sender != owner) throw; 
              _;
          }
      
          modifier onlyAuthorizedCaller() {
              if (msg.sender != authorizedCaller) throw; 
              _;
          }
      
          modifier onlyAdmins() {
              if (msg.sender != authorizedCaller && msg.sender != owner) throw; 
              _;
          }
      
          function Controller() 
          {
              owner = msg.sender;
              destination = msg.sender;
              authorizedCaller = msg.sender;
          }
      
          function changeAuthorizedCaller(address _newCaller) onlyOwner {
              authorizedCaller = _newCaller;
          }
      
          function changeDestination(address _dest) onlyOwner {
              destination = _dest;
          }
      
          function changeOwner(address _owner) onlyOwner {
              owner = _owner;
          }
      
          function makeWallet() onlyAdmins returns (address wallet)  {
              wallet = address(new UserWallet(this));
              LogNewWallet(wallet);
          }
      
          function halt() onlyAdmins {
              halted = true;
          }
      
          function start() onlyOwner {
              halted = false;
          }
      
          address public defaultSweeper = address(new DefaultSweeper(this));
          mapping (address => address) sweepers;
      
          function addSweeper(address _token, address _sweeper) onlyOwner {
              sweepers[_token] = _sweeper;
          }
      
          function sweeperOf(address _token) returns (address) {
              address sweeper = sweepers[_token];
              if (sweeper == 0) sweeper = defaultSweeper;
              return sweeper;
          }
      
          function logSweep(address from, address to, address token, uint amount) {
              LogSweep(from, to, token, amount);
          }
      }