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!
* ============================================================================
*/
Submitted on: 2025-10-24 16:26:33
Comments
Log in to comment.
No comments yet.