ETH Price: $2,054.10 (-0.19%)

Transaction Decoder

Block:
8857380 at Nov-02-2019 06:33:52 AM +UTC
Transaction Fee:
0.00135487 ETH $2.78
Gas Used:
61,585 Gas / 22 Gwei

Emitted Events:

40 StandardToken.Transfer( from=[Receiver] UserWallet, to=[Sender] 0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98, value=239968996190000000000 )
41 Controller.LogSweep( from=[Receiver] UserWallet, to=[Sender] 0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98, token=StandardToken, amount=239968996190000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x4a220E60...248254675
(F2Pool Old)
3,699.825074182839663846 Eth3,699.826429052839663846 Eth0.00135487
0xFBb1b73C...f520fBB98
(Bittrex)
144,382.858285978280596762 Eth
Nonce: 8441601
144,382.856931108280596762 Eth
Nonce: 8441602
0.00135487

Execution Trace

UserWallet.sweep( _token=0x4a220E6096B25EADb88358cb44068A3248254675, _amount=239968996190000000000 ) => ( True )
  • Controller.sweeperOf( _token=0x4a220E6096B25EADb88358cb44068A3248254675 ) => ( 0xb2233FCEC42c588Ee71A594d9A25AA695345426c )
  • DefaultSweeper.sweep( _token=0x4a220E6096B25EADb88358cb44068A3248254675, _amount=239968996190000000000 ) => ( True )
    • Controller.CALL( )
    • Controller.CALL( )
    • Controller.CALL( )
    • Controller.CALL( )
    • StandardToken.balanceOf( _owner=0xAd77D1f9CA9679794933e2E05D28592d565F8874 ) => ( balance=239968996199374614223 )
    • StandardToken.transfer( _to=0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98, _value=239968996190000000000 ) => ( True )
    • Controller.logSweep( from=0xAd77D1f9CA9679794933e2E05D28592d565F8874, to=0xFBb1b73C4f0BDa4f67dcA266ce6Ef42f520fBB98, token=0x4a220E6096B25EADb88358cb44068A3248254675, amount=239968996190000000000 )
      File 1 of 4: UserWallet
      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 2 of 4: StandardToken
      pragma solidity ^0.4.21;
      
      /**
       * @title ERC20Basic
       * @dev Simpler version of ERC20 interface
       * @dev see https://github.com/ethereum/EIPs/issues/179
       */
      contract ERC20Basic {
        function totalSupply() public view returns (uint256);
        function balanceOf(address who) public view returns (uint256);
        function transfer(address to, uint256 value) public returns (bool);
        event Transfer(address indexed from, address indexed to, uint256 value);
      }
      
      /**
       * @title SafeMath
       * @dev Math operations with safety checks that throw on error
       */
      library SafeMath {
      
        /**
         * @dev Multiplies two numbers, throws on overflow.
         */
        function mul(uint256 a, uint256 b) internal pure returns (uint256) {
          if (a == 0) {
            return 0;
          }
          uint256 c = a * b;
          assert(c / a == b);
          return c;
        }
      
        /**
         * @dev Integer division of two numbers, truncating the quotient.
         */
        function div(uint256 a, uint256 b) internal pure 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;
        }
      
        /**
         * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
         */
        function sub(uint256 a, uint256 b) internal pure returns (uint256) {
          assert(b <= a);
          return a - b;
        }
      
        /**
         * @dev Adds two numbers, throws on overflow.
         */
        function add(uint256 a, uint256 b) internal pure returns (uint256) {
          uint256 c = a + b;
          assert(c >= a);
          return c;
        }
      }
      
      /**
       * @title Basic token
       * @dev Basic version of StandardToken, with no allowances.
       */
      contract BasicToken is ERC20Basic {
        using SafeMath for uint256;
      
        mapping(address => uint256) balances;
      
        uint256 totalSupply_ = 45467000000000000000000000;
      
        /**
        * @dev total number of tokens in existence
        */
        function totalSupply() public view returns (uint256) {
          return totalSupply_;
        }
      
        /**
        * @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 <= 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);
          emit 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 view 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 view 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 {
      
        // Name of the token
        string constant public name = "Quant";
        // Token abbreviation
        string constant public symbol = "QNT";
        // Decimal places
        uint8 constant public decimals = 18;
        // Zeros after the point
        uint256 constant public DECIMAL_ZEROS = 1000000000000000000;
      
        mapping (address => mapping (address => uint256)) internal allowed;
      
        address public crowdsale;
      
        modifier onlyCrowdsale() {
          require(msg.sender == crowdsale);
          _;
        }
      
        function StandardToken(address _crowdsale) public {
          require(_crowdsale != address(0));
          crowdsale = _crowdsale;
        }
      
        function mint(address _address, uint256 _value) public onlyCrowdsale {
          balances[_address] = balances[_address].add(_value);
          emit Transfer(0, _address, _value);
        }
      
        /**
         * @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 <= 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);
          emit 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;
          emit 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 view returns (uint256) {
          return allowed[_owner][_spender];
        }
      
        /**
         * @dev Increase the amount of tokens that an owner allowed to a spender.
         *
         * approve should be called when allowed[_spender] == 0. To increment
         * allowed value is better to use this function to avoid 2 calls (and wait until
         * the first transaction is mined)
         * From MonolithDAO Token.sol
         * @param _spender The address which will spend the funds.
         * @param _addedValue The amount of tokens to increase the allowance by.
         */
        function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
          allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
          emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
          return true;
        }
      
        /**
         * @dev Decrease the amount of tokens that an owner allowed to a spender.
         *
         * approve should be called when allowed[_spender] == 0. To decrement
         * allowed value is better to use this function to avoid 2 calls (and wait until
         * the first transaction is mined)
         * From MonolithDAO Token.sol
         * @param _spender The address which will spend the funds.
         * @param _subtractedValue The amount of tokens to decrease the allowance by.
         */
        function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
          uint oldValue = allowed[msg.sender][_spender];
          if (_subtractedValue > oldValue) {
            allowed[msg.sender][_spender] = 0;
          } else {
            allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
          }
          emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
          return true;
        }
      
      }

      File 3 of 4: 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 4 of 4: 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);
          }
      }