MegaBeast_DualFlashloan_SECURED

Description:

Decentralized Finance (DeFi) protocol contract providing Swap, Factory functionality.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

// =================================================================================
// INTERFACES
// =================================================================================

interface IERC20 {
    function approve(address spender, uint256 amount) external returns (bool);
    function transfer(address to, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
}

interface IUniswapV2Router02 {
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
}

// AAVE V3 interfaces
interface IPool {
    function flashLoanSimple(
        address receiverAddress,
        address asset,
        uint256 amount,
        bytes calldata params,
        uint16 referralCode
    ) external;
}

interface IPoolAddressesProvider {
    function getPool() external view returns (address);
}

// Uniswap/PancakeSwap interfaces
interface IUniswapV2Pair {
    function token0() external view returns (address);
    function token1() external view returns (address);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}

interface IUniswapV2Factory {
    function getPair(address tokenA, address tokenB) external view returns (address pair);
}

// =================================================================================
// CONTRACT
// =================================================================================

/// @title MegaBeast_DualFlashloan_SECURED
/// @notice Optimized and secured for deployment on Ethereum (Aave) and BSC (PancakeSwap).
contract MegaBeast_DualFlashloan_SECURED {
    address public immutable owner;
    address public immutable relay;

    // AAVE (Ethereum) variables
    IPool public POOL;
    address public immutable AAVE_PROVIDER;

    // PancakeSwap (BSC) variables
    IUniswapV2Factory public immutable PANCAKE_FACTORY;

    event ArbitrageExecuted(address indexed profitToken, uint256 netProfit);

    modifier onlyRelay() { require(msg.sender == relay, "relay only"); _; } 
    modifier onlyOwner() { require(msg.sender == owner, "owner only"); _; }

    constructor(
        address _aaveAddressesProvider, // e.g., 0x2f39... on ETH
        address _pancakeFactory, // e.g., 0xcA14... on BSC
        address _owner,
        address _relay
    ) {
        owner = _owner;
        relay = _relay;
        AAVE_PROVIDER = _aaveAddressesProvider;
        PANCAKE_FACTORY = IUniswapV2Factory(_pancakeFactory);
    }

    /// @notice Initializes the Aave Pool contract address. Ethereum only.
    function initializePool() external onlyOwner {
        require(block.chainid == 1, "Not Ethereum");
        require(address(POOL) == address(0), "Pool already set");
        POOL = IPool(IPoolAddressesProvider(AAVE_PROVIDER).getPool());
    }

    /// @notice Entry point for both Ethereum + BSC multi-hop arbitrage.
    function startArbitrage(
        address asset,
        uint256 amount,
        bytes calldata params // Universal params: abi.encode(address[], address[][], uint256[])
    ) external onlyRelay {
        
        if (block.chainid == 1) { // Ethereum: Aave Flash Loan
            require(address(POOL) != address(0), "Pool not initialized");

            uint256 totalDebtEstimate = amount + (amount / 2000); // Principal + 0.05% fee approx.
            IERC20(asset).approve(address(POOL), totalDebtEstimate);
            
            POOL.flashLoanSimple(address(this), asset, amount, params, 0);

        } else if (block.chainid == 56) { // BSC: PancakeSwap Flash Swap
            ( , address[][] memory paths, ) = abi.decode(params, (address[], address[][], uint256[]));
            require(paths.length > 0 && paths[0].length >= 2, "Invalid path");

            address tokenA = paths[0][0];
            address tokenB = paths[0][1];

            require(tokenA == asset || tokenB == asset, "Path must start with loan asset");

            address pair = PANCAKE_FACTORY.getPair(tokenA, tokenB);
            require(pair != address(0), "Pair not found");

            address token0 = IUniswapV2Pair(pair).token0();
            uint amount0Out = asset == token0 ? amount : 0;
            uint amount1Out = asset == token0 ? 0 : amount;

            // Initiate the flash swap
            IUniswapV2Pair(pair).swap(amount0Out, amount1Out, address(this), params);
        } else {
            revert("Unsupported chain");
        }
    }

    // AAVE Flash Loan Callback
    function executeOperation(
        address asset,
        uint256 amount,
        uint256 premium,
        address initiator,
        bytes calldata params
    ) external returns (bool) {
        require(block.chainid == 1, "Not Ethereum");
        require(msg.sender == address(POOL), "not aave pool");
        require(initiator == address(this), "bad initiator");

        _executeSwaps(asset, amount, premium, params);
        
        return true;
    }

    // PancakeSwap Flash Swap Callback
    function pancakeCall(address /*sender*/, uint amount0, uint amount1, bytes calldata data) external { // ✅ FIX: Commented out the unused 'sender' variable.
        require(block.chainid == 56, "Not BSC");
        
        address pairAddress = msg.sender;
        
        uint256 amount = amount0 > 0 ? amount0 : amount1;
        address asset = amount0 > 0 ? IUniswapV2Pair(pairAddress).token0() : IUniswapV2Pair(pairAddress).token1();
        
        _executeSwaps(asset, amount, 0, data); 

        // Repay the PancakeSwap flash loan
        uint256 fee = ((amount * 3) / 997) + 1;
        uint256 amountToRepay = amount + fee;
        
        IERC20(asset).transfer(msg.sender, amountToRepay);
    }

    /// @notice Shared internal logic for executing swaps and handling profits.
    function _executeSwaps(
        address asset,
        uint256 amount,
        uint256 premium,
        bytes calldata params
    ) internal {
        (address[] memory routers, address[][] memory paths, uint256[] memory minOuts) =
            abi.decode(params, (address[], address[][], uint256[]));

        uint256 currentAmount = amount;
        for (uint i = 0; i < routers.length; i++) {
            currentAmount = IERC20(paths[i][0]).balanceOf(address(this));
            
            IERC20(paths[i][0]).approve(routers[i], currentAmount);
            
            IUniswapV2Router02(routers[i]).swapExactTokensForTokens(
                currentAmount, minOuts.length > i ? minOuts[i] : 0, paths[i], address(this), block.timestamp
            );
        }

        uint256 totalDebt = amount + premium;

        address finalTokenAddress = paths[routers.length - 1][paths[routers.length - 1].length - 1];
        
        require(finalTokenAddress == asset, "Arbitrage must be a closed loop");

        IERC20 finalTokenContract = IERC20(finalTokenAddress);
        uint256 balance = finalTokenContract.balanceOf(address(this));

        if (block.chainid == 1) {
            require(balance >= totalDebt, "Aave: Repayment + fee failed");
        } else if (block.chainid == 56) {
            uint256 fee = ((amount * 3) / 997) + 1;
            uint256 pancakeDebt = amount + fee;
            require(balance >= pancakeDebt, "Pancake: Repayment failed");
        }
        
        uint256 netProfit = balance - totalDebt;
        
        if (netProfit > 0) {
            finalTokenContract.transfer(owner, netProfit);
            emit ArbitrageExecuted(finalTokenAddress, netProfit);
        }
    }

    // --- Helper Functions ---
    function rescueEther() external onlyOwner {
        (bool ok,) = payable(owner).call{value: address(this).balance}("");
        require(ok, "eth transfer failed");
    }

    function rescueToken(address tokenAddress, uint256 tokenAmount) external onlyOwner {
        IERC20(tokenAddress).transfer(owner, tokenAmount);
    }
    
    receive() external payable {}
}

Tags:
DeFi, Swap, Factory|addr:0xffdf7427a554751b6c63a904bc6df937bdde5b73|verified:true|block:23543604|tx:0x8dc742950330a625001c1fd1dd81c106334a0ae66f6d912538ef4e894c3902ca|first_check:1760081294

Submitted on: 2025-10-10 09:28:15

Comments

Log in to comment.

No comments yet.