账户
0x02...e5c9
0x02...E5C9

0x02...E5C9

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.20+commit.a1b79de6
语言
Solidity
合同源代码
文件 1 的 1:bridge.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IERC20Like {
    function transfer(address to, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool success);
}

interface IStarknetCore {
    /**
      Sends a message to an L2 contract.

      Returns the hash of the message.
    */
    function sendMessageToL2(
        uint256 toAddress,
        uint256 selector,
        uint256[] calldata payload
    ) external payable returns (bytes32);

    /**
      Consumes a message that was sent from an L2 contract.

      Returns the hash of the message.
    */
    function consumeMessageFromL2(
        uint256 fromAddress,
        uint256[] calldata payload
    ) external returns (bytes32);
}

contract LordsL1Bridge {
    /// @notice The Starknet Core contract address on L1
    address public immutable starknet;

    /// @notice The $LORDS ERC20 contract address on L1
    address public immutable l1Token;

    /// @notice The L2 address of the $LORDS bridge, the counterpart to this contract
    uint256 public immutable l2Bridge;

    event LogDeposit(
        address indexed l1Sender,
        uint256 amount,
        uint256 l2Recipient
    );
    event LogWithdrawal(address indexed l1Recipient, uint256 amount);

    // 2 ** 251 + 17 * 2 ** 192 + 1;
    uint256 private constant CAIRO_PRIME =
        3618502788666131213697322783095070105623107215331596699973092056135872020481;

    // from starkware.starknet.compiler.compile import get_selector_from_name
    // print(get_selector_from_name('handle_deposit'))
    uint256 private constant DEPOSIT_SELECTOR =
        1285101517810983806491589552491143496277809242732141897358598292095611420389;

    // operation ID sent in the L2 -> L1 message
    uint256 private constant PROCESS_WITHDRAWAL = 1;

    function splitUint256(uint256 value)
        internal
        pure
        returns (uint256, uint256)
    {
        uint256 low = value & ((1 << 128) - 1);
        uint256 high = value >> 128;
        return (low, high);
    }

    constructor(
        address _starknet,
        address _l1Token,
        uint256 _l2Bridge
    ) {
        require(_l2Bridge < CAIRO_PRIME, "Invalid L2 bridge address");

        starknet = _starknet;
        l1Token = _l1Token;
        l2Bridge = _l2Bridge;
    }

    /// @notice Function used to bridge $LORDS from L1 to L2
    /// @param amount How many $LORDS to send from msg.sender
    /// @param l2Recipient To which L2 address should we deposit the $LORDS to
    /// @param fee Compulsory fee paid to the sequencer for passing on the message
    function deposit(uint256 amount, uint256 l2Recipient, uint256 fee) external payable {
        require(amount > 0, "Amount is 0");
        require(
            l2Recipient != 0 &&
            l2Recipient != l2Bridge &&
            l2Recipient < CAIRO_PRIME,
            "Invalid L2 recipient"
        );

        uint256[] memory payload = new uint256[](3);
        payload[0] = l2Recipient;
        (payload[1], payload[2]) = splitUint256(amount);

        IERC20Like(l1Token).transferFrom(msg.sender, address(this), amount);
        IStarknetCore(starknet).sendMessageToL2{value: fee}(
            l2Bridge,
            DEPOSIT_SELECTOR,
            payload
        );

        emit LogDeposit(msg.sender, amount, l2Recipient);
    }

    /// @notice Function to process the L2 withdrawal
    /// @param amount How many $LORDS were sent from L2
    /// @param l1Recipient Recipient of the (de)bridged $LORDS
    function withdraw(uint256 amount, address l1Recipient) external {
        uint256[] memory payload = new uint256[](4);
        payload[0] = PROCESS_WITHDRAWAL;
        payload[1] = uint256(uint160(l1Recipient));
        (payload[2], payload[3]) = splitUint256(amount);

        // The call to consumeMessageFromL2 will succeed only if a
        // matching L2->L1 message exists and is ready for consumption.
        IStarknetCore(starknet).consumeMessageFromL2(l2Bridge, payload);
        IERC20Like(l1Token).transfer(l1Recipient, amount);

        emit LogWithdrawal(l1Recipient, amount);
    }
}
设置
{
  "compilationTarget": {
    "src/l1/bridge.sol": "LordsL1Bridge"
  },
  "evmVersion": "paris",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [
    ":create3-factory/=lib/create3-factory/src/",
    ":ds-test/=lib/create3-factory/lib/forge-std/lib/ds-test/src/",
    ":forge-std/=lib/create3-factory/lib/forge-std/src/",
    ":solmate/=lib/create3-factory/lib/solmate/src/"
  ]
}
ABI
[{"inputs":[{"internalType":"address","name":"_starknet","type":"address"},{"internalType":"address","name":"_l1Token","type":"address"},{"internalType":"uint256","name":"_l2Bridge","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"l1Sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"l2Recipient","type":"uint256"}],"name":"LogDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"l1Recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LogWithdrawal","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"l2Recipient","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"l1Token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2Bridge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"starknet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"l1Recipient","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]