// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "../interfaces/IAavePool.sol"; import "../interfaces/IERC20.sol"; /** * @title AaveFlashLoanReceiver * @notice Example flash loan receiver for Aave v3 * @dev This contract receives flash loans and must repay them in executeOperation */ contract AaveFlashLoanReceiver is IFlashLoanReceiver { IAavePool public immutable pool; address public owner; modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; } constructor(address pool_) { pool = IAavePool(pool_); owner = msg.sender; } /** * @notice Execute flash loan operation * @param asset The flash loaned asset * @param amount The flash loaned amount * @param premium The premium to repay * @param initiator The initiator of the flash loan * @param params Additional parameters (can encode arbitrage data, etc.) * @return true if successful */ function executeOperation( address asset, uint256 amount, uint256 premium, address initiator, bytes calldata params ) external override returns (bool) { // Verify this was called by the pool require(msg.sender == address(pool), "Invalid caller"); require(initiator == address(this), "Invalid initiator"); // Your logic here (e.g., arbitrage, liquidation, etc.) // Example: swap on DEX, arbitrage, etc. // Calculate total amount to repay (loan + premium) uint256 amountOwed = amount + premium; // Approve pool to take repayment IERC20(asset).approve(address(pool), amountOwed); // Return true to indicate successful operation return true; } /** * @notice Execute flash loan (single asset) * @param asset The asset to flash loan * @param amount The amount to flash loan * @param params Additional parameters for executeOperation */ function flashLoanSimple( address asset, uint256 amount, bytes calldata params ) external onlyOwner { pool.flashLoanSimple( address(this), asset, amount, params, 0 // referral code ); } /** * @notice Execute flash loan (multiple assets) * @param assets The assets to flash loan * @param amounts The amounts to flash loan * @param modes The flash loan modes (0 = no debt, 2 = variable debt) * @param params Additional parameters for executeOperation */ function flashLoan( address[] calldata assets, uint256[] calldata amounts, uint256[] calldata modes, bytes calldata params ) external onlyOwner { pool.flashLoan( address(this), assets, amounts, modes, address(this), params, 0 // referral code ); } /** * @notice Withdraw tokens (emergency) */ function withdrawToken(address token, uint256 amount) external onlyOwner { IERC20(token).transfer(owner, amount); } }