/** * Aave v3: Single-asset flash loan * * This example demonstrates how to execute a flash loan for a single asset. * Flash loans must be repaid within the same transaction, including a premium. */ 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: 'flashLoanSimple', type: 'function', stateMutability: 'nonpayable', inputs: [ { name: 'receiverAddress', type: 'address' }, { name: 'asset', type: 'address' }, { name: 'amount', type: 'uint256' }, { name: 'params', type: 'bytes' }, { name: 'referralCode', type: 'uint16' }, ], outputs: [], }, ] as const; // Flash loan receiver contract ABI (you need to deploy this) interface IFlashLoanReceiver { executeOperation: ( asset: Address, amount: bigint, premium: bigint, initiator: Address, params: Hex ) => Promise; } /** * Example flash loan receiver contract address * * In production, you would deploy your own flash loan receiver contract * that implements IFlashLoanReceiver and performs your desired logic. */ const FLASH_LOAN_RECEIVER = process.env.FLASH_LOAN_RECEIVER as `0x${string}`; async function flashLoanSimple() { 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); const token = getTokenMetadata(CHAIN_ID, 'USDC'); const amount = parseTokenAmount('10000', token.decimals); // 10,000 USDC console.log(`Executing flash loan for ${amount} ${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 flash loan // The receiver contract must: // 1. Receive the loaned tokens // 2. Perform desired operations // 3. Approve the pool for (amount + premium) // 4. Return true from executeOperation const tx = await walletClient.writeContract({ address: poolAddress, abi: POOL_ABI, functionName: 'flashLoanSimple', args: [ FLASH_LOAN_RECEIVER, // Your flash loan receiver contract token.address, amount, '0x' as Hex, // Optional params 0, // Referral code ], }); await waitForTransaction(publicClient, tx); console.log(`Flash loan executed: ${tx}`); console.log('\n✅ Flash loan completed successfully!'); } // Run if executed directly if (import.meta.url === `file://${process.argv[1]}`) { flashLoanSimple().catch(console.error); } export { flashLoanSimple };