ETH Price: $1,975.50 (+0.08%)

Transaction Decoder

Block:
24214714 at Jan-11-2026 11:19:59 PM +UTC
Transaction Fee:
0.00000245720760018 ETH $0.004854
Gas Used:
57,394 Gas / 0.04281297 Gwei

Emitted Events:

723 chiliZ.Transfer( from=Forwarder, to=[Receiver] 0xd6a062cae6123c158768a5c444ca0896cc60d6b1, value=267992080000000000000000 )
724 Forwarder.TokensFlushed( tokenContractAddress=chiliZ, value=267992080000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x3506424F...5F8e3b4AF
(Titan Builder)
19.179373170000268617 Eth19.179373236003368617 Eth0.0000000660031
0xddC50252...23E9117d5
(Coinjar: Deployer 1)
21.220015665782089551 Eth
Nonce: 144977
21.220013208574489371 Eth
Nonce: 144978
0.00000245720760018

Execution Trace

Coinjar 3.2da03409( )
  • WalletSimple.flushForwarderTokens( forwarderAddress=0x66fc8Eb395DCCc80A10483c0B87b6C0ef9DaA29f, tokenContractAddress=0x3506424F91fD33084466F402d5D97f05F8e3b4AF )
    • Forwarder.flushTokens( tokenContractAddress=0x3506424F91fD33084466F402d5D97f05F8e3b4AF )
      • chiliZ.balanceOf( owner=0x66fc8Eb395DCCc80A10483c0B87b6C0ef9DaA29f ) => ( 267992080000000000000000 )
      • chiliZ.transfer( to=0xd6a062CAE6123C158768A5C444CA0896CC60D6B1, value=267992080000000000000000 ) => ( True )
        File 1 of 3: Forwarder
        pragma solidity ^0.4.14;
        
        /**
         * Contract that exposes the needed erc20 token functions
         */
        
        contract ERC20Interface {
          // Send _value amount of tokens to address _to
          function transfer(address _to, uint256 _value) returns (bool success);
          // Get the account balance of another account with address _owner
          function balanceOf(address _owner) constant returns (uint256 balance);
        }
        
        /**
         * Contract that will forward any incoming Ether to its creator
         */
        contract Forwarder {
          // Address to which any funds sent to this contract will be forwarded
          address public parentAddress;
          event ForwarderDeposited(address from, uint value, bytes data);
        
          event TokensFlushed(
            address tokenContractAddress, // The contract address of the token
            uint value // Amount of token sent
          );
        
          /**
           * Create the contract, and set the destination address to that of the creator
           */
          function Forwarder() {
            parentAddress = msg.sender;
          }
        
          /**
           * Modifier that will execute internal code block only if the sender is a parent of the forwarder contract
           */
          modifier onlyParent {
            if (msg.sender != parentAddress) {
              throw;
            }
            _;
          }
        
          /**
           * Default function; Gets called when Ether is deposited, and forwards it to the destination address
           */
          function() payable {
            if (!parentAddress.call.value(msg.value)(msg.data))
              throw;
            // Fire off the deposited event if we can forward it  
            ForwarderDeposited(msg.sender, msg.value, msg.data);
          }
        
          /**
           * Execute a token transfer of the full balance from the forwarder token to the main wallet contract
           * @param tokenContractAddress the address of the erc20 token contract
           */
          function flushTokens(address tokenContractAddress) onlyParent {
            ERC20Interface instance = ERC20Interface(tokenContractAddress);
            var forwarderAddress = address(this);
            var forwarderBalance = instance.balanceOf(forwarderAddress);
            if (forwarderBalance == 0) {
              return;
            }
            if (!instance.transfer(parentAddress, forwarderBalance)) {
              throw;
            }
            TokensFlushed(tokenContractAddress, forwarderBalance);
          }
        
          /**
           * It is possible that funds were sent to this address before the contract was deployed.
           * We can flush those funds to the destination address.
           */
          function flush() {
            if (!parentAddress.call.value(this.balance)())
              throw;
          }
        }
        
        /**
         * Basic multi-signer wallet designed for use in a co-signing environment where 2 signatures are required to move funds.
         * Typically used in a 2-of-3 signing configuration. Uses ecrecover to allow for 2 signatures in a single transaction.
         */
        contract WalletSimple {
          // Events
          event Deposited(address from, uint value, bytes data);
          event SafeModeActivated(address msgSender);
          event Transacted(
            address msgSender, // Address of the sender of the message initiating the transaction
            address otherSigner, // Address of the signer (second signature) used to initiate the transaction
            bytes32 operation, // Operation hash (sha3 of toAddress, value, data, expireTime, sequenceId)
            address toAddress, // The address the transaction was sent to
            uint value, // Amount of Wei sent to the address
            bytes data // Data sent when invoking the transaction
          );
          event TokenTransacted(
            address msgSender, // Address of the sender of the message initiating the transaction
            address otherSigner, // Address of the signer (second signature) used to initiate the transaction
            bytes32 operation, // Operation hash (sha3 of toAddress, value, tokenContractAddress, expireTime, sequenceId)
            address toAddress, // The address the transaction was sent to
            uint value, // Amount of token sent
            address tokenContractAddress // The contract address of the token
          );
        
          // Public fields
          address[] public signers; // The addresses that can co-sign transactions on the wallet
          bool public safeMode = false; // When active, wallet may only send to signer addresses
        
          // Internal fields
          uint constant SEQUENCE_ID_WINDOW_SIZE = 10;
          uint[10] recentSequenceIds;
        
          /**
           * Modifier that will execute internal code block only if the sender is an authorized signer on this wallet
           */
          modifier onlysigner {
            if (!isSigner(msg.sender)) {
              throw;
            }
            _;
          }
        
          /**
           * Set up a simple multi-sig wallet by specifying the signers allowed to be used on this wallet.
           * 2 signers will be required to send a transaction from this wallet.
           * Note: The sender is NOT automatically added to the list of signers.
           * Signers CANNOT be changed once they are set
           *
           * @param allowedSigners An array of signers on the wallet
           */
          function WalletSimple(address[] allowedSigners) {
            if (allowedSigners.length != 3) {
              // Invalid number of signers
              throw;
            }
            signers = allowedSigners;
          }
        
          /**
           * Gets called when a transaction is received without calling a method
           */
          function() payable {
            if (msg.value > 0) {
              // Fire deposited event if we are receiving funds
              Deposited(msg.sender, msg.value, msg.data);
            }
          }
        
          /**
           * Create a new contract (and also address) that forwards funds to this contract
           * returns address of newly created forwarder address
           */
          function createForwarder() onlysigner returns (address) {
            return new Forwarder();
          }
        
          /**
           * Execute a multi-signature transaction from this wallet using 2 signers: one from msg.sender and the other from ecrecover.
           * The signature is a signed form (using eth.sign) of tightly packed toAddress, value, data, expireTime and sequenceId
           * Sequence IDs are numbers starting from 1. They are used to prevent replay attacks and may not be repeated.
           *
           * @param toAddress the destination address to send an outgoing transaction
           * @param value the amount in Wei to be sent
           * @param data the data to send to the toAddress when invoking the transaction
           * @param expireTime the number of seconds since 1970 for which this transaction is valid
           * @param sequenceId the unique sequence id obtainable from getNextSequenceId
           * @param signature the result of eth.sign on the operationHash sha3(toAddress, value, data, expireTime, sequenceId)
           */
          function sendMultiSig(address toAddress, uint value, bytes data, uint expireTime, uint sequenceId, bytes signature) onlysigner {
            // Verify the other signer
            var operationHash = sha3("ETHER", toAddress, value, data, expireTime, sequenceId);
            
            var otherSigner = verifyMultiSig(toAddress, operationHash, signature, expireTime, sequenceId);
        
            // Success, send the transaction
            if (!(toAddress.call.value(value)(data))) {
              // Failed executing transaction
              throw;
            }
            Transacted(msg.sender, otherSigner, operationHash, toAddress, value, data);
          }
          
          /**
           * Execute a multi-signature token transfer from this wallet using 2 signers: one from msg.sender and the other from ecrecover.
           * The signature is a signed form (using eth.sign) of tightly packed toAddress, value, tokenContractAddress, expireTime and sequenceId
           * Sequence IDs are numbers starting from 1. They are used to prevent replay attacks and may not be repeated.
           *
           * @param toAddress the destination address to send an outgoing transaction
           * @param value the amount in tokens to be sent
           * @param tokenContractAddress the address of the erc20 token contract
           * @param expireTime the number of seconds since 1970 for which this transaction is valid
           * @param sequenceId the unique sequence id obtainable from getNextSequenceId
           * @param signature the result of eth.sign on the operationHash sha3(toAddress, value, tokenContractAddress, expireTime, sequenceId)
           */
          function sendMultiSigToken(address toAddress, uint value, address tokenContractAddress, uint expireTime, uint sequenceId, bytes signature) onlysigner {
            // Verify the other signer
            var operationHash = sha3("ERC20", toAddress, value, tokenContractAddress, expireTime, sequenceId);
            
            var otherSigner = verifyMultiSig(toAddress, operationHash, signature, expireTime, sequenceId);
            
            ERC20Interface instance = ERC20Interface(tokenContractAddress);
            if (!instance.transfer(toAddress, value)) {
                throw;
            }
            TokenTransacted(msg.sender, otherSigner, operationHash, toAddress, value, tokenContractAddress);
          }
        
          /**
           * Execute a token flush from one of the forwarder addresses. This transfer needs only a single signature and can be done by any signer
           *
           * @param forwarderAddress the address of the forwarder address to flush the tokens from
           * @param tokenContractAddress the address of the erc20 token contract
           */
          function flushForwarderTokens(address forwarderAddress, address tokenContractAddress) onlysigner {    
            Forwarder forwarder = Forwarder(forwarderAddress);
            forwarder.flushTokens(tokenContractAddress);
          }  
          
          /**
           * Do common multisig verification for both eth sends and erc20token transfers
           *
           * @param toAddress the destination address to send an outgoing transaction
           * @param operationHash the sha3 of the toAddress, value, data/tokenContractAddress and expireTime
           * @param signature the tightly packed signature of r, s, and v as an array of 65 bytes (returned by eth.sign)
           * @param expireTime the number of seconds since 1970 for which this transaction is valid
           * @param sequenceId the unique sequence id obtainable from getNextSequenceId
           * returns address of the address to send tokens or eth to
           */
          function verifyMultiSig(address toAddress, bytes32 operationHash, bytes signature, uint expireTime, uint sequenceId) private returns (address) {
        
            var otherSigner = recoverAddressFromSignature(operationHash, signature);
        
            // Verify if we are in safe mode. In safe mode, the wallet can only send to signers
            if (safeMode && !isSigner(toAddress)) {
              // We are in safe mode and the toAddress is not a signer. Disallow!
              throw;
            }
            // Verify that the transaction has not expired
            if (expireTime < block.timestamp) {
              // Transaction expired
              throw;
            }
        
            // Try to insert the sequence ID. Will throw if the sequence id was invalid
            tryInsertSequenceId(sequenceId);
        
            if (!isSigner(otherSigner)) {
              // Other signer not on this wallet or operation does not match arguments
              throw;
            }
            if (otherSigner == msg.sender) {
              // Cannot approve own transaction
              throw;
            }
        
            return otherSigner;
          }
        
          /**
           * Irrevocably puts contract into safe mode. When in this mode, transactions may only be sent to signing addresses.
           */
          function activateSafeMode() onlysigner {
            safeMode = true;
            SafeModeActivated(msg.sender);
          }
        
          /**
           * Determine if an address is a signer on this wallet
           * @param signer address to check
           * returns boolean indicating whether address is signer or not
           */
          function isSigner(address signer) returns (bool) {
            // Iterate through all signers on the wallet and
            for (uint i = 0; i < signers.length; i++) {
              if (signers[i] == signer) {
                return true;
              }
            }
            return false;
          }
        
          /**
           * Gets the second signer's address using ecrecover
           * @param operationHash the sha3 of the toAddress, value, data/tokenContractAddress and expireTime
           * @param signature the tightly packed signature of r, s, and v as an array of 65 bytes (returned by eth.sign)
           * returns address recovered from the signature
           */
          function recoverAddressFromSignature(bytes32 operationHash, bytes signature) private returns (address) {
            if (signature.length != 65) {
              throw;
            }
            // We need to unpack the signature, which is given as an array of 65 bytes (from eth.sign)
            bytes32 r;
            bytes32 s;
            uint8 v;
            assembly {
              r := mload(add(signature, 32))
              s := mload(add(signature, 64))
              v := and(mload(add(signature, 65)), 255)
            }
            if (v < 27) {
              v += 27; // Ethereum versions are 27 or 28 as opposed to 0 or 1 which is submitted by some signing libs
            }
            return ecrecover(operationHash, v, r, s);
          }
        
          /**
           * Verify that the sequence id has not been used before and inserts it. Throws if the sequence ID was not accepted.
           * We collect a window of up to 10 recent sequence ids, and allow any sequence id that is not in the window and
           * greater than the minimum element in the window.
           * @param sequenceId to insert into array of stored ids
           */
          function tryInsertSequenceId(uint sequenceId) onlysigner private {
            // Keep a pointer to the lowest value element in the window
            uint lowestValueIndex = 0;
            for (uint i = 0; i < SEQUENCE_ID_WINDOW_SIZE; i++) {
              if (recentSequenceIds[i] == sequenceId) {
                // This sequence ID has been used before. Disallow!
                throw;
              }
              if (recentSequenceIds[i] < recentSequenceIds[lowestValueIndex]) {
                lowestValueIndex = i;
              }
            }
            if (sequenceId < recentSequenceIds[lowestValueIndex]) {
              // The sequence ID being used is lower than the lowest value in the window
              // so we cannot accept it as it may have been used before
              throw;
            }
            if (sequenceId > (recentSequenceIds[lowestValueIndex] + 10000)) {
              // Block sequence IDs which are much higher than the lowest value
              // This prevents people blocking the contract by using very large sequence IDs quickly
              throw;
            }
            recentSequenceIds[lowestValueIndex] = sequenceId;
          }
        
          /**
           * Gets the next available sequence ID for signing when using executeAndConfirm
           * returns the sequenceId one higher than the highest currently stored
           */
          function getNextSequenceId() returns (uint) {
            uint highestSequenceId = 0;
            for (uint i = 0; i < SEQUENCE_ID_WINDOW_SIZE; i++) {
              if (recentSequenceIds[i] > highestSequenceId) {
                highestSequenceId = recentSequenceIds[i];
              }
            }
            return highestSequenceId + 1;
          }
        }

        File 2 of 3: chiliZ
        pragma solidity ^0.4.24;
        
        // File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol
        
        /**
         * @title ERC20 interface
         * @dev see https://github.com/ethereum/EIPs/issues/20
         */
        interface IERC20 {
          function totalSupply() external view returns (uint256);
        
          function balanceOf(address who) external view returns (uint256);
        
          function allowance(address owner, address spender)
            external view returns (uint256);
        
          function transfer(address to, uint256 value) external returns (bool);
        
          function approve(address spender, uint256 value)
            external returns (bool);
        
          function transferFrom(address from, address to, uint256 value)
            external returns (bool);
        
          event Transfer(
            address indexed from,
            address indexed to,
            uint256 value
          );
        
          event Approval(
            address indexed owner,
            address indexed spender,
            uint256 value
          );
        }
        
        // File: openzeppelin-solidity/contracts/math/SafeMath.sol
        
        /**
         * @title SafeMath
         * @dev Math operations with safety checks that revert on error
         */
        library SafeMath {
        
          /**
          * @dev Multiplies two numbers, reverts on overflow.
          */
          function mul(uint256 a, uint256 b) internal pure returns (uint256) {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
            if (a == 0) {
              return 0;
            }
        
            uint256 c = a * b;
            require(c / a == b);
        
            return c;
          }
        
          /**
          * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
          */
          function div(uint256 a, uint256 b) internal pure returns (uint256) {
            require(b > 0); // Solidity only automatically asserts 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, reverts on overflow (i.e. if subtrahend is greater than minuend).
          */
          function sub(uint256 a, uint256 b) internal pure returns (uint256) {
            require(b <= a);
            uint256 c = a - b;
        
            return c;
          }
        
          /**
          * @dev Adds two numbers, reverts on overflow.
          */
          function add(uint256 a, uint256 b) internal pure returns (uint256) {
            uint256 c = a + b;
            require(c >= a);
        
            return c;
          }
        
          /**
          * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
          * reverts when dividing by zero.
          */
          function mod(uint256 a, uint256 b) internal pure returns (uint256) {
            require(b != 0);
            return a % b;
          }
        }
        
        // File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol
        
        /**
         * @title Standard ERC20 token
         *
         * @dev Implementation of the basic standard token.
         * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
         * Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
         */
        contract ERC20 is IERC20 {
          using SafeMath for uint256;
        
          mapping (address => uint256) private _balances;
        
          mapping (address => mapping (address => uint256)) private _allowed;
        
          uint256 private _totalSupply;
        
          /**
          * @dev Total number of tokens in existence
          */
          function totalSupply() public view returns (uint256) {
            return _totalSupply;
          }
        
          /**
          * @dev Gets the balance of the specified address.
          * @param owner The address to query the balance of.
          * @return An uint256 representing the amount owned by the passed address.
          */
          function balanceOf(address owner) public view returns (uint256) {
            return _balances[owner];
          }
        
          /**
           * @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 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) {
            _transfer(msg.sender, 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) {
            require(spender != address(0));
        
            _allowed[msg.sender][spender] = value;
            emit Approval(msg.sender, spender, value);
            return true;
          }
        
          /**
           * @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(value <= _allowed[from][msg.sender]);
        
            _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);
            _transfer(from, to, value);
            return true;
          }
        
          /**
           * @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 increaseAllowance(
            address spender,
            uint256 addedValue
          )
            public
            returns (bool)
          {
            require(spender != address(0));
        
            _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 decreaseAllowance(
            address spender,
            uint256 subtractedValue
          )
            public
            returns (bool)
          {
            require(spender != address(0));
        
            _allowed[msg.sender][spender] = (
              _allowed[msg.sender][spender].sub(subtractedValue));
            emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
            return true;
          }
        
          /**
          * @dev Transfer token for a specified addresses
          * @param from The address to transfer from.
          * @param to The address to transfer to.
          * @param value The amount to be transferred.
          */
          function _transfer(address from, address to, uint256 value) internal {
            require(value <= _balances[from]);
            require(to != address(0));
        
            _balances[from] = _balances[from].sub(value);
            _balances[to] = _balances[to].add(value);
            emit Transfer(from, to, value);
          }
        
          /**
           * @dev Internal function that mints an amount of the token and assigns it to
           * an account. This encapsulates the modification of balances such that the
           * proper events are emitted.
           * @param account The account that will receive the created tokens.
           * @param value The amount that will be created.
           */
          function _mint(address account, uint256 value) internal {
            require(account != 0);
            _totalSupply = _totalSupply.add(value);
            _balances[account] = _balances[account].add(value);
            emit Transfer(address(0), account, value);
          }
        
          /**
           * @dev Internal function that burns an amount of the token of a given
           * account.
           * @param account The account whose tokens will be burnt.
           * @param value The amount that will be burnt.
           */
          function _burn(address account, uint256 value) internal {
            require(account != 0);
            require(value <= _balances[account]);
        
            _totalSupply = _totalSupply.sub(value);
            _balances[account] = _balances[account].sub(value);
            emit Transfer(account, address(0), value);
          }
        
          /**
           * @dev Internal function that burns an amount of the token of a given
           * account, deducting from the sender's allowance for said account. Uses the
           * internal burn function.
           * @param account The account whose tokens will be burnt.
           * @param value The amount that will be burnt.
           */
          function _burnFrom(address account, uint256 value) internal {
            require(value <= _allowed[account][msg.sender]);
        
            // Should https://github.com/OpenZeppelin/zeppelin-solidity/issues/707 be accepted,
            // this function needs to emit an event with the updated approval.
            _allowed[account][msg.sender] = _allowed[account][msg.sender].sub(
              value);
            _burn(account, value);
          }
        }
        
        // File: openzeppelin-solidity/contracts/access/Roles.sol
        
        /**
         * @title Roles
         * @dev Library for managing addresses assigned to a Role.
         */
        library Roles {
          struct Role {
            mapping (address => bool) bearer;
          }
        
          /**
           * @dev give an account access to this role
           */
          function add(Role storage role, address account) internal {
            require(account != address(0));
            require(!has(role, account));
        
            role.bearer[account] = true;
          }
        
          /**
           * @dev remove an account's access to this role
           */
          function remove(Role storage role, address account) internal {
            require(account != address(0));
            require(has(role, account));
        
            role.bearer[account] = false;
          }
        
          /**
           * @dev check if an account has this role
           * @return bool
           */
          function has(Role storage role, address account)
            internal
            view
            returns (bool)
          {
            require(account != address(0));
            return role.bearer[account];
          }
        }
        
        // File: openzeppelin-solidity/contracts/access/roles/PauserRole.sol
        
        contract PauserRole {
          using Roles for Roles.Role;
        
          event PauserAdded(address indexed account);
          event PauserRemoved(address indexed account);
        
          Roles.Role private pausers;
        
          constructor() internal {
            _addPauser(msg.sender);
          }
        
          modifier onlyPauser() {
            require(isPauser(msg.sender));
            _;
          }
        
          function isPauser(address account) public view returns (bool) {
            return pausers.has(account);
          }
        
          function addPauser(address account) public onlyPauser {
            _addPauser(account);
          }
        
          function renouncePauser() public {
            _removePauser(msg.sender);
          }
        
          function _addPauser(address account) internal {
            pausers.add(account);
            emit PauserAdded(account);
          }
        
          function _removePauser(address account) internal {
            pausers.remove(account);
            emit PauserRemoved(account);
          }
        }
        
        // File: openzeppelin-solidity/contracts/lifecycle/Pausable.sol
        
        /**
         * @title Pausable
         * @dev Base contract which allows children to implement an emergency stop mechanism.
         */
        contract Pausable is PauserRole {
          event Paused(address account);
          event Unpaused(address account);
        
          bool private _paused;
        
          constructor() internal {
            _paused = false;
          }
        
          /**
           * @return true if the contract is paused, false otherwise.
           */
          function paused() public view returns(bool) {
            return _paused;
          }
        
          /**
           * @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() public onlyPauser whenNotPaused {
            _paused = true;
            emit Paused(msg.sender);
          }
        
          /**
           * @dev called by the owner to unpause, returns to normal state
           */
          function unpause() public onlyPauser whenPaused {
            _paused = false;
            emit Unpaused(msg.sender);
          }
        }
        
        // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Pausable.sol
        
        /**
         * @title Pausable token
         * @dev ERC20 modified with pausable transfers.
         **/
        contract ERC20Pausable is ERC20, Pausable {
        
          function transfer(
            address to,
            uint256 value
          )
            public
            whenNotPaused
            returns (bool)
          {
            return super.transfer(to, value);
          }
        
          function transferFrom(
            address from,
            address to,
            uint256 value
          )
            public
            whenNotPaused
            returns (bool)
          {
            return super.transferFrom(from, to, value);
          }
        
          function approve(
            address spender,
            uint256 value
          )
            public
            whenNotPaused
            returns (bool)
          {
            return super.approve(spender, value);
          }
        
          function increaseAllowance(
            address spender,
            uint addedValue
          )
            public
            whenNotPaused
            returns (bool success)
          {
            return super.increaseAllowance(spender, addedValue);
          }
        
          function decreaseAllowance(
            address spender,
            uint subtractedValue
          )
            public
            whenNotPaused
            returns (bool success)
          {
            return super.decreaseAllowance(spender, subtractedValue);
          }
        }
        
        // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol
        
        /**
         * @title ERC20Detailed token
         * @dev The decimals are only for visualization purposes.
         * All the operations are done using the smallest and indivisible token unit,
         * just as on Ethereum all the operations are done in wei.
         */
        contract ERC20Detailed is IERC20 {
          string private _name;
          string private _symbol;
          uint8 private _decimals;
        
          constructor(string name, string symbol, uint8 decimals) public {
            _name = name;
            _symbol = symbol;
            _decimals = decimals;
          }
        
          /**
           * @return the name of the token.
           */
          function name() public view returns(string) {
            return _name;
          }
        
          /**
           * @return the symbol of the token.
           */
          function symbol() public view returns(string) {
            return _symbol;
          }
        
          /**
           * @return the number of decimals of the token.
           */
          function decimals() public view returns(uint8) {
            return _decimals;
          }
        }
        
        // File: openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol
        
        /**
         * @title SafeERC20
         * @dev Wrappers around ERC20 operations that throw on failure.
         * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
         * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
         */
        library SafeERC20 {
        
          using SafeMath for uint256;
        
          function safeTransfer(
            IERC20 token,
            address to,
            uint256 value
          )
            internal
          {
            require(token.transfer(to, value));
          }
        
          function safeTransferFrom(
            IERC20 token,
            address from,
            address to,
            uint256 value
          )
            internal
          {
            require(token.transferFrom(from, to, value));
          }
        
          function safeApprove(
            IERC20 token,
            address spender,
            uint256 value
          )
            internal
          {
            // safeApprove should only be called when setting an initial allowance, 
            // or when resetting it to zero. To increase and decrease it, use 
            // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
            require((value == 0) || (token.allowance(msg.sender, spender) == 0));
            require(token.approve(spender, value));
          }
        
          function safeIncreaseAllowance(
            IERC20 token,
            address spender,
            uint256 value
          )
            internal
          {
            uint256 newAllowance = token.allowance(address(this), spender).add(value);
            require(token.approve(spender, newAllowance));
          }
        
          function safeDecreaseAllowance(
            IERC20 token,
            address spender,
            uint256 value
          )
            internal
          {
            uint256 newAllowance = token.allowance(address(this), spender).sub(value);
            require(token.approve(spender, newAllowance));
          }
        }
        
        // File: contracts/Chiliz-with-imports.sol
        
        contract chiliZ is ERC20, ERC20Detailed, ERC20Pausable {
           using SafeERC20 for ERC20;
        
           constructor()
               ERC20()
               ERC20Detailed("chiliZ", "CHZ", 18)
               ERC20Pausable()
               public
           {
               _mint(msg.sender, 8888888888 * (uint256(10) ** 18));
           }
        }

        File 3 of 3: WalletSimple
        pragma solidity ^0.4.14;
        
        /**
         * Contract that exposes the needed erc20 token functions
         */
        
        contract ERC20Interface {
          // Send _value amount of tokens to address _to
          function transfer(address _to, uint256 _value) returns (bool success);
          // Get the account balance of another account with address _owner
          function balanceOf(address _owner) constant returns (uint256 balance);
        }
        
        /**
         * Contract that will forward any incoming Ether to its creator
         */
        contract Forwarder {
          // Address to which any funds sent to this contract will be forwarded
          address public parentAddress;
          event ForwarderDeposited(address from, uint value, bytes data);
        
          event TokensFlushed(
            address tokenContractAddress, // The contract address of the token
            uint value // Amount of token sent
          );
        
          /**
           * Create the contract, and set the destination address to that of the creator
           */
          function Forwarder() {
            parentAddress = msg.sender;
          }
        
          /**
           * Modifier that will execute internal code block only if the sender is a parent of the forwarder contract
           */
          modifier onlyParent {
            if (msg.sender != parentAddress) {
              throw;
            }
            _;
          }
        
          /**
           * Default function; Gets called when Ether is deposited, and forwards it to the destination address
           */
          function() payable {
            if (!parentAddress.call.value(msg.value)(msg.data))
              throw;
            // Fire off the deposited event if we can forward it  
            ForwarderDeposited(msg.sender, msg.value, msg.data);
          }
        
          /**
           * Execute a token transfer of the full balance from the forwarder token to the main wallet contract
           * @param tokenContractAddress the address of the erc20 token contract
           */
          function flushTokens(address tokenContractAddress) onlyParent {
            ERC20Interface instance = ERC20Interface(tokenContractAddress);
            var forwarderAddress = address(this);
            var forwarderBalance = instance.balanceOf(forwarderAddress);
            if (forwarderBalance == 0) {
              return;
            }
            if (!instance.transfer(parentAddress, forwarderBalance)) {
              throw;
            }
            TokensFlushed(tokenContractAddress, forwarderBalance);
          }
        
          /**
           * It is possible that funds were sent to this address before the contract was deployed.
           * We can flush those funds to the destination address.
           */
          function flush() {
            if (!parentAddress.call.value(this.balance)())
              throw;
          }
        }
        
        /**
         * Basic multi-signer wallet designed for use in a co-signing environment where 2 signatures are required to move funds.
         * Typically used in a 2-of-3 signing configuration. Uses ecrecover to allow for 2 signatures in a single transaction.
         */
        contract WalletSimple {
          // Events
          event Deposited(address from, uint value, bytes data);
          event SafeModeActivated(address msgSender);
          event Transacted(
            address msgSender, // Address of the sender of the message initiating the transaction
            address otherSigner, // Address of the signer (second signature) used to initiate the transaction
            bytes32 operation, // Operation hash (sha3 of toAddress, value, data, expireTime, sequenceId)
            address toAddress, // The address the transaction was sent to
            uint value, // Amount of Wei sent to the address
            bytes data // Data sent when invoking the transaction
          );
          event TokenTransacted(
            address msgSender, // Address of the sender of the message initiating the transaction
            address otherSigner, // Address of the signer (second signature) used to initiate the transaction
            bytes32 operation, // Operation hash (sha3 of toAddress, value, tokenContractAddress, expireTime, sequenceId)
            address toAddress, // The address the transaction was sent to
            uint value, // Amount of token sent
            address tokenContractAddress // The contract address of the token
          );
        
          // Public fields
          address[] public signers; // The addresses that can co-sign transactions on the wallet
          bool public safeMode = false; // When active, wallet may only send to signer addresses
        
          // Internal fields
          uint constant SEQUENCE_ID_WINDOW_SIZE = 10;
          uint[10] recentSequenceIds;
        
          /**
           * Modifier that will execute internal code block only if the sender is an authorized signer on this wallet
           */
          modifier onlysigner {
            if (!isSigner(msg.sender)) {
              throw;
            }
            _;
          }
        
          /**
           * Set up a simple multi-sig wallet by specifying the signers allowed to be used on this wallet.
           * 2 signers will be required to send a transaction from this wallet.
           * Note: The sender is NOT automatically added to the list of signers.
           * Signers CANNOT be changed once they are set
           *
           * @param allowedSigners An array of signers on the wallet
           */
          function WalletSimple(address[] allowedSigners) {
            if (allowedSigners.length != 3) {
              // Invalid number of signers
              throw;
            }
            signers = allowedSigners;
          }
        
          /**
           * Gets called when a transaction is received without calling a method
           */
          function() payable {
            if (msg.value > 0) {
              // Fire deposited event if we are receiving funds
              Deposited(msg.sender, msg.value, msg.data);
            }
          }
        
          /**
           * Create a new contract (and also address) that forwards funds to this contract
           * returns address of newly created forwarder address
           */
          function createForwarder() onlysigner returns (address) {
            return new Forwarder();
          }
        
          /**
           * Execute a multi-signature transaction from this wallet using 2 signers: one from msg.sender and the other from ecrecover.
           * The signature is a signed form (using eth.sign) of tightly packed toAddress, value, data, expireTime and sequenceId
           * Sequence IDs are numbers starting from 1. They are used to prevent replay attacks and may not be repeated.
           *
           * @param toAddress the destination address to send an outgoing transaction
           * @param value the amount in Wei to be sent
           * @param data the data to send to the toAddress when invoking the transaction
           * @param expireTime the number of seconds since 1970 for which this transaction is valid
           * @param sequenceId the unique sequence id obtainable from getNextSequenceId
           * @param signature the result of eth.sign on the operationHash sha3(toAddress, value, data, expireTime, sequenceId)
           */
          function sendMultiSig(address toAddress, uint value, bytes data, uint expireTime, uint sequenceId, bytes signature) onlysigner {
            // Verify the other signer
            var operationHash = sha3("ETHER", toAddress, value, data, expireTime, sequenceId);
            
            var otherSigner = verifyMultiSig(toAddress, operationHash, signature, expireTime, sequenceId);
        
            // Success, send the transaction
            if (!(toAddress.call.value(value)(data))) {
              // Failed executing transaction
              throw;
            }
            Transacted(msg.sender, otherSigner, operationHash, toAddress, value, data);
          }
          
          /**
           * Execute a multi-signature token transfer from this wallet using 2 signers: one from msg.sender and the other from ecrecover.
           * The signature is a signed form (using eth.sign) of tightly packed toAddress, value, tokenContractAddress, expireTime and sequenceId
           * Sequence IDs are numbers starting from 1. They are used to prevent replay attacks and may not be repeated.
           *
           * @param toAddress the destination address to send an outgoing transaction
           * @param value the amount in tokens to be sent
           * @param tokenContractAddress the address of the erc20 token contract
           * @param expireTime the number of seconds since 1970 for which this transaction is valid
           * @param sequenceId the unique sequence id obtainable from getNextSequenceId
           * @param signature the result of eth.sign on the operationHash sha3(toAddress, value, tokenContractAddress, expireTime, sequenceId)
           */
          function sendMultiSigToken(address toAddress, uint value, address tokenContractAddress, uint expireTime, uint sequenceId, bytes signature) onlysigner {
            // Verify the other signer
            var operationHash = sha3("ERC20", toAddress, value, tokenContractAddress, expireTime, sequenceId);
            
            var otherSigner = verifyMultiSig(toAddress, operationHash, signature, expireTime, sequenceId);
            
            ERC20Interface instance = ERC20Interface(tokenContractAddress);
            if (!instance.transfer(toAddress, value)) {
                throw;
            }
            TokenTransacted(msg.sender, otherSigner, operationHash, toAddress, value, tokenContractAddress);
          }
        
          /**
           * Execute a token flush from one of the forwarder addresses. This transfer needs only a single signature and can be done by any signer
           *
           * @param forwarderAddress the address of the forwarder address to flush the tokens from
           * @param tokenContractAddress the address of the erc20 token contract
           */
          function flushForwarderTokens(address forwarderAddress, address tokenContractAddress) onlysigner {    
            Forwarder forwarder = Forwarder(forwarderAddress);
            forwarder.flushTokens(tokenContractAddress);
          }  
          
          /**
           * Do common multisig verification for both eth sends and erc20token transfers
           *
           * @param toAddress the destination address to send an outgoing transaction
           * @param operationHash the sha3 of the toAddress, value, data/tokenContractAddress and expireTime
           * @param signature the tightly packed signature of r, s, and v as an array of 65 bytes (returned by eth.sign)
           * @param expireTime the number of seconds since 1970 for which this transaction is valid
           * @param sequenceId the unique sequence id obtainable from getNextSequenceId
           * returns address of the address to send tokens or eth to
           */
          function verifyMultiSig(address toAddress, bytes32 operationHash, bytes signature, uint expireTime, uint sequenceId) private returns (address) {
        
            var otherSigner = recoverAddressFromSignature(operationHash, signature);
        
            // Verify if we are in safe mode. In safe mode, the wallet can only send to signers
            if (safeMode && !isSigner(toAddress)) {
              // We are in safe mode and the toAddress is not a signer. Disallow!
              throw;
            }
            // Verify that the transaction has not expired
            if (expireTime < block.timestamp) {
              // Transaction expired
              throw;
            }
        
            // Try to insert the sequence ID. Will throw if the sequence id was invalid
            tryInsertSequenceId(sequenceId);
        
            if (!isSigner(otherSigner)) {
              // Other signer not on this wallet or operation does not match arguments
              throw;
            }
            if (otherSigner == msg.sender) {
              // Cannot approve own transaction
              throw;
            }
        
            return otherSigner;
          }
        
          /**
           * Irrevocably puts contract into safe mode. When in this mode, transactions may only be sent to signing addresses.
           */
          function activateSafeMode() onlysigner {
            safeMode = true;
            SafeModeActivated(msg.sender);
          }
        
          /**
           * Determine if an address is a signer on this wallet
           * @param signer address to check
           * returns boolean indicating whether address is signer or not
           */
          function isSigner(address signer) returns (bool) {
            // Iterate through all signers on the wallet and
            for (uint i = 0; i < signers.length; i++) {
              if (signers[i] == signer) {
                return true;
              }
            }
            return false;
          }
        
          /**
           * Gets the second signer's address using ecrecover
           * @param operationHash the sha3 of the toAddress, value, data/tokenContractAddress and expireTime
           * @param signature the tightly packed signature of r, s, and v as an array of 65 bytes (returned by eth.sign)
           * returns address recovered from the signature
           */
          function recoverAddressFromSignature(bytes32 operationHash, bytes signature) private returns (address) {
            if (signature.length != 65) {
              throw;
            }
            // We need to unpack the signature, which is given as an array of 65 bytes (from eth.sign)
            bytes32 r;
            bytes32 s;
            uint8 v;
            assembly {
              r := mload(add(signature, 32))
              s := mload(add(signature, 64))
              v := and(mload(add(signature, 65)), 255)
            }
            if (v < 27) {
              v += 27; // Ethereum versions are 27 or 28 as opposed to 0 or 1 which is submitted by some signing libs
            }
            return ecrecover(operationHash, v, r, s);
          }
        
          /**
           * Verify that the sequence id has not been used before and inserts it. Throws if the sequence ID was not accepted.
           * We collect a window of up to 10 recent sequence ids, and allow any sequence id that is not in the window and
           * greater than the minimum element in the window.
           * @param sequenceId to insert into array of stored ids
           */
          function tryInsertSequenceId(uint sequenceId) onlysigner private {
            // Keep a pointer to the lowest value element in the window
            uint lowestValueIndex = 0;
            for (uint i = 0; i < SEQUENCE_ID_WINDOW_SIZE; i++) {
              if (recentSequenceIds[i] == sequenceId) {
                // This sequence ID has been used before. Disallow!
                throw;
              }
              if (recentSequenceIds[i] < recentSequenceIds[lowestValueIndex]) {
                lowestValueIndex = i;
              }
            }
            if (sequenceId < recentSequenceIds[lowestValueIndex]) {
              // The sequence ID being used is lower than the lowest value in the window
              // so we cannot accept it as it may have been used before
              throw;
            }
            if (sequenceId > (recentSequenceIds[lowestValueIndex] + 10000)) {
              // Block sequence IDs which are much higher than the lowest value
              // This prevents people blocking the contract by using very large sequence IDs quickly
              throw;
            }
            recentSequenceIds[lowestValueIndex] = sequenceId;
          }
        
          /**
           * Gets the next available sequence ID for signing when using executeAndConfirm
           * returns the sequenceId one higher than the highest currently stored
           */
          function getNextSequenceId() returns (uint) {
            uint highestSequenceId = 0;
            for (uint i = 0; i < SEQUENCE_ID_WINDOW_SIZE; i++) {
              if (recentSequenceIds[i] > highestSequenceId) {
                highestSequenceId = recentSequenceIds[i];
              }
            }
            return highestSequenceId + 1;
          }
        }