Skip to main content

Mint & Redeem Simulation Functions

These functions come from the IPActionMintRedeemStatic facet. They simulate every mint and redeem operation supported by the live Router, plus two view helpers for reading the current PY index.


SY Mint / Redeem

mintSyFromTokenStatic

Simulates minting SY from an input token.

function mintSyFromTokenStatic(address SY, address tokenIn, uint256 netTokenIn)
external
view
returns (uint256 netSyOut)

Parameters

NameTypeDescription
SYaddressSY contract address
tokenInaddressInput token address
netTokenInuint256Exact token amount to mint with

Return Values

NameTypeDescription
netSyOutuint256SY received

getAmountTokenToMintSy

Inverse of mintSyFromTokenStatic — returns how many tokens are required to mint a target amount of SY.

function getAmountTokenToMintSy(address SY, address tokenIn, uint256 netSyOut)
external
view
returns (uint256 netTokenIn)

Parameters

NameTypeDescription
SYaddressSY contract address
tokenInaddressInput token address
netSyOutuint256Target SY amount to receive

Return Values

NameTypeDescription
netTokenInuint256Token amount required to mint netSyOut SY

Use Case Useful for constructing "exact SY out" flows — e.g. when you need a precise SY amount before adding dual-sided liquidity.


redeemSyToTokenStatic

Simulates redeeming SY for an output token.

function redeemSyToTokenStatic(address SY, address tokenOut, uint256 netSyIn)
external
view
returns (uint256 netTokenOut)

Parameters

NameTypeDescription
SYaddressSY contract address
tokenOutaddressDesired output token address
netSyInuint256SY amount to redeem

Return Values

NameTypeDescription
netTokenOutuint256Token received

PY Mint / Redeem

mintPyFromSyStatic

Simulates minting PT and YT from SY.

function mintPyFromSyStatic(address YT, uint256 netSyToMint)
external
view
returns (uint256 netPYOut)

Parameters

NameTypeDescription
YTaddressYT contract address
netSyToMintuint256SY amount to mint from

Return Values

NameTypeDescription
netPYOutuint256PT and YT received (equal amounts of each)

mintPyFromTokenStatic

Simulates minting PT and YT directly from an input token (token → SY → PT+YT).

function mintPyFromTokenStatic(address YT, address tokenIn, uint256 netTokenIn)
external
view
returns (uint256 netPyOut)

Parameters

NameTypeDescription
YTaddressYT contract address
tokenInaddressInput token address
netTokenInuint256Token amount to mint from

Return Values

NameTypeDescription
netPyOutuint256PT and YT received

redeemPyToSyStatic

Simulates redeeming PT and YT back to SY. Equal amounts of PT and YT must be provided.

function redeemPyToSyStatic(address YT, uint256 netPYToRedeem)
external
view
returns (uint256 netSyOut)

Parameters

NameTypeDescription
YTaddressYT contract address
netPYToRedeemuint256Amount of PT (and YT) to redeem

Return Values

NameTypeDescription
netSyOutuint256SY received

redeemPyToTokenStatic

Simulates redeeming PT and YT directly to an output token (PT+YT → SY → token).

function redeemPyToTokenStatic(address YT, uint256 netPYToRedeem, address tokenOut)
external
view
returns (uint256 netTokenOut)

Parameters

NameTypeDescription
YTaddressYT contract address
netPYToRedeemuint256Amount of PT (and YT) to redeem
tokenOutaddressDesired output token address

Return Values

NameTypeDescription
netTokenOutuint256Token received

PY Index Views

The PY index is the exchange rate between SY and PT/YT. It is used internally to price minting and redemption. These helpers let you read it without triggering a state-write (unlike the real pyIndexCurrent which may update the index on-chain).

pyIndexCurrentViewMarket

Returns the current PY index for a market without writing state.

function pyIndexCurrentViewMarket(address market) external view returns (uint256)

Parameters

NameTypeDescription
marketaddressPendle market address

Return Values

TypeDescription
uint256Current PY index (18 decimals)

pyIndexCurrentViewYt

Returns the current PY index for a given YT without writing state.

function pyIndexCurrentViewYt(address yt) external view returns (uint256)

Parameters

NameTypeDescription
ytaddressYT contract address

Return Values

TypeDescription
uint256Current PY index (18 decimals)

Use Case Use either index view to manually calculate the SY ↔ PT/YT conversion rate. For example, netSyOut = netPYToRedeem * pyIndex / 1e18.


Examples

Recommended: Use the Pendle API

The examples below show direct RouterStatic usage. For most integrations, the Pendle Hosted SDK / API is the better choice — it handles approximation, limit-order filling, and zap routing automatically.

Mint PT & YT from token — simulate then execute

const tokenIn  = WSTETH_ADDRESS;
const amountIn = ethers.parseEther("1");

// 1. Simulate
const netPyOut = await routerStatic.mintPyFromTokenStatic(YT_ADDRESS, tokenIn, amountIn);

console.log(`Expected PT+YT out: ${ethers.formatEther(netPyOut)} each`);

// 2. Execute
await IERC20(tokenIn).approve(ROUTER_ADDRESS, amountIn);
await router.mintPyFromToken(
signer.address,
YT_ADDRESS,
(netPyOut * 995n) / 1000n, // minPyOut (0.5% slippage)
createTokenInputStruct(tokenIn, amountIn)
);

Redeem PT & YT to token — simulate then execute

const tokenOut = WSTETH_ADDRESS;
const pyAmount = ethers.parseEther("1");

// 1. Simulate
const netTokenOut = await routerStatic.redeemPyToTokenStatic(YT_ADDRESS, pyAmount, tokenOut);

console.log(`Expected token out: ${ethers.formatEther(netTokenOut)}`);

// 2. Execute (both PT and YT must be approved in equal amounts)
await IERC20(PT_ADDRESS).approve(ROUTER_ADDRESS, pyAmount);
await IERC20(YT_ADDRESS).approve(ROUTER_ADDRESS, pyAmount);
await router.redeemPyToToken(
signer.address,
YT_ADDRESS,
pyAmount,
createTokenOutputStruct(tokenOut, (netTokenOut * 995n) / 1000n)
);

Determine how much token to spend for a target SY amount

Use getAmountTokenToMintSy when you have a downstream requirement for a fixed SY quantity (e.g. dual-asset liquidity add).

const targetSyOut = ethers.parseEther("1.5");

// 1. How many tokens do I need?
const netTokenIn = await routerStatic.getAmountTokenToMintSy(SY_ADDRESS, WSTETH_ADDRESS, targetSyOut);

console.log(`Need ${ethers.formatEther(netTokenIn)} wstETH to mint ${ethers.formatEther(targetSyOut)} SY`);

// Sanity-check by simulating the forward direction
const syOutCheck = await routerStatic.mintSyFromTokenStatic(SY_ADDRESS, WSTETH_ADDRESS, netTokenIn);
console.log(`Forward check: ${ethers.formatEther(syOutCheck)} SY`); // should ≈ targetSyOut

// 2. Execute
await IERC20(WSTETH_ADDRESS).approve(ROUTER_ADDRESS, netTokenIn);
await router.mintSyFromToken(
signer.address,
SY_ADDRESS,
(targetSyOut * 995n) / 1000n, // minSyOut
createTokenInputStruct(WSTETH_ADDRESS, netTokenIn)
);

Use pyIndex to value a PT/YT position

// Read current PY index (no state write)
const pyIndex = await routerStatic.pyIndexCurrentViewMarket(MARKET_ADDRESS);
// pyIndex is an 18-decimal exchange rate: 1 SY = pyIndex PY units

// Value 100 PT in SY terms
const ptBalance = ethers.parseEther("100");
const syValue = (ptBalance * ethers.parseEther("1")) / pyIndex;
console.log(`100 PT ≈ ${ethers.formatEther(syValue)} SY at current index`);