Deploy Your Own Pool in Perpetual Pools V2A Developer's Guide to Deploying Your Own Market on Perpetual Pools V2
Authored by CalabashSquash
One of the most exciting features of Tracer Perpetual Pools V2 is the ability for anyone, anywhere to deploy their own derivative market. The permissionless nature of Tracer means that communities and individuals have the power of derivatives at their palms, without requiring any input from the Tracer team.
Currently permissionless deployment is active on V2, however there is currently no interface to interact with for this, meaning you need some knowledge to be able to deploy your own market. While this interface is coming soon and will enable the everyday user to deploy new markets, there is nothing stopping you from doing this yourself, right now, with a little bit of tooling and technical know-how.
What is a pool?
A pool, in Tracer’s Perpetual Pools, refers to a market where you can deposit collateral (The “settlement token”), and gain leveraged exposure to a particular price feed.
For example, right now on the pools.tracer.finance page, you can see a pool which allows users to deposit USDC into and gain exposure to the ETH/USD price feed with 10x leverage. In fact, I recently deployed that myself, without any governance interactions. 100% permissionlessly. Let’s see how I did it.
What parameters are configurable?
Before we get into the nitty-gritty, I want to explain which parameters you can actually change.
The amount of settlement tokens that are transferred from the losing side to the winning side are dependent on the change in the underlying price feed, and the leverage. The function for calculating this can be found here.
The update interval is the frequency of market updates in seconds. e.g. 3600 is 1 hour.
A market update refers to the process that occurs at a fixed time interval, where the pool’s balances are updated based on the oracle price, and new commitments are executed.
The frontrunning interval is the minimum number of seconds one must wait before their commitment is executed. This exists because otherwise, individuals could frontrun the oracle and mint into the favourable side of a price change, capturing at least a very large percentage of the value transfer.
Minting & Burning Fees
The minting/burning fee is the percentage of each mint/burn that is taken and then put back into that side's collateral. This exists as a potential way to mitigate against volatility decay, because each mint adds back a little bit to the valuation of all tokens.
- It is worth noting that the burning fee should be set to a value above zero with caution. This is because it may be perceived as rug pull-ish if people can enter a pool, but have to pay a fee to leave. For this reason, their is a smart contract-enforced limit on the burn fee of 10%.
The changeInterval is the amount which the minting fee can change per update interval based on whether there is volatility decay. That is to say
longPrice * shortPrice < 1 -> mintingFee += changeInterval. It is recommended to set this to 0 unless you know what you are doing.
The Settlement Token
The settlement token is which ERC20 token that is used to invest into the pool. This is one of the unique features of pools. You can have an ETH/USD market settled in $gOHM. Or a BTC/ETH market settled in $WBTC. The possibilities for experimenting with new markets are endless.
- It is recommended to not use rebasing tokens for settlement.
The address that controls the minting/burning fees and the change interval. It is recommended to set this to the Tracer developer multisig (0x0f79e82aE88E1318B8cfC8b4A205fE2F982B928A), otherwise you might have a hard time getting people to trust your market (besides, it likely won’t get approved and listed on our front-end).
The Pool Name
This is just a string that can be used to identify the pool easily. It is recommended to follow the format “BASE/QUOTE+SETTLEMENT”. For example “BTC/USD+USDC” for a BTC/USD market settled in USDC. The smart contract factory automatically prepends the leverage to the pool name.
The Price Feed
The feed of data used to determine price changes of the leveraged tokens. For example, the
10-ETH/USD+USDC market uses an 8 hour SMA (simple moving average) ETH/USD oracle.
Length of SMA Sampling Period
If you are using a SMA price feed, you can choose how many hours you want to sample from. For example, you can do the past 24 hours, or the past 5 hours, etc.
- Note that your pool’s front-running interval should generally be equal to or greater than the sample length. Your pool’s update interval should also equal the frequency of SMA polling (e.g. polling the SMA price every hour means your pool should have an update interval of 1 hour).
How to Deploy a Pool
Now we can look at how to execute the deployment.
There is a script in the Perpetual Pools repo that makes pool deployment easy. You can find this script here: https://github.com/tracer-protocol/perpetual-pools-contracts/blob/73a7b787b4dca2509f010089afa3a0fea50f1cdd/scripts/deploy.ts
Starting from this line, you can start modifying parameters. Make sure to read the comments to better understand what each one does.
To make things just a little bit more complicated, you have the option of using a spot price oracle wrapper, or a Simple Moving Average (SMA) price oracle wrapper.
SMA oracle wrappers work by taking in a
ChainlinkOracleWrapper, and wrapping itself around that. Read these lines in the deployment script, to see the deployment process, and refer to the diagram below to visualise this.
Figure 1: SMAOracles wrap around a ChainlinkOracleWrapper, which wraps around a Chainlink Oracle.
Because of this, you can modify the
usingSMA variable to
false if you would like to instead use a spot price. This will skip the deployment of the
SMAOracle. Keeping it set to
true will, however, deploy a spot price oracle wrapper, and deploy an
SMAOracle using this oracle wrapper as its input price feed.
Running the script
Once you have gone into the script and modified all of the parameters, you are ready to run the script.
First, clone the perpetual-pools contract:
git clone https://github.com/tracer-protocol/perpetual-pools-contracts.git
Then, set your environment variables
For Arbitrum Mainnet:
export ALCHEMY_API_ARBITRUM_URL="<YOUR_RPC_URL>" export ARBITRUM_PRIVATE_KEY="<YOUR_PRIVATE_KEY>"
or for Arbitrum Rinkeby Testnet:
export ALCHEMY_API_TESTNET_URL="<YOUR_RPC_URL>" export TESTNET_PRIVATE_KEY="<YOUR_PRIVATE_KEY>"
npx hardhat --network <network_name> run scripts/deploy.ts
<network_name> is either
arb for Arbitrum Mainnet, or
You should get output similar to this:
~/path/to/perpetual-pools-contracts$ npx hardhat --network arbRinkeby run scripts/deploy.ts No need to generate any newer typings. Deployed oracleWrapper: 0xA9E26Abb9c1Bf75D2336A4dF82F5601Fec2a92dA ##### Deploying a market with the following parameters ##### poolName: BTC/USD+USDC frontRunningInterval: 28800 updateInterval: 3600 leverageAmount: 1 settlementToken: 0xb0Ad46bD50b44cBE47E2d83143E0E415d6A842F6 oracleWrapper: 0x24De9Ffc6E1C7097bB49DC883E89CBEC519Acd18 settlementEthOracle: 0x33C0257eda38e0b85Da0ed54Bc27D03dFa62664d feeController: 0xb0Ad46bD50b44cBE47E2d83143E0E415d6A842F6 mintingFee: 0 burningFee: 0 changeInterval: 0 Pool address: 0x2bF00aFFDFD5d95A26471CA8dcCc10e92818c281 PoolCommitter address: 0x4101704C3177533C8B442413d6874aAe70dd59e1
How do I get this market added to the front-end?
There are two ways this can be done.
You can either add it manually, by scrolling to the bottom of the page, clicking “Display Alternative Pool”, and copy the
Pool address: from the command-line output you got when running the script.
The other way is to follow the process described here: https://pools.docs.tracer.finance/factory/pools-factory/adding-a-market-to-the-app
It can be a bit of an involved process, but once you get an understanding of the script it’s quite simple. Now you can deploy any market you can think of (provided there is a price feed!). Go and try for yourself.