PendleRouter
Quick Start
- To see examples of how to call various functions, check our Example repository.
- To generate calldata for any functions, it's highly recommended to use Pendle's Hosted SDK. Using the SDK provides significant advantages in terms of gas efficiency, accurate price impacts, and ease of integration.
Overview
PendleRouter is a contract that aggregates callers' actions with various different SYs, PTs, YTs, and Markets. It does not have any special permissions or whitelists on any contracts it interacts with. Therefore, any third-party protocols can freely embed the router's logic into their code for better gas efficiency.
Please note that new versions of PendleRouter are released a couple of times per year. While older versions will continue to operate correctly, they will not receive new features. Up until now, the Router has had four versions:
- RouterV1, deployed on 23/11/2022 at
0x41FAD93F225b5C1C95f2445A5d7fcB85bA46713f
- RouterV2, deployed on 21/02/2023 at
0x0000000001e4ef00d069e71d6ba041b0a16f7ea0
, 15% to 20% more gas-optimized - RouterV3, deployed on 18/12/2023 at
0x00000000005BBB0EF59571E58418F9a4357b68A0
, supporting limit orders - RouterV4, deployed on 29/04/2023 at
0x888888888889758F76e7103c6CbF23ABbF58F946
, upgradable router to support new features and optimize the algorithm more easily without requiring partners to migrate. This is likely the last version of the Router with features being added gradually.
Since PendleRouter is a proxy to multiple implementations, the caller can call the desired functions, and the Router will resolve to the correct implementation. Please refer to the list of callable functions.
For a comprehensive understanding of the Pendle ecosystem, including key concepts and terminology, please refer to the Overview document.
Common Functions
Add/Remove Liquidity
addLiquiditySingleToken
: Add liquidity to a market with any ERC20 tokens.removeLiquiditySingleToken
: Remove liquidity from a market with ERC20 tokens.
Buy/Sell PT, YT
swapExactTokenForPt
: Swap an exact amount of a supported ERC20 token for PT.swapExactPtForToken
: Swap an exact amount of PT for a supported ERC20 token.swapExactTokenForYt
: Swap an exact amount of a supported ERC20 token for YT.swapExactYtForToken
: Swap an exact amount of YT for a supported ERC20 token.
Redeeming PT post-expiry for the underlying
RedeemPyToToken
: PY stands for PT and YT. Post-expiry, you no longer need YT to redeem.
Redeeming LP, YT yield
redeemDueInterestAndRewards
: Redeem the accrued interest and rewards from both the LP position and YT.
Importance of Using Pendle's SDK
We highly recommend using Pendle's SDK to generate calldata for several reasons:
- Gas Efficiency: The SDK leverages off-chain data to optimize gas usage, potentially reducing gas costs significantly.
- Accurate Price Impacts: The SDK provides precise calculations for swaps, ensuring better price impacts for users.
- Ease of Integration: By using the SDK, developers can seamlessly integrate Pendle's functionality into their applications, leveraging the full power of the swap aggregator, limit order system, and off-chain data preparation.
For on-chain operations, our Example repository contains useful helper functions and examples to assist you.
Off-chain Helpers
PendleRouter heavily relies on off-chain data to address three main issues:
- Swap Execution: Currently, Pendle's AMM only supports the built-in
swapExactPtForSy
andswapSyForExactPt
. To execute aswapExactTokenForPt
(which is essentially the same asswapExactSyForPt
), the router will conduct a binary search to determine the amount of PT to swap. While the binary search can be done entirely on-chain, limiting the search range off-chain will result in significantly less gas consumption for this function. - Liquidity Fragmentation: Liquidity is currently fragmented across a large number of pools across various DEXes. Integrating only Uniswap or Balancer has proven to be insufficient. As a result, PendleRouter has natively integrated KyberSwap to swap from any ERC20 token to another. For KyberSwap to work, the routing algorithm must be called off-chain and then pass the routing results to the Router to execute.
- Limit Order System: The limit order system of Pendle exists solely off-chain. Including these limit orders in on-chain swaps can significantly improve the price impact for users, particularly during large-size swaps.
Important Structs in PendleRouter
While most function arguments should be straightforward, using structs can be less intuitive. PendleRouter is a sophisticated contract that supports various powerful features and relies on off-chain pre-computed data to help save gas. Below are the important structs and instructions on how to fill them:
ApproxParams
struct ApproxParams {
uint256 guessMin;
uint256 guessMax;
uint256 guessOffchain;
uint256 maxIteration;
uint256 eps;
}
guessMin
andguessMax
: The minimum and maximum values for binary search.maxIteration
: The maximum number of times binary search will be performed.eps
: The precision of binary search - the maximum proportion of the input that can be unused.eps
is 1e18-based, so aneps
of 1e14 implies that no more than 0.01% of the input might be unused.guessOffchain
: This is the first answer to be checked before performing any binary search. If the answer already satisfies the conditions, we skip the search and save significant gas.
In case off-chain data cannot be provided, the parameters can be passed as:
guessMin: 0, // adjust as desired
guessMax: type(uint256).max, // adjust as desired
guessOffchain: 0, // strictly 0
maxIteration: 256, // adjust as desired
eps: 1e14 // max 0.01% unused, adjust as desired
Please note that in this situation, the parameters can be fine-tuned to narrow the search range for optimal gas usage or to reduce the number of unused inputs.
TokenInput & TokenOutput
struct TokenInput {
// TOKEN DATA
address tokenIn;
uint256 netTokenIn;
address tokenMintSy;
// AGGREGATOR DATA
address pendleSwap;
SwapData swapData;
}
struct TokenOutput {
// TOKEN DATA
address tokenOut;
uint256 minTokenOut;
address tokenRedeemSy;
// AGGREGATOR DATA
address pendleSwap;
SwapData swapData;
}
Overview
Pendle system doesn't interact with the underlying token. Swaps happen between SY <-> PT, SY <-> YT, etc. Hence, TokenInput
& TokenOutput
are data about the conversion between the underlying token and the corresponding SY.
- TokenInput: Users start with
netTokenIn
oftokenIn
, using a swap aggregator to convert those tokens totokenMintSy
, and thosetokenMintSy
is used to mint SY. - TokenOutput: Users receive SY & redeem the SY to
tokenRedeemSy
. These tokens are swapped through an aggregator totokenOut
.
TokenInput
tokenIn
&netTokenIn
: Token & amount that the user starts with.tokenMintSy
: The token used to mint SY. Must be inSY.getTokensIn()
. IftokenMintSy != tokenIn
, aggregator data must be populated.pendleSwap
: Address of swap helper, do not hardcode.swapData
: Data for swap, generated by Pendle's SDK.
Aggregator data can be generated by Pendle's SDK. If no aggregator is used, tokenIn = tokenMintSy
, pendleSwap = address(0)
, and swapData
is empty.
TokenOutput
tokenOut
&minTokenOut
: Token & minimal amount that the user finally receives.tokenRedeemSy
: The token used to redeem SY. Must be inSY.getTokensOut()
. IftokenRedeemSy != tokenOut
, aggregator data must be populated.pendleSwap
: Address of swap helper, do not hardcode.swapData
: Data for swap, generated by Pendle's SDK.
If no aggregator is used, tokenOut = tokenRedeemSy
, pendleSwap = address(0)
, and swapData
is empty.
LimitOrderData
struct LimitOrderData {
address limitRouter;
uint256 epsSkipMarket;
FillOrderParams[] normalFills;
FillOrderParams[] flashFills;
bytes optData;
}
LimitOrderData is generated using Pendle's SDK. If not using a limit order, all fields can be set to address(0)
or empty.