MatrixBridge_L1_Fixed

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

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

/**
 * ============================================================================
 * MATRIX BRIDGE L1 - CORRECTED INBOX ADDRESS
 * ============================================================================
 * 
 * FIXED: Using correct Inbox address from L2Beat
 * 
 * ✅ CORRECT ADDRESSES (from L2Beat):
 * - Inbox (for retryable tickets): 0xE92D05b99b53e3cc1c48Ceb77e09c2F8c2f5dea7
 * - SequencerInbox (different!):   0x93CA3db0dF3e78e798004bbE14e1ADE222B14dFa  
 * - Bridge: 0xd3643255ea784c75a5325CC5a4A549C7CD62E499
 * - PEPU L1: 0x93aA0ccD1e5628d3A841C4DbdF602D9eb04085d6
 * - PEPU L2: 0xF9Cf4A16d26979b929Be7176bAc4e7084975FCB8
 */

interface IERC20 {
    function transfer(address to, uint256 amount) external returns (bool);
    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);
}

interface IInbox {
    function createRetryableTicket(
        address to,
        uint256 l2CallValue,
        uint256 maxSubmissionCost,
        address excessFeeRefundAddress,
        address callValueRefundAddress,
        uint256 gasLimit,
        uint256 maxFeePerGas,
        bytes calldata data
    ) external payable returns (uint256);
}

contract MatrixBridge_L1_Fixed {
    
    // ✅ CORRECTED: Using Inbox, not SequencerInbox!
    address public constant INBOX = 0xe92d05b99B53E3CC1C48CeB77E09C2F8c2F5DEA7;
    address public constant BRIDGE = 0xd3643255ea784c75a5325CC5a4A549C7CD62E499;
    address public constant PEPU_L1 = 0x93aA0ccD1e5628d3A841C4DbdF602D9eb04085d6;
    address public constant PEPU_L2 = 0xF9Cf4A16d26979b929Be7176bAc4e7084975FCB8;
    
    address public l2MatrixBridge;
    address public feeCollector;
    address public owner;
    
    // Conservative gas settings
    uint256 public feeBps = 30;              // 0.3%
    uint256 public l2Gas = 300000;           // Increased from 200k
    uint256 public l2MaxFeePerGas = 2 gwei;  // Increased from 1 gwei
    uint256 public maxSubmissionCost = 0.002 ether;  // Increased from 0.001
    
    bool public paused;
    
    uint256 private constant BPS_DENOMINATOR = 10000;
    
    event BridgePEPU(
        address indexed user,
        uint256 amount,
        address outputToken,
        uint256 ticketId
    );
    
    constructor(address _l2MatrixBridge, address _feeCollector) {
        require(_l2MatrixBridge != address(0), "Zero L2");
        require(_feeCollector != address(0), "Zero collector");
        l2MatrixBridge = _l2MatrixBridge;
        feeCollector = _feeCollector;
        owner = msg.sender;
    }
    
    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }
    
    modifier whenNotPaused() {
        require(!paused, "Paused");
        _;
    }
    
    /**
     * @notice Calculate L2 gas cost
     */
    function calculateL2GasCost() public view returns (uint256) {
        return maxSubmissionCost + (l2Gas * l2MaxFeePerGas);
    }
    
    /**
     * @notice Bridge PEPU to L2
     * @param amount Amount of PEPU to bridge
     * @param outputToken Token you want on L2
     */
    function bridgePEPU(
        uint256 amount,
        address outputToken
    ) external payable whenNotPaused {
        require(amount > 0, "Zero amount");
        require(outputToken != address(0), "Zero token");
        
        // Calculate required ETH for L2
        uint256 l2GasCost = calculateL2GasCost();
        require(msg.value >= l2GasCost, "Insufficient ETH for L2 gas");
        
        // Transfer PEPU from user
        require(
            IERC20(PEPU_L1).transferFrom(msg.sender, address(this), amount),
            "PEPU transfer failed"
        );
        
        // Take 0.3% fee
        uint256 feeAmount = (amount * feeBps) / BPS_DENOMINATOR;
        uint256 amountAfterFee = amount - feeAmount;
        
        if (feeAmount > 0) {
            require(
                IERC20(PEPU_L1).transfer(feeCollector, feeAmount),
                "Fee transfer failed"
            );
        }
        
        // Encode L2 call
        bytes memory l2CallData = abi.encodeWithSignature(
            "receiveFromL1(address,uint256,address)",
            msg.sender,
            amountAfterFee,
            outputToken
        );
        
        // Approve PEPU for Bridge
        require(
            IERC20(PEPU_L1).approve(BRIDGE, amountAfterFee),
            "Approve failed"
        );
        
        // Create retryable ticket - NOW USING CORRECT INBOX!
        uint256 ticketId = IInbox(INBOX).createRetryableTicket{value: l2GasCost}(
            l2MatrixBridge,
            0,
            maxSubmissionCost,
            msg.sender,
            msg.sender,
            l2Gas,
            l2MaxFeePerGas,
            l2CallData
        );
        
        // Refund excess ETH
        if (msg.value > l2GasCost) {
            payable(msg.sender).transfer(msg.value - l2GasCost);
        }
        
        emit BridgePEPU(msg.sender, amountAfterFee, outputToken, ticketId);
    }
    
    /**
     * @notice Adjust gas if needed
     */
    function setGasParameters(uint256 _gas, uint256 _feePerGas, uint256 _submission) external onlyOwner {
        l2Gas = _gas;
        l2MaxFeePerGas = _feePerGas;
        maxSubmissionCost = _submission;
    }
    
    function setFee(uint256 newFee) external onlyOwner {
        require(newFee <= 500, "Fee too high");
        feeBps = newFee;
    }
    
    function pause() external onlyOwner {
        paused = true;
    }
    
    function unpause() external onlyOwner {
        paused = false;
    }
    
    function rescueETH() external onlyOwner {
        payable(owner).transfer(address(this).balance);
    }
    
    function rescueTokens(address token, uint256 amount) external onlyOwner {
        IERC20(token).transfer(owner, amount);
    }
    
    receive() external payable {}
}

/**
 * ============================================================================
 * KEY FIX
 * ============================================================================
 * 
 * CHANGED:
 * ❌ OLD: INBOX = 0x93CA3db0dF3e78e798004bbE14e1ADE222B14dFa (SequencerInbox)
 * ✅ NEW: INBOX = 0xE92D05b99b53e3cc1c48Ceb77e09c2F8c2f5dea7 (Correct Inbox)
 * 
 * Also increased gas parameters to be more conservative:
 * - l2Gas: 200k → 300k
 * - l2MaxFeePerGas: 1 gwei → 2 gwei  
 * - maxSubmissionCost: 0.001 → 0.002 ETH
 * 
 * DEPLOY THIS VERSION!
 * ============================================================================
 */

Tags:
Factory|addr:0x73c7aca3f501e09f96a16721daec3b6c1816702e|verified:true|block:23643278|tx:0x21a3a227c6340cf44a4b0dba66b66ecfa9a54bb80288ac840c1473c2c9b1ebca|first_check:1761315990

Submitted on: 2025-10-24 16:26:33

Comments

Log in to comment.

No comments yet.