ETH Price: $3,378.45 (+4.54%)
 

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

> 10 Internal Transactions and > 10 Token Transfers found.

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
196180162024-04-09 12:14:23289 days ago1712664863
0xe09801dA...D68073D1a
0.35450408 ETH
196180162024-04-09 12:14:23289 days ago1712664863
0xe09801dA...D68073D1a
0.35450408 ETH
195834952024-04-04 16:09:59294 days ago1712246999
0xe09801dA...D68073D1a
0.1263683 ETH
195834952024-04-04 16:09:59294 days ago1712246999
0xe09801dA...D68073D1a
0.1263683 ETH
195638272024-04-01 22:02:59297 days ago1712008979
0xe09801dA...D68073D1a
1.11875973 ETH
195638272024-04-01 22:02:59297 days ago1712008979
0xe09801dA...D68073D1a
1.11875973 ETH
195636452024-04-01 21:26:35297 days ago1712006795
0xe09801dA...D68073D1a
0.92372621 ETH
195636452024-04-01 21:26:35297 days ago1712006795
0xe09801dA...D68073D1a
0.92372621 ETH
195115232024-03-25 12:34:11304 days ago1711370051
0xe09801dA...D68073D1a
1.0952491 ETH
195115232024-03-25 12:34:11304 days ago1711370051
0xe09801dA...D68073D1a
1.0952491 ETH
195102282024-03-25 8:10:59304 days ago1711354259
0xe09801dA...D68073D1a
3.16143673 ETH
195102282024-03-25 8:10:59304 days ago1711354259
0xe09801dA...D68073D1a
3.16143673 ETH
194901042024-03-22 12:16:11307 days ago1711109771
0xe09801dA...D68073D1a
0.15992355 ETH
194901042024-03-22 12:16:11307 days ago1711109771
0xe09801dA...D68073D1a
0.15992355 ETH
194889132024-03-22 8:15:59307 days ago1711095359
0xe09801dA...D68073D1a
6.45203347 ETH
194889132024-03-22 8:15:59307 days ago1711095359
0xe09801dA...D68073D1a
6.45203347 ETH
194758532024-03-20 12:17:11309 days ago1710937031
0xe09801dA...D68073D1a
0.16685723 ETH
194758532024-03-20 12:17:11309 days ago1710937031
0xe09801dA...D68073D1a
0.16685723 ETH
194567262024-03-17 19:45:11312 days ago1710704711
0xe09801dA...D68073D1a
0.20972679 ETH
194567262024-03-17 19:45:11312 days ago1710704711
0xe09801dA...D68073D1a
0.20972679 ETH
194344182024-03-14 16:26:47315 days ago1710433607
0xe09801dA...D68073D1a
4.10201737 ETH
194344182024-03-14 16:26:47315 days ago1710433607
0xe09801dA...D68073D1a
4.10201737 ETH
193918172024-03-08 17:04:11321 days ago1709917451
0xe09801dA...D68073D1a
6.01110835 ETH
193918172024-03-08 17:04:11321 days ago1709917451
0xe09801dA...D68073D1a
6.01110835 ETH
193701402024-03-05 16:24:35324 days ago1709655875
0xe09801dA...D68073D1a
5.46399771 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CurveStEthBridge

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 100000 runs

Other Settings:
default evmVersion
File 1 of 13 : CurveStEthBridge.sol
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Aztec.
pragma solidity >=0.8.4;

import {ICurvePool} from "../../interfaces/curve/ICurvePool.sol";
import {ILido} from "../../interfaces/lido/ILido.sol";
import {IWstETH} from "../../interfaces/lido/IWstETH.sol";
import {IRollupProcessor} from "../../aztec/interfaces/IRollupProcessor.sol";

import {BridgeBase} from "../base/BridgeBase.sol";
import {ErrorLib} from "../base/ErrorLib.sol";
import {AztecTypes} from "../../aztec/libraries/AztecTypes.sol";

import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

/**
 * @notice A DeFiBridge for trading between Eth and wstEth using curve and the stEth wrapper.
 * @dev Synchronous and stateless bridge that will hold no funds beyond dust for gas-savings.
 * @author Aztec Team
 */
contract CurveStEthBridge is BridgeBase {
    using SafeERC20 for ILido;
    using SafeERC20 for IWstETH;

    error InvalidConfiguration();
    error InvalidUnwrapReturnValue();

    ILido public constant LIDO = ILido(0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84);
    IWstETH public constant WRAPPED_STETH = IWstETH(0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0);
    ICurvePool public constant CURVE_POOL = ICurvePool(0xDC24316b9AE028F1497c275EB9192a3Ea0f67022);

    uint256 public constant PRECISION = 1e18;

    // Indexes of the assets in the curve pool
    int128 private constant CURVE_ETH_INDEX = 0;
    int128 private constant CURVE_STETH_INDEX = 1;

    /**
     * @notice Sets the address of the RollupProcessor and pre-approve tokens
     * @dev As the contract will not be holding state nor tokens, it can be approved safely.
     * @param _rollupProcessor The address of the RollupProcessor to use
     */
    constructor(address _rollupProcessor) BridgeBase(_rollupProcessor) {
        if (CURVE_POOL.coins(uint256(uint128(CURVE_STETH_INDEX))) != address(LIDO)) {
            revert InvalidConfiguration();
        }

        LIDO.safeIncreaseAllowance(address(WRAPPED_STETH), type(uint256).max);
        LIDO.safeIncreaseAllowance(address(CURVE_POOL), type(uint256).max);
        WRAPPED_STETH.safeIncreaseAllowance(ROLLUP_PROCESSOR, type(uint256).max);
    }

    // Empty receive function for the contract to be able to receive Eth
    receive() external payable {}

    /**
     * @notice Swaps between the eth<->wstEth tokens through the curve eth/stEth pool and wrapping stEth
     * @param _inputAssetA The inputAsset (eth or wstEth)
     * @param _outputAssetA The output asset (eth or wstEth) opposite `_inputAssetB`
     * @param _totalInputValue The amount of token deposited
     * @param _interactionNonce The nonce of the DeFi interaction, used when swapping wstEth -> eth
     * @param _auxData For eth->wstEth, the minimum acceptable amount of stEth per 1 eth, for wstEth->eth, the minimum
     *                 acceptable amount of eth per 1 wstEth.
     * @return outputValueA The amount of `_outputAssetA` that the RollupProcessor should pull
     */
    function convert(
        AztecTypes.AztecAsset calldata _inputAssetA,
        AztecTypes.AztecAsset calldata,
        AztecTypes.AztecAsset calldata _outputAssetA,
        AztecTypes.AztecAsset calldata,
        uint256 _totalInputValue,
        uint256 _interactionNonce,
        uint64 _auxData,
        address
    )
        external
        payable
        override(BridgeBase)
        onlyRollup
        returns (
            uint256 outputValueA,
            uint256,
            bool
        )
    {
        bool isETHInput = _inputAssetA.assetType == AztecTypes.AztecAssetType.ETH;
        bool isWstETHInput = _inputAssetA.assetType == AztecTypes.AztecAssetType.ERC20 &&
            _inputAssetA.erc20Address == address(WRAPPED_STETH);

        if (!(isETHInput || isWstETHInput)) {
            revert ErrorLib.InvalidInputA();
        }

        outputValueA = isETHInput
            ? _wrapETH(_totalInputValue, _outputAssetA, _auxData)
            : _unwrapETH(_totalInputValue, _outputAssetA, _auxData, _interactionNonce);
    }

    /**
     * @notice Swaps eth to stEth through curve and wrap the stEth into wstEth
     * @dev Reverts if `_outputAsset` is not wstEth
     * @param _totalInputValue The amount of token that is deposited
     * @param _outputAsset The asset that the DeFi interaction specify as output, must be wstEth
     * @param _minStEthPerEth Smallest acceptable amount of steth for each eth
     * @return outputValue The amount of wstEth received from the interaction
     */
    function _wrapETH(
        uint256 _totalInputValue,
        AztecTypes.AztecAsset calldata _outputAsset,
        uint256 _minStEthPerEth
    ) private returns (uint256 outputValue) {
        if (
            _outputAsset.assetType != AztecTypes.AztecAssetType.ERC20 ||
            _outputAsset.erc20Address != address(WRAPPED_STETH)
        ) {
            revert ErrorLib.InvalidOutputA();
        }

        uint256 minDy = (_totalInputValue * _minStEthPerEth) / PRECISION;

        // Swap eth -> stEth on curve
        uint256 dy = CURVE_POOL.exchange{value: _totalInputValue}(
            CURVE_ETH_INDEX,
            CURVE_STETH_INDEX,
            _totalInputValue,
            minDy
        );

        // wrap stEth
        outputValue = WRAPPED_STETH.wrap(dy);
    }

    /**
     * @notice Unwraps wstEth and swap stEth to eth through curve
     * @dev Reverts if `_outputAsset` is not eth
     * @param _totalInputValue The amount of token that is deposited
     * @param _outputAsset The asset that the DeFi interaction specify as output, must be eth
     * @param _minEthPerStEth Smallest acceptable amount of eth for each steth
     * @return outputValue The amount of eth received from the interaction
     */
    function _unwrapETH(
        uint256 _totalInputValue,
        AztecTypes.AztecAsset calldata _outputAsset,
        uint256 _minEthPerStEth,
        uint256 _interactionNonce
    ) private returns (uint256 outputValue) {
        if (_outputAsset.assetType != AztecTypes.AztecAssetType.ETH) {
            revert ErrorLib.InvalidOutputA();
        }

        // Convert wstETH to stETH so we can exchange it on curve
        uint256 stETH = WRAPPED_STETH.unwrap(_totalInputValue);

        uint256 minDy = (stETH * _minEthPerStEth) / PRECISION;
        // Exchange stETH to ETH via curve
        uint256 dy = CURVE_POOL.exchange(CURVE_STETH_INDEX, CURVE_ETH_INDEX, stETH, minDy);

        outputValue = address(this).balance;
        if (outputValue < dy) {
            revert InvalidUnwrapReturnValue();
        }

        // Send ETH to rollup processor
        IRollupProcessor(ROLLUP_PROCESSOR).receiveEthFromBridge{value: outputValue}(_interactionNonce);
    }
}

File 2 of 13 : ICurvePool.sol
// SPDX-License-Identifier: GPLv2
pragma solidity >=0.8.4;

interface ICurvePool {
    function coins(uint256) external view returns (address);

    function get_dy(
        int128 i,
        int128 j,
        uint256 dx
    ) external view returns (uint256);

    function exchange(
        int128 i,
        int128 j,
        uint256 dx,
        uint256 min_dy
    ) external payable returns (uint256);
}

File 3 of 13 : ILido.sol
// SPDX-License-Identifier: GPLv2
pragma solidity >=0.8.4;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface ILido is IERC20 {
    function getTotalShares() external view returns (uint256);

    function sharesOf(address _account) external view returns (uint256);

    function getSharesByPooledEth(uint256 _amount) external view returns (uint256);

    function getPooledEthByShares(uint256 _amount) external view returns (uint256);

    function submit(address _referral) external payable returns (uint256);
}

File 4 of 13 : IWstETH.sol
// SPDX-License-Identifier: GPLv2
pragma solidity >=0.8.4;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IWstETH is IERC20 {
    function wrap(uint256 _stETHAmount) external returns (uint256);

    function unwrap(uint256 _wstETHAmount) external returns (uint256);

    function getStETHByWstETH(uint256 _wstETHAmount) external view returns (uint256);

    function getWstETHByStETH(uint256 _stETHAmount) external view returns (uint256);
}

File 5 of 13 : IRollupProcessor.sol
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Aztec
pragma solidity >=0.8.4;

// @dev For documentation of the functions within this interface see RollupProcessor contract
interface IRollupProcessor {
    /*----------------------------------------
    EVENTS
    ----------------------------------------*/
    event OffchainData(uint256 indexed rollupId, uint256 chunk, uint256 totalChunks, address sender);
    event RollupProcessed(uint256 indexed rollupId, bytes32[] nextExpectedDefiHashes, address sender);
    event DefiBridgeProcessed(
        uint256 indexed encodedBridgeCallData,
        uint256 indexed nonce,
        uint256 totalInputValue,
        uint256 totalOutputValueA,
        uint256 totalOutputValueB,
        bool result,
        bytes errorReason
    );
    event AsyncDefiBridgeProcessed(
        uint256 indexed encodedBridgeCallData,
        uint256 indexed nonce,
        uint256 totalInputValue
    );
    event Deposit(uint256 indexed assetId, address indexed depositorAddress, uint256 depositValue);
    event WithdrawError(bytes errorReason);
    event AssetAdded(uint256 indexed assetId, address indexed assetAddress, uint256 assetGasLimit);
    event BridgeAdded(uint256 indexed bridgeAddressId, address indexed bridgeAddress, uint256 bridgeGasLimit);
    event RollupProviderUpdated(address indexed providerAddress, bool valid);
    event VerifierUpdated(address indexed verifierAddress);
    event Paused(address account);
    event Unpaused(address account);

    /*----------------------------------------
      MUTATING FUNCTIONS
      ----------------------------------------*/

    function pause() external;

    function unpause() external;

    function setRollupProvider(address _provider, bool _valid) external;

    function setVerifier(address _verifier) external;

    function setAllowThirdPartyContracts(bool _allowThirdPartyContracts) external;

    function setDefiBridgeProxy(address _defiBridgeProxy) external;

    function setSupportedAsset(address _token, uint256 _gasLimit) external;

    function setSupportedBridge(address _bridge, uint256 _gasLimit) external;

    function processRollup(bytes calldata _encodedProofData, bytes calldata _signatures) external;

    function receiveEthFromBridge(uint256 _interactionNonce) external payable;

    function approveProof(bytes32 _proofHash) external;

    function depositPendingFunds(
        uint256 _assetId,
        uint256 _amount,
        address _owner,
        bytes32 _proofHash
    ) external payable;

    function offchainData(
        uint256 _rollupId,
        uint256 _chunk,
        uint256 _totalChunks,
        bytes calldata _offchainTxData
    ) external;

    function processAsyncDefiInteraction(uint256 _interactionNonce) external returns (bool);

    /*----------------------------------------
      NON-MUTATING FUNCTIONS
      ----------------------------------------*/

    function rollupStateHash() external view returns (bytes32);

    function userPendingDeposits(uint256 _assetId, address _user) external view returns (uint256);

    function defiBridgeProxy() external view returns (address);

    function prevDefiInteractionsHash() external view returns (bytes32);

    function paused() external view returns (bool);

    function verifier() external view returns (address);

    function getDataSize() external view returns (uint256);

    function getPendingDefiInteractionHashesLength() external view returns (uint256);

    function getDefiInteractionHashesLength() external view returns (uint256);

    function getAsyncDefiInteractionHashesLength() external view returns (uint256);

    function getSupportedBridge(uint256 _bridgeAddressId) external view returns (address);

    function getSupportedBridgesLength() external view returns (uint256);

    function getSupportedAssetsLength() external view returns (uint256);

    function getSupportedAsset(uint256 _assetId) external view returns (address);

    function getEscapeHatchStatus() external view returns (bool, uint256);
}

File 6 of 13 : BridgeBase.sol
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Aztec.
pragma solidity >=0.8.4;

import {IDefiBridge} from "../../aztec/interfaces/IDefiBridge.sol";
import {AztecTypes} from "../../aztec/libraries/AztecTypes.sol";
import {ErrorLib} from "./ErrorLib.sol";

/**
 * @title BridgeBase
 * @notice A base that bridges can be built upon which imports a limited set of features
 * @dev Reverts `convert` with missing implementation, and `finalise` with async disabled
 * @author Lasse Herskind
 */
abstract contract BridgeBase is IDefiBridge {
    error MissingImplementation();

    address public immutable ROLLUP_PROCESSOR;

    constructor(address _rollupProcessor) {
        ROLLUP_PROCESSOR = _rollupProcessor;
    }

    modifier onlyRollup() {
        if (msg.sender != ROLLUP_PROCESSOR) {
            revert ErrorLib.InvalidCaller();
        }
        _;
    }

    function convert(
        AztecTypes.AztecAsset calldata,
        AztecTypes.AztecAsset calldata,
        AztecTypes.AztecAsset calldata,
        AztecTypes.AztecAsset calldata,
        uint256,
        uint256,
        uint64,
        address
    )
        external
        payable
        virtual
        override(IDefiBridge)
        returns (
            uint256,
            uint256,
            bool
        )
    {
        revert MissingImplementation();
    }

    function finalise(
        AztecTypes.AztecAsset calldata,
        AztecTypes.AztecAsset calldata,
        AztecTypes.AztecAsset calldata,
        AztecTypes.AztecAsset calldata,
        uint256,
        uint64
    )
        external
        payable
        virtual
        override(IDefiBridge)
        returns (
            uint256,
            uint256,
            bool
        )
    {
        revert ErrorLib.AsyncDisabled();
    }
}

File 7 of 13 : ErrorLib.sol
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Aztec.
pragma solidity >=0.8.4;

library ErrorLib {
    error InvalidCaller();

    error InvalidInput();
    error InvalidInputA();
    error InvalidInputB();
    error InvalidOutputA();
    error InvalidOutputB();
    error InvalidInputAmount();
    error InvalidAuxData();

    error ApproveFailed(address token);
    error TransferFailed(address token);

    error InvalidNonce();
    error AsyncDisabled();
}

File 8 of 13 : AztecTypes.sol
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Aztec
pragma solidity >=0.8.4;

library AztecTypes {
    enum AztecAssetType {
        NOT_USED,
        ETH,
        ERC20,
        VIRTUAL
    }

    struct AztecAsset {
        uint256 id;
        address erc20Address;
        AztecAssetType assetType;
    }
}

File 9 of 13 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 10 of 13 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 11 of 13 : IDefiBridge.sol
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Aztec
pragma solidity >=0.8.4;

import {AztecTypes} from "../libraries/AztecTypes.sol";

interface IDefiBridge {
    /**
     * @notice A function which converts input assets to output assets.
     * @param _inputAssetA A struct detailing the first input asset
     * @param _inputAssetB A struct detailing the second input asset
     * @param _outputAssetA A struct detailing the first output asset
     * @param _outputAssetB A struct detailing the second output asset
     * @param _totalInputValue An amount of input assets transferred to the bridge (Note: "total" is in the name
     *                         because the value can represent summed/aggregated token amounts of users actions on L2)
     * @param _interactionNonce A globally unique identifier of this interaction/`convert(...)` call.
     * @param _auxData Bridge specific data to be passed into the bridge contract (e.g. slippage, nftID etc.)
     * @return outputValueA An amount of `_outputAssetA` returned from this interaction.
     * @return outputValueB An amount of `_outputAssetB` returned from this interaction.
     * @return isAsync A flag indicating if the interaction is async.
     * @dev This function is called from the RollupProcessor contract via the DefiBridgeProxy. Before this function is
     *      called _RollupProcessor_ contract will have sent you all the assets defined by the input params. This
     *      function is expected to convert input assets to output assets (e.g. on Uniswap) and return the amounts
     *      of output assets to be received by the _RollupProcessor_. If output assets are ERC20 tokens the bridge has
     *      to _RollupProcessor_ as a spender before the interaction is finished. If some of the output assets is ETH
     *      it has to be sent to _RollupProcessor_ via the `receiveEthFromBridge(uint256 _interactionNonce)` method
     *      inside before the `convert(...)` function call finishes.
     * @dev If there are two input assets, equal amounts of both assets will be transferred to the bridge before this
     *      method is called.
     * @dev **BOTH** output assets could be virtual but since their `assetId` is currently assigned as
     *      `_interactionNonce` it would simply mean that more of the same virtual asset is minted.
     * @dev If this interaction is async the function has to return `(0,0 true)`. Async interaction will be finalised at
     *      a later time and its output assets will be returned in a `IDefiBridge.finalise(...)` call.
     **/
    function convert(
        AztecTypes.AztecAsset calldata _inputAssetA,
        AztecTypes.AztecAsset calldata _inputAssetB,
        AztecTypes.AztecAsset calldata _outputAssetA,
        AztecTypes.AztecAsset calldata _outputAssetB,
        uint256 _totalInputValue,
        uint256 _interactionNonce,
        uint64 _auxData,
        address _rollupBeneficiary
    )
        external
        payable
        returns (
            uint256 outputValueA,
            uint256 outputValueB,
            bool isAsync
        );

    /**
     * @notice A function that finalises asynchronous interaction.
     * @param _inputAssetA A struct detailing the first input asset
     * @param _inputAssetB A struct detailing the second input asset
     * @param _outputAssetA A struct detailing the first output asset
     * @param _outputAssetB A struct detailing the second output asset
     * @param _interactionNonce A globally unique identifier of this interaction/`convert(...)` call.
     * @param _auxData Bridge specific data to be passed into the bridge contract (e.g. slippage, nftID etc.)
     * @return outputValueA An amount of `_outputAssetA` returned from this interaction.
     * @return outputValueB An amount of `_outputAssetB` returned from this interaction.
     * @dev This function should use the `BridgeBase.onlyRollup()` modifier to ensure it can only be called from
     *      the `RollupProcessor.processAsyncDefiInteraction(uint256 _interactionNonce)` method.
     **/
    function finalise(
        AztecTypes.AztecAsset calldata _inputAssetA,
        AztecTypes.AztecAsset calldata _inputAssetB,
        AztecTypes.AztecAsset calldata _outputAssetA,
        AztecTypes.AztecAsset calldata _outputAssetB,
        uint256 _interactionNonce,
        uint64 _auxData
    )
        external
        payable
        returns (
            uint256 outputValueA,
            uint256 outputValueB,
            bool interactionComplete
        );
}

File 12 of 13 : draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 13 of 13 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

Settings
{
  "remappings": [
    "@openzeppelin/=node_modules/@openzeppelin/",
    "ds-test/=lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "src/=src/",
    "src/=src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 100000
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_rollupProcessor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AsyncDisabled","type":"error"},{"inputs":[],"name":"InvalidCaller","type":"error"},{"inputs":[],"name":"InvalidConfiguration","type":"error"},{"inputs":[],"name":"InvalidInputA","type":"error"},{"inputs":[],"name":"InvalidOutputA","type":"error"},{"inputs":[],"name":"InvalidUnwrapReturnValue","type":"error"},{"inputs":[],"name":"MissingImplementation","type":"error"},{"inputs":[],"name":"CURVE_POOL","outputs":[{"internalType":"contract ICurvePool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LIDO","outputs":[{"internalType":"contract ILido","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROLLUP_PROCESSOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WRAPPED_STETH","outputs":[{"internalType":"contract IWstETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"_inputAssetA","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"_outputAssetA","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"internalType":"uint256","name":"_totalInputValue","type":"uint256"},{"internalType":"uint256","name":"_interactionNonce","type":"uint256"},{"internalType":"uint64","name":"_auxData","type":"uint64"},{"internalType":"address","name":"","type":"address"}],"name":"convert","outputs":[{"internalType":"uint256","name":"outputValueA","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"erc20Address","type":"address"},{"internalType":"enum AztecTypes.AztecAssetType","name":"assetType","type":"uint8"}],"internalType":"struct AztecTypes.AztecAsset","name":"","type":"tuple"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"finalise","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a06040523480156200001157600080fd5b506040516200169438038062001694833981016040819052620000349162000522565b6001600160a01b03811660805260405163c661065760e01b81526001600482015273ae7ab96520de3a18e5e111b5eaab095312d7fe849073dc24316b9ae028f1497c275eb9192a3ea0f670229063c661065790602401602060405180830381865afa158015620000a8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ce919062000522565b6001600160a01b031614620000f65760405163c52a9bd360e01b815260040160405180910390fd5b6200013973ae7ab96520de3a18e5e111b5eaab095312d7fe84737f39c581f595b53c5cb19bd0b3f8da6c935e2ca0600019620001c0602090811b620003a317901c565b6200017c73ae7ab96520de3a18e5e111b5eaab095312d7fe8473dc24316b9ae028f1497c275eb9192a3ea0f67022600019620001c0602090811b620003a317901c565b620001b9608051600019737f39c581f595b53c5cb19bd0b3f8da6c935e2ca06001600160a01b0316620001c060201b620003a3179092919060201c565b5062000634565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801562000212573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200023891906200054d565b62000244919062000567565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b17909152919250620002a091869190620002a616565b50505050565b600062000302826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200038d60201b620004de179092919060201c565b8051909150156200038857808060200190518101906200032391906200058e565b620003885760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b505050565b60606200039e8484600085620003a8565b90505b9392505050565b6060824710156200040b5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016200037f565b6001600160a01b0385163b620004645760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016200037f565b600080866001600160a01b03168587604051620004829190620005e1565b60006040518083038185875af1925050503d8060008114620004c1576040519150601f19603f3d011682016040523d82523d6000602084013e620004c6565b606091505b509092509050620004d9828286620004e4565b979650505050505050565b60608315620004f5575081620003a1565b825115620005065782518084602001fd5b8160405162461bcd60e51b81526004016200037f9190620005ff565b6000602082840312156200053557600080fd5b81516001600160a01b0381168114620003a157600080fd5b6000602082840312156200056057600080fd5b5051919050565b600082198211156200058957634e487b7160e01b600052601160045260246000fd5b500190565b600060208284031215620005a157600080fd5b81518015158114620003a157600080fd5b60005b83811015620005cf578181015183820152602001620005b5565b83811115620002a05750506000910152565b60008251620005f5818460208701620005b2565b9190910192915050565b602081526000825180602084015262000620816040850160208701620005b2565b601f01601f19169190910160400192915050565b6080516110366200065e600039600081816101a1015281816101df015261071d01526110366000f3fe6080604052600436106100745760003560e01c80638b21f1701161004e5780638b21f1701461012a5780639b07d34214610152578063aaf5eb6814610165578063ae9467b51461018f57600080fd5b806312280c191461008057806326c3b515146100d257806386a8b4b51461010257600080fd5b3661007b57005b600080fd5b34801561008c57600080fd5b506100a8737f39c581f595b53c5cb19bd0b3f8da6c935e2ca081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100e56100e0366004610cfb565b6101c3565b6040805193845260208401929092521515908201526060016100c9565b34801561010e57600080fd5b506100a873dc24316b9ae028f1497c275eb9192a3ea0f6702281565b34801561013657600080fd5b506100a873ae7ab96520de3a18e5e111b5eaab095312d7fe8481565b6100e5610160366004610d8d565b61036c565b34801561017157600080fd5b50610181670de0b6b3a764000081565b6040519081526020016100c9565b34801561019b57600080fd5b506100a87f000000000000000000000000000000000000000000000000000000000000000081565b600080803373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610236576040517f48f5c3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600161024a60608e0160408f01610e31565b600381111561025b5761025b610e02565b149050600060028d60400160208101906102759190610e31565b600381111561028657610286610e02565b1480156102e45750737f39c581f595b53c5cb19bd0b3f8da6c935e2ca073ffffffffffffffffffffffffffffffffffffffff168d60200160208101906102cc9190610e52565b73ffffffffffffffffffffffffffffffffffffffff16145b905081806102ef5750805b610325576040517fc582880b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8161034557610340898c8967ffffffffffffffff168b6104f7565b61035a565b61035a898c8967ffffffffffffffff1661079b565b94505050985098509895505050505050565b60008060006040517f26d18eab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801561041a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043e9190610e6d565b6104489190610eb5565b6040805173ffffffffffffffffffffffffffffffffffffffff8616602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529091506104d89085906109a3565b50505050565b60606104ed8484600085610ab9565b90505b9392505050565b6000600161050b6060860160408701610e31565b600381111561051c5761051c610e02565b14610553576040517f6c98dcaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fde0e9a3e00000000000000000000000000000000000000000000000000000000815260048101869052600090737f39c581f595b53c5cb19bd0b3f8da6c935e2ca09063de0e9a3e906024016020604051808303816000875af11580156105c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e59190610e6d565b90506000670de0b6b3a76400006105fc8684610ecd565b6106069190610f0a565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260016004820152600060248201819052604482018590526064820183905291925073dc24316b9ae028f1497c275eb9192a3ea0f6702290633df02124906084016020604051808303816000875af115801561068b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106af9190610e6d565b9050479350808410156106ee576040517fe44b5b5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f12a53623000000000000000000000000000000000000000000000000000000008152600481018690527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906312a536239086906024016000604051808303818588803b15801561077757600080fd5b505af115801561078b573d6000803e3d6000fd5b5050505050505050949350505050565b600060026107af6060850160408601610e31565b60038111156107c0576107c0610e02565b1415806108065750737f39c581f595b53c5cb19bd0b3f8da6c935e2ca06107ed6040850160208601610e52565b73ffffffffffffffffffffffffffffffffffffffff1614155b1561083d576040517f6c98dcaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000670de0b6b3a76400006108528487610ecd565b61085c9190610f0a565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260006004820181905260016024830152604482018890526064820183905291925073dc24316b9ae028f1497c275eb9192a3ea0f6702290633df0212490889060840160206040518083038185885af11580156108e2573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109079190610e6d565b6040517fea598cb000000000000000000000000000000000000000000000000000000000815260048101829052909150737f39c581f595b53c5cb19bd0b3f8da6c935e2ca09063ea598cb0906024016020604051808303816000875af1158015610975573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109999190610e6d565b9695505050505050565b6000610a05826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104de9092919063ffffffff16565b805190915015610ab45780806020019051810190610a239190610f45565b610ab4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b606082471015610b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aab565b73ffffffffffffffffffffffffffffffffffffffff85163b610bc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aab565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610bf29190610f93565b60006040518083038185875af1925050503d8060008114610c2f576040519150601f19603f3d011682016040523d82523d6000602084013e610c34565b606091505b5091509150610c44828286610c4f565b979650505050505050565b60608315610c5e5750816104f0565b825115610c6e5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aab9190610faf565b600060608284031215610cb457600080fd5b50919050565b803567ffffffffffffffff81168114610cd257600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610cd257600080fd5b600080600080600080600080610200898b031215610d1857600080fd5b610d228a8a610ca2565b9750610d318a60608b01610ca2565b9650610d408a60c08b01610ca2565b9550610d508a6101208b01610ca2565b945061018089013593506101a08901359250610d6f6101c08a01610cba565b9150610d7e6101e08a01610cd7565b90509295985092959890939650565b6000806000806000806101c08789031215610da757600080fd5b610db18888610ca2565b9550610dc08860608901610ca2565b9450610dcf8860c08901610ca2565b9350610ddf886101208901610ca2565b92506101808701359150610df66101a08801610cba565b90509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610e4357600080fd5b8135600481106104f057600080fd5b600060208284031215610e6457600080fd5b6104f082610cd7565b600060208284031215610e7f57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610ec857610ec8610e86565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610f0557610f05610e86565b500290565b600082610f40577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060208284031215610f5757600080fd5b815180151581146104f057600080fd5b60005b83811015610f82578181015183820152602001610f6a565b838111156104d85750506000910152565b60008251610fa5818460208701610f67565b9190910192915050565b6020815260008251806020840152610fce816040850160208701610f67565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122070ed59b3eed8fbc29113d761ac3f752014b097f393444074a569edb3cdea931864736f6c634300080a0033000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b351680455

Deployed Bytecode

0x6080604052600436106100745760003560e01c80638b21f1701161004e5780638b21f1701461012a5780639b07d34214610152578063aaf5eb6814610165578063ae9467b51461018f57600080fd5b806312280c191461008057806326c3b515146100d257806386a8b4b51461010257600080fd5b3661007b57005b600080fd5b34801561008c57600080fd5b506100a8737f39c581f595b53c5cb19bd0b3f8da6c935e2ca081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100e56100e0366004610cfb565b6101c3565b6040805193845260208401929092521515908201526060016100c9565b34801561010e57600080fd5b506100a873dc24316b9ae028f1497c275eb9192a3ea0f6702281565b34801561013657600080fd5b506100a873ae7ab96520de3a18e5e111b5eaab095312d7fe8481565b6100e5610160366004610d8d565b61036c565b34801561017157600080fd5b50610181670de0b6b3a764000081565b6040519081526020016100c9565b34801561019b57600080fd5b506100a87f000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b35168045581565b600080803373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b3516804551614610236576040517f48f5c3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600161024a60608e0160408f01610e31565b600381111561025b5761025b610e02565b149050600060028d60400160208101906102759190610e31565b600381111561028657610286610e02565b1480156102e45750737f39c581f595b53c5cb19bd0b3f8da6c935e2ca073ffffffffffffffffffffffffffffffffffffffff168d60200160208101906102cc9190610e52565b73ffffffffffffffffffffffffffffffffffffffff16145b905081806102ef5750805b610325576040517fc582880b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8161034557610340898c8967ffffffffffffffff168b6104f7565b61035a565b61035a898c8967ffffffffffffffff1661079b565b94505050985098509895505050505050565b60008060006040517f26d18eab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152600091839186169063dd62ed3e90604401602060405180830381865afa15801561041a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043e9190610e6d565b6104489190610eb5565b6040805173ffffffffffffffffffffffffffffffffffffffff8616602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529091506104d89085906109a3565b50505050565b60606104ed8484600085610ab9565b90505b9392505050565b6000600161050b6060860160408701610e31565b600381111561051c5761051c610e02565b14610553576040517f6c98dcaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fde0e9a3e00000000000000000000000000000000000000000000000000000000815260048101869052600090737f39c581f595b53c5cb19bd0b3f8da6c935e2ca09063de0e9a3e906024016020604051808303816000875af11580156105c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e59190610e6d565b90506000670de0b6b3a76400006105fc8684610ecd565b6106069190610f0a565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260016004820152600060248201819052604482018590526064820183905291925073dc24316b9ae028f1497c275eb9192a3ea0f6702290633df02124906084016020604051808303816000875af115801561068b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106af9190610e6d565b9050479350808410156106ee576040517fe44b5b5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f12a53623000000000000000000000000000000000000000000000000000000008152600481018690527f000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b35168045573ffffffffffffffffffffffffffffffffffffffff16906312a536239086906024016000604051808303818588803b15801561077757600080fd5b505af115801561078b573d6000803e3d6000fd5b5050505050505050949350505050565b600060026107af6060850160408601610e31565b60038111156107c0576107c0610e02565b1415806108065750737f39c581f595b53c5cb19bd0b3f8da6c935e2ca06107ed6040850160208601610e52565b73ffffffffffffffffffffffffffffffffffffffff1614155b1561083d576040517f6c98dcaf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000670de0b6b3a76400006108528487610ecd565b61085c9190610f0a565b6040517f3df0212400000000000000000000000000000000000000000000000000000000815260006004820181905260016024830152604482018890526064820183905291925073dc24316b9ae028f1497c275eb9192a3ea0f6702290633df0212490889060840160206040518083038185885af11580156108e2573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906109079190610e6d565b6040517fea598cb000000000000000000000000000000000000000000000000000000000815260048101829052909150737f39c581f595b53c5cb19bd0b3f8da6c935e2ca09063ea598cb0906024016020604051808303816000875af1158015610975573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109999190610e6d565b9695505050505050565b6000610a05826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166104de9092919063ffffffff16565b805190915015610ab45780806020019051810190610a239190610f45565b610ab4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b505050565b606082471015610b4b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610aab565b73ffffffffffffffffffffffffffffffffffffffff85163b610bc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610aab565b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051610bf29190610f93565b60006040518083038185875af1925050503d8060008114610c2f576040519150601f19603f3d011682016040523d82523d6000602084013e610c34565b606091505b5091509150610c44828286610c4f565b979650505050505050565b60608315610c5e5750816104f0565b825115610c6e5782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aab9190610faf565b600060608284031215610cb457600080fd5b50919050565b803567ffffffffffffffff81168114610cd257600080fd5b919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610cd257600080fd5b600080600080600080600080610200898b031215610d1857600080fd5b610d228a8a610ca2565b9750610d318a60608b01610ca2565b9650610d408a60c08b01610ca2565b9550610d508a6101208b01610ca2565b945061018089013593506101a08901359250610d6f6101c08a01610cba565b9150610d7e6101e08a01610cd7565b90509295985092959890939650565b6000806000806000806101c08789031215610da757600080fd5b610db18888610ca2565b9550610dc08860608901610ca2565b9450610dcf8860c08901610ca2565b9350610ddf886101208901610ca2565b92506101808701359150610df66101a08801610cba565b90509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600060208284031215610e4357600080fd5b8135600481106104f057600080fd5b600060208284031215610e6457600080fd5b6104f082610cd7565b600060208284031215610e7f57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610ec857610ec8610e86565b500190565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610f0557610f05610e86565b500290565b600082610f40577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600060208284031215610f5757600080fd5b815180151581146104f057600080fd5b60005b83811015610f82578181015183820152602001610f6a565b838111156104d85750506000910152565b60008251610fa5818460208701610f67565b9190910192915050565b6020815260008251806020840152610fce816040850160208701610f67565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea264697066735822122070ed59b3eed8fbc29113d761ac3f752014b097f393444074a569edb3cdea931864736f6c634300080a0033

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

000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b351680455

-----Decoded View---------------
Arg [0] : _rollupProcessor (address): 0xFF1F2B4ADb9dF6FC8eAFecDcbF96A2B351680455

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000ff1f2b4adb9df6fc8eafecdcbf96a2b351680455


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  ]

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.