Protocol
Guides
Creating a pool

Creating a pool

Asset & quote pair

Before trying to create a new pool, the first thing to do is to check if the pair of asset & quote tokens we want to use already exists. This can be done by calling the getPairId function:

address USDC = 0x07865c6E87B9F70255377e024ace6630C1Eaa37F;
address USDT = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
 
uint24 pairId = portfolio.getPairId(USDC, USDT);

If the returned pairId is 0, this means that the pair does not exist yet and must be created. To do so, we are going to use the createPair function:

address USDC = 0x07865c6E87B9F70255377e024ace6630C1Eaa37F;
address USDT = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
 
uint24 pairId = portfolio.createPair(USDC, USDT);

This function will then return the pairId of the newly created pair. Pairs only need to be created once and can be reused in the future for different pools, read more about them here.

ℹ️

Keep in mind that only tokens with 6 to 18 decimals are supported.

Pool parameters

Primitive Portfolio is a permissionless protocol, meaning that the only requirement to create new pools is to pass valid parameters. Since we just created a new pair, it's now time to use it to create a new pool by calling the createPool function.

Here is a list of the parameters that are required by the createPool function:

NameTypeDescription
pairIduint24Nonce of the target pair. A 0 is a magic variable to use the state variable getPairNonce instead.
controlleraddressAn address that can change the fee and priorityFee parameters of the created pool.
priorityFeeuint16Priority fee for the pool (10,000 being 100%). This is a percentage of fees paid by the controller when swapping.
feeuint16Fee for the pool (10,000 being 100%). This is a percentage of fees paid by the users when swapping.
volatilityuint16Expected volatility of the pool in basis points, minimum of 1 (0.01%) and maximum of 25,000 (250%).
durationuint16Quantity of days (in units of days) until the pool "expires". Uses type(uint16).max as a magic variable to set perpetual = true.
strikePriceuint128Terminal price of the pool once maturity is reached (expressed in the quote token), in WAD units.
priceuint128Initial price of the pool (expressed in the quote token), in WAD units.

This is what a call looks like:

uint64 poolId = portfolio.createPool(pairId, address(this), 10, 100, 10_000, 365, 1 ether, 1 ether);

Example

Here is a complete working example showing how to create a pair and a pool:

CreatePoolExample.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
 
import "portfolio/interfaces/IPortfolio.sol";
 
contract CreatePoolExample {
  IPortfolio public portfolio;
  address public asset;
  address public quote;
 
  constructor(address portfolio_, address asset_, address quote_) {
      portfolio = IPortfolio(portfolio_);
      asset = asset_;
      quote = quote_;
  }
 
  function createPool() external {
      // Creating a new pool is quite simple, first we need to get the pairId
      // for our asset / quote pair. We can use the function `getPairId`.
      // Note that If the `pairId` is 0, this means that we need to create
      // a new pair before trying to create the pool.
      uint24 pairId = portfolio.getPairId(asset, quote);
 
      // Lastly, we can call the `createPool` function with our parameters:
      portfolio.createPool(
          pairId, address(this), 10, 100, 10_000, 365, 1 ether, 1 ether
      );
  }
}

You can check out the full code showing how to create a pair (opens in a new tab) and how to create a pool (opens in a new tab) in our Portfolio Solidity examples repository (opens in a new tab) on Github.

© 2023 Primitive™