Architecture
Last updated
Last updated
This project features multiple market contracts centered around PredyPool. The market contracts define financial products and order types. Markets can leverage positions by utilizing PredyPool for token lending and borrowing. This architecture is highly scalable. For example, developers can create new futures exchanges with minimal code and gain leverage by connecting to PredyPool.
Currently, the Operator and PoolCreator are the same and hold the admin role in the Predy protocol. Operator can register pairs and PoolCreator can update the parameters of registered pairs.
A Lender is a user who provides tokens to Predy. These provided tokens are borrowed by traders when they open positions. Traders pay interest to the Lender, and in return, the Lender provides leverage to the traders.
The Trader deposits margin and trades perps and Squarts. The Trader signs the order and passes the order and signature to the Filler. The Filler is responsible for executing the actual transaction.
The Filler is responsible for actually submitting and executing the Trader's orders on the blockchain. The Filler can determine the token exchange routes.
When a trader's position meets the conditions for liquidation, the Liquidator forcibly closes the position. Liquidators can earn profits from the differences in the liquidation process.
The Reallocator is responsible for reallocating the Uniswap V3 LP positions held by PredyPool to maintain Squart. Reallocation can be performed by anyone. The protocol does not incur any losses from the reallocation process.
Register a pair of quoteToken and baseToken. In practice, register the corresponding Uniswap pool with the quoteToken. The token in the Uniswap pool that is not the quoteToken will become the baseToken.
For example, when specifying the address of USDC as the quoteToken
and the ETH/USDC pool as the uniswapPool
, the baseToken
is automatically set to ETH, and a new pair is registered in Predy.
Let's look at the parameters in detail. We have already explained quoteToken
and uniswapPool
. quoteIrmParams
and baseIrmParams
define the interest rate curves for the deposited tokens. For specific usage, please refer to the Interest Rate Model. poolOwner specifies the address that can update the pool's settings. priceFeed
specifies the contract that can obtain the oracle price for the pair. If a zero address is specified, the TWAP from the UniswapPool will be used as the oracle price. The fee
indicates the percentage of the fee. it`s the same as the feeRatio. When whitelistEnabled
is set to true, only specific addresses can trade in this pool. In assetRiskParams
, risk parameters that determine the Min. Value and the range size of Uniswap LP position are specified.
The minSlippage
and maxSlippage
parameters define the slippage tolerance of the execution price from the oracle price during liquidation. The slippage tolerance is determined within the range of minSlippage
and maxSlippage
, based on the value of vaultValue / minMargin.
The feeRatio
indicates the percentage of the fee. For example, if the feeRatio
is 10%, 10% of the borrowing interest is collected as a fee. Half of this, 5%, goes to the protocol, and the other half, 5%, goes to the pool creator.
It is a function to provide either the quoteToken or the baseToken to the lending pool. In return, the lender receives bond tokens.
It is a function to withdraw either the quoteToken or the baseToken from the lending pool. In return, the lender burns the bond tokens.
It is a function to trade perp and Squart using quoteToken as collateral. It is intended to be called by the market contract.
In tradeParams
, specify pairId
, vaultId
, and the amounts of perp and Squart. If vaultId
is 0, a new vault is created. settlementData
is passed directly to predySettlementCallback
, and extraData
will be used inpredyTradeAfterCallback
.
If the Vault Value becomes smaller than the Min. Margin, the vault can be forcefully closed. The liquidation price is determined through a Dutch auction, based on the ratio of Vault Value to Min Margin.
The value of slippageTolerance
is determined by the ratio of vaultValue
to minMargin
. The smaller the vaultValue/minMargin ratio, the larger the slippageTolerance
. As slippageTolerance
increases, the difference between the market price and the liquidation price also grows, thereby providing a greater incentive for the liquidator. https://github.com/predyprotocol/predyx/blob/main/src/libraries/logic/LiquidationLogic.sol#L159
The Reallocate
function repositions the LP (Liquidity Provider) funds within the specified range as described in Squart. This function can be called by anyone.
This section explains how to allocate the LP range effectively. The relevant parameters for this process are rangeSize
and rebalanceThreshold
.
rangeSize
specifies the width of the LP range.
rebalanceThreshold
specifies the threshold at which reallocation occurs.
For example, if the current tick of the UniswapPool is 100, the rangeSize
is 200, and the rebalanceThreshold
is 100, the initial range is (-100, 300), and the reallocation threshold is set at (0, 200). If the tick exceeds 200, the LP position is reallocated around the current tick. If the tick becomes 210, the new range will be (10, 410).
For specific reallocation methods, please refer to Squart and the activity flow.
The take
function is explained here.
The MarketContract defines the specifics of a market. For example, it implements an intent-based approach (signature verification with permit2, swaps on Uniswap, delta hedging, etc.). The MarketContract needs to have the following functions:
predySettlementCallback: defines the method for exchanging tokens.
predyTradeAfterCallback: defines the method for adding collateral.
Within the callback, the MarketContract can call the take
function of the PredyPool. The take
function allows any amount of tokens to be sent from the PredyPool to any destination. After the callback finishes, the PredyPool verifies that there are no issues with the token amount difference.
Specifically, in the case of predySettlementCallback
, the difference in quoteToken is reflected in the entryValue (i.e., the entry price). In the case of predyTradeAfterCallback
, the difference in quoteToken is reflected in the collateral. The system then checks the safety of the vault and verifies that there are no issues with the trade.
PriceFeedFactory is the factory contract for the PriceFeed contract. The PriceFeed contract can be used as the priceFeed
parameter when registering a pair. In quotePrice
, specify the Chainlink address corresponding to the USD-denominated price of the quoteToken
. In priceId
, specify the Pyth address corresponding to the USD-denominated price of the baseToken
. The decimalsDiff
parameter adjusts the decimal places. As a return value, the address of the PriceFeed contract is returned.
It returns the square root value of the baseToken price denominated in quoteToken. Similar to Uniswap's sqrtPriceX96, the value is scaled by 2^96.
Let's look at the parameters in detail. The riskRatio
and debtRiskRatio
are parameters used to calculate the minimum margin required to maintain a position. They correspond to and in this equation. The rangeSize
and rebalanceThreshold
are explained in the Reallocation section.