MatrixBridge_L1

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

/**
 * ============================================================================
 * MATRIX BRIDGE L1 CONTRACT - FOR REMIX IDE
 * Bridge ANY Ethereum token → Pepe Unchained → Swap to ANY L2 token
 * ============================================================================
 * 
 * DEPLOYMENT ON ETHEREUM MAINNET:
 * 1. Switch MetaMask to Ethereum Mainnet
 * 2. Compile this contract in Remix (0.8.20+)
 * 3. Deploy with constructor parameters:
 *    _l2Receiver: [Your L2 contract address from Step 1]
 *    _feeCollector: [Your fee wallet]
 * 4. Confirm transaction (~$200-300 gas)
 * 5. Save deployed address
 * 6. Verify on Etherscan
 */

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

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

interface IUniswapV2Router {
    function swapExactETHForTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable returns (uint[] memory amounts);
    
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    
    function WETH() external pure returns (address);
}

interface IL1StandardBridge {
    function depositERC20To(
        address _l1Token,
        address _l2Token,
        address _to,
        uint256 _amount,
        uint32 _l2Gas,
        bytes calldata _data
    ) external;
}

contract MatrixBridge_L1 {
    
    // ========================================================================
    // CONSTANTS - Ethereum L1 Addresses (ALL CHECKSUMMED)
    // ========================================================================
    
    // PEPU Token on Ethereum
    address public constant PEPU_L1 = 0x93aA0ccD1e5628d3A841C4DbdF602D9eb04085d6;
    address public constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    
    // Infrastructure
    address public constant UNISWAP_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    address public constant L1_BRIDGE = 0xE92Df19F4e0Fd067FE3b788Cf03ffD06Cd9Be4A7;
    address public constant WPEPU_L2 = 0xF9Cf4A16d26979b929Be7176bAc4e7084975FCB8;
    
    uint32 public constant L2_GAS = 1000000; // 1M gas for L2
    uint256 private constant DEADLINE_BUFFER = 300; // 5 minutes
    
    // ========================================================================
    // STATE VARIABLES
    // ========================================================================
    
    address public l2ReceiverContract;
    address public feeCollector;
    address public owner;
    
    // Fee: 30 basis points = 0.3%
    uint256 public feeBps = 30;
    uint256 private constant MAX_FEE = 500; // 5% max
    uint256 private constant BPS_DENOMINATOR = 10000;
    
    // ========================================================================
    // EVENTS
    // ========================================================================
    
    event BridgeInitiated(
        address indexed user,
        address indexed inputToken,
        uint256 inputAmount,
        uint256 pepuAmount,
        uint256 feeAmount,
        address outputToken
    );
    
    event FeeCollected(uint256 amount);
    event FeeUpdated(uint256 newFeeBps);
    
    // ========================================================================
    // ERRORS
    // ========================================================================
    
    error ZeroAmount();
    error ZeroAddress();
    error TransferFailed();
    error ExcessiveFee();
    error Unauthorized();
    error SwapFailed();
    
    // ========================================================================
    // CONSTRUCTOR
    // ========================================================================
    
    /**
     * @notice Deploy L1 contract on Ethereum Mainnet
     * @param _l2Receiver L2 contract address from your L2 deployment
     * @param _feeCollector Your wallet to collect fees
     */
    constructor(address _l2Receiver, address _feeCollector) {
        if (_l2Receiver == address(0) || _feeCollector == address(0)) revert ZeroAddress();
        l2ReceiverContract = _l2Receiver;
        feeCollector = _feeCollector;
        owner = msg.sender;
    }
    
    modifier onlyOwner() {
        if (msg.sender != owner) revert Unauthorized();
        _;
    }
    
    // ========================================================================
    // MAIN BRIDGE FUNCTIONS
    // ========================================================================
    
    /**
     * @notice Bridge ETH → PEPU → L2 → Swap to ANY token
     * @param minPepuOut Minimum PEPU from ETH swap (slippage protection)
     * @param outputToken Desired token on L2 (MFG, USDC, USDT, WETH, etc.)
     */
    function bridgeETH(uint256 minPepuOut, address outputToken) external payable {
        if (msg.value == 0) revert ZeroAmount();
        
        // Swap ETH → PEPU on Uniswap
        address[] memory path = new address[](2);
        path[0] = WETH;
        path[1] = PEPU_L1;
        
        uint256 balanceBefore = IERC20(PEPU_L1).balanceOf(address(this));
        
        IUniswapV2Router(UNISWAP_ROUTER).swapExactETHForTokens{value: msg.value}(
            minPepuOut,
            path,
            address(this),
            block.timestamp + DEADLINE_BUFFER
        );
        
        uint256 pepuReceived = IERC20(PEPU_L1).balanceOf(address(this)) - balanceBefore;
        
        // Collect fee and bridge
        uint256 feeCollected = _collectFeeAndBridge(msg.sender, pepuReceived, outputToken);
        
        emit BridgeInitiated(msg.sender, address(0), msg.value, pepuReceived, feeCollected, outputToken);
    }
    
    /**
     * @notice Bridge PEPU directly (if you already have PEPU)
     * @param amount Amount of PEPU to bridge
     * @param outputToken Desired token on L2
     */
    function bridgePEPU(uint256 amount, address outputToken) external {
        if (amount == 0) revert ZeroAmount();
        
        // Transfer PEPU from user
        if (!IERC20(PEPU_L1).transferFrom(msg.sender, address(this), amount)) {
            revert TransferFailed();
        }
        
        // Collect fee and bridge
        uint256 bridgeFee = _collectFeeAndBridge(msg.sender, amount, outputToken);
        
        emit BridgeInitiated(msg.sender, PEPU_L1, amount, amount, bridgeFee, outputToken);
    }
    
    /**
     * @notice Bridge ANY ERC20 token → PEPU → L2 → Swap to desired token
     * @param inputToken Token you're bridging (USDT, USDC, DAI, any ERC20)
     * @param amount Amount of input token
     * @param minPepuOut Minimum PEPU to receive (slippage protection)
     * @param outputToken Desired token on L2
     */
    function bridgeAnyToken(
        address inputToken,
        uint256 amount,
        uint256 minPepuOut,
        address outputToken
    ) external {
        if (amount == 0) revert ZeroAmount();
        if (inputToken == address(0)) revert ZeroAddress();
        
        // Transfer input token from user
        if (!IERC20(inputToken).transferFrom(msg.sender, address(this), amount)) {
            revert TransferFailed();
        }
        
        // If input token is already PEPU, skip swap
        if (inputToken == PEPU_L1) {
            uint256 pepuFee = _collectFeeAndBridge(msg.sender, amount, outputToken);
            emit BridgeInitiated(msg.sender, inputToken, amount, amount, pepuFee, outputToken);
            return;
        }
        
        // Approve Uniswap to spend input token
        IERC20(inputToken).approve(UNISWAP_ROUTER, amount);
        
        // Build swap path
        address[] memory path;
        
        if (inputToken == WETH) {
            // WETH → PEPU (direct)
            path = new address[](2);
            path[0] = WETH;
            path[1] = PEPU_L1;
        } else {
            // Any Token → WETH → PEPU
            path = new address[](3);
            path[0] = inputToken;
            path[1] = WETH;
            path[2] = PEPU_L1;
        }
        
        uint256 balanceBefore = IERC20(PEPU_L1).balanceOf(address(this));
        
        // Execute swap
        IUniswapV2Router(UNISWAP_ROUTER).swapExactTokensForTokens(
            amount,
            minPepuOut,
            path,
            address(this),
            block.timestamp + DEADLINE_BUFFER
        );
        
        uint256 pepuReceived = IERC20(PEPU_L1).balanceOf(address(this)) - balanceBefore;
        
        if (pepuReceived == 0) revert SwapFailed();
        
        // Collect fee and bridge
        uint256 swapFee = _collectFeeAndBridge(msg.sender, pepuReceived, outputToken);
        
        emit BridgeInitiated(msg.sender, inputToken, amount, pepuReceived, swapFee, outputToken);
    }
    
    // ========================================================================
    // INTERNAL FUNCTIONS
    // ========================================================================
    
    /**
     * @dev Collect 0.3% fee in PEPU and bridge remainder to L2
     * @param user User address
     * @param pepuAmount Amount of PEPU
     * @param outputToken Desired token on L2
     * @return feeAmount Fee collected
     */
    function _collectFeeAndBridge(
        address user,
        uint256 pepuAmount,
        address outputToken
    ) private returns (uint256 feeAmount) {
        
        // Calculate 0.3% fee
        feeAmount = (pepuAmount * feeBps) / BPS_DENOMINATOR;
        uint256 amountAfterFee = pepuAmount - feeAmount;
        
        // Transfer fee to collector
        if (feeAmount > 0) {
            IERC20(PEPU_L1).transfer(feeCollector, feeAmount);
            emit FeeCollected(feeAmount);
        }
        
        // Approve bridge
        IERC20(PEPU_L1).approve(L1_BRIDGE, amountAfterFee);
        
        // Encode user address + output token preference for L2 contract
        bytes memory userData = abi.encode(user, outputToken);
        
        // Bridge PEPU to L2 (becomes WPEPU on L2)
        IL1StandardBridge(L1_BRIDGE).depositERC20To(
            PEPU_L1,
            WPEPU_L2,
            l2ReceiverContract,
            amountAfterFee,
            L2_GAS,
            userData
        );
        
        return feeAmount;
    }
    
    // ========================================================================
    // ADMIN FUNCTIONS
    // ========================================================================
    
    /**
     * @notice Update fee (owner only)
     * @param newFeeBps New fee in basis points (30 = 0.3%, max 500 = 5%)
     */
    function setFee(uint256 newFeeBps) external onlyOwner {
        if (newFeeBps > MAX_FEE) revert ExcessiveFee();
        feeBps = newFeeBps;
        emit FeeUpdated(newFeeBps);
    }
    
    /**
     * @notice Update fee collector
     */
    function setFeeCollector(address newCollector) external onlyOwner {
        if (newCollector == address(0)) revert ZeroAddress();
        feeCollector = newCollector;
    }
    
    /**
     * @notice Update L2 receiver contract
     */
    function setL2Receiver(address newReceiver) external onlyOwner {
        if (newReceiver == address(0)) revert ZeroAddress();
        l2ReceiverContract = newReceiver;
    }
    
    /**
     * @notice Transfer ownership
     */
    function transferOwnership(address newOwner) external onlyOwner {
        if (newOwner == address(0)) revert ZeroAddress();
        owner = newOwner;
    }
    
    /**
     * @notice Emergency: rescue stuck tokens
     */
    function rescueTokens(address token, uint256 amount) external onlyOwner {
        IERC20(token).transfer(owner, amount);
    }
    
    /**
     * @notice Emergency: rescue stuck ETH
     */
    function rescueETH() external onlyOwner {
        payable(owner).transfer(address(this).balance);
    }
    
    // Allow contract to receive ETH
    receive() external payable {}
}

/**
 * ============================================================================
 * DEPLOYMENT PARAMETERS - COPY THESE!
 * ============================================================================
 * 
 * _l2Receiver: [YOUR L2 CONTRACT ADDRESS FROM STEP 1]
 * _feeCollector: [YOUR WALLET ADDRESS]
 * 
 * Example (comma-separated, no spaces):
 * 0x58B4aCd076fA13e5C1Ef71e64F45844192F2bc62,0xYourWallet
 * 
 * IMPORTANT: Deploy L2 FIRST, then use that address here!
 * 
 * ============================================================================
 */

Tags:
Factory|addr:0x0b629b1968511c97038d35d75df415c3631ef683|verified:true|block:23635124|tx:0xebc0602962c8b3a55d1333c2c2edec252000cfba504ddb65ca9d196e938f90bc|first_check:1761292671

Submitted on: 2025-10-24 09:57:53

Comments

Log in to comment.

No comments yet.