Predy V6
  • Welcome to Predy V6
  • Trader
    • Apps
    • Tutorial: Perp
    • Tutorial: Gamma
  • dev
    • Predy Protocol
    • Architecture
      • Flowchart
    • Squart
    • Position Value
    • Interest Rate Model
    • Market Contracts
    • Contracts
  • Github
  • Resources
Powered by GitBook
On this page
  • Overview
  • Functional Diagram
  • Actors
  • Operator/PoolCreator
  • Lender
  • Trader
  • Filler
  • Liquidator
  • Reallocator
  • PredyPool
  • RegisterPair
  • updateAssetRiskParams
  • updateFeeRatio
  • Supply
  • Withdraw
  • Trade
  • Liquidation
  • Reallocation
  • Take
  • Market Contracts
  • Interact with the pool and manage funds
  • Example Sequence of a Trade
  • PriceFeedFactory
  • PriceFeed
  • getSqrtPrice
  1. dev

Architecture

PreviousPredy ProtocolNextFlowchart

Last updated 12 months ago

Overview

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.

Functional Diagram

Actors

Operator/PoolCreator

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.

Lender

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.

Trader

Filler

The Filler is responsible for actually submitting and executing the Trader's orders on the blockchain. The Filler can determine the token exchange routes.

Liquidator

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.

Reallocator

PredyPool

RegisterPair

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.

struct AddPairParams {
    address quoteToken;
    address poolOwner;
    address uniswapPool;
    address priceFeed;
    bool whitelistEnabled;
    uint8 fee;
    Perp.AssetRiskParams assetRiskParams;
    InterestRateModel.IRMParams quoteIrmParams;
    InterestRateModel.IRMParams baseIrmParams;
}

updateAssetRiskParams

struct AssetRiskParams {
    uint128 riskRatio;
    uint128 debtRiskRatio;
    int24 rangeSize;
    int24 rebalanceThreshold;
    uint64 minSlippage;
    uint64 maxSlippage;
}

updateFeeRatio

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.

Supply

It is a function to provide either the quoteToken or the baseToken to the lending pool. In return, the lender receives bond tokens.

Withdraw

It is a function to withdraw either the quoteToken or the baseToken from the lending pool. In return, the lender burns the bond tokens.

Trade

function trade(TradeParams memory tradeParams, bytes memory settlementData)
    external
    returns (TradeResult memory tradeResult);

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.

struct TradeParams {
    uint256 pairId;
    uint256 vaultId;
    int256 tradeAmount;
    int256 tradeAmountSqrt;
    bytes extraData;
}

Liquidation

Calculating Slippage Tolerance

Reallocation

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).

Take

Market Contracts

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.

interface IHooks {
    function predySettlementCallback(
        address quoteToken,
        address baseToken,
        bytes memory settlementData,
        int256 baseAmountDelta
    ) external;

    function predyTradeAfterCallback(
        IPredyPool.TradeParams memory tradeParams,
        IPredyPool.TradeResult memory tradeResult
    ) external;

Interact with the pool and manage funds

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.

Example Sequence of a Trade

PriceFeedFactory

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.

function createPriceFeed(
  address quotePrice,
  bytes32 priceId,
  uint256 decimalsDiff
) external returns (address)

PriceFeed

getSqrtPrice

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.

The Trader deposits margin and trades perps and . The Trader signs the order and passes the order and signature to the . The Filler is responsible for executing the actual transaction.

The Reallocator is responsible for reallocating the Uniswap V3 LP positions held by PredyPool to maintain . Reallocation can be performed by anyone. The protocol does not incur any losses from the reallocation process.

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 . poolOwner specifies the address that can update the pool's settings. priceFeed specifies 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 . When whitelistEnabled is set to true, only specific addresses can trade in this pool. In assetRiskParams, risk parameters that determine the and the range size of Uniswap LP position are specified.

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 rrr and rdebtr_{debt}rdebt​ in The rangeSize and rebalanceThreshold are explained in the .

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 / .

It is a function to trade perp and using quoteToken as collateral. It is intended to be called by the .

If the 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.

For specific reallocation methods, please refer to and .

The take function is explained .

Squart
https://github.com/predyprotocol/predyx/blob/main/src/libraries/logic/LiquidationLogic.sol#L159
Squarts
Filler
Squart
market contract
here
Interest Rate Model
the contract
feeRatio
Squart
Reallocation section
the activity flow
Min. Value
this equation.
vaultValue
minMargin
Vault Value
The process of shorting 1 WETH with a collateral of 100 USDC
Drawing