This tutorial demonstrates how to leverage Biconomy's Modular Execution Environment (MEE) and AbstractJS SDK to enable one-click position migration from Aave to Venus Protocol. The implementation showcases the power of composable orchestration to execute multiple complex transactions with a single user signature.
Overview
This implementation enables users to:
- Transfer any accrued aToken interest to their Companion Account (via Fusion Mode)
- Withdraw their entire Aave position
- Approve the Venus pool to spend the withdrawn tokens
- Mint vTokens on Venus protocol on behalf of the user
All these operations happen atomically in a single transaction flow, abstracting away the complexity of multiple approvals and cross-protocol interactions.
Understanding Fusion Mode
Since external wallets like MetaMask or Rabby cannot directly install smart account logic on EOAs, this implementation uses Fusion Mode - a passthrough mechanism that enables MEE orchestration through a Companion smart account.
How Fusion Mode Works:
- Trigger Signature: User signs a trigger transaction containing the hash of all orchestration instructions
- Funds Transfer: Funds temporarily move to a non-custodial Companion Account owned by the user
- Instruction Execution: All operations execute using the Companion Account
- Return to EOA: Resulting assets automatically return to the user's EOA
- Stateless Design: The Companion Account remains clean with no dust after execution
The Power of Biconomy's Composable Architecture
Runtime Balance Resolution
One of the most powerful features demonstrated here is the use of runtimeERC20BalanceOf
. This function dynamically resolves token balances at execution time rather than at signing time:
runtimeERC20BalanceOf({
targetAddress: accountAddress,
tokenAddress: position.aTokenAddress,
constraints: [greaterThanOrEqualTo(100n)],
})
This is crucial for DeFi operations because:
- Interest accrues between signing and execution
- Exact amounts aren't known until execution time
- It prevents transactions from failing due to insufficient balance
The Complete Implementation
Let's examine how the Fusion trigger and composable instructions work together:
The Trigger Transaction
The trigger is the entry point that initiates the entire orchestration:
trigger: {
chainId,
tokenAddress: position.aTokenAddress,
amount: position.userATokenBalanceMantissa,
approvalAmount: bufferAmount, // Buffered to account for interest
gasLimit: 500000n,
}
This trigger:
- Transfers the user's aToken balance to the Companion Account
- Only transfers the "right to future interest" - accrued interest remains on the EOA as additional aTokens
- Uses a buffered approval amount to ensure enough allowance for the entire process
- Contains the hash of all orchestration instructions, authorizing the full sequence with one signature
Step 1: Transfer Accrued Interest (aTokens)
const transferInterest = await nexusAccount.buildComposable({
type: 'transferFrom',
data: {
recipient: nexusAccountAddress, // Companion Account address
sender: accountAddress, // User's EOA
tokenAddress: position.aTokenAddress,
amount: runtimeERC20BalanceOf({
targetAddress: accountAddress,
tokenAddress: position.aTokenAddress,
constraints: [greaterThanOrEqualTo(100n)],
}),
chainId,
gasLimit: 100000n,
},
});
This instruction:
- Transfers any remaining aTokens (representing accrued interest) from the user's EOA to their Companion Account
- Uses runtime balance to capture ALL available aTokens that remain after the trigger transaction
- Sets a constraint ensuring at least 100 units are transferred (prevents dust transactions)
- Combined with the trigger, this ensures the user's entire aToken position (principal + all interest) moves to the Companion Account
Step 2: Withdraw Entire Aave Position
const withdrawFromAave = await nexusAccount.buildComposable({
type: 'default',
data: {
to: aaveV3PoolContractAddress,
abi: aaveV3PoolAbi,
functionName: 'withdraw',
args: [
position.tokenAddress, // Asset to withdraw
MAX_UINT256.toFixed(), // Amount (MAX = entire position)
nexusAccountAddress, // Recipient
],
chainId,
gasLimit: 100000n,
},
});
Key insights:
- Uses
MAX_UINT256
to withdraw the entire position, including any interest accrued during transaction processing - The
default
type allows calling any smart contract function - Withdrawn funds go to the Nexus account for further operations
Step 3: Approve Venus to Spend Tokens
const approveVenus = await nexusAccount.buildComposable({
type: 'approve',
data: {
tokenAddress: position.tokenAddress,
spender: vToken.address,
amount: runtimeERC20BalanceOf({
targetAddress: nexusAccountAddress,
tokenAddress: position.tokenAddress,
constraints: [greaterThanOrEqualTo(100n)],
}),
chainId,
gasLimit: 100000n,
},
});
This showcases another powerful MEE feature:
- Approves the EXACT amount received from Aave withdrawal
- No need to over-approve or guess amounts
- Runtime resolution ensures the approval matches the available balance perfectly
Step 4: Mint vTokens on Venus
const mintVTokens = await nexusAccount.buildComposable({
type: 'default',
data: {
to: vToken.address,
abi: vBep20Abi,
functionName: 'mintBehalf',
args: [
accountAddress, // Mint on behalf of user's EOA
runtimeERC20BalanceOf({
targetAddress: nexusAccountAddress,
tokenAddress: position.tokenAddress,
constraints: [greaterThanOrEqualTo(100n)],
}),
],
chainId,
gasLimit: 100000n,
},
});
The magic here:
mintBehalf
allows the SCA to mint tokens for the user's EOA- Again uses runtime balance to mint the EXACT amount available
- The user receives vTokens directly in their main wallet
Creating the Fusion Quote
The Fusion Quote packages everything together with a trigger transaction:
// Buffer the approval amount to account for interest accrual
const approvalAmount = buffer({
amountMantissa: position.userATokenBalanceWithInterestsMantissa,
});
const fusionQuote = await meeClient.getFusionQuote({
trigger: {
chainId,
tokenAddress: position.aTokenAddress,
amount: position.userATokenBalanceMantissa,
approvalAmount, // Buffered amount
gasLimit: 500000n,
},
instructions: [
transferInterest,
withdrawFromAave,
approveVenus,
mintVTokens
],
sponsorship: true, // Enable gasless execution
});
Key features:
- Trigger: The initial aToken approval that starts the entire flow. This creates the Fusion trigger transaction that the user signs
- Trigger Type: The SDK automatically detects if aTokens support ERC20Permit for gasless execution, otherwise uses standard approval
- Buffering: Accounts for interest that accrues between signing and execution
- Sponsorship: Makes the transaction gasless for users (bypasses the Fusion constraint that execution tokens must pay for gas)
- Atomic Execution: All instructions execute in sequence or none execute
- Fusion Constraints: Only consumes one token type (aTokens) per user signature
Understanding the Buffer Strategy
The buffer
function plays a crucial role in handling Aave's interest accrual mechanism. Here's why it's needed:
When transferring aTokens to the Companion Account, there's a nuance with how Aave handles interest:
- The Trigger transaction transfers the user's aToken balance to the Companion Account, but this only transfers the right to receive future interest
- Accrued interest remains on the EOA - it stays there as additional aTokens that weren't included in the initial transfer
- The first instruction (
transferInterest
) then pulls these remaining aTokens (the accrued interest) to the Companion Account
The buffer ensures we approve enough aTokens to cover both:
- The initial balance
- Any interest that accrues between signing and execution
This two-step process ensures the entire aToken position (principal + all accrued interest) is captured for the migration. The implementation effectively allows the user to transfer all of their aTokens AND all accrued interest to the Companion Account, ensuring no value is left behind on the EOA.
Advanced Concepts Demonstrated
1. Cross-Protocol Composability
This implementation seamlessly bridges two major DeFi protocols (Aave and Venus) in a single transaction. The MEE handles all the complexity of:
- Protocol-specific interfaces
- Token approvals and transfers
- State management between operations
2. Dynamic Amount Handling
Traditional transactions require knowing exact amounts upfront. With MEE's runtime values:
- Amounts are resolved at execution time
- No failed transactions due to slight balance changes
- Perfect efficiency with no leftover approvals
3. Smart Contract Account Benefits
The Nexus account acts as an intermediary that:
- Holds funds temporarily during the operation
- Executes actions on behalf of the user
- Enables complex flows that would be impossible from an EOA
3. Companion Account Benefits (Fusion Mode)
The Companion Account acts as a stateless intermediary that:
- Temporarily holds funds during orchestration
- Executes all complex operations on behalf of the user
- Returns all assets to the user's EOA automatically
- Remains non-custodial - user maintains full ownership
- Leaves no dust or residual state after execution
4. Constraint System
constraints: [greaterThanOrEqualTo(100n)]
Constraints ensure operations only execute if conditions are met, preventing:
- Dust transactions
- Insufficient balance errors
- Wasted gas on operations that would fail
Why This Matters
Traditional Approach (Multiple Transactions)
- User approves aToken transfer
- User transfers aTokens
- User withdraws from Aave
- User approves Venus
- User mints on Venus
Problems: 5 signatures, 5 gas payments, risk of partial execution, complex UX
Biconomy MEE Approach (Fusion Mode)
- User signs once (trigger transaction)
Benefits:
- Single signature for entire orchestration
- Works with any external wallet (MetaMask, Rabby, etc.)
- Optional gas sponsorship (completely gasless if aTokens support ERC20Permit)
- Atomic execution with automatic cleanup on failure
- Seamless UX with assets returning directly to EOA
Conclusion
This implementation showcases how Biconomy's MEE with Fusion Mode transforms complex DeFi operations into simple, user-friendly experiences. By leveraging composable instructions, runtime values, and atomic execution through a Companion Account, developers can build sophisticated cross-protocol integrations that work with any external wallet.
The key innovations demonstrated:
- Fusion Mode Orchestration: Enables MEE features on standard EOAs through a stateless Companion Account
- Runtime Composability: Dynamic values that adapt to changing on-chain state
- Cross-Protocol Orchestration: Seamless interaction between different DeFi protocols
- Single-Signature Execution: Complex flows with minimal user friction
- Gas Abstraction: Optional sponsorship for truly gasless experiences (automatic with ERC20Permit tokens)
- Automatic Asset Return: All resulting tokens return to user's EOA without manual intervention
This pattern can be applied to any multi-step DeFi operation, from yield optimization to portfolio rebalancing, making it a powerful tool for building advanced Web3 experiences that work with mainstream wallets.