Integrate Your dApp With the Aggregator

There are two main interfaces contracts that enable the interaction with the AMM Aggregator: the AMM Interface (IAMM) and the AMM Aggregator Interface (IAMMAggregator).

IAMM

For each AMM supported by the Aggregator, there is a specific model contract that has all the specific methods to interact with that specific AMM. So there are:

Each supported AMM has its own specific model because each AMM might have specific methods different from the others to interact with.

Each model contract implements the IAMM interface that provides general methods to execute operations on the AMM. Since all the model implements the same IAMM interface contract, you can interact with all the AMM supported in a common way, using the same methods. The IAMM facilitates interaction with the API of anyone AMM whitelisted by the Aggregator.

This means that a developer doesn't have to write specific methods to interact with a specific AMM in the code of its application but can use the general purpose methods that the IAMM interface proposes.

Think of a Farming contract where a developer would have to write methods for adding and removing liquidity to/from the pool of an AMM using the specific addLiquidity and removeLiquidity methods. To support a second AMM he should create another separate Farming contract or he could add in the code the specific methods of addLiquidity and removeLiquidity and so on. Using the AMM Aggregator it is possible to create a Farming contract that using the add/remove liquidity methods of the IAMM supports all the AMMs whitelisted by the Aggregator.

Using the AMM Aggregator it is possible to create DeFi general purpose multi-AMM applications and protocols.

API List

The following methods are the IAMM methods that all supported AMM models have:

function info() external view returns(string memory name, uint256 version)

Retrieve the specific AMM model name and current version.

function data() external view returns(address ethereumAddress, uint256 maxTokensPerLiquidityPool, bool hasUniqueLiquidityPools);

Retrieve, for a specific AMM, the address by which it represents ETH (e.g. the WETH address in case of Uniswap), the max number of tokens composing a pair (e.g. 2 for Uniswap, Sushiswap and Mooniswap and 0 representing infinite for Balancer), and a boolean value representing if the AMM of that specific pair supports multiple LPs with the same tokens inside (e.g. true for Uniswap, Sushiswap and Mooniswap) or not (e.g. false for Balancer).

function balanceOf(address liquidityPoolAddress, address owner) external view returns(uint256, uint256[] memory, address[] memory);

Pass the LP token address and the LP token holder (owner) to retrieve: the LP token balance of the owner, the pair tokens amount corresponding to the LP balance of the owner, and the addresses of the pair tokens.

function byLiquidityPool(address liquidityPoolAddress) external view returns(uint256, uint256[] memory, address[] memory);

Pass an LP token address to retrieve: the circulating amount of the LP token of that pool, the total amounts of the pair tokens in the pool, and the addresses of the pair tokens.

function byTokens(address[] calldata liquidityPoolTokens) external view returns(uint256, uint256[] memory, address, address[] memory);

Pass the pair token addresses to retrieve the circulating amount of the corresponding LP token; the LP token address; the amounts of the pair tokens in that pool; and addresses of the pair tokens. This method works only if _hasUniqueLiquidityPools is true for that specific AMM; so, only if the AMM does not support multiple LPs with the same pairs. The function always returns the ordered list of tokens exactly as the AMM itself returns it.

function byPercentage(address liquidityPoolAddress, uint256 numerator, uint256 denominator) external view returns (uint256, uint256[] memory, address[] memory);

Pass an LP token address, a numerator and a denominator useful for calculating a precise percentage, to retrieve: the relevant LP token amount percentage calculated as LP token total amount in the pool*(numerator/denominator),the pair token amounts as percentages calculated as tokens amount in the pool*(numerator/denominator); and the addresses of the pair tokens.

function byLiquidityPoolAmount(address liquidityPoolAddress, uint256 liquidityPoolAmount) external view returns(uint256[] memory, address[] memory);

Pass an LP token address and an LP token amount to retrieve the corresponding amounts of the pair tokens and the addresses of the pair tokens.

function byTokenAmount(address liquidityPoolAddress, address tokenAddress, uint256 tokenAmount) external view returns(uint256, uint256[] memory, address[] memory);

Pass an LP token address, the address of one of the pair tokens and an amount of that token to retrieve the equivalent amount of the LP token, the equivalent amount of the pair tokens (so the first one will be the amount expressed in the token amount input field); and the addresses of the pair tokens.

function createLiquidityPoolAndAddLiquidity(address[] calldata tokenAddresses, uint256[] calldata amounts, bool involvingETH, address receiver) external payable returns(uint256, uint256[] memory, address, address[] memory);

This function is used to create a new liquidity pool and add liquidity to it in the specific AMM. Pass the pair token addresses, the token amounts, a boolean value representing if ETH is involved as one of the tokens (true) or not (false), and the receiver address (pass addresss(0) if the receiver is the msg.sender). Retrieves the LP token amount achieved, the corresponding pair token amounts added, the created LP token address and the corresponding tokens addresses used to create the pool. This method is not supported in Balancer verticalization.

function addLiquidity(LiquidityPoolData calldata data) external payable returns(uint256, uint256[] memory, address[] memory);

Pass the LiquidityPoolData struct to add liquidity to a specific AMM. Retrieves the resulting LP amount, the respective equivalent in pair tokens, and the addresses of the pair tokens.

function addLiquidityBatch(LiquidityPoolData[] calldata data) external payable returns(uint256[] memory, uint256[][] memory, address[][] memory);

Pass an array containing one or more LiquidityPoolData struct (look at the previous point) and retrieve the resulting LP amount array, an array containing the array of the respective equivalent in pair tokens, and an array containing the array of the pair tokens addresses.

function removeLiquidity(LiquidityPoolData calldata data) external returns(uint256, uint256[] memory, address[] memory);

Pass the LiquidityPoolData struct to remove liquidity from a specific AMM and retrieve the resulting LP amount , the respective equivalent in pair tokens, and the pair token addresses.

function removeLiquidityBatch(LiquidityPoolData[] calldata data) external returns(uint256[] memory, uint256[][] memory, address[][] memory);

Pass an array containing one or more LiquidityPoolData struct and retrieve the resulting LP amount array, an array containing the array of the respective equivalent in pair tokens, and an array containing the array of the pair token addresses.

function getSwapOutput(address tokenAddress, uint256 tokenAmount, address[] calldata, address[] calldata path) view external returns(uint256[] memory);

Pass a token address, the desired amount to swap, an array containing the LP addresses involved in the swap operation and an array representing the path the operation must follow, and retrieve an array containing the amount of tokens used during the swap operation, including the final token amount (in the last position) and the input token amount (in the first position).

function swapLiquidity(SwapData calldata data) external payable returns(uint256);

Pass the swapData struct to swap liquidity through a specific AMM following a fixed path. Retrieves the output token amount swapped.

function swapLiquidityBatch(SwapData[] calldata data) external payable returns(uint256[] memory);

Pass an array of swapData to swap multiple liquidities through a specific AMM following a fixed path. Retrieves an array containing the swapped output tokens.

IAMMAggregator

The IAMMAggregator, on the other hand, facilitates direct interaction with the APIs of the Aggregator. It provides some general utility methods to retrieve information and data at once from all the AMM, and so all the models contracts, whitelisted by the Aggregator.

The following methods are the IAMMAggregator methods:

function amms() external view returns (address[] memory);

Retrieve all the AMM models instances addresses supported by the AMM Aggregator.

function findByLiquidityPool(address liquidityPoolAddress) external view returns(uint256, uint256[] memory, address[] memory, address);

Pass an LP token address (of any of the whitelisted AMMs) as input and retrieve the LP token total circulating amount, the pair tokens respective total amount in the pool, the pair tokens respective addresses and the address of the AMM model instance in consideration.

function info(address liquidityPoolAddress) external view returns(string memory name, uint256 version, address amm);

Pass an LP token (of any of the whitelisted AMMs) address as input and retrieve the relevant name, version and the address of the AMM model instance in consideration.

function data(address liquidityPoolAddress) external view returns(address ethereumAddress, uint256 maxTokensPerLiquidityPool, bool hasUniqueLiquidityPools, address amm);

Pass an LP token address and retrieve by which address Ethereum is represented (e.g. WETH address in case of Uniswap), the max number of tokens that can possibly compose the pair of that specific liquidity pool (if the number is infinite, it returns 0; so, for example, 2 for a Uniswap pool and 0 for Balancer), a boolean value representing if the AMM of that specific pool supports multiple LPs with the same tokens inside (e.g. true for an Uniswap pool, false for a Balancer one) and the address of the AMM in consideration.

Last updated