Develop a solution that utilizes the concept of multi calls to fetch prices from Uniswap. The solution should allow for the retrieval of multiple token prices in a single call, rather than multiple separate API requests. The objective is to improve efficiency by reducing the number of calls to the blockchain node. The user should be able to input an index of the desired token prices, and the solution should return the prices in a single call.
-
Uniswap is a decentralized exchange that enables peer-to-peer market making. Uniswap API is commonly used by developers to build DeFi applications like Token swapping, AMM, and Decentralized Exchange(DEX), etc.
-
Uniswap V2 : It is used to determine the price of tokens and it has improved token listing process.
-
Reason to retrieve multiple token prices in a single API call : To improve efficiency by reducing the number of calls to the blockchain node.
-
Batch Requests : Batch Requests to our blockchain node, are when we send a list of data inputs to our call to our blockchain nodes. BUT batching requests has some issue as they can't handle a lot of nodes and some service don't even support them. So instead of batch requests we use Multicall.
-
Multicall : Instead of making a ton of requests like massive batch thing, we call one function of an on-chain contract that takes unlimited parameter and we define the functions we want the contract to call. So basically we are going to make a single API call to retrieve data of function having multiple parameters and this is known as Multicall.
- Store Multicall Address in
UniswapMulticallAddress
variable. - Store ABI(Application Binary Interface) of Multicall in
UniswapMulticallABI
variable which provides necessary information about contract like functions, etc.
const UniswapMulticallAddress = Address;
const UniswapMulticallABI = [{},];
- Now use new web3.eth.Contract() which is used to interact with Smart Contract.
const UniswapMulticall = new web3.eth.Contract(UniswapMulticallABI, UniswapMulticallAddress);
-
Create a async function fetchTokenPrices which takes an array of token indices as its input arguement. The purpose of the function is to retrieve the token prices for the token specified by the indices and return them in a single call.
-
Make an array calls which will contain a list of objects, each representing a call to the Uniswap Multicall contract to retrieve the price of a specific token.
-
Add encodeFunctionCall which is a function provided by Web3.js library to encode the data of function call into the ABI format.
- first arguement will hold information about the function name, type and inputs.
- second arguement will hold the tokenIndex which represents the index of token whose price is to be retrieved from Multicall contract.
async function fetchTokenPrices(tokenIndices) {
const calls = tokenIndices.map((tokenIndex) => {
return web3.eth.abi.encodeFunctionCall(
{
name: 'getTokenPrice',
type: 'function',
inputs: [
{
type: 'address',
name: 'token',
},
],
},
[tokenIndex],
);
});
-
Add the .aggregate method which is the main method of the contract that allows for multiple calls to be made in a single transaction.
-
Pass calls in the aggregate method, it is the array that is created in previous step, which contains the encoded function calls to retrieve the prices of multiple tokens.
-
Call .call(), it is a method which sends a read-only request to the Ethereum Network. The result of this is stored in result variable which is an array of 32 bytes encoded values representing the token prices returned by Multicall contract.
const result = await UniswapMulticall.methods
.aggregate(calls)
.call();
-
Create a loop that decodes the result returned from contract, basically traverse till calls length.
-
In each iteration of the loop, encodedResult is assigned the next 32 bytes (Here 32 bytes means token prices).
-
Then the encodedResult is passed as an arguement to the web3.eth.abi.decodeParameter to decode the result using uint256 ABI encoding.
-
Return the tokenPrices.
const tokenPrices = {};
for (let i = 0; i < calls.length; i++) {
const encodedResult = result.slice(i * 32, (i + 1) * 32);
const decodedResult = web3.eth.abi.decodeParameter('uint256', encodedResult);
tokenPrices[tokenIndices[i]] = decodedResult;
}
return tokenPrices;
}
-
Store the token index in tokenIndices.
-
And finally use our function fetchTokenPrices and pass tokenIndices as an arguement to get the price of tokens at a single call.
const tokenIndices = [
'xxxxxx1',
'xxxxxx2',
'xxxxxx3',
];
fetchTokenPrices(tokenIndices)
.then((tokenPrices) => {
console.log(tokenPrices);
})
.catch((error) => {
console.error(error);
});
- Output :
Output: { 'xxxxxx1': 100.0, 'xxxxxx2': 200.0, 'xxxxxx3': 300.0 }
- Utilizes the concept of multi calls to fetch prices from Uniswap
- Retrieval of multiple tokens prices in a single call
- Improved Efficiency
- User can input the index of the desired token prices
- Returns prices in a single call