ETH Price: $3,869.89 (+7.24%)

Contract

0xc3Bb52E6118F05Dd8ad4e1C1a1398281cd7c4C7f
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Deposit WETH213316052024-12-04 20:44:352 mins ago1733345075IN
Aevo: L1 Deposit Helper
2 ETH0.0074546334.96662211
Deposit ERC20Wit...213315032024-12-04 20:24:1122 mins ago1733343851IN
Aevo: L1 Deposit Helper
0 ETH0.0091138343.34368539
Deposit ERC20Wit...213308292024-12-04 18:08:592 hrs ago1733335739IN
Aevo: L1 Deposit Helper
0 ETH0.0070993536.689183
Deposit WETH213307332024-12-04 17:49:352 hrs ago1733334575IN
Aevo: L1 Deposit Helper
0.2795 ETH0.0060608828.47489679
Deposit WETH213294432024-12-04 13:30:477 hrs ago1733319047IN
Aevo: L1 Deposit Helper
69.5 ETH0.0042436519.08640157
Deposit ERC20Wit...213293662024-12-04 13:15:117 hrs ago1733318111IN
Aevo: L1 Deposit Helper
0 ETH0.0042916721.07493869
Deposit WETH213289412024-12-04 11:49:238 hrs ago1733312963IN
Aevo: L1 Deposit Helper
33.3 ETH0.0041754718.70731251
Deposit ERC20Wit...213274572024-12-04 6:51:1113 hrs ago1733295071IN
Aevo: L1 Deposit Helper
0 ETH0.0038670818.74585797
Deposit WETH213273542024-12-04 6:30:3514 hrs ago1733293835IN
Aevo: L1 Deposit Helper
88 ETH0.0041469918.1873718
Deposit ERC20Wit...213271812024-12-04 5:55:1114 hrs ago1733291711IN
Aevo: L1 Deposit Helper
0 ETH0.0037136616.38581379
Deposit ERC20Wit...213260812024-12-04 2:13:3518 hrs ago1733278415IN
Aevo: L1 Deposit Helper
0 ETH0.0044245720.14888937
Deposit ERC20Wit...213258472024-12-04 1:26:4719 hrs ago1733275607IN
Aevo: L1 Deposit Helper
0 ETH0.0041758220.97834805
Deposit ERC20Wit...213256962024-12-04 0:56:3519 hrs ago1733273795IN
Aevo: L1 Deposit Helper
0 ETH0.0051902624.3396601
Deposit WETH213251162024-12-03 23:00:1121 hrs ago1733266811IN
Aevo: L1 Deposit Helper
28.2 ETH0.0043050319.42248583
Deposit WETH213232702024-12-03 16:48:3527 hrs ago1733244515IN
Aevo: L1 Deposit Helper
0.25 ETH0.007330234.43838102
Deposit ERC20Wit...213199242024-12-03 5:35:3539 hrs ago1733204135IN
Aevo: L1 Deposit Helper
0 ETH0.0036406115.55538689
Deposit WETH213198832024-12-03 5:27:2339 hrs ago1733203643IN
Aevo: L1 Deposit Helper
0.1 ETH0.0034845714.49490616
Deposit ERC20Wit...213187912024-12-03 1:47:3542 hrs ago1733190455IN
Aevo: L1 Deposit Helper
0 ETH0.0033244715.68628774
Deposit WETH213182612024-12-03 0:00:3544 hrs ago1733184035IN
Aevo: L1 Deposit Helper
0.083 ETH0.0051666324.0179968
Deposit WETH213180922024-12-02 23:26:1145 hrs ago1733181971IN
Aevo: L1 Deposit Helper
0.0714497 ETH0.0058024627.26081927
Deposit WETH213172742024-12-02 20:41:232 days ago1733172083IN
Aevo: L1 Deposit Helper
1.3 ETH0.02474338116.24796822
Deposit WETH213164852024-12-02 18:02:352 days ago1733162555IN
Aevo: L1 Deposit Helper
0.8 ETH0.008242338.66122345
Deposit WETH213163372024-12-02 17:32:592 days ago1733160779IN
Aevo: L1 Deposit Helper
1 ETH0.0082681238.78234023
Deposit WETH213162802024-12-02 17:21:232 days ago1733160083IN
Aevo: L1 Deposit Helper
0.15 ETH0.0084655339.7082955
Deposit WETH213160232024-12-02 16:29:472 days ago1733156987IN
Aevo: L1 Deposit Helper
0.7 ETH0.0061800328.98796138
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
213316052024-12-04 20:44:352 mins ago1733345075
Aevo: L1 Deposit Helper
2 ETH
213307332024-12-04 17:49:352 hrs ago1733334575
Aevo: L1 Deposit Helper
0.2795 ETH
213294432024-12-04 13:30:477 hrs ago1733319047
Aevo: L1 Deposit Helper
69.5 ETH
213289412024-12-04 11:49:238 hrs ago1733312963
Aevo: L1 Deposit Helper
33.3 ETH
213273542024-12-04 6:30:3514 hrs ago1733293835
Aevo: L1 Deposit Helper
88 ETH
213251162024-12-03 23:00:1121 hrs ago1733266811
Aevo: L1 Deposit Helper
28.2 ETH
213232702024-12-03 16:48:3527 hrs ago1733244515
Aevo: L1 Deposit Helper
0.25 ETH
213198832024-12-03 5:27:2339 hrs ago1733203643
Aevo: L1 Deposit Helper
0.1 ETH
213182612024-12-03 0:00:3544 hrs ago1733184035
Aevo: L1 Deposit Helper
0.083 ETH
213180922024-12-02 23:26:1145 hrs ago1733181971
Aevo: L1 Deposit Helper
0.0714497 ETH
213172742024-12-02 20:41:232 days ago1733172083
Aevo: L1 Deposit Helper
1.3 ETH
213164852024-12-02 18:02:352 days ago1733162555
Aevo: L1 Deposit Helper
0.8 ETH
213163372024-12-02 17:32:592 days ago1733160779
Aevo: L1 Deposit Helper
1 ETH
213162802024-12-02 17:21:232 days ago1733160083
Aevo: L1 Deposit Helper
0.15 ETH
213160232024-12-02 16:29:472 days ago1733156987
Aevo: L1 Deposit Helper
0.7 ETH
213158392024-12-02 15:52:352 days ago1733154755
Aevo: L1 Deposit Helper
1 ETH
213157142024-12-02 15:27:352 days ago1733153255
Aevo: L1 Deposit Helper
0.8 ETH
213153332024-12-02 14:10:592 days ago1733148659
Aevo: L1 Deposit Helper
1.25 ETH
213124562024-12-02 4:31:352 days ago1733113895
Aevo: L1 Deposit Helper
0.5 ETH
213106212024-12-01 22:22:352 days ago1733091755
Aevo: L1 Deposit Helper
3.7 ETH
213084002024-12-01 14:56:473 days ago1733065007
Aevo: L1 Deposit Helper
1 ETH
213055412024-12-01 5:22:473 days ago1733030567
Aevo: L1 Deposit Helper
0.09 ETH
213022542024-11-30 18:22:474 days ago1732990967
Aevo: L1 Deposit Helper
15.6 ETH
212999952024-11-30 10:48:114 days ago1732963691
Aevo: L1 Deposit Helper
18.9 ETH
212987482024-11-30 6:37:234 days ago1732948643
Aevo: L1 Deposit Helper
22.2 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
L1DepositHelper

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 5 : L1DepositHelper.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.15;

import {ERC20} from "solmate/tokens/ERC20.sol";
import {WETHInterface} from "../interfaces/WETHInterface.sol";
import {IL1ERC20Bridge} from "./interfaces/IL1ERC20Bridge.sol";
import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";

/// @title L1DepositHelper
/// @notice The L1 deposit helper for depositing tokens to L2 with a permit message
contract L1DepositHelper {
    using SafeTransferLib for ERC20;

    /*//////////////////////////////////////////////////////////////
                               IMMUTABLES
    //////////////////////////////////////////////////////////////*/

    /// @notice The L1 bridge contract
    IL1ERC20Bridge public immutable l1Bridge;

    /// @notice The WETH address
    address public immutable weth;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    /// @notice Constructor
    /// @param _l1Bridge The L1 bridge
    /// @param _weth The WETH address
    constructor(address _l1Bridge, address _weth) {
        l1Bridge = IL1ERC20Bridge(_l1Bridge);
        weth = _weth;

        // Max approve WETH to the L1 bridge
        ERC20(_weth).safeApprove(_l1Bridge, type(uint256).max);
    }

    /*//////////////////////////////////////////////////////////////
                             DEPOSIT LOGIC
    //////////////////////////////////////////////////////////////*/

    /// @notice Deposit an amount of the ERC20 to the senders balance on L2 using an EIP-2612 permit signature
    /// @param l1Token Address of the L1 ERC20 we are depositing
    /// @param l2Token Address of the L1 respective L2 ERC20
    /// @param amount Amount of the ERC20 to deposit
    /// @param l2Gas Gas limit required to complete the deposit on L2
    /// @param data Optional data to forward to L2
    /// @param deadline A timestamp, the current blocktime must be less than or equal to this timestamp
    /// @param v Must produce valid secp256k1 signature from the holder along with r and s
    /// @param r Must produce valid secp256k1 signature from the holder along with v and s
    /// @param s Must produce valid secp256k1 signature from the holder along with r and v
    function depositERC20WithPermit(
        address l1Token,
        address l2Token,
        uint256 amount,
        uint32 l2Gas,
        bytes calldata data,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        // Approve the tokens from the sender to this contract
        ERC20(l1Token).permit(msg.sender, address(this), amount, deadline, v, r, s);

        // Transfer the tokens from the sender to this contract
        ERC20(l1Token).safeTransferFrom(msg.sender, address(this), amount);

        // Approve the tokens from this contract to the L1 bridge
        ERC20(l1Token).safeApprove(address(l1Bridge), amount);

        // Deposit the tokens to the senders balance on L2
        l1Bridge.depositERC20To(l1Token, l2Token, msg.sender, amount, l2Gas, data);
    }

    /// @notice Deposit an amount of ERC20 to a recipients balance on L2 using an EIP-2612 permit signature
    /// @param l1Token Address of the L1 ERC20 we are depositing
    /// @param l2Token Address of the L1 respective L2 ERC20
    /// @param to The recipient address on L2
    /// @param amount Amount of the ERC20 to deposit
    /// @param l2Gas Gas limit required to complete the deposit on L2
    /// @param data Optional data to forward to L2
    /// @param deadline A timestamp, the current blocktime must be less than or equal to this timestamp
    /// @param v Must produce valid secp256k1 signature from the holder along with r and s
    /// @param r Must produce valid secp256k1 signature from the holder along with v and s
    /// @param s Must produce valid secp256k1 signature from the holder along with r and v
    function depositERC20ToWithPermit(
        address l1Token,
        address l2Token,
        address to,
        uint256 amount,
        uint32 l2Gas,
        bytes calldata data,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        // Approve the tokens from the sender to this contract
        ERC20(l1Token).permit(msg.sender, address(this), amount, deadline, v, r, s);

        // Transfer the tokens from the sender to this contract
        ERC20(l1Token).safeTransferFrom(msg.sender, address(this), amount);

        // Approve the tokens from this contract to the L1 bridge
        ERC20(l1Token).safeApprove(address(l1Bridge), amount);

        // Deposit the tokens to the recipients balance on L2
        l1Bridge.depositERC20To(l1Token, l2Token, to, amount, l2Gas, data);
    }

    /// @notice Deposit an amount of ETH as WETH to the senders balance on L2
    /// @param l2Token Address of the L1 respective L2 ERC20
    /// @param l2Gas Gas limit required to complete the deposit on L2
    /// @param data Optional data to forward to L2
    function depositWETH(address l2Token, uint32 l2Gas, bytes calldata data) external payable {
        // Mint WETH
        WETHInterface(weth).deposit{value: msg.value}();

        // Deposit the tokens to the senders balance on L2
        l1Bridge.depositERC20To(weth, l2Token, msg.sender, msg.value, l2Gas, data);
    }

    /// @notice Deposit an amount of ETH as WETH to the senders balance on L2
    /// @param l2Token Address of the L1 respective L2 ERC20
    /// @param to The recipient address on L2
    /// @param l2Gas Gas limit required to complete the deposit on L2
    /// @param data Optional data to forward to L2
    function depositWETHTo(address l2Token, address to, uint32 l2Gas, bytes calldata data) external payable {
        // Mint WETH
        WETHInterface(weth).deposit{value: msg.value}();

        // Deposit the tokens to the recipients balance on L2
        l1Bridge.depositERC20To(weth, l2Token, to, msg.value, l2Gas, data);
    }
}

File 2 of 5 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 3 of 5 : WETHInterface.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.15;

/// @title Interface for WETH9
interface WETHInterface {
    /// @notice Deposit ether to get wrapped ether
    function deposit() external payable;

    /// @notice Withdraw wrapped ether to get ether
    function withdraw(uint256) external;
}

File 4 of 5 : IL1ERC20Bridge.sol
// SPDX-License-Identifier: MIT
pragma solidity >0.5.0 <0.9.0;

/**
 * @title IL1ERC20Bridge
 */
interface IL1ERC20Bridge {
    /**
     *
     * Events *
     *
     */

    event ERC20DepositInitiated(
        address indexed _l1Token,
        address indexed _l2Token,
        address indexed _from,
        address _to,
        uint256 _amount,
        bytes _data
    );

    event ERC20WithdrawalFinalized(
        address indexed _l1Token,
        address indexed _l2Token,
        address indexed _from,
        address _to,
        uint256 _amount,
        bytes _data
    );

    /**
     *
     * Public Functions *
     *
     */

    /**
     * @dev get the address of the corresponding L2 bridge contract.
     * @return Address of the corresponding L2 bridge contract.
     */
    function l2TokenBridge() external returns (address);

    /**
     * @dev deposit an amount of the ERC20 to the caller's balance on L2.
     * @param _l1Token Address of the L1 ERC20 we are depositing
     * @param _l2Token Address of the L1 respective L2 ERC20
     * @param _amount Amount of the ERC20 to deposit
     * @param _l2Gas Gas limit required to complete the deposit on L2.
     * @param _data Optional data to forward to L2. This data is provided
     *        solely as a convenience for external contracts. Aside from enforcing a maximum
     *        length, these contracts provide no guarantees about its content.
     */
    function depositERC20(address _l1Token, address _l2Token, uint256 _amount, uint32 _l2Gas, bytes calldata _data)
        external;

    /**
     * @dev deposit an amount of ERC20 to a recipient's balance on L2.
     * @param _l1Token Address of the L1 ERC20 we are depositing
     * @param _l2Token Address of the L1 respective L2 ERC20
     * @param _to L2 address to credit the withdrawal to.
     * @param _amount Amount of the ERC20 to deposit.
     * @param _l2Gas Gas limit required to complete the deposit on L2.
     * @param _data Optional data to forward to L2. This data is provided
     *        solely as a convenience for external contracts. Aside from enforcing a maximum
     *        length, these contracts provide no guarantees about its content.
     */
    function depositERC20To(
        address _l1Token,
        address _l2Token,
        address _to,
        uint256 _amount,
        uint32 _l2Gas,
        bytes calldata _data
    ) external;

    /**
     *
     * Cross-chain Functions *
     *
     */

    /**
     * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the
     * L1 ERC20 token.
     * This call will fail if the initialized withdrawal from L2 has not been finalized.
     *
     * @param _l1Token Address of L1 token to finalizeWithdrawal for.
     * @param _l2Token Address of L2 token where withdrawal was initiated.
     * @param _from L2 address initiating the transfer.
     * @param _to L1 address to credit the withdrawal to.
     * @param _amount Amount of the ERC20 to deposit.
     * @param _data Data provided by the sender on L2. This data is provided
     *   solely as a convenience for external contracts. Aside from enforcing a maximum
     *   length, these contracts provide no guarantees about its content.
     */
    function finalizeERC20Withdrawal(
        address _l1Token,
        address _l2Token,
        address _from,
        address _to,
        uint256 _amount,
        bytes calldata _data
    ) external;
}

File 5 of 5 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), from) // Append the "from" argument.
            mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
    "solmate/=lib/solmate/src/",
    "lib/forge-std:ds-test/=lib/forge-std/lib/ds-test/src/",
    "lib/solmate:ds-test/=lib/solmate/lib/ds-test/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_l1Bridge","type":"address"},{"internalType":"address","name":"_weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"l1Token","type":"address"},{"internalType":"address","name":"l2Token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint32","name":"l2Gas","type":"uint32"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"depositERC20ToWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"l1Token","type":"address"},{"internalType":"address","name":"l2Token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint32","name":"l2Gas","type":"uint32"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"depositERC20WithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"l2Token","type":"address"},{"internalType":"uint32","name":"l2Gas","type":"uint32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"depositWETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"l2Token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint32","name":"l2Gas","type":"uint32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"depositWETHTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"l1Bridge","outputs":[{"internalType":"contract IL1ERC20Bridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c060405234801561001057600080fd5b50604051610c51380380610c5183398101604081905261002f91610100565b6001600160a01b03828116608052811660a081905261005c9083600019610063602090811b61062417901c565b5050610133565b600060405163095ea7b360e01b8152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806100de5760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b604482015260640160405180910390fd5b50505050565b80516001600160a01b03811681146100fb57600080fd5b919050565b6000806040838503121561011357600080fd5b61011c836100e4565b915061012a602084016100e4565b90509250929050565b60805160a051610ab561019c60003960008181608e01528181610293015281816103490152818161050101526105b701526000818160f1015281816101d50152818161021101528181610319015281816104440152818161048001526105870152610ab56000f3fe6080604052600436106100555760003560e01c80630e47e9e31461005a5780633fc8cef31461007c5780637ac5d5a9146100cc578063969b53da146100df578063b4b6260914610113578063f469f82414610133575b600080fd5b34801561006657600080fd5b5061007a6100753660046107ba565b610146565b005b34801561008857600080fd5b506100b07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200160405180910390f35b61007a6100da366004610879565b610291565b3480156100eb57600080fd5b506100b07f000000000000000000000000000000000000000000000000000000000000000081565b34801561011f57600080fd5b5061007a61012e3660046108da565b6103b5565b61007a610141366004610987565b6104ff565b60405163d505accf60e01b81526001600160a01b038c169063d505accf9061017e90339030908d908a908a908a908a906004016109fd565b600060405180830381600087803b15801561019857600080fd5b505af11580156101ac573d6000803e3d6000fd5b506101c6925050506001600160a01b038c1633308b6106a6565b6101fa6001600160a01b038c167f00000000000000000000000000000000000000000000000000000000000000008a610624565b60405163041c592960e51b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063838b252090610252908e908e908e908e908e908e908e90600401610a3e565b600060405180830381600087803b15801561026c57600080fd5b505af1158015610280573d6000803e3d6000fd5b505050505050505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156102ec57600080fd5b505af1158015610300573d6000803e3d6000fd5b505060405163041c592960e51b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016935063838b2520925061037d91507f0000000000000000000000000000000000000000000000000000000000000000908890339034908a908a908a90600401610a3e565b600060405180830381600087803b15801561039757600080fd5b505af11580156103ab573d6000803e3d6000fd5b5050505050505050565b60405163d505accf60e01b81526001600160a01b038b169063d505accf906103ed90339030908d908a908a908a908a906004016109fd565b600060405180830381600087803b15801561040757600080fd5b505af115801561041b573d6000803e3d6000fd5b50610435925050506001600160a01b038b1633308b6106a6565b6104696001600160a01b038b167f00000000000000000000000000000000000000000000000000000000000000008a610624565b60405163041c592960e51b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063838b2520906104c1908d908d9033908e908e908e908e90600401610a3e565b600060405180830381600087803b1580156104db57600080fd5b505af11580156104ef573d6000803e3d6000fd5b5050505050505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561055a57600080fd5b505af115801561056e573d6000803e3d6000fd5b505060405163041c592960e51b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016935063838b252092506105eb91507f0000000000000000000000000000000000000000000000000000000000000000908990899034908a908a908a90600401610a3e565b600060405180830381600087803b15801561060557600080fd5b505af1158015610619573d6000803e3d6000fd5b505050505050505050565b600060405163095ea7b360e01b8152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806106a05760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b60448201526064015b60405180910390fd5b50505050565b60006040516323b872dd60e01b81528460048201528360248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806107295760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610697565b5050505050565b80356001600160a01b038116811461074757600080fd5b919050565b803563ffffffff8116811461074757600080fd5b60008083601f84011261077257600080fd5b50813567ffffffffffffffff81111561078a57600080fd5b6020830191508360208285010111156107a257600080fd5b9250929050565b803560ff8116811461074757600080fd5b60008060008060008060008060008060006101408c8e0312156107dc57600080fd5b6107e58c610730565b9a506107f360208d01610730565b995061080160408d01610730565b985060608c0135975061081660808d0161074c565b965060a08c013567ffffffffffffffff81111561083257600080fd5b61083e8e828f01610760565b90975095505060c08c0135935061085760e08d016107a9565b92506101008c013591506101208c013590509295989b509295989b9093969950565b6000806000806060858703121561088f57600080fd5b61089885610730565b93506108a66020860161074c565b9250604085013567ffffffffffffffff8111156108c257600080fd5b6108ce87828801610760565b95989497509550505050565b6000806000806000806000806000806101208b8d0312156108fa57600080fd5b6109038b610730565b995061091160208c01610730565b985060408b0135975061092660608c0161074c565b965060808b013567ffffffffffffffff81111561094257600080fd5b61094e8d828e01610760565b90975095505060a08b0135935061096760c08c016107a9565b925060e08b013591506101008b013590509295989b9194979a5092959850565b60008060008060006080868803121561099f57600080fd5b6109a886610730565b94506109b660208701610730565b93506109c46040870161074c565b9250606086013567ffffffffffffffff8111156109e057600080fd5b6109ec88828901610760565b969995985093965092949392505050565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b6001600160a01b0388811682528781166020830152861660408201526060810185905263ffffffff8416608082015260c060a0820181905281018290526000828460e0840137600060e0848401015260e0601f19601f85011683010190509897505050505050505056fea164736f6c634300080f000a0000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c574000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

Deployed Bytecode

0x6080604052600436106100555760003560e01c80630e47e9e31461005a5780633fc8cef31461007c5780637ac5d5a9146100cc578063969b53da146100df578063b4b6260914610113578063f469f82414610133575b600080fd5b34801561006657600080fd5b5061007a6100753660046107ba565b610146565b005b34801561008857600080fd5b506100b07f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6040516001600160a01b03909116815260200160405180910390f35b61007a6100da366004610879565b610291565b3480156100eb57600080fd5b506100b07f0000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c57481565b34801561011f57600080fd5b5061007a61012e3660046108da565b6103b5565b61007a610141366004610987565b6104ff565b60405163d505accf60e01b81526001600160a01b038c169063d505accf9061017e90339030908d908a908a908a908a906004016109fd565b600060405180830381600087803b15801561019857600080fd5b505af11580156101ac573d6000803e3d6000fd5b506101c6925050506001600160a01b038c1633308b6106a6565b6101fa6001600160a01b038c167f0000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c5748a610624565b60405163041c592960e51b81526001600160a01b037f0000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c574169063838b252090610252908e908e908e908e908e908e908e90600401610a3e565b600060405180830381600087803b15801561026c57600080fd5b505af1158015610280573d6000803e3d6000fd5b505050505050505050505050505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156102ec57600080fd5b505af1158015610300573d6000803e3d6000fd5b505060405163041c592960e51b81526001600160a01b037f0000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c57416935063838b2520925061037d91507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2908890339034908a908a908a90600401610a3e565b600060405180830381600087803b15801561039757600080fd5b505af11580156103ab573d6000803e3d6000fd5b5050505050505050565b60405163d505accf60e01b81526001600160a01b038b169063d505accf906103ed90339030908d908a908a908a908a906004016109fd565b600060405180830381600087803b15801561040757600080fd5b505af115801561041b573d6000803e3d6000fd5b50610435925050506001600160a01b038b1633308b6106a6565b6104696001600160a01b038b167f0000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c5748a610624565b60405163041c592960e51b81526001600160a01b037f0000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c574169063838b2520906104c1908d908d9033908e908e908e908e90600401610a3e565b600060405180830381600087803b1580156104db57600080fd5b505af11580156104ef573d6000803e3d6000fd5b5050505050505050505050505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561055a57600080fd5b505af115801561056e573d6000803e3d6000fd5b505060405163041c592960e51b81526001600160a01b037f0000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c57416935063838b252092506105eb91507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2908990899034908a908a908a90600401610a3e565b600060405180830381600087803b15801561060557600080fd5b505af1158015610619573d6000803e3d6000fd5b505050505050505050565b600060405163095ea7b360e01b8152836004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806106a05760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b60448201526064015b60405180910390fd5b50505050565b60006040516323b872dd60e01b81528460048201528360248201528260448201526020600060648360008a5af13d15601f3d11600160005114161716915050806107295760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610697565b5050505050565b80356001600160a01b038116811461074757600080fd5b919050565b803563ffffffff8116811461074757600080fd5b60008083601f84011261077257600080fd5b50813567ffffffffffffffff81111561078a57600080fd5b6020830191508360208285010111156107a257600080fd5b9250929050565b803560ff8116811461074757600080fd5b60008060008060008060008060008060006101408c8e0312156107dc57600080fd5b6107e58c610730565b9a506107f360208d01610730565b995061080160408d01610730565b985060608c0135975061081660808d0161074c565b965060a08c013567ffffffffffffffff81111561083257600080fd5b61083e8e828f01610760565b90975095505060c08c0135935061085760e08d016107a9565b92506101008c013591506101208c013590509295989b509295989b9093969950565b6000806000806060858703121561088f57600080fd5b61089885610730565b93506108a66020860161074c565b9250604085013567ffffffffffffffff8111156108c257600080fd5b6108ce87828801610760565b95989497509550505050565b6000806000806000806000806000806101208b8d0312156108fa57600080fd5b6109038b610730565b995061091160208c01610730565b985060408b0135975061092660608c0161074c565b965060808b013567ffffffffffffffff81111561094257600080fd5b61094e8d828e01610760565b90975095505060a08b0135935061096760c08c016107a9565b925060e08b013591506101008b013590509295989b9194979a5092959850565b60008060008060006080868803121561099f57600080fd5b6109a886610730565b94506109b660208701610730565b93506109c46040870161074c565b9250606086013567ffffffffffffffff8111156109e057600080fd5b6109ec88828901610760565b969995985093965092949392505050565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b6001600160a01b0388811682528781166020830152861660408201526060810185905263ffffffff8416608082015260c060a0820181905281018290526000828460e0840137600060e0848401015260e0601f19601f85011683010190509897505050505050505056fea164736f6c634300080f000a

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c574000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2

-----Decoded View---------------
Arg [0] : _l1Bridge (address): 0x4082C9647c098a6493fb499EaE63b5ce3259c574
Arg [1] : _weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000004082c9647c098a6493fb499eae63b5ce3259c574
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.