Elastic Periphery Core Contracts

Router

The Router contract to handle swapping.

Struct: ExactInputSingleParams

Contains data for swap exact input with a single pool.

ExactInputSingleParams
    address tokenIn;     // source token to swap
    address tokenOut;    // dest token to receive
    uint16 fee;          // fee of the pool to swap
    address recipient;   // the recipient of tokenOut
    uint256 deadline;    // deadline for the transaction
    uint256 amountIn;    // the amount of tokenIn to swap
    uint256 minAmountOut;// min acceptable amount of tokenOut
    uint160 limitSqrtP;  // the limit of sqrt price, partial swap if price reaches the limitation

Struct: ExactInputParams

Contains data for swap exact input with one or multiple pools.

ExactInputParams
    bytes path;           // contains data to identify list of pools to use for the swap
    address recipient;    // the recipient of token out
    uint256 deadline;     // deadline for the transaction
    uint256 amountIn;     // the amount of token in to swap
    uint256 minAmountOut; // the min acceptable amount of token out

Struct: ExactOutputSingleParams

Contains data for swap to an exact amount out of token out, using only one pool.

Struct: ExactOutputParams

Contains data for swap to an exact amount out of token out using one or multiple pools.

swapCallback()

Callback function that is be triggerred by the pool when swapping tokens. Either deltaQty0 or deltaQty1 must be positive. Positive value means the pool (also the caller) is expecting to receive that amount of token.

swapExactInputSingle()

Given the params of ExactInputSingleParams, it uses only one pool to swap exact an amountIn of tokenIn to tokenOut and return the amount of tokenOut from the swap. It calls the swap function in the pool contract, the pool will transfer the tokenOut to the Router, and expect to receive the corresponding tokenIn in the swap callback function.

swapExactInput()

Given the params of ExactInputParams, it uses only one or multiple pools that can be decoded from the path. It calls the swap function in each pool contract that is decoded from the path param, and uses callback to handle transferring tokens.

Flow:

  • Swap path: tokenIn -> token0 -> token1 -> ... -> tokenOut.

  • Call the first pool to borrow token0 to the Router, then transfer tokenIn from user's wallet to the first pool.

  • Call the second pool to borrow token1 to the Router, then transfer token0 from the Router to the second pool.

  • Repeat the action until the last pool, and transfer tokenOut directly to the recipient.

swapExactOutputSingle()

Given the params of ExactOutputSingleParams, it uses only one pool to swap to get exact amountOut of tokenOut (or stop if price limit reaches).

  • Call the swap function in the pool contract.

  • The pool transfers the tokenOut to the recipient, and make the swap callback.

  • The Router transfer the corresponding tokenIn from user's wallet to the pool. The required amount of tokenIn should not be greater than maxAmountIn.

swapExactOutput()

Given the params of ExactOutputParams, it uses one or multiple pools that can be decoded from the path. It calls the swap function in each pool contract that is decoded from the path param, and uses callback to handle transferring tokens. The list of pools in the path params should be in the reverse order, i.e the last pool first since we don't know the exact amount of token in to be used.

Flow:

  • Origial swap path: tokenIn -> token0 -> token1 -> ... -> tokenN -> tokenOut.

  • Reverse swap path: tokenOut -> tokenN -> ... -> token1 -> token0 -> tokenIn.

  • Consider as we are swapping from amountOut of tokenOut to tokenIn.

BasePositionManager

Inherit from an ERC721 contract, it stores all positions of all liquidity providers and mint corresponding NFT.

Users can use the PositionManager to create & unlock pool, mint new position, add/remove liquidity to/from an existing position and burn their reinvestment tokens to receive back the LP fees.

It also inherits from Multicall contract, thus, users can make multiple function/method calls to the PositionManager in a single transaction.

All reinvestment tokens will be held in the contract, thus, it blocks anyone from transferring reinvestment tokens out. As a result, the contract can not support pools with any reinvestment tokens.

Struct: MintParams

Params for the first time adding liquidity, mint new nft to sender

Struct: IncreaseLiquidityParams

Params for adding liquidity to the existing position

Struct: RemoveLiquidityParams

Params for remove liquidity from the existing position

Struct: BurnRTokenParams

Burn the rTokens to get back token0 + token1 as fees

createAndUnlockPoolIfNecessary()

Use this function to create & unlock a pool if needed given (token0, token1, fee) params and the initial sqrt price. Required: token0 < token1

mint()

Call the _addLiquidity function in the LiquidityHelper contract with the data from *params. It mints a new NFT token represents the position to the recipient, stores the position data and pool information.

addLiquidity()

Call the _addLiquidity function in the LiquidityHelper contract with the data from params to add more liquidity to a given position (i.e tokenId). Calculate and update the additional reinvestment tokens that the position should have earned.

removeLiquidity()

Call the burn function in the pool contract with the data from params to remove liquidity and get back 2 tokens. Calculate and update the additional reinvestment tokens that the position should have earned.

burnRTokens()

Call the burnRTokens function in the pool contract to burn all reinvestment tokens from the position and get back 2 tokens. Return the amount of reinvestment tokens to burn and expected amounts of 2 tokens to receive

Functions: tokenURI(), getApproved(), _approve(), _getAndIncrementNonce()

Overriding functions for the inherited ERC721 and permit contracts.

AntiSnipAttackPositionManager

Inherits BasePositionManager and adds the anti-sniping attack feature into addLiquidity and removeLiquidity functions.

Reinvestment tokens of a position will be locked and vested to prevent LPs from adding then removing liquidity within a small period of time.

The motivation, mechanism and formula for Anti-Sniping Attack can be found here. The AntiSnipingAttack library will be of interest as well.

Last updated

Was this helpful?