Links

Integrate Your dApp With the Aggregator

The AMM Aggregator provides a set of fully on-chain, general-purpose Solidity APIs that any dApp can use to integrate the Aggregator, and thus exploit its full potential. There are two main interfaces that enable this at the contract level: the AMM Interface (IAMM) and the AMM Aggregator Interface (IAMMAggregator).
The IAMM facilitates interaction with the API of any one AMM whitelisted by the Aggregator (such as Uniswap or Balancer). For each, there is a dedicated interface for dApp integration. Each interface is unique, but since all inherit the same code and interfaces, they are fundamentally similar, making integration with different AMMs very easy.
The IAMMAggregator, on the other hand, facilitates direct interaction with the APIs of the Aggregator.
IAMM
IAMMAggregator
  • Retrieve the IAMM name and current version
function info() external view returns(string memory name, uint256 version);
  • Retrieve, for a specific AMM, the address by which it represents Ethereum (e.g. the WETH address in case of Uniswap), the max number of tokens composing a pair, and a boolean value representing if the AMM of that specific pair supports multiple LPs with the same tokens inside (true) or not (false)
function data() external view returns(address ethereumAddress, uint256 maxTokensPerLiquidityPool, bool hasUniqueLiquidityPools);
  • Pass the LP token address and the LP token holder (owner) to retrieve the LP token balance, the respective LP token for the pair and the addresses of the pair tokens
function balanceOf(address liquidityPoolAddress, address owner) external view returns(uint256, uint256[] memory, address[] memory);
  • Pass an LP token address and 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 byLiquidityPool(address liquidityPoolAddress) external view returns(uint256, uint256[] memory, address[] memory);
  • Pass the pair token addresses and retrieve the circulating mount of the LP token of that pool; the LP token's 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 byTokens(address[] calldata liquidityPoolTokens) external view returns(uint256, uint256[] memory, address, address[] memory);
  • Pass an LP token token address, a numerator and a denominator useful for calculating a precise percentage, and retrieve: the relevant LP token amount percentage (calculated as LP token circulating total amount * numerator)/denominator); the pair token amounts as percentages (calculated as token amount in the pool * numerator)/denominator); and the addresses of the pair tokens
function byPercentage(address liquidityPoolAddress, uint256 numerator, uint256 denominator) external view returns (uint256, uint256[] memory, address[] memory);
  • Pass an LP token address and an LP token amount to retrieve the amounts of the pair tokens 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, 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 token (so the first one will be the amount expressed in the token amount input field); and the addresses of the pair tokens
function byTokenAmount(address liquidityPoolAddress, address tokenAddress, uint256 tokenAmount) external view returns(uint256, uint256[] memory, address[] memory);
  • This function is used to create a new liquidity pool and add liquidity to it in a specific AMM. Pass the array of 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. Retrieves the LP token amount achieved, the array containing the corresponding pair token amounts, the created LP token address and the array containing the corresponding tokens addresses. This method is not supported in Balancer verticalization.
function createLiquidityPoolAndAddLiquidity(address[] calldata tokenAddresses, uint256[] calldata amounts, bool involvingETH, address receiver) external payable returns(uint256, uint256[] memory, address, address[] memory);
  • Pass the LiquidityPoolData data to add liquidity to a specific AMM. Retrieves the resulting LP amount, an array containing the respective equivalent in pair tokens, and an array containing the addresses of the pair tokens.
function addLiquidity(LiquidityPoolData calldata data) external payable returns(uint256, uint256[] memory, address[] memory);
  • Pass an array containing one or more LiquidityPoolData data (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 thepair tokens addresses.
function addLiquidityBatch(LiquidityPoolData[] calldata data) external payable returns(uint256[] memory, uint256[][] memory, address[][] memory);
  • Pass the LiquidityPoolData data to remove liquidity from a specific AMM and retrieve the resulting LP amount , an array containing the respective equivalent in pair tokens, and an array containing the pair token addresses.
function removeLiquidity(LiquidityPoolData calldata data) external returns(uint256, uint256[] memory, address[] memory);
  • Pass an array containing one or more LiquidityPoolData 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 removeLiquidityBatch(LiquidityPoolData[] calldata data) external returns(uint256[] memory, uint256[][] memory, address[][] 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 getSwapOutput(address tokenAddress, uint256 tokenAmount, address[] calldata, address[] calldata path) view external returns(uint256[] memory);
  • Pass the swapData to swap liquidity through a specific AMM following a fixed path. Retrieves the output token amount swapped.
function swapLiquidity(SwapData calldata data) external payable returns(uint256);
  • Pass an array of swapData to swap multiple liquidities through specific AMMs following a fixed path. Retrieves an array containing the swapped output tokens.
function swapLiquidityBatch(SwapData[] calldata data) external payable returns(uint256[] memory);
  • Retrieve all IAMM instances addresses supported by the AMM Aggregator
function amms() external view returns (address[] memory);
  • Pass a liquidity pool token address 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 IAMM instance in consideration
function findByLiquidityPool(address liquidityPoolAddress) external view returns(uint256, uint256[] memory, address[] memory, address);
  • Pass a liquidity pool token address as input and retrieve the relevant name, version and the address of the IAMM instance in consideration
function info(address liquidityPoolAddress) external view returns(string memory name, uint256 version, address amm);
  • Pass a liquidity pool 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 a Balancer one), 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
function data(address liquidityPoolAddress) external view returns(address ethereumAddress, uint256 maxTokensPerLiquidityPool, bool hasUniqueLiquidityPools, address amm);

AMM Data Structures

The LiquidityPoolData struct used in addLiquidity, addLiquidityBatch, removeLiquidity and removeLiquidityBatch operations is composed as follows:
struct LiquidityPoolData {
address liquidityPoolAddress;
uint256 amount;
address tokenAddress;
bool amountIsLiquidityPool;
bool involvingETH;
address receiver;
}
  • liquidityPoolAddress -> the LP address chosen. This parameter must always be populated with the relative LP address even if you are using a pair token
  • amount -> the LP token amount or the pair token amount desired to be added/removed. If an LP token is being used the parameter represents the amount of LP tokens, if a pair token is being used the parameter represents the amount of pair tokens.
  • tokenAddress -> represents the address of the pair token (if used). If an LP token is being used (and therefore amountIsLiquidityPool == true), this parameter must be passed to 0x0000000000000000000000000000000000000000.
  • amountIsLiquidityPool -> a boolean value representing if the amount passed is a LP token (true) or pair token amount (false). In any case, as stated in the first point, the LP address parameter must always be passed
  • involvingETH -> a boolean value representing if ETH is involved in the LP or one of the pair tokens -> this is crucial for AMMs like Uniswap where Ethereum is represented by WETH. So for example if the LP is ETH/BUIDL involvingETH is true, if it is WETH/BUIDLinvolvingETH is false
  • receiver -> the receiver address of the addLiquidity or removeLiquidity operation
The SwapData struct used in swapLiquidity and swapLiquidityBatch operations is composed as follows:
struct SwapData {
bool enterInETH;
bool exitInETH;
address[] liquidityPoolAddresses;
address[] path;
address inputToken;
uint256 amount;
address receiver;
}
  • enterInETH -> a boolean value representing if the input token is ETH (true) or not (false). So for example if the input token is ETH enterInETH is true; if the input token is WETH enterInETH is false
  • exitInETH -> a boolean value representing if the output token is ETH (true) or not (false). So for example if the output token is ETH exitInETH is true, if output token is WETH exitInETH is false
  • liquidityPoolAddresses -> array containing the liquidity pool token addresses to be used in the swap operation. The first element of the array must necessarily contain the input token.
  • path -> array containing the path (represented by the tokens used) that the swap operation must follow
  • inputToken -> the address of the input token you want to swap
  • amount -> the input token amount to swap in the operation
  • receiver -> the output token receiver address
For example, if an operation swaps BUIDL for UNIFI and then for ARTE, BUIDL will be the input token and ARTE will be the output token. The liquidityPoolAddresses array will contain the BUIDL/UNIFI LP address in the first position, and the UNIFI/ARTE LP address in the second one. The swapPath array will contain UNIFI in the first position, and ARTE in the second one.