Looking for a simpler approach? Check out the Intent-Based flow — it handles bridging and swapping as a single intent managed by Pendle's backend.
This script helps performing the bridging and swapping PT with another token. Basically it allows to do the following actions sequentially, in one go:
- Bridge PT from chain
Ato chainB(via LayerZero natively); - Swap PT to another token on chain
B(via PendleRouter); - Bridge the token from chain
Bback to chainA(via Bungee).
Pendle deploys PT (Principal Token) on a native chain (e.g. Arbitrum), but also provides bridged PTs on other chains (e.g. Unichain) via LayerZero's OFT (Omnichain Fungible Token) standard. The bridged PT cannot be swapped directly on the non-native chain because the Pendle Router and liquidity only exist on the native chain. Therefore, a round-trip is required:
Chain A (Bridged PT) Chain B (Original PT)
┌──────────────┐ LayerZero OFT bridge ┌──────────────────────┐
│ Bridged PT │ ──────────────────────────> │ Original PT │
└──────────────┘ Step 1 │ │ │
│ │ │
│ Pendle Convert API │
│ │ │
│ V │
┌──────────────┐ Bungee bridge │ Output Token (e.g. │
│ Token (e.g. │ <────────────────────────── │ USDC) │
│ USDC) │ Step 3 └──────────────────────┘
└──────────────┘ Step 2
- Looks up the destination chain's OFT peer address using the LayerZero metadata API.
- Calculates the minimum acceptable amount after slippage (
rawAmount * (1 - slippage)). - If the PT is a wrapped token, approves the OFT contract as spender.
- Calls
quoteSend()on the OFT contract to estimate the native gas fee. - Simulates and then executes the
send()transaction on the OFT contract, paying the quoted fee. - Polls the LayerZero Scan API until the cross-chain message status is
DELIVERED(with exponential backoff). - Returns the actual amount sent (may differ from
rawAmountdue to dust/fees).
- Approval — Checks the PT token allowance for the Pendle Router (
0x888888888889758F76e7103c6CbF23ABbF58F946). If insufficient, sends an approval transaction. Throws if the wallet balance is insufficient or the user cancels. - Route Discovery — Builds a convert request body (with inputs, outputs, slippage, aggregator and limit order settings) and calls the Pendle Convert API to find the best swap route.
- Swap Execution — Logs the estimated output amount, asks for user confirmation, then sends the on-chain transaction returned by the API. Waits for the transaction receipt.
- Result — Measures the actual token output by comparing the receiver's token balance before and after the swap, and returns it as
rawAmountTokenOut.
- Fetches a quote from the Bungee API with the token amount, source/destination chains, and slippage.
- If the token has not been approved for Bungee's Permit2 contract (
0x000000000022D473030F116dDEE9F6B43aC78BA3), sends an approval transaction. - Signs a Permit2 request using EIP-712 typed data (the signature data comes from the quote response).
- Submits the signed request to Bungee.
- Polls the Bungee status API until the request is
FULFILLEDorSETTLED(with exponential backoff). Fails ifCANCELLED,EXPIRED, orREFUNDED. - The output token arrives in the wallet on chain A.
Clone this repo. Run
yarn installCopy .env.example to .env and fill in the parameters.
- Note that the parameters uses the naming convention for chain
Aand chainB.- Chain
Ais where the bridged PT is deployed. - Chain
Bis where the original PT is deployed.
- Chain
PRIVATE_KEYis used to derive your account on both chainAand chainBto.- All tokens are sent to your account in every action.
RAW_AMOUNTis the amount of bridged PT you want to swap, in wei.- Foundry command like
cast to-weiandcast to-unitis helpful to convert between units.
- Foundry command like
An example of an .env file for bridging and swapping bridged 15 PT USDai (2026JUN) on unichain to USDC.
PRIVATE_KEY=0xYourPrivateKey
RAW_AMOUNT=15000000000000000000 # 15 * 10**18 (as the PT has 18 decimals)
SLIPPAGE=0.005 # 0.5%
A_RPC_URL=https://rpc-url-for-unichain
A_OFT=0xa6656e5456809b028c05531ad20dc2897b4dad91 # bridged PT address on unichain
A_TOKEN=0x078D782b760474a361dDA0AF3839290b0EF57AD6 # usdc on unichain
B_RPC_URL=https://rpc-url-for-arbitrum # arbitrum is where the original PT USDai (2026JUN) is deployed
B_TOKEN=0xaf88d065e77c8cC2239327C5EDb3A432268e5831 # usdc on arbitrum- The bridge PT address can be found directly on Pendle APP:
Click the Specs button |
See the addresses |
|---|---|
![]() |
![]() |
- The full list of tokens that is supported by Bungee can be found via Bungee's API: https://public-backend.bungee.exchange/api/v1/tokens/list
yarn bridge-pt-swap-bridge-backThis command will read the .env file and execute the bridge, swap, and bridge back in order.
There is also an intent-based version that uses the same .env setup but runs through Pendle's Cross-Chain Swap API instead. It only requires an additional B_MARKET env var (the Pendle market address on chain B).
yarn bridge-pt-swap-bridge-back --usePendleBackendSee Cross-Chain Swap README for more details on how the intent-based flow works.
Please note that the script prompts you for confirmation at every steps. If you wish to run this script without any confirmation, set the environment variable NO_CONFIRM=1:
NO_CONFIRM=1 yarn bridge-pt-swap-bridge-backIf you wish to run each steps individually to confirm the result of each steps, or to recover from failure from the main script bridge-pt-swap-bridge-back, run the following commands.
# Bridge pt from chain A to chain B
yarn bridge-pt
# swap pt to token on chain B
yarn pendle-swap-pt-to-token
# bridge token from chain B back to chain A
yarn bridge-token-via-bungeeThese scripts are designed to be simple for recovery, therefore it will not save immediate values anywhere. They only rely on the .env file and the current blockchain state:
bridge-ptandpendle-swap-pt-to-tokenwill useRAW_AMOUNTas the amount to bridge/swap.bridge-token-via-bungeewill NOT useRAW_AMOUNT. Instead, it will bridge ALL balance of token. Proceed with caution, and confirm the script's prompts at every step.
- Bungee will not produce any routes if the bridge amount is too small (< 1$). Check your bridging amount first.



