Description:
Decentralized Finance (DeFi) protocol contract providing Swap, Factory functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"contracts/FlashLoanExecutor.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @notice Minimal ERC20 interface
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
}
/// @notice Aave v3 lending pool interface (flashLoanSimple)
interface IAavePool {
function flashLoanSimple(
address receiver,
address asset,
uint256 amount,
bytes calldata params,
uint16 referralCode
) external;
}
/// @notice Balancer vault interface (single-token flash loan)
interface IBalancerVault {
function flashLoan(
address recipient,
address[] calldata tokens,
uint256[] calldata amounts,
bytes calldata userData
) external;
}
interface IBalancerFlashLoanRecipient {
function receiveFlashLoan(
address[] calldata tokens,
uint256[] calldata amounts,
uint256[] calldata feeAmounts,
bytes calldata userData
) external;
}
/// @notice Uniswap v3 pool interface (flash)
interface IUniswapV3Pool {
function flash(
address recipient,
uint256 amount0,
uint256 amount1,
bytes calldata data
) external;
function token0() external view returns (address);
function token1() external view returns (address);
}
interface IUniswapV3FlashCallback {
function uniswapV3FlashCallback(
uint256 fee0,
uint256 fee1,
bytes calldata data
) external;
}
/// @notice Lightweight ownable helper
abstract contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
require(initialOwner != address(0), "EXECUTOR:ZERO_OWNER");
owner = initialOwner;
emit OwnershipTransferred(address(0), initialOwner);
}
modifier onlyOwner() {
require(msg.sender == owner, "EXECUTOR:NOT_OWNER");
_;
}
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "EXECUTOR:ZERO_OWNER");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
/// @notice Flash loan executor that routes between multiple providers
contract FlashLoanExecutor is Ownable, IBalancerFlashLoanRecipient, IUniswapV3FlashCallback {
struct SwapPayload {
address buyTarget;
bytes buyData;
uint256 buyValue;
address sellTarget;
bytes sellData;
uint256 sellValue;
}
struct ProviderConfig {
bool enabled;
address target;
bytes providerData;
uint16 assumedFeeBps; // informational
}
struct FlashContext {
bool active;
uint8 providerId;
address asset;
uint256 amount;
SwapPayload payload;
address initiator;
}
mapping(uint8 => ProviderConfig) public providers;
FlashContext private _ctx;
event ProviderConfigured(uint8 indexed providerId, address target, bool enabled);
error UnknownProvider(uint8 providerId);
error ProviderDisabled(uint8 providerId);
error InvalidCaller(uint8 providerId);
error InFlightFlashLoan();
constructor(address initialOwner) Ownable(initialOwner) {}
// ---------------------------------------------------------------------
// Provider configuration
// ---------------------------------------------------------------------
function setProvider(
uint8 providerId,
bool enabled,
address target,
bytes calldata providerData,
uint16 assumedFeeBps
) external onlyOwner {
providers[providerId] = ProviderConfig({
enabled: enabled,
target: target,
providerData: providerData,
assumedFeeBps: assumedFeeBps
});
emit ProviderConfigured(providerId, target, enabled);
}
function getContext() external view returns (FlashContext memory) {
return _ctx;
}
// ---------------------------------------------------------------------
// Entry point invoked off-chain via bundle builder
// ---------------------------------------------------------------------
function executeFlashArb(
uint8 providerId,
address asset,
uint256 amount,
bytes calldata swapPayload
) external onlyOwner {
ProviderConfig memory config = providers[providerId];
if (!config.enabled) revert ProviderDisabled(providerId);
if (_ctx.active) revert InFlightFlashLoan();
SwapPayload memory payload = abi.decode(swapPayload, (SwapPayload));
_ctx = FlashContext({
active: true,
providerId: providerId,
asset: asset,
amount: amount,
payload: payload,
initiator: msg.sender
});
if (providerId == 1) {
_executeAave(config, asset, amount, payload);
} else if (providerId == 2) {
_executeBalancer(config, asset, amount);
} else if (providerId == 3) {
_executeUniswap(config, asset, amount);
} else {
_ctx.active = false;
revert UnknownProvider(providerId);
}
_ctx.active = false;
}
// ---------------------------------------------------------------------
// Provider-specific implementations
// ---------------------------------------------------------------------
function _executeAave(
ProviderConfig memory config,
address asset,
uint256 amount,
SwapPayload memory payload
) internal {
address pool = config.target;
require(pool != address(0), "EXECUTOR:AAVE_TARGET");
bytes memory params = abi.encode(payload);
IAavePool(pool).flashLoanSimple(address(this), asset, amount, params, 0);
}
function executeOperation(
address asset,
uint256 amount,
uint256 premium,
address initiator,
bytes calldata params
) external returns (bool) {
require(_ctx.active && _ctx.providerId == 1, "EXECUTOR:AAVE_STATE");
require(initiator == address(this), "EXECUTOR:AAVE_INITIATOR");
require(msg.sender == providers[1].target, "EXECUTOR:AAVE_CALLER");
SwapPayload memory payload = abi.decode(params, (SwapPayload));
_performSwaps(payload);
_repay(asset, msg.sender, amount + premium);
return true;
}
function _executeBalancer(
ProviderConfig memory config,
address asset,
uint256 amount
) internal {
address vault = config.target;
require(vault != address(0), "EXECUTOR:BAL_TARGET");
address[] memory tokens = new address[](1);
tokens[0] = asset;
uint256[] memory amounts = new uint256[](1);
amounts[0] = amount;
IBalancerVault(vault).flashLoan(address(this), tokens, amounts, "");
}
function receiveFlashLoan(
address[] calldata tokens,
uint256[] calldata amounts,
uint256[] calldata feeAmounts,
bytes calldata /*userData*/
) external override {
require(_ctx.active && _ctx.providerId == 2, "EXECUTOR:BAL_STATE");
require(msg.sender == providers[2].target, "EXECUTOR:BAL_CALLER");
_performSwaps(_ctx.payload);
_repay(tokens[0], msg.sender, amounts[0] + feeAmounts[0]);
}
function _executeUniswap(
ProviderConfig memory config,
address asset,
uint256 amount
) internal {
(address pool, bool borrowToken0) = abi.decode(config.providerData, (address, bool));
require(pool != address(0), "EXECUTOR:UNI_POOL");
if (borrowToken0) {
require(IUniswapV3Pool(pool).token0() == asset, "EXECUTOR:UNI_TOKEN0");
IUniswapV3Pool(pool).flash(address(this), amount, 0, abi.encode(asset));
} else {
require(IUniswapV3Pool(pool).token1() == asset, "EXECUTOR:UNI_TOKEN1");
IUniswapV3Pool(pool).flash(address(this), 0, amount, abi.encode(asset));
}
}
function uniswapV3FlashCallback(
uint256 fee0,
uint256 fee1,
bytes calldata data
) external override {
require(_ctx.active && _ctx.providerId == 3, "EXECUTOR:UNI_STATE");
require(msg.sender == providers[3].target, "EXECUTOR:UNI_CALLER");
address asset = abi.decode(data, (address));
_performSwaps(_ctx.payload);
uint256 repayAmount = _ctx.amount + (fee0 > 0 ? fee0 : fee1);
_repay(asset, msg.sender, repayAmount);
}
// ---------------------------------------------------------------------
// Internal helpers
// ---------------------------------------------------------------------
function _performSwaps(SwapPayload memory payload) internal {
if (payload.buyData.length > 0) {
(bool success, bytes memory returndata) = payload.buyTarget.call{value: payload.buyValue}(payload.buyData);
require(success, string(returndata.length > 0 ? returndata : bytes("EXECUTOR:BUY_FAIL")));
}
if (payload.sellData.length > 0) {
(bool success, bytes memory returndata) = payload.sellTarget.call{value: payload.sellValue}(payload.sellData);
require(success, string(returndata.length > 0 ? returndata : bytes("EXECUTOR:SELL_FAIL")));
}
}
function _repay(address token, address target, uint256 amount) internal {
require(IERC20(token).transfer(target, amount), "EXECUTOR:REPAY" );
}
// Allow owner to recover tokens/ETH accidentally left in the contract
function sweep(address token, address to) external onlyOwner {
if (token == address(0)) {
(bool ok, ) = to.call{value: address(this).balance}('');
require(ok, "EXECUTOR:SWEEP_ETH");
} else {
uint256 bal = IERC20(token).balanceOf(address(this));
require(IERC20(token).transfer(to, bal), "EXECUTOR:SWEEP_TOKEN");
}
}
receive() external payable {}
}
"
}
},
"settings": {
"evmVersion": "paris",
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}
}}
Submitted on: 2025-10-13 09:33:47
Comments
Log in to comment.
No comments yet.