Contract Overview
Balance: 0 Ether
Ether Value: $0
Transactions: 1 txn
Misc:
Address Watch: Add To Watch List
Contract Creator: 0xf6e914d07d12636759868a61e52973d17ed7111bat txn 0x722fc3270a083b31922dd26e2bfdb33009f5582bfa5fc1677c33fb5159f7b63b
 Latest 1 txn

TxHash Age From To Value [TxFee]
0x722fc3270a083b31922dd26e2bfdb33009f5582bfa5fc1677c33fb5159f7b63b16 days 21 hrs agodeltabalances  IN    Contract Creation0 Ether0.00230258




[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
View All
ParentTxHash Block Age From To Value
Contract Source Code Verified (Exact Match)
Contract Name: DeltaBalances
Compiler Text: v0.5.2+commit.1df8f40c
Optimization Enabled: Yes
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

pragma solidity ^0.5.0;

/* 
    Contract for DeltaBalances.github.io V5.
    Check values for multiple ERC20 tokens in a single request
    - token balances
    - token allowances
    - deposited token balances (decentralized exchanges)	
    
    V5 changes:
    - Update to Solidity 0.5 (breaking changes)
    - Add support for alternative balance functions using function selectors
    
    
    Address 0x0 is used to resemble ETH as a token (as used in EtherDelta, IDEX and more).
    
    
    To call the new 'generic' functions, this contract uses function selectors based on the hash of function signatures (see getFunctionSelector).
    
    Some useful function signatures (bytes4):
    
    SIGNATURE                      SELECTOR     FUNCTION                   CONTRACTS
    ----------------------------------------------------------------------------------------------------------------------------
    "balanceOf(address)"           0x70a08231   balanceOf(user)            (ERC20, ERC223, ERC777 and more)
    "allowance(address,address)"   0xdd62ed3e   allowance(owner, spender)  (ERC20 tokens)

    "balanceOf(address,address)"   0xf7888aec   balanceOf(token, user)     (EtherDelta, IDEX, Token Store, R1 protocol, and more)
    "getBalance(address,address)"  0xd4fac45d   getBalance(token, user)    (JOYSO)
    "balances(address,address)"    0xc23f001f   balances(user, token)      (Switcheo)
    "balances(address)"            0x27e235e3   balances(user)             (ETHEN ETH)
    "tokens(address,address)"      0x508493bc   tokens(user, tokens)       (ETHEN tokens)
    
    
    
    Preious version (V4)  -> 0x40a38911e470fc088beeb1a9480c2d69c847bcec
*/



// ERC20 contract interface for token transfers.
contract Token {
  function transfer(address to, uint tokens) public returns (bool success);
}

// Exchange contract Interface for EtherDelta and forks.
contract Exchange {
  function balanceOf(address token, address user) public view returns (uint);
}

contract DeltaBalances {
    
  address payable public admin; 

  constructor() public {
    admin = msg.sender;
  }
  
  
  /* admin functionality */

  // Limit withdrawals to the contract creator.
  modifier isAdmin() {
    require(msg.sender == admin);
    _;
  }
  
  // Backup withdraw, in case ETH gets in here.
  function withdraw() external isAdmin {
    admin.transfer(address(this).balance);
  }

  // Backup withdraw, in case ERC20 tokens get in here.
  function withdrawToken(address token, uint amount) external isAdmin {
    require(token != address(0x0) && Token(token).transfer(msg.sender, amount));
  }




  /* public functions */


 /* Get the function selector from a function signature.
    functionSignature: 
      - remove whitespace and variable names.
        use "balanceOf(address,address)"  NOT "balanceOf(address token, address user)"
      
    See the top comment for common selectors.
 */
  function getFunctionSelector(string calldata functionSignature) external pure returns (bytes4) {
    // calculate the keccak256 hash of the function signature and return a 4 bytes value
    return bytes4(keccak256(abi.encodePacked(functionSignature)));
  }

  /* Check the ERC20 token balances of a wallet for multiple tokens.
     Returns array of token balances in wei units. */
  function tokenBalances(address user,  address[] calldata tokens) external view returns (uint[] memory balances) {
    balances = new uint[](tokens.length);
    
    for(uint i = 0; i < tokens.length; i++) {
      if(tokens[i] != address(0x0)) { 
        balances[i] = tokenBalance(user, tokens[i]); // check token balance and catch errors
      } else {
        balances[i] = user.balance; // ETH balance    
      }
    }    
    return balances;
  }
  
  /* Check the token allowances of a specific contract for multiple tokens.
     Returns array of deposited token balances in wei units. */
  function tokenAllowances(address spenderContract, address user, address[] calldata tokens) external view returns (uint[] memory allowances) {
    allowances = new uint[](tokens.length);
    
    for(uint i = 0; i < tokens.length; i++) {
      allowances[i] = tokenAllowance(spenderContract, user, tokens[i]); // check token allowance and catch errors
    }    
    return allowances;
  }


  /* Get multiple token balances deposited on a DEX using the traditional balanceOf function (EtherDelta, IDEX, Token Store, R1 protocol and many more).
     Returns array of deposited token balances in wei units. 
     
     This doesn't use the generic version (below) as this format is the most common and it is more efficient hardcoded
  */
  function depositedBalances(address exchange, address user, address[] calldata tokens) external view returns (uint[] memory balances) {
    balances = new uint[](tokens.length);
    Exchange ex = Exchange(exchange);
    
    for(uint i = 0; i < tokens.length; i++) {
      balances[i] = ex.balanceOf(tokens[i], user); //Errors if exchange does not implement 'balanceOf' correctly, use depositedBalancesGeneric instead.
    }    
    return balances;
  }

  /* Get multiple token balances deposited on a DEX with a function selector
       - Selector: hashed function signature, see 'getFunctionSelector'  
       - userFist:  determines whether the function uses foo(user, token) or foo(token, user)
     Returns array of deposited token balances in wei units. */
  function depositedBalancesGeneric(address exchange, bytes4 selector, address user, address[] calldata tokens, bool userFirst) external view returns (uint[] memory balances) {
    balances = new uint[](tokens.length);
    
    if(userFirst) {
      for(uint i = 0; i < tokens.length; i++) {
        balances[i] = getNumberTwoArgs(exchange, selector, user, tokens[i]);
      } 
    } else {
      for(uint i = 0; i < tokens.length; i++) {
        balances[i] = getNumberTwoArgs(exchange, selector, tokens[i], user);
      } 
    }
    return balances;
  }
  
  /* Get the deposited ETH balance for a DEX that uses a separate function for ETH balance instead of token 0x0.
       - Selector: hashed function signature, see 'getFunctionSelector'  
     Returns deposited balance in wei units. */
  function depositedEtherGeneric(address exchange, bytes4 selector, address user) external view returns (uint) {
    return getNumberOneArg(exchange, selector, user);
  }

  
 /* Private functions */


 /* Check the token balance of a wallet in a token contract.
    Returns 0 on a bad token contract   */
  function tokenBalance(address user, address token) internal view returns (uint) {
    // token.balanceOf(user), selector 0x70a08231
    return getNumberOneArg(token, 0x70a08231, user);
  }
  
  
  /* Check the token allowance of a wallet for a specific contract.
     Returns 0 on a bad token contract.   */
  function tokenAllowance(address spenderContract, address user, address token) internal view returns (uint) {
      // token.allowance(owner, spender), selector 0xdd62ed3e
      return getNumberTwoArgs(token, 0xdd62ed3e, user, spenderContract);
  }
  
  
  
  
  /* Generic private functions */
  
  // Get a token or exchange value that requires 1 address argument (most likely arg1 == user).
  // selector is the hashed function signature (see top comments)
  function getNumberOneArg(address contractAddr, bytes4 selector, address arg1) internal view returns (uint) {
    if(isAContract(contractAddr)) {
      (bool success, bytes memory result) = contractAddr.staticcall(abi.encodeWithSelector(selector, arg1));
      // if the contract call succeeded & the result looks good to parse
      if(success && result.length == 32) {
        return abi.decode(result, (uint)); // return the result as uint
      } else {
        return 0; // function call failed, return 0
      }
    } else {
      return 0; // not a valid contract, return 0 instead of error
    }
  }
  
  // Get an exchange balance requires 2 address arguments ( (token, user) and  (user, token) are both common).
  // selector is the hashed function signature (see top comments)
  function getNumberTwoArgs(address contractAddr, bytes4 selector, address arg1, address arg2) internal view returns (uint) {
    if(isAContract(contractAddr)) {
      (bool success, bytes memory result) = contractAddr.staticcall(abi.encodeWithSelector(selector, arg1, arg2));
      // if the contract call succeeded & the result looks good to parse
      if(success && result.length == 32) {
        return abi.decode(result, (uint)); // return the result as uint
      } else {
        return 0; // function call failed, return 0
      }
    } else {
      return 0; // not a valid contract, return 0 instead of error
    }
  }
  
  // check if contract (token, exchange) is actually a smart contract and not a 'regular' address
  function isAContract(address contractAddr) internal view returns (bool) {
    uint256 codeSize;
    assembly { codeSize := extcodesize(contractAddr) } // contract code size
    return codeSize > 0; 
    // Might not be 100% foolproof, but reliable enough for an early return in 'view' functions 
  }
}

    Contract ABI  
[{"constant":true,"inputs":[{"name":"exchange","type":"address"},{"name":"user","type":"address"},{"name":"tokens","type":"address[]"}],"name":"depositedBalances","outputs":[{"name":"balances","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"user","type":"address"},{"name":"tokens","type":"address[]"}],"name":"tokenBalances","outputs":[{"name":"balances","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"exchange","type":"address"},{"name":"selector","type":"bytes4"},{"name":"user","type":"address"},{"name":"tokens","type":"address[]"},{"name":"userFirst","type":"bool"}],"name":"depositedBalancesGeneric","outputs":[{"name":"balances","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"token","type":"address"},{"name":"amount","type":"uint256"}],"name":"withdrawToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"functionSignature","type":"string"}],"name":"getFunctionSelector","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"spenderContract","type":"address"},{"name":"user","type":"address"},{"name":"tokens","type":"address[]"}],"name":"tokenAllowances","outputs":[{"name":"allowances","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"admin","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"exchange","type":"address"},{"name":"selector","type":"bytes4"},{"name":"user","type":"address"}],"name":"depositedEtherGeneric","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]

  Contract Creation Code Switch To Opcodes View
608060405234801561001057600080fd5b5060008054600160a060020a03191633179055610c8c806100326000396000f3fe608060405234801561001057600080fd5b50600436106100b0576000357c0100000000000000000000000000000000000000000000000000000000900480639e281a98116100835780639e281a98146102b3578063de38c3d0146102df578063ed5835061461036c578063f851a440146103f5578063fe8b270714610419576100b0565b80631621c4e5146100b55780633ad206cc1461018e5780633ccfd60b1461020e57806383dfb65a14610218575b600080fd5b61013e600480360360608110156100cb57600080fd5b600160a060020a0382358116926020810135909116918101906060810160408201356401000000008111156100ff57600080fd5b82018360208201111561011157600080fd5b8035906020019184602083028401116401000000008311171561013357600080fd5b50909250905061046b565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561017a578181015183820152602001610162565b505050509050019250505060405180910390f35b61013e600480360360408110156101a457600080fd5b600160a060020a0382351691908101906040810160208201356401000000008111156101cf57600080fd5b8201836020820111156101e157600080fd5b8035906020019184602083028401116401000000008311171561020357600080fd5b509092509050610585565b610216610664565b005b61013e600480360360a081101561022e57600080fd5b600160a060020a038235811692600160e060020a03196020820135169260408201359092169181019060808101606082013564010000000081111561027257600080fd5b82018360208201111561028457600080fd5b803590602001918460208302840111640100000000831117156102a657600080fd5b91935091503515156106b9565b610216600480360360408110156102c957600080fd5b50600160a060020a0381351690602001356107a4565b61034f600480360360208110156102f557600080fd5b81019060208101813564010000000081111561031057600080fd5b82018360208201111561032257600080fd5b8035906020019184600183028401116401000000008311171561034457600080fd5b509092509050610872565b60408051600160e060020a03199092168252519081900360200190f35b61013e6004803603606081101561038257600080fd5b600160a060020a0382358116926020810135909116918101906060810160408201356401000000008111156103b657600080fd5b8201836020820111156103c857600080fd5b803590602001918460208302840111640100000000831117156103ea57600080fd5b5090925090506108ac565b6103fd610935565b60408051600160a060020a039092168252519081900360200190f35b6104596004803603606081101561042f57600080fd5b50600160a060020a038135811691600160e060020a03196020820135169160409091013516610944565b60408051918252519081900360200190f35b604080518281526020808402820101909152606090828015610497578160200160208202803883390190505b5090508460005b8381101561057a57600160a060020a03821663f7888aec8686848181106104c157fe5b604080517c010000000000000000000000000000000000000000000000000000000063ffffffff8716028152600160a060020a036020938402959095013585166004820152938c166024850152516044808501949293509091829003018186803b15801561052e57600080fd5b505afa158015610542573d6000803e3d6000fd5b505050506040513d602081101561055857600080fd5b5051835184908390811061056857fe5b6020908102909101015260010161049e565b50505b949350505050565b6040805182815260208084028201019091526060908280156105b1578160200160208202803883390190505b50905060005b8281101561065b5760008484838181106105cd57fe5b90506020020135600160a060020a0316600160a060020a031614151561062f57610612858585848181106105fd57fe5b90506020020135600160a060020a0316610951565b828281518110151561062057fe5b60209081029091010152610653565b84600160a060020a031631828281518110151561064857fe5b602090810290910101525b6001016105b7565b505b9392505050565b600054600160a060020a0316331461067b57600080fd5b60008054604051600160a060020a0390911691303180156108fc02929091818181858888f193505050501580156106b6573d6000803e3d6000fd5b50565b6040805183815260208085028201019091526060908380156106e5578160200160208202803883390190505b50905081156107465760005b838110156107405761072088888888888681811061070b57fe5b90506020020135600160a060020a031661097e565b828281518110151561072e57fe5b602090810290910101526001016106f1565b5061079a565b60005b8381101561079857610778888887878581811061076257fe5b90506020020135600160a060020a03168961097e565b828281518110151561078657fe5b60209081029091010152600101610749565b505b9695505050505050565b600054600160a060020a031633146107bb57600080fd5b600160a060020a038216158015906108635750604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018390529051600160a060020a0384169163a9059cbb9160448083019260209291908290030181600087803b15801561083657600080fd5b505af115801561084a573d6000803e3d6000fd5b505050506040513d602081101561086057600080fd5b50515b151561086e57600080fd5b5050565b6000828260405160200180838380828437808301925050509250505060405160208183030381529060405280519060200120905092915050565b6040805182815260208084028201019091526060908280156108d8578160200160208202803883390190505b50905060005b8281101561092c5761090c86868686858181106108f757fe5b90506020020135600160a060020a0316610ad8565b828281518110151561091a57fe5b602090810290910101526001016108de565b50949350505050565b600054600160a060020a031681565b600061057d848484610b06565b600061065d827f70a082310000000000000000000000000000000000000000000000000000000085610b06565b600061098985610c58565b15610ad05760408051600160a060020a03858116602483015284811660448084019190915283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160e060020a0319891617815292518251600094606094938b169392918291908083835b60208310610a275780518252601f199092019160209182019101610a08565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114610a87576040519150601f19603f3d011682016040523d82523d6000602084013e610a8c565b606091505b5091509150818015610a9f575080516020145b15610ac557808060200190516020811015610ab957600080fd5b5051925061057d915050565b60009250505061057d565b50600061057d565b600061057d827fdd62ed3e00000000000000000000000000000000000000000000000000000000858761097e565b6000610b1184610c58565b15610c505760408051600160a060020a0384811660248084019190915283518084039091018152604490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16600160e060020a0319881617815292518251600094606094938a169392918291908083835b60208310610ba75780518252601f199092019160209182019101610b88565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855afa9150503d8060008114610c07576040519150601f19603f3d011682016040523d82523d6000602084013e610c0c565b606091505b5091509150818015610c1f575080516020145b15610c4557808060200190516020811015610c3957600080fd5b5051925061065d915050565b60009250505061065d565b50600061065d565b6000903b119056fea165627a7a723058209ec1b34e9428b104fd526403777143a32de84c73d0a325812cd5d4b6310b69480029

   Swarm Source:
bzzr://9ec1b34e9428b104fd526403777143a32de84c73d0a325812cd5d4b6310b6948

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.