ETH Price: $3,329.89 (+0.62%)
 

Overview

ETH Balance

0 ETH

ETH Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Parent Transaction Hash Block From To
181647002024-08-08 12:05:47528 days ago1723118747  Contract Creation0 ETH

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DataTransferFacet

Compiler Version
v0.8.22+commit.4fc1097e

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

import {LibDiamond} from "hardhat-deploy/solc_0.8/diamond/libraries/LibDiamond.sol";
import {DelegatedCallType, LibGuard} from "../../libraries/LibGuard.sol";
import {AppStorage, LayerZeroSettings, WormholeSettings} from "../../libraries/LibMagpieAggregator.sol";
import {LibDataTransfer} from "../LibDataTransfer.sol";
import {LibLayerZero} from "../LibLayerZero.sol";
import {LibWormhole} from "../LibWormhole.sol";
import {IDataTransfer} from "../interfaces/IDataTransfer.sol";
import {DataTransferInArgs, DataTransferOutArgs, TransferKey} from "../LibCommon.sol";

contract DataTransferFacet is IDataTransfer {
    AppStorage internal s;

    /// @dev See {IDataTransfer-updateLayerZeroSettings}
    function updateLayerZeroSettings(LayerZeroSettings calldata layerZeroSettings) external override {
        LibDiamond.enforceIsContractOwner();
        LibLayerZero.updateSettings(layerZeroSettings);
    }

    /// @dev See {IDataTransfer-addLayerZeroChainIds}
    function addLayerZeroChainIds(uint16[] calldata networkIds, uint16[] calldata chainIds) external override {
        LibDiamond.enforceIsContractOwner();
        LibLayerZero.addLayerZeroChainIds(networkIds, chainIds);
    }

    /// @dev See {IDataTransfer-addLayerZeroNetworkIds}
    function addLayerZeroNetworkIds(uint16[] calldata chainIds, uint16[] calldata networkIds) external override {
        LibDiamond.enforceIsContractOwner();
        LibLayerZero.addLayerZeroNetworkIds(chainIds, networkIds);
    }

    /// @dev See {IDataTransfer-updateWormholeSettings}
    function updateWormholeSettings(WormholeSettings calldata wormholeSettings) external override {
        LibDiamond.enforceIsContractOwner();
        LibWormhole.updateSettings(wormholeSettings);
    }

    /// @dev See {IDataTransfer-addWormholeNetworkIds}
    function addWormholeNetworkIds(uint16[] calldata chainIds, uint16[] calldata networkIds) external override {
        LibDiamond.enforceIsContractOwner();
        LibWormhole.addWormholeNetworkIds(chainIds, networkIds);
    }

    /// @dev See {IDataTransfer-getWormholeCoreSequence}
    function getWormholeCoreSequence(uint64 transferKeyCoreSequence) external view returns (uint64) {
        return LibWormhole.getCoreSequence(transferKeyCoreSequence);
    }

    /// @dev See {IDataTransfer-lzReceive}
    function lzReceive(
        uint16 senderChainId,
        bytes calldata localAndRemoteAddresses,
        uint64,
        bytes calldata extendedPayload
    ) external override {
        LibLayerZero.enforce();
        LibLayerZero.lzReceive(senderChainId, localAndRemoteAddresses, extendedPayload);
    }

    /// @dev See {IDataTransfer-dataTransferIn}
    function dataTransferIn(DataTransferInArgs calldata dataTransferInArgs) external payable override {
        LibGuard.enforceDelegatedCallGuard(DelegatedCallType.DataTransferIn);
        LibDataTransfer.dataTransfer(dataTransferInArgs);
    }

    /// @dev See {IDataTransfer-dataTransferOut}
    function dataTransferOut(
        DataTransferOutArgs calldata dataTransferOutArgs
    ) external payable override returns (TransferKey memory, bytes memory) {
        LibGuard.enforceDelegatedCallGuard(DelegatedCallType.DataTransferOut);
        return LibDataTransfer.getPayload(dataTransferOutArgs);
    }
}

File 2 of 14 : LibCommon.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

import {TransferKey} from "../libraries/LibTransferKey.sol";

enum DataTransferType {
    Wormhole,
    LayerZero
}

struct DataTransferInProtocol {
    uint16 networkId;
    DataTransferType dataTransferType;
    bytes payload;
}

struct DataTransferInArgs {
    DataTransferInProtocol protocol;
    TransferKey transferKey;
    bytes payload;
}

struct DataTransferOutArgs {
    DataTransferType dataTransferType;
    bytes payload;
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

import {LibBytes} from "../libraries/LibBytes.sol";
import {AppStorage, LibMagpieAggregator} from "../libraries/LibMagpieAggregator.sol";
import {LibTransferKey, TransferKey} from "../libraries/LibTransferKey.sol";
import {LibLayerZero} from "./LibLayerZero.sol";
import {LibWormhole} from "./LibWormhole.sol";
import {DataTransferInArgs, DataTransferOutArgs, DataTransferType} from "./LibCommon.sol";

error InvalidDataTransferType();

library LibDataTransfer {
    using LibBytes for bytes;

    /// @dev Extract the original payload without transfer keys.
    /// @param extendedPayload Transfer key + Payload.
    function getOriginalPayload(bytes memory extendedPayload) private pure returns (bytes memory) {
        return extendedPayload.slice(42, extendedPayload.length - 42);
    }

    /// @dev See {IDataTransfer-dataTransferIn}
    function dataTransfer(DataTransferInArgs memory dataTransferInArgs) internal {
        bytes memory extendedPayload = LibTransferKey.encode(dataTransferInArgs.transferKey).concat(
            dataTransferInArgs.payload
        );

        if (dataTransferInArgs.protocol.dataTransferType == DataTransferType.Wormhole) {
            LibWormhole.dataTransfer(extendedPayload);
        } else if (dataTransferInArgs.protocol.dataTransferType == DataTransferType.LayerZero) {
            LibLayerZero.dataTransfer(extendedPayload, dataTransferInArgs.protocol);
        } else {
            revert InvalidDataTransferType();
        }
    }

    /// @dev Get payload on the receiver side. See {IDataTransfer-dataTransferOut}.
    /// @param dataTransferOutArgs Arguments that are required to get payload.
    /// @return transferKey Swap identifier.
    /// @return payload Data for crosschain swap validation.
    function getPayload(
        DataTransferOutArgs memory dataTransferOutArgs
    ) internal returns (TransferKey memory transferKey, bytes memory payload) {
        if (dataTransferOutArgs.dataTransferType == DataTransferType.Wormhole) {
            payload = LibWormhole.getPayload(dataTransferOutArgs.payload);
        } else if (dataTransferOutArgs.dataTransferType == DataTransferType.LayerZero) {
            payload = LibLayerZero.getPayload(dataTransferOutArgs.payload);
        } else {
            revert InvalidDataTransferType();
        }

        transferKey = LibTransferKey.decode(payload);
        payload = getOriginalPayload(payload);
    }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

import {ILayerZero} from "../interfaces/layer-zero/ILayerZero.sol";
import {AppStorage, LayerZeroSettings, LibMagpieAggregator} from "../libraries/LibMagpieAggregator.sol";
import {LibTransferKey, TransferKey} from "../libraries/LibTransferKey.sol";
import {DataTransferInProtocol, DataTransferType} from "./LibCommon.sol";

struct LayerZeroDataTransferInData {
    uint256 gasLimit;
    uint256 fee;
}

error LayerZeroInvalidPayload();
error LayerZeroInvalidSender();
error LayerZeroSequenceHasPayload();

library LibLayerZero {
    event UpdateLayerZeroSettings(address indexed sender, LayerZeroSettings layerZeroSettings);

    /// @dev See {IDataTransfer-updateLayerZeroSettings}
    function updateSettings(LayerZeroSettings memory layerZeroSettings) internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        s.layerZeroSettings = layerZeroSettings;

        emit UpdateLayerZeroSettings(msg.sender, layerZeroSettings);
    }

    event AddLayerZeroChainIds(address indexed sender, uint16[] networkIds, uint16[] chainIds);

    /// @dev See {IDataTransfer-addLayerZeroChainIds}
    function addLayerZeroChainIds(uint16[] memory networkIds, uint16[] memory chainIds) internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        uint256 i;
        uint256 l = networkIds.length;
        for (i = 0; i < l; ) {
            s.layerZeroChainIds[networkIds[i]] = chainIds[i];

            unchecked {
                i++;
            }
        }

        emit AddLayerZeroChainIds(msg.sender, networkIds, chainIds);
    }

    event AddLayerZeroNetworkIds(address indexed sender, uint16[] chainIds, uint16[] networkIds);

    /// @dev See {IDataTransfer-addLayerZeroNetworkIds}
    function addLayerZeroNetworkIds(uint16[] memory chainIds, uint16[] memory networkIds) internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        uint256 i;
        uint256 l = chainIds.length;
        for (i = 0; i < l; ) {
            s.layerZeroNetworkIds[chainIds[i]] = networkIds[i];

            unchecked {
                i++;
            }
        }

        emit AddLayerZeroNetworkIds(msg.sender, chainIds, networkIds);
    }

    /// @dev Converts dataTransferInPayload into proper struct.
    /// @param dataTransferInPayload Payload required for transfering data from one chain to another.
    /// @return dataTransferInData
    function decodeDataTransferInPayload(
        bytes memory dataTransferInPayload
    ) internal pure returns (LayerZeroDataTransferInData memory dataTransferInData) {
        assembly {
            mstore(dataTransferInData, mload(add(dataTransferInPayload, 32)))
            mstore(add(dataTransferInData, 32), mload(add(dataTransferInPayload, 64)))
        }
    }

    /// @dev Merge remote and local addresses for LayerZero.
    /// @param remoteAddress Target address.
    /// @param localAddress Source address.
    /// @return encodedRemoteAndLocalAddresses Merged target and source address.
    function encodeRemoteAndLocalAddresses(
        bytes32 remoteAddress,
        bytes32 localAddress
    ) private pure returns (bytes memory encodedRemoteAndLocalAddresses) {
        encodedRemoteAndLocalAddresses = new bytes(40);

        assembly {
            mstore(add(encodedRemoteAndLocalAddresses, 32), shl(96, remoteAddress))
            mstore(add(encodedRemoteAndLocalAddresses, 52), shl(96, localAddress))
        }
    }

    /// @dev See {IDataTransfer-dataTransferIn}
    function dataTransfer(bytes memory payload, DataTransferInProtocol memory protocol) internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        LayerZeroDataTransferInData memory dataTransferInData = decodeDataTransferInPayload(protocol.payload);

        bytes memory adapterParams = hex"00010000000000000000000000000000000000000000000000000000000000000000";

        assembly {
            mstore(add(adapterParams, 34), mload(dataTransferInData))
        }

        ILayerZero(s.layerZeroSettings.routerAddress).send{value: dataTransferInData.fee}(
            s.layerZeroChainIds[protocol.networkId],
            encodeRemoteAndLocalAddresses(
                s.magpieAggregatorAddresses[protocol.networkId],
                bytes32(uint256(uint160(address(this))))
            ),
            payload,
            payable(msg.sender),
            address(0x0),
            adapterParams
        );
    }

    /// @dev See {IDataTransfer-LibDataTransfer}
    function getPayload(bytes memory dataTransferOutPayload) internal returns (bytes memory extendedPayload) {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        TransferKey memory transferKey = LibTransferKey.decode(dataTransferOutPayload);
        bytes memory srcAddress = encodeRemoteAndLocalAddresses(
            bytes32(uint256(uint160(address(this)))),
            s.magpieAggregatorAddresses[transferKey.networkId]
        );

        ILayerZero layerZero = ILayerZero(s.layerZeroSettings.routerAddress);

        if (layerZero.hasStoredPayload(s.layerZeroChainIds[transferKey.networkId], srcAddress)) {
            layerZero.retryPayload(s.layerZeroChainIds[transferKey.networkId], srcAddress, dataTransferOutPayload);
        }

        if (
            s.payloadHashes[uint16(DataTransferType.LayerZero)][transferKey.networkId][transferKey.senderAddress][
                transferKey.swapSequence
            ] == keccak256(dataTransferOutPayload)
        ) {
            extendedPayload = dataTransferOutPayload;
        } else {
            // Fallback
            extendedPayload = s.payloads[uint16(DataTransferType.LayerZero)][transferKey.networkId][
                transferKey.senderAddress
            ][transferKey.swapSequence];

            if (extendedPayload.length == 0) {
                revert LayerZeroInvalidPayload();
            }
        }
    }

    /// @dev Registers the extended payload for for future validation.
    /// @param transferKey Swap identifier.
    /// @param extendedPayload Transfer key + Payload.
    function registerPayload(TransferKey memory transferKey, bytes memory extendedPayload) private {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        if (
            s.payloadHashes[uint16(DataTransferType.LayerZero)][transferKey.networkId][transferKey.senderAddress][
                transferKey.swapSequence
            ] != bytes32(0)
        ) {
            revert LayerZeroSequenceHasPayload();
        }

        s.payloadHashes[uint16(DataTransferType.LayerZero)][transferKey.networkId][transferKey.senderAddress][
            transferKey.swapSequence
        ] = keccak256(extendedPayload);
    }

    event LzReceive(TransferKey transferKey, bytes payload);

    /// @dev See {IDataTransfer-lzReceive}
    function lzReceive(
        uint16 senderChainId,
        bytes memory localAndRemoteAddresses,
        bytes memory extendedPayload
    ) internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        bytes32 senderAddress;

        assembly {
            senderAddress := shr(96, mload(add(localAndRemoteAddresses, 32)))
        }

        TransferKey memory transferKey = LibTransferKey.decode(extendedPayload);

        LibTransferKey.validate(
            transferKey,
            TransferKey({
                networkId: s.layerZeroNetworkIds[senderChainId],
                senderAddress: senderAddress,
                swapSequence: transferKey.swapSequence
            })
        );

        registerPayload(transferKey, extendedPayload);

        emit LzReceive(transferKey, extendedPayload);
    }

    function enforce() internal view {
        AppStorage storage s = LibMagpieAggregator.getStorage();
        if (msg.sender != s.layerZeroSettings.routerAddress) {
            revert LayerZeroInvalidSender();
        }
    }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

import {AppStorage, LibMagpieAggregator, WormholeSettings} from "../libraries/LibMagpieAggregator.sol";
import {LibTransferKey, TransferKey} from "../libraries/LibTransferKey.sol";
import {IWormholeCore} from "../interfaces/wormhole/IWormholeCore.sol";

library LibWormhole {
    event UpdateWormholeSettings(address indexed sender, WormholeSettings wormholeSettings);

    /// @dev See {IDataTransfer-updateWormholeSettings}
    function updateSettings(WormholeSettings memory wormholeSettings) internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        s.wormholeSettings = wormholeSettings;

        emit UpdateWormholeSettings(msg.sender, wormholeSettings);
    }

    event AddWormholeNetworkIds(address indexed sender, uint16[] chainIds, uint16[] networkIds);

    /// @dev See {IDataTransfer-addWormholeNetworkIds}
    function addWormholeNetworkIds(uint16[] memory chainIds, uint16[] memory networkIds) internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        uint256 i;
        uint256 l = chainIds.length;
        for (i = 0; i < l; ) {
            s.wormholeNetworkIds[chainIds[i]] = networkIds[i];

            unchecked {
                i++;
            }
        }

        emit AddWormholeNetworkIds(msg.sender, chainIds, networkIds);
    }

    /// @dev See {IDataTransfer-dataTransferIn}
    function dataTransfer(bytes memory payload) internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        uint64 wormholeCoreSequence = IWormholeCore(s.wormholeSettings.bridgeAddress).publishMessage(
            uint32(block.timestamp % 2 ** 32),
            payload,
            s.wormholeSettings.consistencyLevel
        );

        s.wormholeCoreSequences[s.swapSequence] = wormholeCoreSequence;
    }

    /// @dev See {IDataTransfer-getWormholeCoreSequence}
    function getCoreSequence(uint64 swapSequence) internal view returns (uint64) {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        return s.wormholeCoreSequences[swapSequence];
    }

    /// @dev See {IDataTransfer-LibDataTransfer}
    function getPayload(bytes memory dataTransferOutPayload) internal view returns (bytes memory extendedPayload) {
        AppStorage storage s = LibMagpieAggregator.getStorage();
        IWormholeCore.VM memory vm = IWormholeCore(s.wormholeSettings.bridgeAddress).parseVM(dataTransferOutPayload);

        if (s.relayerAddress != msg.sender || s.relayerAddress == address(0)) {
            (bool valid, string memory reason) = IWormholeCore(s.wormholeSettings.bridgeAddress).verifyVM(vm);
            require(valid, reason);
        }

        TransferKey memory transferKey = LibTransferKey.decode(vm.payload);

        LibTransferKey.validate(
            transferKey,
            TransferKey({
                networkId: s.wormholeNetworkIds[vm.emitterChainId],
                senderAddress: vm.emitterAddress,
                swapSequence: transferKey.swapSequence
            })
        );

        extendedPayload = vm.payload;
    }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

import {LayerZeroSettings, WormholeSettings} from "../../libraries/LibMagpieAggregator.sol";
import {DataTransferInArgs, DataTransferOutArgs, TransferKey} from "../LibCommon.sol";

interface IDataTransfer {
    event UpdateLayerZeroSettings(address indexed sender, LayerZeroSettings layerZeroSettings);

    /// @dev Allows the contract owner to update the LayerZero settings
    /// @param layerZeroSettings LayerZero related parameters.
    function updateLayerZeroSettings(LayerZeroSettings calldata layerZeroSettings) external;

    event AddLayerZeroChainIds(address indexed sender, uint16[] networkIds, uint16[] chainIds);

    /// @dev Allows the contract owner to add LayerZero chain ids to the corresponding magpie network ids.
    /// @param networkIds An array containing identifiers for Magpie networks.
    /// @param chainIds An array containing chain identifiers corresponding to the network ids.
    function addLayerZeroChainIds(uint16[] calldata networkIds, uint16[] calldata chainIds) external;

    event AddLayerZeroNetworkIds(address indexed sender, uint16[] chainIds, uint16[] networkIds);

    /// @dev Allows the contract owner to add Magpie network ids to the corresponding LayerZero chain ids.
    /// @param chainIds An array containing chain identifiers corresponding to the network ids.
    /// @param networkIds An array containing identifiers for Magpie networks.
    function addLayerZeroNetworkIds(uint16[] calldata chainIds, uint16[] calldata networkIds) external;

    event UpdateWormholeSettings(address indexed sender, WormholeSettings wormholeSettings);

    /// @dev Allows the contract owner to update the settings required for interaction with Wormhole.
    /// @param wormholeSettings Wormhole related parameters.
    function updateWormholeSettings(WormholeSettings calldata wormholeSettings) external;

    event AddWormholeNetworkIds(address indexed sender, uint16[] chainIds, uint16[] networkIds);

    /// @dev Allows the contract owner to add Magpie network ids to the corresponding Wormhole chain ids.
    /// @param chainIds An array containing chain identifiers corresponding to the network ids.
    /// @param networkIds An array containing identifiers for Magpie networks.
    function addWormholeNetworkIds(uint16[] calldata chainIds, uint16[] calldata networkIds) external;

    /// @dev Retrieves the Wormhole core sequence.
    /// @param transferKeyCoreSequence Magpie transferKey sequence that is generated for each crosschain swap.
    function getWormholeCoreSequence(uint64 transferKeyCoreSequence) external view returns (uint64);

    event LzReceive(TransferKey transferKey, bytes payload);

    /// @dev Allows LayerZero to send message corresponding to a specific crosschain swap.
    /// @param senderChainId The LayerZero chain identifier for the source chain.
    /// @param senderAddress The address of the origin contract.
    /// @param nonce Unique identifier for the message.
    /// @param extendedPayload Payload of the specific crosschain swap.
    function lzReceive(
        uint16 senderChainId,
        bytes calldata senderAddress,
        uint64 nonce,
        bytes calldata extendedPayload
    ) external;

    /// @dev Sends swap data to a data transfer protocol
    function dataTransferIn(DataTransferInArgs calldata dataTransferInArgs) external payable;

    /// @dev Recives swap data from a data transfer protocol
    function dataTransferOut(
        DataTransferOutArgs calldata dataTransferOutArgs
    ) external payable returns (TransferKey memory, bytes memory);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

interface ILayerZero {
    function send(
        uint16 _dstChainId,
        bytes calldata _remoteAndLocalAddresses,
        bytes calldata _payload,
        address payable _refundAddress,
        address _zroPaymentAddress,
        bytes calldata _adapterParams
    ) external payable;

    function estimateFees(
        uint16 _dstChainId,
        address _userApplication,
        bytes calldata _payload,
        bool _payInZRO,
        bytes calldata _adapterParams
    ) external view returns (uint256 nativeFee, uint256 zroFee);

    function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);

    function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

interface IWormholeCore {
    function publishMessage(
        uint32 nonce,
        bytes memory payload,
        uint8 consistencyLevel
    ) external payable returns (uint64 sequence);

    function parseAndVerifyVM(
        bytes calldata encodedVM
    ) external view returns (IWormholeCore.VM memory vm, bool valid, string memory reason);

    function parseVM(bytes memory encodedVM) external pure returns (VM memory vm);

    function verifyVM(IWormholeCore.VM memory vm) external view returns (bool valid, string memory reason);

    struct Signature {
        bytes32 r;
        bytes32 s;
        uint8 v;
        uint8 guardianIndex;
    }

    struct VM {
        uint8 version;
        uint32 timestamp;
        uint32 nonce;
        uint16 emitterChainId;
        bytes32 emitterAddress;
        uint64 sequence;
        uint8 consistencyLevel;
        bytes payload;
        uint32 guardianSetIndex;
        Signature[] signatures;
        bytes32 hash;
    }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

error AddressOutOfBounds();

library LibBytes {
    using LibBytes for bytes;

    /// @dev Converts bytes into an address.
    /// @param self The bytes that contains the address.
    /// @param start The starting position to retrieve the address from the bytes.
    /// @return tempAddress The retrieved address from the bytes.
    function toAddress(bytes memory self, uint256 start) internal pure returns (address) {
        if (self.length < start + 20) {
            revert AddressOutOfBounds();
        }
        address tempAddress;

        assembly {
            tempAddress := mload(add(add(self, 20), start))
        }

        return tempAddress;
    }

    /// @dev Extracts a slice of bytes.
    /// @param self The string of bytes that needs to be sliced.
    /// @param start The starting position to begin slicing.
    /// @param length The length of the byte.
    /// @return tempBytes The sliced byte.
    function slice(bytes memory self, uint256 start, uint256 length) internal pure returns (bytes memory) {
        require(length + 31 >= length, "slice_overflow");
        require(self.length >= start + length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(length)
            case 0 {
                tempBytes := mload(0x40)
                let lengthmod := and(length, 31)
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, length)

                for {
                    let cc := add(add(add(self, lengthmod), mul(0x20, iszero(lengthmod))), start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, length)

                mstore(0x40, and(add(mc, 31), not(31)))
            }
            default {
                tempBytes := mload(0x40)
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    /// @dev Merge two byte arrays.
    /// @param self The bytes that needs to be merged.
    /// @param postBytes The bytes that needs to be merged.
    /// @return tempBytes The merged bytes.
    function concat(bytes memory self, bytes memory postBytes) internal pure returns (bytes memory) {
        bytes memory tempBytes;

        assembly {
            tempBytes := mload(0x40)

            let length := mload(self)
            mstore(tempBytes, length)

            let mc := add(tempBytes, 0x20)
            let end := add(mc, length)

            for {
                let cc := add(self, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            length := mload(postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            mc := end
            end := add(mc, length)

            for {
                let cc := add(postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            mstore(0x40, and(add(add(end, iszero(add(length, mload(self)))), 31), not(31)))
        }

        return tempBytes;
    }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

import {AppStorage, LibMagpieAggregator} from "../libraries/LibMagpieAggregator.sol";

error ReentrantCall();
error InvalidDelegatedCall();

enum DelegatedCallType {
    BridgeIn,
    BridgeOut,
    DataTransferIn,
    DataTransferOut
}

library LibGuard {
    /// @dev Checks if the guarded flag is set.
    function enforcePreGuard() internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        if (s.guarded) {
            revert ReentrantCall();
        }

        s.guarded = true;
    }

    /// @dev Sets the guarded flag to false.
    function enforcePostGuard() internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        s.guarded = false;
    }

    /// @dev Reverts the transaction to prevent reentrancy. If no such call is in progress, it sets the delegated call state to true for that call type.
    /// @param delegatedCallType The value of the call type.
    function enforceDelegatedCallPreGuard(DelegatedCallType delegatedCallType) internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        if (s.delegatedCalls[uint8(delegatedCallType)]) {
            revert ReentrantCall();
        }

        s.delegatedCalls[uint8(delegatedCallType)] = true;
    }

    /// @dev Accesses the contract storage to confirm whether a particular type of delegated call is currently in progress. If the expected call is not in progress, it reverts the transaction, indicating an invalid delegated call.
    /// @param delegatedCallType The value of the call type.
    function enforceDelegatedCallGuard(DelegatedCallType delegatedCallType) internal view {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        if (!s.delegatedCalls[uint8(delegatedCallType)]) {
            revert InvalidDelegatedCall();
        }
    }

    /// @dev Sets the delegated call state back to false for the specified type of delegated call.
    /// @param delegatedCallType The value of the call type.
    function enforceDelegatedCallPostGuard(DelegatedCallType delegatedCallType) internal {
        AppStorage storage s = LibMagpieAggregator.getStorage();

        s.delegatedCalls[uint8(delegatedCallType)] = false;
    }
}

File 11 of 14 : LibMagpieAggregator.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

// Deprecated
struct CurveSettings {
    address mainRegistry; // Address of the main registry of the curve protocol.
    address cryptoRegistry; // Address of the crypto registry of the curve protocol
    address cryptoFactory; // Address of the crypto factory of the crypto factory
}

struct Amm {
    uint8 protocolId; // The protocol identifier provided by magpie team.
    bytes4 selector; // The function selector of the AMM.
    address addr; // The address of the facet of the AMM.
}

struct WormholeBridgeSettings {
    address bridgeAddress; // The wormhole token bridge address
}

struct StargateSettings {
    address routerAddress; // The stargate router address.
}

struct WormholeSettings {
    address bridgeAddress; // The wormhole core bridge address.
    uint8 consistencyLevel; // The level of finality the guardians will reach before signing the message
}

struct LayerZeroSettings {
    address routerAddress; // The router address of layer zero protocol
}

struct CelerBridgeSettings {
    address messageBusAddress; // The message bus address of celer bridge
}

struct AppStorage {
    address weth;
    uint16 networkId;
    mapping(uint16 => bytes32) magpieAggregatorAddresses;
    mapping(address => uint256) deposits;
    mapping(address => mapping(address => uint256)) depositsByUser;
    mapping(uint16 => mapping(bytes32 => mapping(uint64 => bool))) usedTransferKeys;
    uint64 swapSequence;
    // Pausable
    bool paused;
    // Reentrancy Guard
    bool guarded;
    // Amm
    mapping(uint16 => Amm) amms;
    // Curve Amm
    CurveSettings curveSettings;
    // Data Transfer
    mapping(uint16 => mapping(uint16 => mapping(bytes32 => mapping(uint64 => bytes)))) payloads;
    // Stargate Bridge
    StargateSettings stargateSettings;
    mapping(uint16 => bytes32) magpieStargateBridgeAddresses;
    // Wormhole Bridge
    WormholeBridgeSettings wormholeBridgeSettings;
    mapping(uint64 => uint64) wormholeTokenSequences;
    // Wormhole Data Transfer
    WormholeSettings wormholeSettings;
    mapping(uint16 => uint16) wormholeNetworkIds;
    mapping(uint64 => uint64) wormholeCoreSequences;
    // LayerZero Data Transfer
    LayerZeroSettings layerZeroSettings;
    mapping(uint16 => uint16) layerZeroChainIds;
    mapping(uint16 => uint16) layerZeroNetworkIds;
    address magpieRouterAddress;
    mapping(uint16 => mapping(bytes32 => mapping(uint64 => mapping(address => uint256)))) stargateDeposits;
    mapping(uint8 => bool) delegatedCalls;
    // Celer Bridge
    CelerBridgeSettings celerBridgeSettings;
    mapping(uint16 => uint64) celerChainIds;
    mapping(uint16 => mapping(bytes32 => mapping(uint64 => mapping(address => uint256)))) celerDeposits;
    mapping(uint16 => mapping(bytes32 => mapping(uint64 => address))) celerRefundAddresses;
    mapping(uint16 => bytes32) magpieCelerBridgeAddresses;
    mapping(uint16 => mapping(uint16 => mapping(bytes32 => mapping(uint64 => bytes32)))) payloadHashes;
    mapping(uint16 => bytes32) magpieStargateBridgeV2Addresses;
    address relayerAddress;
}

library LibMagpieAggregator {
    function getStorage() internal pure returns (AppStorage storage s) {
        assembly {
            s.slot := 0
        }
    }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.22;

struct TransferKey {
    uint16 networkId; // Source network id that is defined by Magpie protocol for each chain
    bytes32 senderAddress; // The sender address in bytes32
    uint64 swapSequence; // Swap sequence (unique identifier) of the crosschain swap
}

error InvalidTransferKey();

library LibTransferKey {
    /// @dev Encodes transferKey.
    /// @param transferKey Swap identifier generated for each crosschain swap.
    /// @return payload Encoded transferKey.
    function encode(TransferKey memory transferKey) internal pure returns (bytes memory) {
        bytes memory payload = new bytes(42);

        assembly {
            mstore(add(payload, 32), shl(240, mload(transferKey)))
            mstore(add(payload, 34), mload(add(transferKey, 32)))
            mstore(add(payload, 66), shl(192, mload(add(transferKey, 64))))
        }

        return payload;
    }

    /// @dev Extracts transfer key from bytes.
    /// @param payload Contains the transferKey struct in bytes.
    /// @return transferKey Swap identifier generated for each crosschain swap.
    function decode(bytes memory payload) internal pure returns (TransferKey memory transferKey) {
        assembly {
            mstore(transferKey, shr(240, mload(add(payload, 32))))
            mstore(add(transferKey, 32), mload(add(payload, 34)))
            mstore(add(transferKey, 64), shr(192, mload(add(payload, 66))))
        }
    }

    /// @dev Compares two transferKeys for validation.
    /// @param self Swap identifier generated for each crosschain swap.
    /// @param transferKey Swap identifier generated for each crosschain swap.
    function validate(TransferKey memory self, TransferKey memory transferKey) internal pure {
        if (
            self.networkId != transferKey.networkId ||
            self.senderAddress != transferKey.senderAddress ||
            self.swapSequence != transferKey.swapSequence
        ) {
            revert InvalidTransferKey();
        }
    }
}

File 13 of 14 : IDiamondCut.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/

interface IDiamondCut {
    enum FacetCutAction {Add, Replace, Remove}
    // Add=0, Replace=1, Remove=2

    struct FacetCut {
        address facetAddress;
        FacetCutAction action;
        bytes4[] functionSelectors;
    }

    /// @notice Add/replace/remove any number of functions and optionally execute
    ///         a function with delegatecall
    /// @param _diamondCut Contains the facet addresses and function selectors
    /// @param _init The address of the contract or facet to execute _calldata
    /// @param _calldata A function call, including function selector and arguments
    ///                  _calldata is executed with delegatecall on _init
    function diamondCut(
        FacetCut[] calldata _diamondCut,
        address _init,
        bytes calldata _calldata
    ) external;

    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/******************************************************************************\
* Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen)
* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
/******************************************************************************/
import { IDiamondCut } from "../interfaces/IDiamondCut.sol";

library LibDiamond {
    bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");

    struct FacetAddressAndPosition {
        address facetAddress;
        uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array
    }

    struct FacetFunctionSelectors {
        bytes4[] functionSelectors;
        uint256 facetAddressPosition; // position of facetAddress in facetAddresses array
    }

    struct DiamondStorage {
        // maps function selector to the facet address and
        // the position of the selector in the facetFunctionSelectors.selectors array
        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
        // maps facet addresses to function selectors
        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
        // facet addresses
        address[] facetAddresses;
        // Used to query if a contract implements an interface.
        // Used to implement ERC-165.
        mapping(bytes4 => bool) supportedInterfaces;
        // owner of the contract
        address contractOwner;
    }

    function diamondStorage() internal pure returns (DiamondStorage storage ds) {
        bytes32 position = DIAMOND_STORAGE_POSITION;
        assembly {
            ds.slot := position
        }
    }

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    function setContractOwner(address _newOwner) internal {
        DiamondStorage storage ds = diamondStorage();
        address previousOwner = ds.contractOwner;
        ds.contractOwner = _newOwner;
        emit OwnershipTransferred(previousOwner, _newOwner);
    }

    function contractOwner() internal view returns (address contractOwner_) {
        contractOwner_ = diamondStorage().contractOwner;
    }

    function enforceIsContractOwner() internal view {
        require(msg.sender == diamondStorage().contractOwner, "LibDiamond: Must be contract owner");
    }

    event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);

    // Internal function version of diamondCut
    function diamondCut(
        IDiamondCut.FacetCut[] memory _diamondCut,
        address _init,
        bytes memory _calldata
    ) internal {
        for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
            IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
            if (action == IDiamondCut.FacetCutAction.Add) {
                addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Replace) {
                replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else if (action == IDiamondCut.FacetCutAction.Remove) {
                removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
            } else {
                revert("LibDiamondCut: Incorrect FacetCutAction");
            }
        }
        emit DiamondCut(_diamondCut, _init, _calldata);
        initializeDiamondCut(_init, _calldata);
    }

    function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();        
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            addFacet(ds, _facetAddress);            
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");
            addFunction(ds, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");
        uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            addFacet(ds, _facetAddress);
        }
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function");
            removeFunction(ds, oldFacetAddress, selector);
            addFunction(ds, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage ds = diamondStorage();
        // if function does not exist then do nothing and return
        require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)");
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
            removeFunction(ds, oldFacetAddress, selector);
        }
    }

    function addFacet(DiamondStorage storage ds, address _facetAddress) internal {
        enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code");
        ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;
        ds.facetAddresses.push(_facetAddress);
    }    


    function addFunction(DiamondStorage storage ds, bytes4 _selector, uint96 _selectorPosition, address _facetAddress) internal {
        ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);
        ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;
    }

    function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal {        
        require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
        // an immutable function is a function defined directly in a diamond
        require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function");
        // replace selector with last selector, then delete last selector
        uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;
        uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;
        // if not the same then replace _selector with lastSelector
        if (selectorPosition != lastSelectorPosition) {
            bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];
            ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;
            ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);
        }
        // delete the last selector
        ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();
        delete ds.selectorToFacetAndPosition[_selector];

        // if no more selectors for facet address then delete the facet address
        if (lastSelectorPosition == 0) {
            // replace facet address with last facet address and delete last facet address
            uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1;
            uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
            if (facetAddressPosition != lastFacetAddressPosition) {
                address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];
                ds.facetAddresses[facetAddressPosition] = lastFacetAddress;
                ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;
            }
            ds.facetAddresses.pop();
            delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
        }
    }

    function initializeDiamondCut(address _init, bytes memory _calldata) internal {
        if (_init == address(0)) {
            require(_calldata.length == 0, "LibDiamondCut: _init is address(0) but_calldata is not empty");
        } else {
            require(_calldata.length > 0, "LibDiamondCut: _calldata is empty but _init is not address(0)");
            if (_init != address(this)) {
                enforceHasContractCode(_init, "LibDiamondCut: _init address has no code");
            }
            (bool success, bytes memory error) = _init.delegatecall(_calldata);
            if (!success) {
                if (error.length > 0) {
                    // bubble up the error
                    revert(string(error));
                } else {
                    revert("LibDiamondCut: _init function reverted");
                }
            }
        }
    }

    function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
        uint256 contractSize;
        assembly {
            contractSize := extcodesize(_contract)
        }
        require(contractSize > 0, _errorMessage);
    }
}

Settings
{
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "runs": 200,
    "enabled": true
  },
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"InvalidDataTransferType","type":"error"},{"inputs":[],"name":"InvalidDelegatedCall","type":"error"},{"inputs":[],"name":"InvalidTransferKey","type":"error"},{"inputs":[],"name":"LayerZeroInvalidPayload","type":"error"},{"inputs":[],"name":"LayerZeroInvalidSender","type":"error"},{"inputs":[],"name":"LayerZeroSequenceHasPayload","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint16[]","name":"networkIds","type":"uint16[]"},{"indexed":false,"internalType":"uint16[]","name":"chainIds","type":"uint16[]"}],"name":"AddLayerZeroChainIds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint16[]","name":"networkIds","type":"uint16[]"},{"indexed":false,"internalType":"uint16[]","name":"chainIds","type":"uint16[]"}],"name":"AddLayerZeroChainIds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint16[]","name":"chainIds","type":"uint16[]"},{"indexed":false,"internalType":"uint16[]","name":"networkIds","type":"uint16[]"}],"name":"AddLayerZeroNetworkIds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint16[]","name":"chainIds","type":"uint16[]"},{"indexed":false,"internalType":"uint16[]","name":"networkIds","type":"uint16[]"}],"name":"AddLayerZeroNetworkIds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint16[]","name":"chainIds","type":"uint16[]"},{"indexed":false,"internalType":"uint16[]","name":"networkIds","type":"uint16[]"}],"name":"AddWormholeNetworkIds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint16[]","name":"chainIds","type":"uint16[]"},{"indexed":false,"internalType":"uint16[]","name":"networkIds","type":"uint16[]"}],"name":"AddWormholeNetworkIds","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint16","name":"networkId","type":"uint16"},{"internalType":"bytes32","name":"senderAddress","type":"bytes32"},{"internalType":"uint64","name":"swapSequence","type":"uint64"}],"indexed":false,"internalType":"struct TransferKey","name":"transferKey","type":"tuple"},{"indexed":false,"internalType":"bytes","name":"payload","type":"bytes"}],"name":"LzReceive","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint16","name":"networkId","type":"uint16"},{"internalType":"bytes32","name":"senderAddress","type":"bytes32"},{"internalType":"uint64","name":"swapSequence","type":"uint64"}],"indexed":false,"internalType":"struct TransferKey","name":"transferKey","type":"tuple"},{"indexed":false,"internalType":"bytes","name":"payload","type":"bytes"}],"name":"LzReceive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"components":[{"internalType":"address","name":"routerAddress","type":"address"}],"indexed":false,"internalType":"struct LayerZeroSettings","name":"layerZeroSettings","type":"tuple"}],"name":"UpdateLayerZeroSettings","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"components":[{"internalType":"address","name":"routerAddress","type":"address"}],"indexed":false,"internalType":"struct LayerZeroSettings","name":"layerZeroSettings","type":"tuple"}],"name":"UpdateLayerZeroSettings","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"components":[{"internalType":"address","name":"bridgeAddress","type":"address"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"}],"indexed":false,"internalType":"struct WormholeSettings","name":"wormholeSettings","type":"tuple"}],"name":"UpdateWormholeSettings","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"components":[{"internalType":"address","name":"bridgeAddress","type":"address"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"}],"indexed":false,"internalType":"struct WormholeSettings","name":"wormholeSettings","type":"tuple"}],"name":"UpdateWormholeSettings","type":"event"},{"inputs":[{"internalType":"uint16[]","name":"networkIds","type":"uint16[]"},{"internalType":"uint16[]","name":"chainIds","type":"uint16[]"}],"name":"addLayerZeroChainIds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"chainIds","type":"uint16[]"},{"internalType":"uint16[]","name":"networkIds","type":"uint16[]"}],"name":"addLayerZeroNetworkIds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"chainIds","type":"uint16[]"},{"internalType":"uint16[]","name":"networkIds","type":"uint16[]"}],"name":"addWormholeNetworkIds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"uint16","name":"networkId","type":"uint16"},{"internalType":"enum DataTransferType","name":"dataTransferType","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct DataTransferInProtocol","name":"protocol","type":"tuple"},{"components":[{"internalType":"uint16","name":"networkId","type":"uint16"},{"internalType":"bytes32","name":"senderAddress","type":"bytes32"},{"internalType":"uint64","name":"swapSequence","type":"uint64"}],"internalType":"struct TransferKey","name":"transferKey","type":"tuple"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct DataTransferInArgs","name":"dataTransferInArgs","type":"tuple"}],"name":"dataTransferIn","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"enum DataTransferType","name":"dataTransferType","type":"uint8"},{"internalType":"bytes","name":"payload","type":"bytes"}],"internalType":"struct DataTransferOutArgs","name":"dataTransferOutArgs","type":"tuple"}],"name":"dataTransferOut","outputs":[{"components":[{"internalType":"uint16","name":"networkId","type":"uint16"},{"internalType":"bytes32","name":"senderAddress","type":"bytes32"},{"internalType":"uint64","name":"swapSequence","type":"uint64"}],"internalType":"struct TransferKey","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64","name":"transferKeyCoreSequence","type":"uint64"}],"name":"getWormholeCoreSequence","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"senderChainId","type":"uint16"},{"internalType":"bytes","name":"localAndRemoteAddresses","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"bytes","name":"extendedPayload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"routerAddress","type":"address"}],"internalType":"struct LayerZeroSettings","name":"layerZeroSettings","type":"tuple"}],"name":"updateLayerZeroSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"bridgeAddress","type":"address"},{"internalType":"uint8","name":"consistencyLevel","type":"uint8"}],"internalType":"struct WormholeSettings","name":"wormholeSettings","type":"tuple"}],"name":"updateWormholeSettings","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506121be806100206000396000f3fe6080604052600436106100855760003560e01c80637f2bf445116100595780637f2bf4451461010c57806383d5b76e1461011f5780638706ee1814610149578063950d657f14610181578063a2acd391146101a157600080fd5b80621d35671461008a57806315c3f38f146100ac5780634204c31b146100cc57806361799b24146100ec575b600080fd5b34801561009657600080fd5b506100aa6100a53660046114a7565b6101c1565b005b3480156100b857600080fd5b506100aa6100c736600461153d565b610245565b3480156100d857600080fd5b506100aa6100e7366004611599565b610267565b3480156100f857600080fd5b506100aa610107366004611616565b6102e2565b6100aa61011a366004611632565b610301565b61013261012d36600461166c565b61031c565b6040516101409291906116f8565b60405180910390f35b34801561015557600080fd5b50610169610164366004611733565b61035f565b6040516001600160401b039091168152602001610140565b34801561018d57600080fd5b506100aa61019c366004611599565b610383565b3480156101ad57600080fd5b506100aa6101bc366004611599565b6103f8565b6101c961046d565b61023d8686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8901819004810282018101909252878152925087915086908190840183828082843760009201919091525061049b92505050565b505050505050565b61024d61054a565b61026461025f36839003830183611841565b6105d8565b50565b61026f61054a565b6102dc8484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061063592505050565b50505050565b6102ea61054a565b6102646102fc36839003830183611899565b610706565b61030b600261077b565b610264610317826119b0565b6107ca565b60408051606081018252600080825260208201819052918101919091526060610345600361077b565b61035661035184611a81565b610855565b91509150915091565b6001600160401b038082166000908152601160205260408120549091165b92915050565b61038b61054a565b6102dc848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506108e492505050565b61040061054a565b6102dc848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506109a692505050565b6012546000906001600160a01b0316331461026457604051637245ed1f60e01b815260040160405180910390fd5b602082015160009060601c816104b084610a68565b6040805160608101825261ffff808a166000908152601488016020908152908490205490911682528101859052818301516001600160401b0316918101919091529091506104ff908290610aa3565b6105098185610b07565b7fe7820063d8cc9ef56e692e9df898249c96f3be178a3c51f911ede4e6c06b05ad818560405161053a9291906116f8565b60405180910390a1505050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b031633146105d65760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b60648201526084015b60405180910390fd5b565b8051601280546001600160a01b0319166001600160a01b03909216918217905560405190815260009033907f5653b9afcdbb9f970275a0e277396e823dc1ec9d67f4fe7f2b9b575e500f4fe1906020015b60405180910390a25050565b815160009081905b808210156106bc5783828151811061065757610657611ad7565b602002602001015183601301600087858151811061067757610677611ad7565b602002602001015161ffff1661ffff16815260200190815260200160002060006101000a81548161ffff021916908361ffff160217905550818060010192505061063d565b336001600160a01b03167f431e828e6e7314653edcc0cf5083ec5187c3947389be4d220b8371949dbfe09786866040516106f7929190611b2d565b60405180910390a25050505050565b8051600f8054602080850180516001600160a01b039095166001600160a81b03199093168317600160a01b60ff96871602179093556040805192835292519093169281019290925260009133917f7a65e97e11bb87a6b3ee737671f002cad37dba58ac8041ce2c0f55019cbd3bee9101610629565b600060178183600381111561079257610792611b5b565b60ff9081168252602082019290925260400160002054166107c65760405163372e6e3d60e01b815260040160405180910390fd5b5050565b60006107e782604001516107e18460200151610bd1565b90610c1d565b90506000825160200151600181111561080257610802611b5b565b03610810576107c681610c9a565b6001825160200151600181111561082957610829611b5b565b0361083c576107c6818360000151610d71565b604051630338336760e41b815260040160405180910390fd5b6040805160608101825260008082526020820181905291810191909152606060008351600181111561088957610889611b5b565b036108a25761089b8360200151610e7e565b90506108c9565b6001835160018111156108b7576108b7611b5b565b0361083c5761089b836020015161103e565b6108d281610a68565b91506108dd816112da565b9050915091565b815160009081905b8082101561096b5783828151811061090657610906611ad7565b602002602001015183601001600087858151811061092657610926611ad7565b602002602001015161ffff1661ffff16815260200190815260200160002060006101000a81548161ffff021916908361ffff16021790555081806001019250506108ec565b336001600160a01b03167faebae210b738066f8aa0fd214dc0b7b5f288b5afc4ba1942bcb27ba0486ff20886866040516106f7929190611b2d565b815160009081905b80821015610a2d578382815181106109c8576109c8611ad7565b60200260200101518360140160008785815181106109e8576109e8611ad7565b602002602001015161ffff1661ffff16815260200190815260200160002060006101000a81548161ffff021916908361ffff16021790555081806001019250506109ae565b336001600160a01b03167f969a1bd9a5110a5f2e7d49eb0b9ae3ee7d542298e78ab27ddc062ab01b77033f86866040516106f7929190611b2d565b604080516060810182526000808252602080830182815293830191825284015160f01c8252602284015190925260429092015160c01c905290565b8051825161ffff9081169116141580610ac457508060200151826020015114155b80610ae9575080604001516001600160401b031682604001516001600160401b031614155b156107c657604051631a84bb2f60e31b815260040160405180910390fd5b60016000908152601d6020908152835161ffff1682527f9de6abd965d55c3bb0cdbf6fa175050624c6ff8fe86f682dc08f2a450ede2278815260408083208583015184528252808320858201516001600160401b0316845290915281205415610b835760405163f83c903760e01b815260040160405180910390fd5b815160209283012060016000908152601d9290920183526040808320855161ffff16845284528083208585015184528452808320948101516001600160401b03168352939092529190912055565b60408051602a8082526060828101909352600091906020820181803683375050845160f01b60208084019190915285015160228301525060409093015160c01b60428401525090919050565b6060806040519050835180825260208201818101602087015b81831015610c4e578051835260209283019201610c36565b50855184518101855292509050808201602086015b81831015610c7b578051835260209283019201610c63565b508651929092011591909101601f01601f191660405250905092915050565b600f5460009081906001600160a01b031663b19a437e610cbf64010000000042611b71565b600f85015460405160e084901b6001600160e01b0319168152610cf392918891600160a01b90910460ff1690600401611b93565b6020604051808303816000875af1158015610d12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d369190611bd0565b60058301546001600160401b03908116600090815260119094016020526040909320805467ffffffffffffffff191691909316179091555050565b600080610da28360400151604080518082018252600080825260208083019182528401518252929091015190915290565b9050600060405180606001604052806022815260200161216760229139825160228201526012840154602080850151875161ffff90811660009081526013890184526040808220548b518416835260018b019095529020549495506001600160a01b039093169363c580310093919290911690610e1f90306112f6565b89336000886040518863ffffffff1660e01b8152600401610e4596959493929190611bed565b6000604051808303818588803b158015610e5e57600080fd5b505af1158015610e72573d6000803e3d6000fd5b50505050505050505050565b600f5460405163a9e1189360e01b815260609160009182916001600160a01b03169063a9e1189390610eb4908790600401611c54565b600060405180830381865afa158015610ed1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ef99190810190611daa565b601f8301549091506001600160a01b031633141580610f235750601f8201546001600160a01b0316155b15610fcc57600f8201546040516343adf01560e11b815260009182916001600160a01b039091169063875be02a90610f5f908690600401611f28565b600060405180830381865afa158015610f7c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fa49190810190612024565b91509150818190610fc85760405162461bcd60e51b81526004016105cd9190611c54565b5050505b6000610fdb8260e00151610a68565b604080516060808201835285015161ffff908116600090815260108801602090815290849020549091168252608086015190820152818301516001600160401b031691810191909152909150611032908290610aa3565b5060e001519392505050565b606060008061104c84610a68565b805161ffff166000908152600184016020526040812054919250906110729030906112f6565b6012840154835161ffff908116600090815260138701602052604090819020549051630757b75360e11b81529394506001600160a01b03909216928392630eaf6ea6926110c6929116908690600401612085565b602060405180830381865afa1580156110e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110791906120a2565b1561118a57825161ffff90811660009081526013860160205260409081902054905163557faf8b60e11b81526001600160a01b0384169263aaff5f16926111579291169086908b906004016120bd565b600060405180830381600087803b15801561117157600080fd5b505af1158015611185573d6000803e3d6000fd5b505050505b855160208088019190912060016000908152601d870183526040808220875161ffff16835284528082208785015183528452808220878201516001600160401b031683529093529190912054036111e3578594506112d1565b60016000908152600a850160209081526040808320865161ffff16845282528083208683015184528252808320868201516001600160401b031684529091529020805461122f906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461125b906120f6565b80156112a85780601f1061127d576101008083540402835291602001916112a8565b820191906000526020600020905b81548152906001019060200180831161128b57829003601f168201915b5050505050945084516000036112d157604051632d8b70b760e11b815260040160405180910390fd5b50505050919050565b606061037d602a8084516112ee9190612140565b84919061132b565b6040805160288082526060828101909352602082018180368337505050606093841b60208201529190921b6034820152919050565b60608161133981601f612153565b10156113785760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b60448201526064016105cd565b6113828284612153565b845110156113c65760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016105cd565b6060821580156113e5576040519150600082526020820160405261142f565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561141e578051835260209283019201611406565b5050858452601f01601f1916604052505b5090505b9392505050565b61ffff8116811461026457600080fd5b60008083601f84011261145c57600080fd5b5081356001600160401b0381111561147357600080fd5b60208301915083602082850101111561148b57600080fd5b9250929050565b6001600160401b038116811461026457600080fd5b600080600080600080608087890312156114c057600080fd5b86356114cb8161143a565b955060208701356001600160401b03808211156114e757600080fd5b6114f38a838b0161144a565b90975095506040890135915061150882611492565b9093506060880135908082111561151e57600080fd5b5061152b89828a0161144a565b979a9699509497509295939492505050565b60006020828403121561154f57600080fd5b50919050565b60008083601f84011261156757600080fd5b5081356001600160401b0381111561157e57600080fd5b6020830191508360208260051b850101111561148b57600080fd5b600080600080604085870312156115af57600080fd5b84356001600160401b03808211156115c657600080fd5b6115d288838901611555565b909650945060208701359150808211156115eb57600080fd5b506115f887828801611555565b95989497509550505050565b60006040828403121561154f57600080fd5b60006040828403121561162857600080fd5b6114338383611604565b60006020828403121561164457600080fd5b81356001600160401b0381111561165a57600080fd5b820160a0818503121561143357600080fd5b60006020828403121561167e57600080fd5b81356001600160401b0381111561169457600080fd5b6116a084828501611604565b949350505050565b60005b838110156116c35781810151838201526020016116ab565b50506000910152565b600081518084526116e48160208601602086016116a8565b601f01601f19169290920160200192915050565b61ffff8351168152602083015160208201526001600160401b0360408401511660408201526080606082015260006116a060808301846116cc565b60006020828403121561174557600080fd5b813561143381611492565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561178857611788611750565b60405290565b604051606081016001600160401b038111828210171561178857611788611750565b604051608081016001600160401b038111828210171561178857611788611750565b60405161016081016001600160401b038111828210171561178857611788611750565b604051601f8201601f191681016001600160401b038111828210171561181d5761181d611750565b604052919050565b80356001600160a01b038116811461183c57600080fd5b919050565b60006020828403121561185357600080fd5b604051602081018181106001600160401b038211171561187557611875611750565b60405261188183611825565b81529392505050565b60ff8116811461026457600080fd5b6000604082840312156118ab57600080fd5b6118b3611766565b6118bc83611825565b815260208301356118cc8161188a565b60208201529392505050565b80356002811061183c57600080fd5b60006001600160401b0382111561190057611900611750565b50601f01601f191660200190565b600082601f83011261191f57600080fd5b813561193261192d826118e7565b6117f5565b81815284602083860101111561194757600080fd5b816020850160208301376000918101602001919091529392505050565b60006060828403121561197657600080fd5b61197e61178e565b9050813561198b8161143a565b81526020828101359082015260408201356119a581611492565b604082015292915050565b600060a082360312156119c257600080fd5b6119ca61178e565b82356001600160401b03808211156119e157600080fd5b8185019150606082360312156119f657600080fd5b6119fe61178e565b8235611a098161143a565b8152611a17602084016118d8565b6020820152604083013582811115611a2e57600080fd5b611a3a3682860161190e565b6040830152508352611a4f3660208701611964565b60208401526080850135915080821115611a6857600080fd5b50611a753682860161190e565b60408301525092915050565b600060408236031215611a9357600080fd5b611a9b611766565b611aa4836118d8565b815260208301356001600160401b03811115611abf57600080fd5b611acb3682860161190e565b60208301525092915050565b634e487b7160e01b600052603260045260246000fd5b60008151808452602080850194506020840160005b83811015611b2257815161ffff1687529582019590820190600101611b02565b509495945050505050565b604081526000611b406040830185611aed565b8281036020840152611b528185611aed565b95945050505050565b634e487b7160e01b600052602160045260246000fd5b600082611b8e57634e487b7160e01b600052601260045260246000fd5b500690565b63ffffffff84168152606060208201526000611bb260608301856116cc565b905060ff83166040830152949350505050565b805161183c81611492565b600060208284031215611be257600080fd5b815161143381611492565b61ffff8716815260c060208201526000611c0a60c08301886116cc565b8281036040840152611c1c81886116cc565b6001600160a01b0387811660608601528616608085015283810360a08501529050611c4781856116cc565b9998505050505050505050565b60208152600061143360208301846116cc565b805161183c8161188a565b805163ffffffff8116811461183c57600080fd5b805161183c8161143a565b6000611c9f61192d846118e7565b9050828152838383011115611cb357600080fd5b6114338360208301846116a8565b600082601f830112611cd257600080fd5b61143383835160208501611c91565b600082601f830112611cf257600080fd5b815160206001600160401b03821115611d0d57611d0d611750565b611d1b818360051b016117f5565b82815260079290921b84018101918181019086841115611d3a57600080fd5b8286015b84811015611d9f5760808189031215611d575760008081fd5b611d5f6117b0565b815181528482015185820152604080830151611d7a8161188a565b90820152606082810151611d8d8161188a565b90820152835291830191608001611d3e565b509695505050505050565b600060208284031215611dbc57600080fd5b81516001600160401b0380821115611dd357600080fd5b908301906101608286031215611de857600080fd5b611df06117d2565b611df983611c67565b8152611e0760208401611c72565b6020820152611e1860408401611c72565b6040820152611e2960608401611c86565b606082015260808301516080820152611e4460a08401611bc5565b60a0820152611e5560c08401611c67565b60c082015260e083015182811115611e6c57600080fd5b611e7887828601611cc1565b60e083015250610100611e8c818501611c72565b908201526101208381015183811115611ea457600080fd5b611eb088828701611ce1565b91830191909152506101409283015192810192909252509392505050565b60008151808452602080850194506020840160005b83811015611b2257815180518852838101518489015260408082015160ff908116918a0191909152606091820151169088015260809096019590820190600101611ee3565b60208152611f3c60208201835160ff169052565b60006020830151611f55604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015161ffff8116608084015250608083015160a083015260a0830151611f9c60c08401826001600160401b03169052565b5060c083015160ff811660e08401525060e08301516101606101008181860152611fca6101808601846116cc565b90860151909250610120611fe58682018363ffffffff169052565b80870151915050610140601f1986850301818701526120048483611ece565b9601519190940152509192915050565b8051801515811461183c57600080fd5b6000806040838503121561203757600080fd5b61204083612014565b915060208301516001600160401b0381111561205b57600080fd5b8301601f8101851361206c57600080fd5b61207b85825160208401611c91565b9150509250929050565b61ffff831681526040602082015260006116a060408301846116cc565b6000602082840312156120b457600080fd5b61143382612014565b61ffff841681526060602082015260006120da60608301856116cc565b82810360408401526120ec81856116cc565b9695505050505050565b600181811c9082168061210a57607f821691505b60208210810361154f57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561037d5761037d61212a565b8082018082111561037d5761037d61212a56fe00010000000000000000000000000000000000000000000000000000000000000000a2646970667358221220be54b3c05aed0bec3baf44692567bb5b6a3f27e13dd1783ac685f412e86dc98f64736f6c63430008160033

Deployed Bytecode

0x6080604052600436106100855760003560e01c80637f2bf445116100595780637f2bf4451461010c57806383d5b76e1461011f5780638706ee1814610149578063950d657f14610181578063a2acd391146101a157600080fd5b80621d35671461008a57806315c3f38f146100ac5780634204c31b146100cc57806361799b24146100ec575b600080fd5b34801561009657600080fd5b506100aa6100a53660046114a7565b6101c1565b005b3480156100b857600080fd5b506100aa6100c736600461153d565b610245565b3480156100d857600080fd5b506100aa6100e7366004611599565b610267565b3480156100f857600080fd5b506100aa610107366004611616565b6102e2565b6100aa61011a366004611632565b610301565b61013261012d36600461166c565b61031c565b6040516101409291906116f8565b60405180910390f35b34801561015557600080fd5b50610169610164366004611733565b61035f565b6040516001600160401b039091168152602001610140565b34801561018d57600080fd5b506100aa61019c366004611599565b610383565b3480156101ad57600080fd5b506100aa6101bc366004611599565b6103f8565b6101c961046d565b61023d8686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8901819004810282018101909252878152925087915086908190840183828082843760009201919091525061049b92505050565b505050505050565b61024d61054a565b61026461025f36839003830183611841565b6105d8565b50565b61026f61054a565b6102dc8484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061063592505050565b50505050565b6102ea61054a565b6102646102fc36839003830183611899565b610706565b61030b600261077b565b610264610317826119b0565b6107ca565b60408051606081018252600080825260208201819052918101919091526060610345600361077b565b61035661035184611a81565b610855565b91509150915091565b6001600160401b038082166000908152601160205260408120549091165b92915050565b61038b61054a565b6102dc848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506108e492505050565b61040061054a565b6102dc848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506109a692505050565b6012546000906001600160a01b0316331461026457604051637245ed1f60e01b815260040160405180910390fd5b602082015160009060601c816104b084610a68565b6040805160608101825261ffff808a166000908152601488016020908152908490205490911682528101859052818301516001600160401b0316918101919091529091506104ff908290610aa3565b6105098185610b07565b7fe7820063d8cc9ef56e692e9df898249c96f3be178a3c51f911ede4e6c06b05ad818560405161053a9291906116f8565b60405180910390a1505050505050565b7fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c600401546001600160a01b031633146105d65760405162461bcd60e51b815260206004820152602260248201527f4c69624469616d6f6e643a204d75737420626520636f6e7472616374206f776e60448201526132b960f11b60648201526084015b60405180910390fd5b565b8051601280546001600160a01b0319166001600160a01b03909216918217905560405190815260009033907f5653b9afcdbb9f970275a0e277396e823dc1ec9d67f4fe7f2b9b575e500f4fe1906020015b60405180910390a25050565b815160009081905b808210156106bc5783828151811061065757610657611ad7565b602002602001015183601301600087858151811061067757610677611ad7565b602002602001015161ffff1661ffff16815260200190815260200160002060006101000a81548161ffff021916908361ffff160217905550818060010192505061063d565b336001600160a01b03167f431e828e6e7314653edcc0cf5083ec5187c3947389be4d220b8371949dbfe09786866040516106f7929190611b2d565b60405180910390a25050505050565b8051600f8054602080850180516001600160a01b039095166001600160a81b03199093168317600160a01b60ff96871602179093556040805192835292519093169281019290925260009133917f7a65e97e11bb87a6b3ee737671f002cad37dba58ac8041ce2c0f55019cbd3bee9101610629565b600060178183600381111561079257610792611b5b565b60ff9081168252602082019290925260400160002054166107c65760405163372e6e3d60e01b815260040160405180910390fd5b5050565b60006107e782604001516107e18460200151610bd1565b90610c1d565b90506000825160200151600181111561080257610802611b5b565b03610810576107c681610c9a565b6001825160200151600181111561082957610829611b5b565b0361083c576107c6818360000151610d71565b604051630338336760e41b815260040160405180910390fd5b6040805160608101825260008082526020820181905291810191909152606060008351600181111561088957610889611b5b565b036108a25761089b8360200151610e7e565b90506108c9565b6001835160018111156108b7576108b7611b5b565b0361083c5761089b836020015161103e565b6108d281610a68565b91506108dd816112da565b9050915091565b815160009081905b8082101561096b5783828151811061090657610906611ad7565b602002602001015183601001600087858151811061092657610926611ad7565b602002602001015161ffff1661ffff16815260200190815260200160002060006101000a81548161ffff021916908361ffff16021790555081806001019250506108ec565b336001600160a01b03167faebae210b738066f8aa0fd214dc0b7b5f288b5afc4ba1942bcb27ba0486ff20886866040516106f7929190611b2d565b815160009081905b80821015610a2d578382815181106109c8576109c8611ad7565b60200260200101518360140160008785815181106109e8576109e8611ad7565b602002602001015161ffff1661ffff16815260200190815260200160002060006101000a81548161ffff021916908361ffff16021790555081806001019250506109ae565b336001600160a01b03167f969a1bd9a5110a5f2e7d49eb0b9ae3ee7d542298e78ab27ddc062ab01b77033f86866040516106f7929190611b2d565b604080516060810182526000808252602080830182815293830191825284015160f01c8252602284015190925260429092015160c01c905290565b8051825161ffff9081169116141580610ac457508060200151826020015114155b80610ae9575080604001516001600160401b031682604001516001600160401b031614155b156107c657604051631a84bb2f60e31b815260040160405180910390fd5b60016000908152601d6020908152835161ffff1682527f9de6abd965d55c3bb0cdbf6fa175050624c6ff8fe86f682dc08f2a450ede2278815260408083208583015184528252808320858201516001600160401b0316845290915281205415610b835760405163f83c903760e01b815260040160405180910390fd5b815160209283012060016000908152601d9290920183526040808320855161ffff16845284528083208585015184528452808320948101516001600160401b03168352939092529190912055565b60408051602a8082526060828101909352600091906020820181803683375050845160f01b60208084019190915285015160228301525060409093015160c01b60428401525090919050565b6060806040519050835180825260208201818101602087015b81831015610c4e578051835260209283019201610c36565b50855184518101855292509050808201602086015b81831015610c7b578051835260209283019201610c63565b508651929092011591909101601f01601f191660405250905092915050565b600f5460009081906001600160a01b031663b19a437e610cbf64010000000042611b71565b600f85015460405160e084901b6001600160e01b0319168152610cf392918891600160a01b90910460ff1690600401611b93565b6020604051808303816000875af1158015610d12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d369190611bd0565b60058301546001600160401b03908116600090815260119094016020526040909320805467ffffffffffffffff191691909316179091555050565b600080610da28360400151604080518082018252600080825260208083019182528401518252929091015190915290565b9050600060405180606001604052806022815260200161216760229139825160228201526012840154602080850151875161ffff90811660009081526013890184526040808220548b518416835260018b019095529020549495506001600160a01b039093169363c580310093919290911690610e1f90306112f6565b89336000886040518863ffffffff1660e01b8152600401610e4596959493929190611bed565b6000604051808303818588803b158015610e5e57600080fd5b505af1158015610e72573d6000803e3d6000fd5b50505050505050505050565b600f5460405163a9e1189360e01b815260609160009182916001600160a01b03169063a9e1189390610eb4908790600401611c54565b600060405180830381865afa158015610ed1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ef99190810190611daa565b601f8301549091506001600160a01b031633141580610f235750601f8201546001600160a01b0316155b15610fcc57600f8201546040516343adf01560e11b815260009182916001600160a01b039091169063875be02a90610f5f908690600401611f28565b600060405180830381865afa158015610f7c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fa49190810190612024565b91509150818190610fc85760405162461bcd60e51b81526004016105cd9190611c54565b5050505b6000610fdb8260e00151610a68565b604080516060808201835285015161ffff908116600090815260108801602090815290849020549091168252608086015190820152818301516001600160401b031691810191909152909150611032908290610aa3565b5060e001519392505050565b606060008061104c84610a68565b805161ffff166000908152600184016020526040812054919250906110729030906112f6565b6012840154835161ffff908116600090815260138701602052604090819020549051630757b75360e11b81529394506001600160a01b03909216928392630eaf6ea6926110c6929116908690600401612085565b602060405180830381865afa1580156110e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110791906120a2565b1561118a57825161ffff90811660009081526013860160205260409081902054905163557faf8b60e11b81526001600160a01b0384169263aaff5f16926111579291169086908b906004016120bd565b600060405180830381600087803b15801561117157600080fd5b505af1158015611185573d6000803e3d6000fd5b505050505b855160208088019190912060016000908152601d870183526040808220875161ffff16835284528082208785015183528452808220878201516001600160401b031683529093529190912054036111e3578594506112d1565b60016000908152600a850160209081526040808320865161ffff16845282528083208683015184528252808320868201516001600160401b031684529091529020805461122f906120f6565b80601f016020809104026020016040519081016040528092919081815260200182805461125b906120f6565b80156112a85780601f1061127d576101008083540402835291602001916112a8565b820191906000526020600020905b81548152906001019060200180831161128b57829003601f168201915b5050505050945084516000036112d157604051632d8b70b760e11b815260040160405180910390fd5b50505050919050565b606061037d602a8084516112ee9190612140565b84919061132b565b6040805160288082526060828101909352602082018180368337505050606093841b60208201529190921b6034820152919050565b60608161133981601f612153565b10156113785760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b60448201526064016105cd565b6113828284612153565b845110156113c65760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b60448201526064016105cd565b6060821580156113e5576040519150600082526020820160405261142f565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561141e578051835260209283019201611406565b5050858452601f01601f1916604052505b5090505b9392505050565b61ffff8116811461026457600080fd5b60008083601f84011261145c57600080fd5b5081356001600160401b0381111561147357600080fd5b60208301915083602082850101111561148b57600080fd5b9250929050565b6001600160401b038116811461026457600080fd5b600080600080600080608087890312156114c057600080fd5b86356114cb8161143a565b955060208701356001600160401b03808211156114e757600080fd5b6114f38a838b0161144a565b90975095506040890135915061150882611492565b9093506060880135908082111561151e57600080fd5b5061152b89828a0161144a565b979a9699509497509295939492505050565b60006020828403121561154f57600080fd5b50919050565b60008083601f84011261156757600080fd5b5081356001600160401b0381111561157e57600080fd5b6020830191508360208260051b850101111561148b57600080fd5b600080600080604085870312156115af57600080fd5b84356001600160401b03808211156115c657600080fd5b6115d288838901611555565b909650945060208701359150808211156115eb57600080fd5b506115f887828801611555565b95989497509550505050565b60006040828403121561154f57600080fd5b60006040828403121561162857600080fd5b6114338383611604565b60006020828403121561164457600080fd5b81356001600160401b0381111561165a57600080fd5b820160a0818503121561143357600080fd5b60006020828403121561167e57600080fd5b81356001600160401b0381111561169457600080fd5b6116a084828501611604565b949350505050565b60005b838110156116c35781810151838201526020016116ab565b50506000910152565b600081518084526116e48160208601602086016116a8565b601f01601f19169290920160200192915050565b61ffff8351168152602083015160208201526001600160401b0360408401511660408201526080606082015260006116a060808301846116cc565b60006020828403121561174557600080fd5b813561143381611492565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b038111828210171561178857611788611750565b60405290565b604051606081016001600160401b038111828210171561178857611788611750565b604051608081016001600160401b038111828210171561178857611788611750565b60405161016081016001600160401b038111828210171561178857611788611750565b604051601f8201601f191681016001600160401b038111828210171561181d5761181d611750565b604052919050565b80356001600160a01b038116811461183c57600080fd5b919050565b60006020828403121561185357600080fd5b604051602081018181106001600160401b038211171561187557611875611750565b60405261188183611825565b81529392505050565b60ff8116811461026457600080fd5b6000604082840312156118ab57600080fd5b6118b3611766565b6118bc83611825565b815260208301356118cc8161188a565b60208201529392505050565b80356002811061183c57600080fd5b60006001600160401b0382111561190057611900611750565b50601f01601f191660200190565b600082601f83011261191f57600080fd5b813561193261192d826118e7565b6117f5565b81815284602083860101111561194757600080fd5b816020850160208301376000918101602001919091529392505050565b60006060828403121561197657600080fd5b61197e61178e565b9050813561198b8161143a565b81526020828101359082015260408201356119a581611492565b604082015292915050565b600060a082360312156119c257600080fd5b6119ca61178e565b82356001600160401b03808211156119e157600080fd5b8185019150606082360312156119f657600080fd5b6119fe61178e565b8235611a098161143a565b8152611a17602084016118d8565b6020820152604083013582811115611a2e57600080fd5b611a3a3682860161190e565b6040830152508352611a4f3660208701611964565b60208401526080850135915080821115611a6857600080fd5b50611a753682860161190e565b60408301525092915050565b600060408236031215611a9357600080fd5b611a9b611766565b611aa4836118d8565b815260208301356001600160401b03811115611abf57600080fd5b611acb3682860161190e565b60208301525092915050565b634e487b7160e01b600052603260045260246000fd5b60008151808452602080850194506020840160005b83811015611b2257815161ffff1687529582019590820190600101611b02565b509495945050505050565b604081526000611b406040830185611aed565b8281036020840152611b528185611aed565b95945050505050565b634e487b7160e01b600052602160045260246000fd5b600082611b8e57634e487b7160e01b600052601260045260246000fd5b500690565b63ffffffff84168152606060208201526000611bb260608301856116cc565b905060ff83166040830152949350505050565b805161183c81611492565b600060208284031215611be257600080fd5b815161143381611492565b61ffff8716815260c060208201526000611c0a60c08301886116cc565b8281036040840152611c1c81886116cc565b6001600160a01b0387811660608601528616608085015283810360a08501529050611c4781856116cc565b9998505050505050505050565b60208152600061143360208301846116cc565b805161183c8161188a565b805163ffffffff8116811461183c57600080fd5b805161183c8161143a565b6000611c9f61192d846118e7565b9050828152838383011115611cb357600080fd5b6114338360208301846116a8565b600082601f830112611cd257600080fd5b61143383835160208501611c91565b600082601f830112611cf257600080fd5b815160206001600160401b03821115611d0d57611d0d611750565b611d1b818360051b016117f5565b82815260079290921b84018101918181019086841115611d3a57600080fd5b8286015b84811015611d9f5760808189031215611d575760008081fd5b611d5f6117b0565b815181528482015185820152604080830151611d7a8161188a565b90820152606082810151611d8d8161188a565b90820152835291830191608001611d3e565b509695505050505050565b600060208284031215611dbc57600080fd5b81516001600160401b0380821115611dd357600080fd5b908301906101608286031215611de857600080fd5b611df06117d2565b611df983611c67565b8152611e0760208401611c72565b6020820152611e1860408401611c72565b6040820152611e2960608401611c86565b606082015260808301516080820152611e4460a08401611bc5565b60a0820152611e5560c08401611c67565b60c082015260e083015182811115611e6c57600080fd5b611e7887828601611cc1565b60e083015250610100611e8c818501611c72565b908201526101208381015183811115611ea457600080fd5b611eb088828701611ce1565b91830191909152506101409283015192810192909252509392505050565b60008151808452602080850194506020840160005b83811015611b2257815180518852838101518489015260408082015160ff908116918a0191909152606091820151169088015260809096019590820190600101611ee3565b60208152611f3c60208201835160ff169052565b60006020830151611f55604084018263ffffffff169052565b50604083015163ffffffff8116606084015250606083015161ffff8116608084015250608083015160a083015260a0830151611f9c60c08401826001600160401b03169052565b5060c083015160ff811660e08401525060e08301516101606101008181860152611fca6101808601846116cc565b90860151909250610120611fe58682018363ffffffff169052565b80870151915050610140601f1986850301818701526120048483611ece565b9601519190940152509192915050565b8051801515811461183c57600080fd5b6000806040838503121561203757600080fd5b61204083612014565b915060208301516001600160401b0381111561205b57600080fd5b8301601f8101851361206c57600080fd5b61207b85825160208401611c91565b9150509250929050565b61ffff831681526040602082015260006116a060408301846116cc565b6000602082840312156120b457600080fd5b61143382612014565b61ffff841681526060602082015260006120da60608301856116cc565b82810360408401526120ec81856116cc565b9695505050505050565b600181811c9082168061210a57607f821691505b60208210810361154f57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b8181038181111561037d5761037d61212a565b8082018082111561037d5761037d61212a56fe00010000000000000000000000000000000000000000000000000000000000000000a2646970667358221220be54b3c05aed0bec3baf44692567bb5b6a3f27e13dd1783ac685f412e86dc98f64736f6c63430008160033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
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.