Initial commit: add .gitignore and README
This commit is contained in:
116
examples/ts/aave-flashloan-multi.ts
Normal file
116
examples/ts/aave-flashloan-multi.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Aave v3: Multi-asset flash loan
|
||||
*
|
||||
* This example demonstrates how to execute a flash loan for multiple assets.
|
||||
* Useful for arbitrage opportunities across multiple tokens.
|
||||
*/
|
||||
|
||||
import { createWalletRpcClient } from '../../src/utils/chain-config.js';
|
||||
import { getAavePoolAddress } from '../../src/utils/addresses.js';
|
||||
import { getTokenMetadata, parseTokenAmount } from '../../src/utils/tokens.js';
|
||||
import { waitForTransaction } from '../../src/utils/rpc.js';
|
||||
import type { Address, Hex } from 'viem';
|
||||
|
||||
const CHAIN_ID = 1; // Mainnet
|
||||
const PRIVATE_KEY = process.env.PRIVATE_KEY as `0x${string}`;
|
||||
|
||||
// Aave Pool ABI
|
||||
const POOL_ABI = [
|
||||
{
|
||||
name: 'flashLoan',
|
||||
type: 'function',
|
||||
stateMutability: 'nonpayable',
|
||||
inputs: [
|
||||
{ name: 'receiverAddress', type: 'address' },
|
||||
{ name: 'assets', type: 'address[]' },
|
||||
{ name: 'amounts', type: 'uint256[]' },
|
||||
{ name: 'modes', type: 'uint256[]' },
|
||||
{ name: 'onBehalfOf', type: 'address' },
|
||||
{ name: 'params', type: 'bytes' },
|
||||
{ name: 'referralCode', type: 'uint16' },
|
||||
],
|
||||
outputs: [],
|
||||
},
|
||||
] as const;
|
||||
|
||||
/**
|
||||
* Flash loan modes:
|
||||
* 0: No debt (just flash loan, repay fully)
|
||||
* 1: Stable debt (deprecated in v3.3+)
|
||||
* 2: Variable debt (open debt position)
|
||||
*/
|
||||
const FLASH_LOAN_MODE_NO_DEBT = 0;
|
||||
const FLASH_LOAN_MODE_VARIABLE_DEBT = 2;
|
||||
|
||||
const FLASH_LOAN_RECEIVER = process.env.FLASH_LOAN_RECEIVER as `0x${string}`;
|
||||
|
||||
async function flashLoanMulti() {
|
||||
const walletClient = createWalletRpcClient(CHAIN_ID, PRIVATE_KEY);
|
||||
const publicClient = walletClient as any;
|
||||
const account = walletClient.account?.address;
|
||||
|
||||
if (!account) {
|
||||
throw new Error('No account available');
|
||||
}
|
||||
|
||||
const poolAddress = getAavePoolAddress(CHAIN_ID);
|
||||
|
||||
// Multiple tokens for flash loan
|
||||
const tokens = [
|
||||
getTokenMetadata(CHAIN_ID, 'USDC'),
|
||||
getTokenMetadata(CHAIN_ID, 'USDT'),
|
||||
];
|
||||
|
||||
const amounts = [
|
||||
parseTokenAmount('10000', tokens[0].decimals), // 10,000 USDC
|
||||
parseTokenAmount('5000', tokens[1].decimals), // 5,000 USDT
|
||||
];
|
||||
|
||||
const assets = tokens.map(t => t.address);
|
||||
const modes = [FLASH_LOAN_MODE_NO_DEBT, FLASH_LOAN_MODE_NO_DEBT];
|
||||
|
||||
console.log('Executing multi-asset flash loan:');
|
||||
tokens.forEach((token, i) => {
|
||||
console.log(` ${amounts[i]} ${token.symbol}`);
|
||||
});
|
||||
console.log(`Pool: ${poolAddress}`);
|
||||
console.log(`Receiver: ${FLASH_LOAN_RECEIVER}`);
|
||||
|
||||
if (!FLASH_LOAN_RECEIVER) {
|
||||
throw new Error('FLASH_LOAN_RECEIVER environment variable not set');
|
||||
}
|
||||
|
||||
// Execute multi-asset flash loan
|
||||
// The receiver contract must:
|
||||
// 1. Receive all loaned tokens
|
||||
// 2. Perform desired operations (e.g., arbitrage)
|
||||
// 3. For each asset, approve the pool for (amount + premium)
|
||||
// 4. If mode = 2, approve for amount only (premium added to debt)
|
||||
// 5. Return true from executeOperation
|
||||
const tx = await walletClient.writeContract({
|
||||
address: poolAddress,
|
||||
abi: POOL_ABI,
|
||||
functionName: 'flashLoan',
|
||||
args: [
|
||||
FLASH_LOAN_RECEIVER,
|
||||
assets,
|
||||
amounts,
|
||||
modes,
|
||||
account, // onBehalfOf
|
||||
'0x' as Hex, // Optional params
|
||||
0, // Referral code
|
||||
],
|
||||
});
|
||||
|
||||
await waitForTransaction(publicClient, tx);
|
||||
console.log(`Multi-asset flash loan executed: ${tx}`);
|
||||
console.log('\n✅ Multi-asset flash loan completed successfully!');
|
||||
}
|
||||
|
||||
// Run if executed directly
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
flashLoanMulti().catch(console.error);
|
||||
}
|
||||
|
||||
export { flashLoanMulti };
|
||||
|
||||
Reference in New Issue
Block a user