Routing
Useful routes to perform protocol operations in a single transaction.
The Router can aggregate operations across ERC4626 protocol vaults, the Principal Token contract and the associated pools (e.g PT-IBT Curve Pools). This gives users access highly-flexible and personalised transactions.
The Router is inspired from the Uniswap UniversalRouter.
How commands work ?
All transactions to the Router
go through the execute
functions:
execute(bytes calldata commands, bytes[] calldata inputs, uint256 deadline)
execute(bytes calldata commands, bytes[] calldata inputs)
The first of these functions checks for a deadline parameter. If the block.timestamp
is after the deadline
provided the transaction will revert. After that check, the 2 functions otherwise execute identically.
The execute
functions takes a list of commands , and a list of encoded inputs for each command and execute them in the order specified.
Available Commands
The flexible commands allow users to:
Add liquidity in the Curve pools
Remove liquidity from the Curve pools
Deposit in Principal Tokens
Deposit in Interest Bearing Tokens
Wrap vault in ERC-4626 Wrapper
Redeem from Principal Tokens
Redeem from Interest Bearing tokens
Unwrap vault from ERC-4626 Wrapper
Transfer ERC-20 tokens from Router to any address
Transfer ERC-20 tokens from
msg.sender
to RouterTransfer ERC-20 tokens from
msg.sender
to Router with ERC-2612 permit. Compatible with ERC-4626 IBTs, PTs and YTs.
The list of all the commands along with the accepted parameters can be found in the Router guide.
Some Useful Routes
Add liquidity
Add liquidity with assets
This route exclusively uses underlying tokens as input and carries out all necessary deposits and computations to deposit in the PT-IBT pool at the current spot price of the pool, maintaining the same ratios.
The steps involve:
TRANSFER_FROM: Transfer the underlying tokens from the depositor's wallet to the Router.
DEPOSIT_ASSET_IN_IBT: Deposit all underlying tokens in the specified ERC4626 IBT contract to receive IBT shares.
CURVE_SPLIT_IBT_LIQUIDITY: From the pool's balances, divide the liquidity between the IBT to be added to the pool and the IBT to be deposited in the Principal Token contract in exchange for PT and YT shares. Send the minted YT shares to the user.
CURVE_ADD_LIQUIDITY: Add IBT and PT liquidity to the Curve Pool. Send the Curve LP token to the user.
Example of how to use the router commands to create transactions in Solidity:
Add liquidity with IBTs
This route directly takes IBT shares as input and performs all necessary deposits and computations to deposit in the PT-IBT pool at the current spot price of the pool, maintaining the same ratios.
The steps involve:
TRANSFER_FROM: Transfer the IBTs from the depositor's wallet to the Router.
CURVE_SPLIT_IBT_LIQUIDITY: From the pool's balances, divide the liquidity between the IBT to add to the pool and the IBT to deposit in the Principal Token contract in exchange for PT and YT shares. Send the minted YT shares to the user.
CURVE_ADD_LIQUIDITY: Add IBT and PT liquidity to the Curve Pool. Send the Curve LP token to the user.
Remove liquidity
Remove liquidity for assets
This route withdraws liquidity from Curve, returning the redeemed underlying assets to the user.
The steps involve:
TRANSFER_FROM: Transfer Curve LP tokens from the user's balance to the Router.
TRANSFER_FROM: Transfer the required amount of YT tokens to the Router. This step is necessary only before expiry, as after expiry, redeeming shares from the PT contract does not require the user to burn the YT.
This step is needed before expiry only as after expiry redeeming shares from the PT contract doesn't require the user to burn the YT.
CURVE_REMOVE_LIQUIDITY: Remove liquidity from Curve to retrieve IBT and PT.
REDEEM_PT_FOR_ASSET: Redeem the PT and YT shares from the PT and send assets to the user.
REDEEM_IBT_FOR_ASSET: Redeem the IBT shares from the IBT and send assets to the user.
TRANSFER: Transfer any remaining PTs or YTs if not all PTs and YTs were burnt during the redemption process.
Remove liquidity for IBTs
This route withdraws liquidity from Curve, returning the IBTs to the user.
The steps involve:
TRANSFER_FROM: Transfer Curve LP tokens from the user's balance to the Router.
TRANSFER_FROM: Transfer the required amount of YT tokens to the Router. This step is necessary only before expiry, as after expiry, redeeming shares from the PT contract does not require the user to burn the YT.
This step is needed before expiry only as after expiry redeeming shares from the PT contract doesn't require the user to burn the YT.
CURVE_REMOVE_LIQUIDITY: Remove liquidity from Curve to retrieve IBT and PT.
REDEEM_PT_FOR_IBT: Redeem the PT and YT shares from the PT and send IBTs to the user.
TRANSFER: Transfer any remaining PTs or YTs if not all PTs and YTs were burnt during the redemption process.
Exchange your Yield Tokens
Exchange IBT for YT
This route is used to exchange IBTs for YTs and involves a flash loan of IBT from the Principal Token contract to borrow IBTs.
The steps involve:
FLASH_LOAN: Perform the flash loan in the PT. The flashloan borrower being the Router that will execute the commands an inputs specified in the flash loan. The flashloan hence involves another nested router execution:
DEPOSIT_IBT_IN_PT: Deposit the borrowed IBT in the PT contract
CURVE_SWAP: Swap the received PT from the deposit for IBTs
Note that the Router's onFlashLoan
function is responsible for calling back to execute upon receiving flash loan funds. This function is also tasked with returning the borrowed amount along with the flash loan fees, using a safeTransferFrom
from the caller's balance.
TRANSFER: Transfer all the YTs to the user
Exchange YT for IBT
This route is used to exchange YTs for IBTs and involves a flash loan of IBT from the Principal Token contract to borrow IBTs.
The steps involve:
FLASH_LOAN: Perform the flash loan in the PT. The flashloan borrower being the Router that will execute the commands an inputs specified in the flash loan. The flashloan hence involves another nested router execution:
CURVE_SWAP: Swap the IBT for PTs to get the same amount of PT than YTs to be able to redeem.
TRANSFER_FROM: Transfer the YTs fro the users balance to the router
REDEEM_PT_FOR_IBT: Redeem PT and YTs for IBTs
Note that the Router's onFlashLoan
function is responsible for calling back to execute upon receiving flash loan funds. This function is also tasked with returning the borrowed amount along with the flash loan fees, using a safeTransferFrom
from the caller's balance.
TRANSFER: Transfer all the IBTs to the user
Previewing execution
Router also includes a preview functionnality, where a sequence of commands, along with encoded imputs can be simulated to preview the resulting rate, i.e. the amount of output token obtained at the end of execution for each wei of input token spent at the start of execution (multiplied by 1 ray unit).
function previewRate( bytes calldata _commands, bytes[] calldata _inputs ) external view returns (uint256)
function previewSpotRate( bytes calldata _commands, bytes[] calldata _inputs ) external view returns (uint256)
For ease of use, these functions take similar parameters than the execute()
function.
Though previewRate
and previewSpotRate
mirror input parameters of execute()
, some commands are not supported for preview. See the Router guide for more details.
Last updated