Aave Flash Loans on Neon EVM with Solana Composability
Aave Flash Loans on Neon EVM with Solana Composability
This week, we’re combining the powers of Ethereum flashloans and Solana DEX swaps into one seamless, atomic transaction.
We’ll walk through how to:
- Use Aave V3 to borrow assets without upfront capital.
- Trigger Solana swaps on Orca using composability requests.
- Repay the flash loan—all in a single transaction.
What We’re Building
We’ll create a smart contract that:
- Requests a flash loan from Aave on Neon EVM.
- Uses composability libraries to swap on Orca (a Solana DEX).
- Repays the loan and fee, all within one atomic transaction.
Here’s the end-to-end flow:
.png)
Repo Setup & Security Update
We’re working in the same repo as the Memecoin Launchpad task. But now, we’ve introduced a more secure way to manage your private keys: instead of storing secrets in .env, use Hardhat’s encrypted keystore.
Follow the updated instructions in the repo’s README to set this up. It’s safer and better for future production-ready projects.
Inside the Flashloan Contract
Step 0: Imports & Setup
We’re using three main components:
import '../precompiles/ICallSolana.sol';
import "@aave/core-v3/contracts/flashloan/base/FlashLoanSimpleReceiverBase.sol";
import "@aave/core-v3/contracts/interfaces/IPoolAddressesProvider.sol";
FlashLoanSimpleReceiverBase
: from Aave V3, it provides flash loan logic.ICallSolana
: lets you issue Solana instructions from Neon.IErc20ForSpl
: ERC-20 interface compatible with Solana SPL tokens.
Flashloan Flow Breakdown
1. Request Flashloan
function flashLoanSimple(address token, uint256 amount, bytes memory instructionData1, bytes memory instructionData2) public {
bytes memory params = abi.encode(instructionData1, instructionData2);
// request flash loan from Aave V3 protocol
POOL.flashLoanSimple(
address(this),
token,
amount,
params,
0
);
}
You call this method with:
token
(e.g. USDC address)amount
(e.g. 10 USDC)swapInstructions
(encoded Solana swap ops)
2. Callback: executeOperation()
Once Aave sends the loan, it immediately calls this function:
function executeOperation(
address asset,
uint256 amount,
uint256 premium,
address initiator,
bytes calldata params
) external override returns (bool)
Let’s unpack what happens here.
Step 1: Security Check
require(msg.sender == address(POOL), "ERROR: AUTH - INVALID POOL");
lastLoan = amount;
lastLoanFee = premium;
Ensures only Aave can call executeOperation
.
Step 2: Transfer Funds to Solana
IErc20ForSpl(asset).transferSolana(
CALL_SOLANA.getSolanaPDA(
ASSOCIATED_TOKEN_PROGRAM,
abi.encodePacked(
CALL_SOLANA.getNeonAddress(address(this)),
TOKEN_PROGRAM,
IErc20ForSpl(asset).tokenMint()
)
),
uint64(amount)
);
This moves the flashloaned tokens to the appropriate associated token account (ATA) on Solana.
Step 3: Decode & Execute Solana Instructions
(bytes memory instructionData1, bytes memory instructionData2) = abi.decode(params, (bytes, bytes));
CALL_SOLANA.execute(0, instructionData1);
CALL_SOLANA.execute(0, instructionData2);
Each instruction executes a swap (e.g. USDC → SAMO → USDC) on Orca or any Solana DEX.
Step 4: Repay Loan + Fee
IErc20ForSpl(asset).approve(address(POOL), amount + premium);
return true;
If the contract approves the repayment, the flash loan succeeds. If not, everything reverts.
Practice Exercise
Fork the repo and run the script to request and repay a flash loan, triggering composable Solana instructions in the process.
Submit a GitHub repo with the links to blockscout that prove you were able to run the script.
The goal is to understand this logic and be able to reproduce it in any of your future projects.
Resources
- GitHub repo with Aave flashloans
- Fill out the form to register your team for the graduation project
Wrap-up
.webp)
.webp)