ETH Price: $3,319.29 (-1.21%)
Gas: 13.1 Gwei

Contract

0xc3Bb52E6118F05Dd8ad4e1C1a1398281cd7c4C7f
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0xff9562095367395cbdf8872a280d6d26c0d1d6c0b50d62e120995f6a1050457f Deposit WETH(pending)2024-11-22 22:42:1643 mins ago1732315336IN
Aevo: L1 Deposit Helper
0.045 ETH(Pending)(Pending)
0x6ac76743d3d9fa1e04511113374e16c5d30f48808f89942d81d1992afdb93431 Deposit WETH(pending)2024-11-22 21:50:551 hr ago1732312255IN
Aevo: L1 Deposit Helper
0.00078 ETH(Pending)(Pending)
Deposit ERC20Wit...212459462024-11-22 21:26:231 hr ago1732310783IN
Aevo: L1 Deposit Helper
0 ETH0.0037381317.92855415
Deposit WETH212458132024-11-22 20:59:472 hrs ago1732309187IN
Aevo: L1 Deposit Helper
0.7 ETH0.0039719917.00924629
Deposit WETH212450892024-11-22 18:34:474 hrs ago1732300487IN
Aevo: L1 Deposit Helper
0.12 ETH0.0041014417.89314635
Deposit WETH212450522024-11-22 18:27:234 hrs ago1732300043IN
Aevo: L1 Deposit Helper
1.5 ETH0.0033123513.38586036
Deposit ERC20Wit...212447152024-11-22 17:19:116 hrs ago1732295951IN
Aevo: L1 Deposit Helper
0 ETH0.0032612314.97550412
Deposit ERC20Wit...212442412024-11-22 15:43:117 hrs ago1732290191IN
Aevo: L1 Deposit Helper
0 ETH0.0036460815.55903457
Deposit ERC20Wit...212415812024-11-22 6:48:1116 hrs ago1732258091IN
Aevo: L1 Deposit Helper
0 ETH0.002264368.5032674
Deposit WETH212392522024-11-21 23:00:1124 hrs ago1732230011IN
Aevo: L1 Deposit Helper
1 ETH0.0032752513.3099382
Deposit ERC20Wit...212386182024-11-21 20:52:5926 hrs ago1732222379IN
Aevo: L1 Deposit Helper
0 ETH0.0038323917.91082433
Deposit WETH212373732024-11-21 16:43:3530 hrs ago1732207415IN
Aevo: L1 Deposit Helper
1 ETH0.004044917.55427974
Deposit ERC20Wit...212373202024-11-21 16:32:5930 hrs ago1732206779IN
Aevo: L1 Deposit Helper
0 ETH0.0041291520.16957308
Deposit ERC20Wit...212364372024-11-21 13:34:5933 hrs ago1732196099IN
Aevo: L1 Deposit Helper
0 ETH0.0059159730.30323452
Deposit WETH212363652024-11-21 13:20:3534 hrs ago1732195235IN
Aevo: L1 Deposit Helper
0.2 ETH0.0082088438.56633613
Deposit ERC20Wit...212358352024-11-21 11:34:3535 hrs ago1732188875IN
Aevo: L1 Deposit Helper
0 ETH0.0039219518.31568625
Deposit WETH212350502024-11-21 8:56:1138 hrs ago1732179371IN
Aevo: L1 Deposit Helper
0.5 ETH0.0028364110.86581198
Deposit WETH212347242024-11-21 7:50:1139 hrs ago1732175411IN
Aevo: L1 Deposit Helper
0.0349583 ETH0.002449569.13115598
Deposit ERC20Wit...212338822024-11-21 5:00:3542 hrs ago1732165235IN
Aevo: L1 Deposit Helper
0 ETH0.0033810515.4018105
Deposit ERC20Wit...212293502024-11-20 13:48:352 days ago1732110515IN
Aevo: L1 Deposit Helper
0 ETH0.0031665814.24760093
Deposit ERC20Wit...212293132024-11-20 13:41:112 days ago1732110071IN
Aevo: L1 Deposit Helper
0 ETH0.0033426915.3
Deposit WETH212289262024-11-20 12:23:232 days ago1732105403IN
Aevo: L1 Deposit Helper
0.045 ETH0.002472948.73130385
Deposit ERC20Wit...212284562024-11-20 10:48:592 days ago1732099739IN
Aevo: L1 Deposit Helper
0 ETH0.0028204211.16144391
Deposit ERC20Wit...212282282024-11-20 10:03:112 days ago1732096991IN
Aevo: L1 Deposit Helper
0 ETH0.0026773611.67590824
Deposit ERC20Wit...212273682024-11-20 7:09:592 days ago1732086599IN
Aevo: L1 Deposit Helper
0 ETH0.002598879.17660907
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
212458132024-11-22 20:59:472 hrs ago1732309187
Aevo: L1 Deposit Helper
0.7 ETH
212450892024-11-22 18:34:474 hrs ago1732300487
Aevo: L1 Deposit Helper
0.12 ETH
212450522024-11-22 18:27:234 hrs ago1732300043
Aevo: L1 Deposit Helper
1.5 ETH
212392522024-11-21 23:00:1124 hrs ago1732230011
Aevo: L1 Deposit Helper
1 ETH
212373732024-11-21 16:43:3530 hrs ago1732207415
Aevo: L1 Deposit Helper
1 ETH
212363652024-11-21 13:20:3534 hrs ago1732195235
Aevo: L1 Deposit Helper
0.2 ETH
212350502024-11-21 8:56:1138 hrs ago1732179371
Aevo: L1 Deposit Helper
0.5 ETH
212347242024-11-21 7:50:1139 hrs ago1732175411
Aevo: L1 Deposit Helper
0.0349583 ETH
212289262024-11-20 12:23:232 days ago1732105403
Aevo: L1 Deposit Helper
0.045 ETH
212260492024-11-20 2:45:232 days ago1732070723
Aevo: L1 Deposit Helper
0.33 ETH
212257402024-11-20 1:43:232 days ago1732067003
Aevo: L1 Deposit Helper
0.08 ETH
212200312024-11-19 6:37:473 days ago1731998267
Aevo: L1 Deposit Helper
0.2 ETH
212196832024-11-19 5:27:473 days ago1731994067
Aevo: L1 Deposit Helper
0.08 ETH
212183992024-11-19 1:10:233 days ago1731978623
Aevo: L1 Deposit Helper
0.13 ETH
212166812024-11-18 19:25:234 days ago1731957923
Aevo: L1 Deposit Helper
0.07 ETH
212150542024-11-18 13:58:354 days ago1731938315
Aevo: L1 Deposit Helper
1 ETH
212133602024-11-18 8:18:474 days ago1731917927
Aevo: L1 Deposit Helper
0.365 ETH
212058032024-11-17 7:01:475 days ago1731826907
Aevo: L1 Deposit Helper
1.2 ETH
212058012024-11-17 7:01:235 days ago1731826883
Aevo: L1 Deposit Helper
0.2 ETH
212010462024-11-16 15:06:236 days ago1731769583
Aevo: L1 Deposit Helper
1 ETH
211991602024-11-16 8:47:596 days ago1731746879
Aevo: L1 Deposit Helper
0.15 ETH
211983732024-11-16 6:10:116 days ago1731737411
Aevo: L1 Deposit Helper
0.07984197 ETH
211963792024-11-15 23:29:236 days ago1731713363
Aevo: L1 Deposit Helper
0.24 ETH
211962072024-11-15 22:54:597 days ago1731711299
Aevo: L1 Deposit Helper
0.2 ETH
211959552024-11-15 22:04:357 days ago1731708275
Aevo: L1 Deposit Helper
0.45898707 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.