Exit vault positions and receive any token you want—on any chain. Biconomy handles the redemption, swap, and bridge in a single transaction.
The Problem It Solves
Without Biconomy, exiting a vault position requires:
- Approve vault withdrawal (signature 1)
- Redeem shares for underlying (signature 2)
- Swap to desired token (signature 3)
- If cross-chain: bridge to destination (more signatures, more waiting)
With Biconomy: One signature. Funds arrive as whatever token you want, wherever you want.
How It Works
User Initiates Withdrawal
User specifies vault shares to redeem and desired output token
API Calculates Best Route
Biconomy finds optimal path: redeem → swap (if needed) → bridge (if needed)
User Signs Once
Single signature authorizes the entire withdrawal flow
Lossless Redemption
Direct vault redemption—no slippage on the withdrawal step
Quick Example
Withdraw from an AAVE vault on Base, receive USDC on Optimism:
const quote = await fetch('https://api.biconomy.io/v1/quote', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
mode: 'eoa',
ownerAddress: userAddress,
composeFlows: [{
type: '/instructions/intent-vault',
data: {
srcChainId: 8453, // Base
srcVault: '0x4e65fE4DbA92790696d040ac24Aa414708F5c0AB', // AAVE vault
dstChainId: 10, // Optimism
dstToken: '0x94b008aa00579c1307b0ef2c499ad98a8ce58e58', // USDT
amount: '1000000000000000000', // Vault shares to redeem
slippage: 0.01
}
}]
})
}).then(r => r.json());
// Sign and execute
const signature = await wallet.signTypedData(quote.typedDataToSign);
const result = await fetch('https://api.biconomy.io/v1/execute', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
signedQuote: quote,
signature
})
}).then(r => r.json());
console.log('Track at:', `https://meescan.biconomy.io/details/${result.supertxHash}`);
Same-Chain Withdrawal
Withdraw and swap to a different token on the same chain:
{
type: '/instructions/intent-vault',
data: {
srcChainId: 8453,
srcVault: YEARN_WETH_VAULT, // Withdraw from Yearn WETH vault
dstChainId: 8453, // Same chain
dstToken: USDC_BASE, // Receive USDC
amount: '5000000000000000000', // 5 vault shares
slippage: 0.01
}
}
Cross-Chain Exit
Exit a vault and receive tokens on a completely different chain:
{
type: '/instructions/intent-vault',
data: {
srcChainId: 137, // Polygon
srcVault: AAVE_POLYGON_VAULT, // AAVE position on Polygon
dstChainId: 1, // Ethereum mainnet
dstToken: ETH_MAINNET, // Receive ETH
amount: '10000000000000000000',
slippage: 0.02, // Higher slippage for volatile pair
allowBridgeProviders: 'across' // Control bridge selection
}
}
Understanding the Response
{
"outputAmount": "985000000",
"minOutputAmount": "975150000",
"route": {
"type": "vault-to-token",
"summary": "vaultsfyi[aave-v3] => across => lifi[uniswap]",
"steps": [
{
"type": "vault-redeem",
"provider": "vaultsfyi",
"protocol": "aave-v3",
"vaultAddress": "0x...",
"inputAmount": "1000000000000000000",
"outputAmount": "1000000000"
},
{
"type": "bridge",
"provider": "across",
"srcChainId": 8453,
"dstChainId": 10
},
{
"type": "swap",
"provider": "lifi",
"tool": "uniswap"
}
],
"totalGasFeesUsd": 0.15,
"totalBridgeFeesUsd": 0.25,
"estimatedTime": 120
}
}
| Field | Description |
|---|
route.type | Always vault-to-token for withdrawals |
vault-redeem step | Direct redemption from vault (lossless) |
bridge step | Cross-chain transfer if needed |
swap step | Token conversion if needed |
Provider Control
Control which DEXs and bridges are used for the post-withdrawal steps:
{
type: '/instructions/intent-vault',
data: {
srcChainId: 8453,
srcVault: MORPHO_VAULT,
dstChainId: 42161,
dstToken: ARB_TOKEN,
amount: '1000000000000000000',
slippage: 0.01,
// Route preferences
allowSwapProviders: 'lifi,uniswap',
allowBridgeProviders: 'across',
denySwapProviders: 'gluex'
}
}
Fee Structure
| Scenario | Fee (BPS) |
|---|
| Same-chain, underlying token | 0 |
| Same-chain with swap | 10 |
| Cross-chain withdrawal | 15 |
Withdrawing to the vault’s native underlying token on the same chain incurs zero protocol fees—only gas.
Error Handling
const quote = await fetch('https://api.biconomy.io/v1/quote', {...})
.then(r => r.json());
// Check for errors
if (quote.error) {
if (quote.error.includes('insufficient balance')) {
console.log('Not enough vault shares');
}
if (quote.error.includes('No route found')) {
console.log('Try a different destination token');
}
return;
}
// Validate output
const minOutput = BigInt(quote.returnedData[0].minOutputAmount);
if (minOutput < userMinimum) {
console.log('Output too low—try reducing slippage or amount');
return;
}
Next Steps