Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example: Multicall using TokenLists (Uniswap default lists) #40

Open
juanfranblanco opened this issue Jun 9, 2021 · 0 comments
Open

Comments

@juanfranblanco
Copy link
Member

using System;
using System.Numerics;
using System.Threading.Tasks;
using Nethereum.Web3;
using Nethereum.ABI.FunctionEncoding.Attributes;
using Nethereum.Contracts;
using System.Collections.Generic;
using Nethereum.Hex.HexConvertors.Extensions;
using System.Collections;
using Newtonsoft.Json;
using System.Linq;

public class Program
{
    //Example of using multicall https://github.com/makerdao/multicall/blob/master/src/Multicall.sol
    //calling contract deployed at https://etherscan.io/address/0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441#code


    public class Version
    {
        public int Major { get; set; }
        public int Minor { get; set; }
        public int Patch { get; set; }
    }

    public class Token
    {
        public int ChainId { get; set; }
        public string Address { get; set; }
        public string Symbol { get; set; }
        public string Name { get; set; }
        public int Decimals { get; set; }
    }

    public class Root
    {
        public string Name { get; set; }
        public DateTime Timestamp { get; set; }
        public List<string> Keywords { get; set; }
        public Version Version { get; set; }
        public List<Token> Tokens { get; set; }
        public string LogoURI { get; set; }
    }

    [Function("balanceOf", "uint256")]
    public class BalanceOfFunction : FunctionMessage
    {
        [Parameter("address", "_owner", 1)] public string Owner { get; set; }
    }


    public partial class Call : CallBase { }

    public class CallBase
    {
        [Parameter("address", "target", 1)]
        public virtual string Target { get; set; }
        [Parameter("bytes", "callData", 2)]
        public virtual byte[] CallData { get; set; }
    }

    public partial class AggregateFunction : AggregateFunctionBase { }

    [Function("aggregate", typeof(AggregateOutputDTO))]
    public class AggregateFunctionBase : FunctionMessage
    {
        [Parameter("tuple[]", "calls", 1)]
        public virtual List<Call> Calls { get; set; }
    }

    public partial class AggregateOutputDTO : AggregateOutputDTOBase { }

    [FunctionOutput]
    public class AggregateOutputDTOBase : IFunctionOutputDTO
    {
        [Parameter("uint256", "blockNumber", 1)]
        public virtual BigInteger BlockNumber { get; set; }
        [Parameter("bytes[]", "returnData", 2)]
        public virtual List<byte[]> ReturnData { get; set; }
    }


    [FunctionOutput]
    public class BalanceOfOutputDTO : IFunctionOutputDTO
    {
        [Parameter("uint256", "balance", 1)]
        public BigInteger Balance { get; set; }
    }

    //https://tokenlists.org/
    public static string TokensJSON = @"{""name"":""Uniswap Default List"",""timestamp"":""2021-01-21T23:57:10.982Z"",""version"":{""major"":2,""minor"":0,""patch"":0},""tags"":{},""logoURI"":""ipfs://QmNa8mQkrNKp1WEEeGjFezDmDeodkWRevGFN8JCV7b4Xir"",""keywords"":[""uniswap"",""default""],""tokens"":[{""chainId"":1,""address"":""0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9"",""name"":""Aave"",""symbol"":""AAVE"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/12645/thumb/AAVE.png?1601374110""},{""chainId"":1,""address"":""0xfF20817765cB7f73d4bde2e66e067E58D11095C2"",""name"":""Amp"",""symbol"":""AMP"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/12409/thumb/amp-200x200.png?1599625397""},{""name"":""Aragon Network Token"",""address"":""0x960b236A07cf122663c4303350609A66A7B288C0"",""symbol"":""ANT"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x960b236A07cf122663c4303350609A66A7B288C0/logo.png""},{""name"":""Balancer"",""address"":""0xba100000625a3754423978a60c9317c58a424e3D"",""symbol"":""BAL"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xba100000625a3754423978a60c9317c58a424e3D/logo.png""},{""chainId"":1,""address"":""0xBA11D00c5f74255f56a5E366F4F77f5A186d7f55"",""name"":""Band Protocol"",""symbol"":""BAND"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/9545/thumb/band-protocol.png?1568730326""},{""name"":""Bancor Network Token"",""address"":""0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C"",""symbol"":""BNT"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x1F573D6Fb3F13d689FF844B4cE37794d79a7FF1C/logo.png""},{""name"":""Compound"",""address"":""0xc00e94Cb662C3520282E6f5717214004A7f26888"",""symbol"":""COMP"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xc00e94Cb662C3520282E6f5717214004A7f26888/logo.png""},{""name"":""Curve DAO Token"",""address"":""0xD533a949740bb3306d119CC777fa900bA034cd52"",""symbol"":""CRV"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xD533a949740bb3306d119CC777fa900bA034cd52/logo.png""},{""chainId"":1,""address"":""0x41e5560054824eA6B0732E656E3Ad64E20e94E45"",""name"":""Civic"",""symbol"":""CVC"",""decimals"":8,""logoURI"":""https://assets.coingecko.com/coins/images/788/thumb/civic.png?1547034556""},{""name"":""Dai Stablecoin"",""address"":""0x6B175474E89094C44Da98b954EedeAC495271d0F"",""symbol"":""DAI"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x6B175474E89094C44Da98b954EedeAC495271d0F/logo.png""},{""chainId"":1,""address"":""0x0AbdAce70D3790235af448C88547603b945604ea"",""name"":""district0x"",""symbol"":""DNT"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/849/thumb/district0x.png?1547223762""},{""name"":""Gnosis Token"",""address"":""0x6810e776880C02933D47DB1b9fc05908e5386b96"",""symbol"":""GNO"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x6810e776880C02933D47DB1b9fc05908e5386b96/logo.png""},{""chainId"":1,""address"":""0xc944E90C64B2c07662A292be6244BDf05Cda44a7"",""name"":""The Graph"",""symbol"":""GRT"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/13397/thumb/Graph_Token.png?1608145566""},{""chainId"":1,""address"":""0x85Eee30c52B0b379b046Fb0F85F4f3Dc3009aFEC"",""name"":""Keep Network"",""symbol"":""KEEP"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/3373/thumb/IuNzUb5b_400x400.jpg?1589526336""},{""name"":""Kyber Network Crystal"",""address"":""0xdd974D5C2e2928deA5F71b9825b8b646686BD200"",""symbol"":""KNC"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xdd974D5C2e2928deA5F71b9825b8b646686BD200/logo.png""},{""name"":""ChainLink Token"",""address"":""0x514910771AF9Ca656af840dff83E8264EcF986CA"",""symbol"":""LINK"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x514910771AF9Ca656af840dff83E8264EcF986CA/logo.png""},{""name"":""Loom Network"",""address"":""0xA4e8C3Ec456107eA67d3075bF9e3DF3A75823DB0"",""symbol"":""LOOM"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xA4e8C3Ec456107eA67d3075bF9e3DF3A75823DB0/logo.png""},{""name"":""LoopringCoin V2"",""address"":""0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD"",""symbol"":""LRC"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xBBbbCA6A901c926F240b89EacB641d8Aec7AEafD/logo.png""},{""chainId"":1,""address"":""0x0F5D2fB29fb7d3CFeE444a200298f468908cC942"",""name"":""Decentraland"",""symbol"":""MANA"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/878/thumb/decentraland-mana.png?1550108745""},{""name"":""Maker"",""address"":""0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2"",""symbol"":""MKR"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2/logo.png""},{""chainId"":1,""address"":""0xec67005c4E498Ec7f55E092bd1d35cbC47C91892"",""name"":""Melon"",""symbol"":""MLN"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/605/thumb/melon.png?1547034295""},{""name"":""Numeraire"",""address"":""0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671"",""symbol"":""NMR"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671/logo.png""},{""chainId"":1,""address"":""0x4fE83213D56308330EC302a8BD641f1d0113A4Cc"",""name"":""NuCypher"",""symbol"":""NU"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/3318/thumb/photo1198982838879365035.jpg?1547037916""},{""name"":""Orchid"",""address"":""0x4575f41308EC1483f3d399aa9a2826d74Da13Deb"",""symbol"":""OXT"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x4575f41308EC1483f3d399aa9a2826d74Da13Deb/logo.png""},{""name"":""Republic Token"",""address"":""0x408e41876cCCDC0F92210600ef50372656052a38"",""symbol"":""REN"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x408e41876cCCDC0F92210600ef50372656052a38/logo.png""},{""name"":""Reputation Augur v1"",""address"":""0x1985365e9f78359a9B6AD760e32412f4a445E862"",""symbol"":""REP"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x1985365e9f78359a9B6AD760e32412f4a445E862/logo.png""},{""name"":""Reputation Augur v2"",""address"":""0x221657776846890989a759BA2973e427DfF5C9bB"",""symbol"":""REPv2"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x221657776846890989a759BA2973e427DfF5C9bB/logo.png""},{""name"":""Synthetix Network Token"",""address"":""0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F"",""symbol"":""SNX"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F/logo.png""},{""name"":""Storj Token"",""address"":""0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC"",""symbol"":""STORJ"",""decimals"":8,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xB64ef51C888972c908CFacf59B47C1AfBC0Ab8aC/logo.png""},{""chainId"":1,""address"":""0x8dAEBADE922dF735c38C80C7eBD708Af50815fAa"",""name"":""tBTC"",""symbol"":""TBTC"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/11224/thumb/tBTC.png?1589620754""},{""name"":""UMA Voting Token v1"",""address"":""0x04Fa0d235C4abf4BcF4787aF4CF447DE572eF828"",""symbol"":""UMA"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x04Fa0d235C4abf4BcF4787aF4CF447DE572eF828/logo.png""},{""name"":""Uniswap"",""address"":""0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"",""symbol"":""UNI"",""decimals"":18,""chainId"":1,""logoURI"":""ipfs://QmXttGpZrECX5qCyXbBQiqgQNytVGeZW5Anewvh2jc4psg""},{""name"":""USDCoin"",""address"":""0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"",""symbol"":""USDC"",""decimals"":6,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/logo.png""},{""name"":""Tether USD"",""address"":""0xdAC17F958D2ee523a2206206994597C13D831ec7"",""symbol"":""USDT"",""decimals"":6,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xdAC17F958D2ee523a2206206994597C13D831ec7/logo.png""},{""name"":""Wrapped BTC"",""address"":""0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"",""symbol"":""WBTC"",""decimals"":8,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599/logo.png""},{""name"":""Wrapped Ether"",""address"":""0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"",""symbol"":""WETH"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/logo.png""},{""chainId"":1,""address"":""0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e"",""name"":""yearn finance"",""symbol"":""YFI"",""decimals"":18,""logoURI"":""https://assets.coingecko.com/coins/images/11849/thumb/yfi-192x192.png?1598325330""},{""name"":""0x Protocol Token"",""address"":""0xE41d2489571d322189246DaFA5ebDe1F4699F498"",""symbol"":""ZRX"",""decimals"":18,""chainId"":1,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xE41d2489571d322189246DaFA5ebDe1F4699F498/logo.png""},{""name"":""Dai Stablecoin"",""address"":""0xaD6D458402F60fD3Bd25163575031ACDce07538D"",""symbol"":""DAI"",""decimals"":18,""chainId"":3,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xaD6D458402F60fD3Bd25163575031ACDce07538D/logo.png""},{""name"":""Uniswap"",""address"":""0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"",""symbol"":""UNI"",""decimals"":18,""chainId"":3,""logoURI"":""ipfs://QmXttGpZrECX5qCyXbBQiqgQNytVGeZW5Anewvh2jc4psg""},{""name"":""Wrapped Ether"",""address"":""0xc778417E063141139Fce010982780140Aa0cD5Ab"",""symbol"":""WETH"",""decimals"":18,""chainId"":3,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xc778417E063141139Fce010982780140Aa0cD5Ab/logo.png""},{""name"":""Dai Stablecoin"",""address"":""0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735"",""symbol"":""DAI"",""decimals"":18,""chainId"":4,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735/logo.png""},{""name"":""Maker"",""address"":""0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85"",""symbol"":""MKR"",""decimals"":18,""chainId"":4,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85/logo.png""},{""name"":""Uniswap"",""address"":""0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"",""symbol"":""UNI"",""decimals"":18,""chainId"":4,""logoURI"":""ipfs://QmXttGpZrECX5qCyXbBQiqgQNytVGeZW5Anewvh2jc4psg""},{""name"":""Wrapped Ether"",""address"":""0xc778417E063141139Fce010982780140Aa0cD5Ab"",""symbol"":""WETH"",""decimals"":18,""chainId"":4,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xc778417E063141139Fce010982780140Aa0cD5Ab/logo.png""},{""name"":""Uniswap"",""address"":""0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"",""symbol"":""UNI"",""decimals"":18,""chainId"":5,""logoURI"":""ipfs://QmXttGpZrECX5qCyXbBQiqgQNytVGeZW5Anewvh2jc4psg""},{""name"":""Wrapped Ether"",""address"":""0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6"",""symbol"":""WETH"",""decimals"":18,""chainId"":5,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6/logo.png""},{""name"":""Dai Stablecoin"",""address"":""0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa"",""symbol"":""DAI"",""decimals"":18,""chainId"":42,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa/logo.png""},{""name"":""Maker"",""address"":""0xAaF64BFCC32d0F15873a02163e7E500671a4ffcD"",""symbol"":""MKR"",""decimals"":18,""chainId"":42,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xAaF64BFCC32d0F15873a02163e7E500671a4ffcD/logo.png""},{""name"":""Uniswap"",""address"":""0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"",""symbol"":""UNI"",""decimals"":18,""chainId"":42,""logoURI"":""ipfs://QmXttGpZrECX5qCyXbBQiqgQNytVGeZW5Anewvh2jc4psg""},{""name"":""Wrapped Ether"",""address"":""0xd0A1E359811322d97991E03f863a0C30C2cF029C"",""symbol"":""WETH"",""decimals"":18,""chainId"":42,""logoURI"":""https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/0xd0A1E359811322d97991E03f863a0C30C2cF029C/logo.png""}]}";

    //async Task Main to enable async methods

    private static async Task Main(string[] args)
    {
        //Connecting to Ethereum mainnet using Infura
        var web3 = new Web3("https://mainnet.infura.io/v3/7238211010344719ad14a89db874158c");
        var tokens = JsonConvert.DeserializeObject<Root>(TokensJSON);
        var aggregateFunction = new AggregateFunction();
        aggregateFunction.Calls = new List<Call>();
        var tokenCount = 30;

        for (int i = 0; i < tokenCount; i++)
        {
            //Setting the owner https://etherscan.io/tokenholdings?a=0x8ee7d9235e01e6b42345120b5d270bdb763624c7
            var balanceOfMessage = new BalanceOfFunction() { Owner = "0x8ee7d9235e01e6b42345120b5d270bdb763624c7" };
            var call = new Call();
            call.CallData = balanceOfMessage.GetCallData();
            call.Target = tokens.Tokens[i].Address;
            aggregateFunction.Calls.Add(call);
        }
     
        
        //Creating a new query handler
        var queryHandler = web3.Eth.GetContractQueryHandler<AggregateFunction>();

        var returnCalls = await queryHandler
            .QueryDeserializingToObjectAsync<AggregateOutputDTO>(aggregateFunction, "0xeefBa1e63905eF1D7ACbA5a8513c70307C1cE441")
            .ConfigureAwait(false);

        for (int i = 0; i < tokenCount; i++)
        {
            var balance = new BalanceOfOutputDTO().DecodeOutput(returnCalls.ReturnData[i].ToHex());
            Console.WriteLine("Balance of " + tokens.Tokens[i].Name);
            Console.WriteLine(Web3.Convert.FromWei(balance.Balance, tokens.Tokens[i].Decimals));
        }

   
    }
@juanfranblanco juanfranblanco changed the title Example: Multicall using TokenLists Example: Multicall using TokenLists (Uniswap default lists) Jun 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant