Source code for uniswap.v3.multicall2
from eth_abi import decode
from eth_typing import ChecksumAddress
from web3.contract.contract import ContractFunction
from uniswap.EtherClient.web3_client import EtherClient
from uniswap.v3.models import Multicall2Call
from .base import BaseContract
[docs]class Multicall2(BaseContract):
"""
Multicall2 smart contract wrapper. It is using for pack
several read or write smart contract call in a one single call.
Please refer official documentation (no real documentation):
https://docs.uniswap.org/contracts/v3/reference/deployments
Refer to source code:
https://etherscan.io/address/0x5ba1e12693dc8f9c48aad8770482f4739beed696#code
Parameters
----------
client : EtherClient
EtherClient Client
address : ChecksumAddress
Address of the Multicall2 smart contract
abi_path : str, optional, default = "../utils/abis/multicall2.abi.json"
Path to the ABI of the Multicall2 start contract.
Attributes
----------
client: EtherClient
"""
def __init__(
self,
client: EtherClient,
address: ChecksumAddress,
abi_path: str = "../utils/abis/multicall2.abi.json",
):
super().__init__(client.w3, address, abi_path)
self.client = client
[docs] def aggregate_and_call(
self, functions: list[ContractFunction]
) -> list[Multicall2Call]:
"""
Run multiple smart contract call at once
Parameters
----------
functions: list[ContractFunction]
A list of contract call with input params.
Returns
-------
calls: list[Multicall2Call]
A list of contract call with returns.
"""
calls: list[Multicall2Call] = [
Multicall2Call(func_call=func) for func in functions
]
for func_call, call in zip(calls, functions):
func_call.outputs = call.abi["outputs"] # to trough exception
func_call.name = call.fn_name
multicall2_call: ContractFunction = self.functions.aggregate(
[
{
"target": call.func_call.address,
"callData": call.func_call._encode_transaction_data(),
}
for call in calls
]
)
block_number, results = multicall2_call.call()
for call, result in zip(calls, results):
list_of_typ = [i["type"] for i in call.outputs]
call.returns = decode(types=list_of_typ, data=result)
call.block_number = block_number
return calls