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