BiPoolManager

This section describes the solidity internals of the BiPoolManager and is intended for smart contract developers. Consumers of the protocol will normally use the SDK to interact with the protocol. If you want to learn more about the overall design check the Asset Exchanges section.

BiPoolManager is the first implementation of an IExchangeProvider which manages virtual asset pools that consist of two assets. It is responsible for managing pools and using their state to price swaps. It also checks if trading is allowed or suspended as decided by the on-chain circuit breaker via the BreakerBox contract.

Pool Structures

The PoolExchange and PoolConfig structures are the underlying data structures used by the BiPoolManager to implement a vAMM bi-pool (i.e. a pool with two assets).

PoolExchange

struct PoolExchange {
  address asset0;
  address asset1;
  IPricingModule pricingModule;
  uint256 bucket0;
  uint256 bucket1;
  uint256 lastBucketUpdate;
  PoolConfig config;
}

PoolConfig

struct PoolConfig {
  FixidityLib.Fraction spread;
  address referenceRateFeedID; // rateFeedID of the price that this pool follows (i.e. it's reference rate)
  uint256 referenceRateResetFrequency;
  uint256 minimumReports;
  uint256 stablePoolResetSize;
}

Discovering Exchanges

IExchangeProvider.Exchange[] memory exchanges = biPoolManager.getExchanges();
bytes32 exchangeId = exchanges[0].exchangeId;
address asset0 = exchanges[0].assets[0];
address asset1 = exchanges[0].assets[1];

This returns the generic exchange structures that are shared between all implementers of the IExchangeProvider interface, this is why the assets is an array, to account for potential 3-asset pools in the future.

You can then also query the internal representation:

IBiPoolManager.PoolExchange pool = biPoolManager.getPoolExchange(exchangeId);

Estimating Swaps

uint256 amountOut = biPoolManager.getAmountOut(
    exchangeId,
    assetIn,
    assetOut,
    amountIn
)

This function calculates the expected output tokens you will receive for a given amount of input tokens. It is what the Broker uses internally in its own estimating swaps function.

There is also getAmountIn which calculates the required input tokens needed to receive a given amount of output tokens.

Executing Swaps

uint256 amountOut = biPoolManager.swapIn(
    exchangeId,
    assetIn,
    assetOut,
    amountIn
);    

This function executes, in that it prices the swap and, specifically when interacting with PoolExchanges utilizing the ConstantProduct pricing module, updates the virtual bucket sizes. However, it’s important to note that for PoolExchanges configured with the ConstantSum pricing module, bucket sizes remain unchanged during swaps. The Broker uses the return value to determine how many output tokens to transfer to the initiator for the input tokens received. Similarly, there's a swapOut function that fixes the output tokens and returns a variable amount of input tokens required.

Both the swapIn and swapOut functions on the BiPoolManager only deal with virtual token amounts. The Broker is responsible for making sure that the initiator has actually given the protocol the tokens required or that the Reserve has enough tokens to pay the initator.

Last updated