Holesky Testnet

Contract

0xF6F6a8685C5aa6CBd9d8BE94FBD8266C827becca

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To
Activate31884182025-01-21 5:49:0018 days ago1737438540IN
0xF6F6a868...C827becca
0.55 ETH0.000001460.00970001
Activate31255872025-01-11 20:33:2427 days ago1736627604IN
0xF6F6a868...C827becca
0 ETH0.000000120.00094091
Deactivate31255822025-01-11 20:32:2427 days ago1736627544IN
0xF6F6a868...C827becca
0 ETH0.000000070.00097001
Activate31254632025-01-11 20:06:4827 days ago1736626008IN
0xF6F6a868...C827becca
0.1 ETH0.000002290.01515626
Deposit31254572025-01-11 20:05:2427 days ago1736625924IN
0xF6F6a868...C827becca
0.3 ETH0.000001090.01212501
Accept Ownership30705462025-01-03 17:05:1235 days ago1735923912IN
0xF6F6a868...C827becca
0 ETH0.000000030.00097001
Transfer Ownersh...30705352025-01-03 17:03:0035 days ago1735923780IN
0xF6F6a868...C827becca
0 ETH0.000000020.00097001
Activate29149442024-12-11 11:21:3658 days ago1733916096IN
0xF6F6a868...C827becca
0 ETH0.000033810.25029191
Deactivate29149402024-12-11 11:20:4858 days ago1733916048IN
0xF6F6a868...C827becca
0 ETH0.000018770.25029191
Accept Ownership28900962024-12-07 14:31:4862 days ago1733581908IN
0xF6F6a868...C827becca
0 ETH0.000010620.32110077
Transfer Ownersh...28899792024-12-07 14:02:4862 days ago1733580168IN
0xF6F6a868...C827becca
0 ETH0.000010430.3399506
Activate28868562024-12-07 1:55:3663 days ago1733536536IN
0xF6F6a868...C827becca
0 ETH0.000064980.48107794
Deposit28854172024-12-06 20:23:2463 days ago1733516604IN
0xF6F6a868...C827becca
0.4 ETH0.000056130.62318835
Activate28707212024-12-04 15:14:0065 days ago1733325240IN
0xF6F6a868...C827becca
0 ETH0.00000550.04071721
Set Tunnel Id28707212024-12-04 15:14:0065 days ago1733325240IN
0xF6F6a868...C827becca
0 ETH0.000001060.04071721
Deactivate28707212024-12-04 15:14:0065 days ago1733325240IN
0xF6F6a868...C827becca
0 ETH0.000003050.04071721
Activate28621512024-12-03 8:32:3667 days ago1733214756IN
0xF6F6a868...C827becca
0.01 ETH0.000006160.04072139
Set Tunnel Id28621512024-12-03 8:32:3667 days ago1733214756IN
0xF6F6a868...C827becca
0 ETH0.000001060.04072139
Deactivate28621512024-12-03 8:32:3667 days ago1733214756IN
0xF6F6a868...C827becca
0 ETH0.000003050.04072139
Activate28621452024-12-03 8:31:2467 days ago1733214684IN
0xF6F6a868...C827becca
0.01 ETH0.000003160.04072139
Activate28621442024-12-03 8:31:1267 days ago1733214672IN
0xF6F6a868...C827becca
0.01 ETH0.000003160.04072139
Activate28559442024-12-02 10:27:1267 days ago1733135232IN
0xF6F6a868...C827becca
0.02 ETH0.000008810.04290514
Set Tunnel Id28559442024-12-02 10:27:1267 days ago1733135232IN
0xF6F6a868...C827becca
0 ETH0.000001970.04290514

Latest 8 internal transactions

Advanced mode:
Parent Transaction Hash Block
From
To
31884182025-01-21 5:49:0018 days ago1737438540
0xF6F6a868...C827becca
0.55 ETH
31254632025-01-11 20:06:4827 days ago1736626008
0xF6F6a868...C827becca
0.1 ETH
31254572025-01-11 20:05:2427 days ago1736625924
0xF6F6a868...C827becca
0.3 ETH
28854172024-12-06 20:23:2463 days ago1733516604
0xF6F6a868...C827becca
0.4 ETH
28621512024-12-03 8:32:3667 days ago1733214756
0xF6F6a868...C827becca
0.01 ETH
28621452024-12-03 8:31:2467 days ago1733214684
0xF6F6a868...C827becca
0.01 ETH
28621442024-12-03 8:31:1267 days ago1733214672
0xF6F6a868...C827becca
0.01 ETH
28559442024-12-02 10:27:1267 days ago1733135232
0xF6F6a868...C827becca
0.02 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PacketConsumer

Compiler Version
v0.8.27+commit.40a35a09

Optimization Enabled:
Yes with 200 runs

Other Settings:
cancun EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 9 : PacketConsumer.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.23;

import "@openzeppelin/contracts/access/Ownable2Step.sol";

import "./interfaces/IPacketConsumer.sol";
import "./interfaces/ITunnelRouter.sol";
import "./interfaces/IVault.sol";

import "./libraries/Address.sol";
import "./libraries/PacketDecoder.sol";

contract PacketConsumer is IPacketConsumer, Ownable2Step {
    // An object that contains the price of a signal ID.
    struct Price {
        uint64 price;
        int64 timestamp;
    }

    // The tunnel router contract.
    address public immutable tunnelRouter;

    // The tunnel ID that this contract is consuming; cannot be immutable or else the create2
    // will result in different address.
    uint64 public tunnelId;
    // Mapping between a signal ID and its corresponding latest price object.
    mapping(bytes32 => Price) public prices;

    modifier onlyTunnelRouter() {
        if (msg.sender != tunnelRouter) {
            revert UnauthorizedTunnelRouter();
        }
        _;
    }

    constructor(address tunnelRouter_, address initialOwner) Ownable(initialOwner) {
        tunnelRouter = tunnelRouter_;
    }

    /**
     * @dev See {IPacketConsumer-process}.
     */
    function process(PacketDecoder.TssMessage memory data) external onlyTunnelRouter {
        PacketDecoder.Packet memory packet = data.packet;
        for (uint256 i = 0; i < packet.signals.length; i++) {
            prices[packet.signals[i].signal] = Price({price: packet.signals[i].price, timestamp: packet.timestamp});

            emit SignalPriceUpdated(packet.signals[i].signal, packet.signals[i].price, packet.timestamp);
        }
    }

    /**
     * @dev See {IPacketConsumer-activate}.
     */
    function activate(uint64 latestSeq) external payable onlyOwner {
        ITunnelRouter(tunnelRouter).activate{value: msg.value}(tunnelId, latestSeq);
    }

    /**
     * @dev See {IPacketConsumer-deactivate}.
     */
    function deactivate() external onlyOwner {
        ITunnelRouter(tunnelRouter).deactivate(tunnelId);
    }

    /**
     * @dev See {IPacketConsumer-deposit}.
     */
    function deposit() external payable {
        IVault vault = ITunnelRouter(tunnelRouter).vault();

        vault.deposit{value: msg.value}(tunnelId, address(this));
    }

    /**
     * @dev See {IPacketConsumer-withdraw}.
     */
    function withdraw(uint256 amount) external onlyOwner {
        IVault vault = ITunnelRouter(tunnelRouter).vault();

        vault.withdraw(tunnelId, msg.sender, amount);
    }

    /**
     * @dev See {IPacketConsumer-withdrawAll}.
     */
    function withdrawAll() external onlyOwner {
        IVault vault = ITunnelRouter(tunnelRouter).vault();

        vault.withdrawAll(tunnelId, msg.sender);
    }

    ///@dev Sets the tunnel ID of the contract.
    function setTunnelId(uint64 tunnelId_) external onlyOwner {
        tunnelId = tunnelId_;
    }
}

File 2 of 9 : Ownable2Step.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.20;

import {Ownable} from "./Ownable.sol";

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is specified at deployment time in the constructor for `Ownable`. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

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

    /**
     * @dev Returns the address of the pending owner.
     */
    function pendingOwner() public view virtual returns (address) {
        return _pendingOwner;
    }

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() public virtual {
        address sender = _msgSender();
        if (pendingOwner() != sender) {
            revert OwnableUnauthorizedAccount(sender);
        }
        _transferOwnership(sender);
    }
}

File 3 of 9 : IPacketConsumer.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.23;

import "../libraries/PacketDecoder.sol";

interface IPacketConsumer {
    // ========================================
    // Events
    // ========================================

    /**
     * @notice Emitted when the signal price is updated.
     *
     * @param signalId The Id of the signal whose price is updated.
     * @param price The new price of the signal.
     * @param timestamp The timestamp of the updated prices.
     */
    event SignalPriceUpdated(bytes32 indexed signalId, uint64 price, int64 timestamp);

    // ========================================
    // Custom Errors
    // ========================================

    /**
     * @notice Reverts if the caller is not the tunnelRouter contract.
     */
    error UnauthorizedTunnelRouter();

    // ========================================
    // Functions
    // ========================================

    /**
     * @dev Processes the relayed message.
     *
     * The relayed message must be evaluated from the tunnelRouter contract and
     * verified by the tssVerifier contract before forwarding to the target contract.
     *
     * @param data The decoded tss message that is relayed from the tunnelRouter contract.
     */
    function process(PacketDecoder.TssMessage memory data) external;

    /**
     * @dev Activates the tunnel and set the sequence on tunnelRouter contract.
     *
     * This function deposits tokens into the vault and sets the latest sequence on the
     * tunnelRouter contract if the current deposit in the vault contract exceeds a threshold.
     * The transaction is reverted if the threshold is not met.
     *
     * This function should be called by the contract owner.
     *
     * @param latestSeq The new sequence of the tunnel.
     */
    function activate(uint64 latestSeq) external payable;

    /**
     * @dev Deactivates the tunnel on tunnelRouter contract.
     *
     * This function should be called by the contract owner.
     */
    function deactivate() external;

    /**
     * @dev Deposits the native tokens into the vault on behalf of the given account and tunnelId.
     * The amount of tokens to be deposited is provided as msg.value in the transaction.
     *
     * The contract calls the vault to deposit the tokens.
     */
    function deposit() external payable;

    /**
     * @dev Withdraws the native tokens from the vault contract with specific amount.
     *
     * This function should be called by the contract owner.
     */
    function withdraw(uint256 amount) external;

    /**
     * @dev Withdraws all native tokens from the vault contract.
     *
     * This function should be called by the contract owner.
     */
    function withdrawAll() external;

    /**
     * @dev Returns The tunnelRouter contract address.
     */
    function tunnelRouter() external view returns (address);

    /**
     * @dev Returns The tunnelId of the contract address.
     */
    function tunnelId() external view returns (uint64);
}

File 4 of 9 : ITunnelRouter.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.23;

import "./IVault.sol";

interface ITunnelRouter {
    // ========================================
    // Events
    // ========================================

    /**
     * @notice Emitted when the callback gas limit is set.
     *
     * @param callbackGasLimit The maximum gas limit can be used when calling the target contract.
     */
    event CallbackGasLimitSet(uint256 callbackGasLimit);

    /**
     * @notice Emitted when the additional gas used is set.
     *
     * @param additionalGasUsed The additional gas estimated for relaying the message;
     * does not include the gas cost for executing the target contract.
     */
    event AdditionalGasUsedSet(uint256 additionalGasUsed);

    /**
     * @notice Emitted after the message is relayed to the target contract
     * to indicate the result of the process.
     *
     * @param originatorHash The originatorHash of the target that the sender is deactivating.
     * @param sequence The sequence of the message.
     * @param isSuccess The flag indicating whether the message is successful execute.
     */
    event MessageProcessed(bytes32 indexed originatorHash, uint64 indexed sequence, bool isSuccess);

    /**
     * @notice Emitted when the target is activated.
     *
     * @param originatorHash The originatorHash of the target that the sender is activating.
     * @param latestSequence The latest sequence of the tunnel.
     */
    event Activated(bytes32 indexed originatorHash, uint64 latestSequence);

    /**
     * @notice Emitted when the target is deactivated.
     *
     * @param originatorHash The originatorHash of the target that the sender is deactivating.
     * @param latestSequence The latest sequence of the tunnel.
     */
    event Deactivated(bytes32 indexed originatorHash, uint64 latestSequence);

    // ========================================
    // Custom Errors
    // ========================================

    /**
     * @notice Reverts if the originatorHash is inactive.
     *
     * @param originatorHash The originatorHash of the target contract and tunnelID.
     */
    error InactiveTunnel(bytes32 originatorHash);

    /**
     * @notice Reverts if the originatorHash is already active.
     *
     * @param originatorHash The originatorHash of the target contract and tunnelID.
     */
    error ActiveTunnel(bytes32 originatorHash);

    /**
     * @notice Reverts if the encoder type is undefined.
     */
    error UndefinedEncoderType();

    /**
     * @notice Reverts if the sequence is incorrect.
     *
     * @param expected The expected sequence of the tunnel.
     * @param input The input sequence of the tunnel.
     */
    error InvalidSequence(uint64 expected, uint64 input);

    /**
     * @notice Reverts if the message and its signature doesn't match.
     */
    error InvalidSignature();

    /**
     * @notice Reverts if the remaining balance is insufficient to withdraw.
     *
     * @param tunnelId The tunnel ID that the sender is withdrawing tokens.
     * @param addr The account from which the sender is withdrawing tokens.
     */
    error InsufficientRemainingBalance(uint64 tunnelId, address addr);

    // ========================================
    // Functions
    // ========================================

    ///@dev Tunnel information
    struct TunnelInfo {
        bool isActive; // whether the tunnel is active or not
        uint64 latestSequence; // the latest sequence of the tunnel
        uint256 balance; // the remaining balance of the tunnel
        bytes32 originatorHash; // the originator hash of the tunnel
    }

    /**
     * @dev Relays the message to the target contract.
     *
     * Verifies the message's sequence and signature before forwarding it to
     * the packet consumer contract. The sender is entitled to a reward from the
     * vault contract, even if the packet consumer contract fails to process the
     * message. The reward is based on the gas consumed during processing plus
     * a predefined additional gas estimate.
     *
     * @param message The message to be relayed.
     * @param randomAddr The random address used in signature.
     * @param signature The signature of the message.
     */
    function relay(bytes calldata message, address randomAddr, uint256 signature) external;

    /**
     * @dev Activates the sender and associated tunnel ID.
     *
     * @param tunnelId The tunnel ID that the sender contract is activating.
     * @param latestSeq The new sequence of the tunnelID.
     */
    function activate(uint64 tunnelId, uint64 latestSeq) external payable;

    /**
     * @dev Deactivates the sender and associated tunnel ID.
     *
     * @param tunnelId The tunnel ID being deactivated.
     */
    function deactivate(uint64 tunnelId) external;

    /**
     * @dev Returns the minimum balance required to keep the tunnel active.
     *
     * @return uint256 The minimum balance threshold.
     */
    function minimumBalanceThreshold() external view returns (uint256);

    /**
     * @dev Returns the tunnel information.
     *
     * @param tunnelId The ID of the tunnel.
     * @param addr The target contract address.
     *
     * @return bool True if the tunnel is active, false otherwise.
     */
    function tunnelInfo(uint64 tunnelId, address addr) external view returns (TunnelInfo memory);

    /**
     * @dev Returns the originator hash of the given tunnel ID and address.
     *
     * @param tunnelId The ID of the tunnel.
     * @param addr The target contract address.
     *
     * @return bytes32 The originator hash of the tunnel.
     */
    function originatorHash(uint64 tunnelId, address addr) external view returns (bytes32);

    /**
     * @dev Returns the active status of the target contract.
     *
     * @param originatorHash The originatorHash of the target contract.
     *
     * @return bool True if the target contract is active, false otherwise.
     */
    function isActive(bytes32 originatorHash) external view returns (bool);

    /**
     * @dev Returns the sequence of the target contract.
     *
     * @param originatorHash The originatorHash of the target contract.
     *
     * @return uint64 The sequence of the target contract.
     */
    function sequence(bytes32 originatorHash) external view returns (uint64);

    /**
     * @dev Returns the vault contract address.
     */
    function vault() external view returns (IVault);

    /**
     * @dev Returns the source chain ID hash.
     */
    function sourceChainIdHash() external view returns (bytes32);

    /**
     * @dev Returns the target chain ID hash.
     */
    function targetChainIdHash() external view returns (bytes32);
}

File 5 of 9 : IVault.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.23;

interface IVault {
    // ========================================
    // Events
    // ========================================

    /**
     * @notice Emitted when the tunnel router contract address is set.
     *
     * @param tunnelRouter The new tunnel router contract address.
     */
    event TunnelRouterSet(address tunnelRouter);

    /**
     * @notice Emitted when the caller deposit native token into the contract.
     *
     * @param originatorHash The originator hash of the account to which the token is deposited.
     * @param from The account from which the token is deposited.
     * @param amount The amount of tokens deposited.
     */
    event Deposited(bytes32 indexed originatorHash, address indexed from, uint256 amount);

    /**
     * @notice Emitted when the caller withdraw native token from the contract.
     *
     * @param originatorHash The originator hash of the account to which the token is deposited.
     * @param to The account to which the token is withdrawn.
     * @param amount The amount of tokens withdrawn.
     */
    event Withdrawn(bytes32 indexed originatorHash, address indexed to, uint256 amount);

    // ========================================
    // Custom Errors
    // ========================================

    /**
     * @notice The caller is not the tunnelRouter contract.
     */
    error UnauthorizedTunnelRouter();

    /**
     * @notice Reverts if the balance is insufficient to allow the withdrawal without exceeding the threshold.
     */
    error WithdrawnAmountExceedsThreshold();

    /**
     * @notice Reverts if the tunnel is active.
     */
    error TunnelIsActive();

    /**
     * @notice Reverts if contract cannot send fee to the specific address.
     *
     * @param addr The address to which the token transfer failed.
     */
    error TokenTransferFailed(address addr);

    // ========================================
    // Functions
    // ========================================

    /**
     * @dev Deposits the native tokens into the vault on behalf of the given account and tunnelID.
     * The deposit amount is provided via `msg.value`.
     *
     * @param tunnelId The ID of the tunnel into which the sender is depositing tokens.
     * @param to The account into which the sender is depositing tokens
     */
    function deposit(uint64 tunnelId, address to) external payable;

    /**
     * @dev Withdraws native tokens from the sender's account associated with the given tunnelID.
     *
     * @param tunnelId the ID of the tunnel from which the sender is withdrawing tokens.
     * @param to The account to which the sender is withdrawing tokens to.
     * @param amount the amount of tokens to withdraw.
     */
    function withdraw(uint64 tunnelId, address to, uint256 amount) external;

    /**
     * @dev Withdraws the entire deposit from the sender's account for the specified tunnel ID.
     * @param to The account to which the sender is withdrawing tokens to.
     * @param tunnelId the ID of the tunnel from which the sender is withdrawing tokens.
     */
    function withdrawAll(uint64 tunnelId, address to) external;

    /**
     * @dev Collects the fee from the given originator hash.
     *
     * This function should be called by the tunnelRouter contract only.
     *
     * @param originatorHash The originator hash of the account to which the token is withdrawn.
     * @param to The account to which the sender is withdrawing tokens to.
     * @param amount the amount of tokens to withdraw.
     */
    function collectFee(bytes32 originatorHash, address to, uint256 amount) external;

    /**
     * @dev Returns the balance of the account.
     *
     * @param tunnelId The ID of the tunnel to check the balance.
     * @param account The account to check the balance.
     */
    function balance(uint64 tunnelId, address account) external view returns (uint256);

    /**
     * @dev Returns the balance of the account by the given originator hash.
     *
     * @param originatorHash The originator hash of the account to which the token is deposited.
     */
    function getBalanceByOriginatorHash(bytes32 originatorHash) external view returns (uint256);

    /**
     * @dev Returns the tunnel router contract address.
     */
    function tunnelRouter() external view returns (address);
}

File 6 of 9 : Address.sol
// SPDX-License-Identifier: MIT
// ref: https://gist.github.com/Y5Yash/721a5f5c3e392a6a28f47db1d3114501
// ref: https://github.com/ethereum/ercs/blob/master/ERCS/erc-55.md

pragma solidity ^0.8.23;

library Address {
    bytes16 private constant _LOWER = "0123456789abcdef";
    bytes16 private constant _CAPITAL = "0123456789ABCDEF";

    ///@dev convert address to checksum address string.
    function toChecksumString(address addr) internal pure returns (string memory) {
        // get the hash of the lowercase address
        bytes memory lowercaseAddr = ToLowercaseBytes(addr);
        bytes32 hashedAddr = keccak256(abi.encodePacked(lowercaseAddr));

        // store checksum address with '0x' prepended in this.
        bytes memory result = new bytes(42);
        result[0] = "0";
        result[1] = "x";

        uint160 addrValue = uint160(addr);
        uint160 hashValue = uint160(bytes20(hashedAddr));

        // checksum logic from EIP-55
        for (uint256 i = 41; i > 1; --i) {
            uint256 b = addrValue & 0xf;

            if (hashValue & 0xf > 7) {
                result[i] = _CAPITAL[b];
            } else {
                result[i] = _LOWER[b];
            }

            addrValue >>= 4;
            hashValue >>= 4;
        }

        return string(abi.encodePacked(result));
    }

    ///@dev get convert address bytes to lowercase char hex bytes (without '0x').
    function ToLowercaseBytes(address addr) internal pure returns (bytes memory) {
        bytes memory s = new bytes(40);

        uint160 x = uint160(addr);
        for (uint256 i = 0; i < 20; i++) {
            uint8 b = uint8(x) & 0xff;
            s[39 - 2 * i - 1] = _LOWER[b >> 4]; // higher index
            s[39 - 2 * i] = _LOWER[b & 0xf]; // lower index
            x >>= 8;
        }

        return s;
    }
}

File 7 of 9 : PacketDecoder.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.23;

library PacketDecoder {
    bytes8 private constant _FIXED_POINT_ENCODER_SELECTOR = 0xd3813e0ccba0ad5a; // keccak256("tunnel")[:4] + keccak256("FixedPointABI")[:4];
    bytes8 private constant _TICK_ENCODER_SELECTOR = 0xd3813e0cdb99b2b3; // keccak256("tunnel")[:4] + keccak256("TickABI")[:4];

    enum EncoderType {
        Undefined,
        FixedPoint,
        Tick
    }

    // info of signals being published in the packet.
    struct SignalPrice {
        bytes32 signal;
        uint64 price;
    }

    // the packet information generated from the tunnel.
    struct Packet {
        uint64 sequence;
        SignalPrice[] signals;
        int64 timestamp;
    }

    // the TSS message structure that is generated by the tunnel and is signed by the tss module.
    struct TssMessage {
        bytes32 originatorHash;
        uint64 sourceTimestamp;
        uint64 signingId;
        EncoderType encoderType;
        Packet packet;
    }

    /**
     * @dev Decode the TSS message from the encoded message.
     * @param message The encoded message.
     * @return TssMessage The decoded TSS message object.
     */
    function decodeTssMessage(bytes calldata message) internal pure returns (TssMessage memory) {
        EncoderType encoder = _toEncoderType(bytes8(message[48:56]));

        Packet memory packet = _decodePacket(message);

        TssMessage memory tssMessage = TssMessage(
            bytes32(message[0:32]), uint64(bytes8(message[32:40])), uint64(bytes8(message[40:48])), encoder, packet
        );

        return tssMessage;
    }

    /**
     * @dev Decode the TSS message from the encoded message.
     * @param message The encoded message.
     * @return TssMessage The decoded TSS message object.
     */
    function _decodePacket(bytes calldata message) internal pure returns (Packet memory) {
        Packet memory packet = abi.decode(message[56:], (Packet));
        return packet;
    }

    /**
     * @dev Convert the selector to the encoder type.
     * @param selector The selector to be converted.
     * @return EncoderType The encoder type.
     */
    function _toEncoderType(bytes8 selector) internal pure returns (EncoderType) {
        if (selector == _FIXED_POINT_ENCODER_SELECTOR) {
            return EncoderType.FixedPoint;
        } else if (selector == _TICK_ENCODER_SELECTOR) {
            return EncoderType.Tick;
        } else {
            return EncoderType.Undefined;
        }
    }
}

File 8 of 9 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 9 of 9 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/",
    "solidity-stringutils/=lib/openzeppelin-foundry-upgrades/lib/solidity-stringutils/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false,
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"tunnelRouter_","type":"address"},{"internalType":"address","name":"initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"UnauthorizedTunnelRouter","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"signalId","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"price","type":"uint64"},{"indexed":false,"internalType":"int64","name":"timestamp","type":"int64"}],"name":"SignalPriceUpdated","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"latestSeq","type":"uint64"}],"name":"activate","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"deactivate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"prices","outputs":[{"internalType":"uint64","name":"price","type":"uint64"},{"internalType":"int64","name":"timestamp","type":"int64"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"originatorHash","type":"bytes32"},{"internalType":"uint64","name":"sourceTimestamp","type":"uint64"},{"internalType":"uint64","name":"signingId","type":"uint64"},{"internalType":"enum PacketDecoder.EncoderType","name":"encoderType","type":"uint8"},{"components":[{"internalType":"uint64","name":"sequence","type":"uint64"},{"components":[{"internalType":"bytes32","name":"signal","type":"bytes32"},{"internalType":"uint64","name":"price","type":"uint64"}],"internalType":"struct PacketDecoder.SignalPrice[]","name":"signals","type":"tuple[]"},{"internalType":"int64","name":"timestamp","type":"int64"}],"internalType":"struct PacketDecoder.Packet","name":"packet","type":"tuple"}],"internalType":"struct PacketDecoder.TssMessage","name":"data","type":"tuple"}],"name":"process","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"tunnelId_","type":"uint64"}],"name":"setTunnelId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tunnelId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tunnelRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a060405234801561000f575f5ffd5b50604051610ed5380380610ed583398101604081905261002e916100fe565b806001600160a01b03811661005c57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61006581610078565b50506001600160a01b031660805261012f565b600180546001600160a01b031916905561009181610094565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146100f9575f5ffd5b919050565b5f5f6040838503121561010f575f5ffd5b610118836100e3565b9150610126602084016100e3565b90509250929050565b608051610d646101715f395f8181610195015281816103050152818161042e0152818161052b01528181610627015281816107d001526109540152610d645ff3fe6080604052600436106100e4575f3560e01c8063853828b611610087578063d0e30db011610057578063d0e30db0146102a3578063e30c3978146102ab578063f2fde38b146102c8578063fc7e4746146102e7575f5ffd5b8063853828b6146102165780638da5cb5b1461022a578063a79c8c0914610246578063bb5114f914610284575f5ffd5b80636a5d9b59116100c25780636a5d9b5914610184578063715018a6146101cf57806379ba5097146101e35780637b30d813146101f7575f5ffd5b80632e1a7d4d146100e857806351b42b001461010957806360846bc61461011d575b5f5ffd5b3480156100f3575f5ffd5b50610107610102366004610a1c565b6102fa565b005b348015610114575f5ffd5b506101076103fe565b348015610128575f5ffd5b5061015d610137366004610a1c565b60026020525f90815260409020546001600160401b03811690600160401b900460070b82565b604080516001600160401b03909316835260079190910b6020830152015b60405180910390f35b34801561018f575f5ffd5b506101b77f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161017b565b3480156101da575f5ffd5b5061010761048f565b3480156101ee575f5ffd5b506101076104a2565b348015610202575f5ffd5b50610107610211366004610a4e565b6104eb565b348015610221575f5ffd5b50610107610520565b348015610235575f5ffd5b505f546001600160a01b03166101b7565b348015610251575f5ffd5b5060015461026c90600160a01b90046001600160401b031681565b6040516001600160401b03909116815260200161017b565b34801561028f575f5ffd5b5061010761029e366004610b2f565b61061c565b6101076107cd565b3480156102b6575f5ffd5b506001546001600160a01b03166101b7565b3480156102d3575f5ffd5b506101076102e2366004610ce4565b6108ab565b6101076102f5366004610a4e565b61091b565b61030261098d565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103839190610cff565b60015460405163349b2b8f60e21b8152600160a01b9091046001600160401b03166004820152336024820152604481018490529091506001600160a01b0382169063d26cae3c906064015f604051808303815f87803b1580156103e4575f5ffd5b505af11580156103f6573d5f5f3e3d5ffd5b505050505050565b61040661098d565b6001546040516343ba231760e11b8152600160a01b9091046001600160401b031660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690638774462e906024015f604051808303815f87803b158015610477575f5ffd5b505af1158015610489573d5f5f3e3d5ffd5b50505050565b61049761098d565b6104a05f6109b9565b565b60015433906001600160a01b031681146104df5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b6104e8816109b9565b50565b6104f361098d565b600180546001600160401b03909216600160a01b0267ffffffffffffffff60a01b19909216919091179055565b61052861098d565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610585573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a99190610cff565b60015460405163fc7a1c2960e01b8152600160a01b9091046001600160401b031660048201523360248201529091506001600160a01b0382169063fc7a1c29906044015f604051808303815f87803b158015610603575f5ffd5b505af1158015610615573d5f5f3e3d5ffd5b5050505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461066557604051636e96d7e160e11b815260040160405180910390fd5b60808101515f5b8160200151518110156107c85760405180604001604052808360200151838151811061069a5761069a610d1a565b6020026020010151602001516001600160401b03168152602001836040015160070b81525060025f846020015184815181106106d8576106d8610d1a565b602090810291909101810151518252818101929092526040015f2082518154938301516001600160401b03908116600160401b026fffffffffffffffffffffffffffffffff199095169116179290921790915582015180518290811061074057610740610d1a565b60200260200101515f01517fa623627c34311a71b36da152b44076ede51861d701868671c9a6dfdd0f5da00a8360200151838151811061078257610782610d1a565b60200260200101516020015184604001516040516107b89291906001600160401b0392909216825260070b602082015260400190565b60405180910390a260010161066c565b505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561082a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061084e9190610cff565b60015460405163576bcd2f60e01b8152600160a01b9091046001600160401b031660048201523060248201529091506001600160a01b0382169063576bcd2f9034906044015b5f604051808303818588803b1580156103e4575f5ffd5b6108b361098d565b600180546001600160a01b0383166001600160a01b031990911681179091556108e35f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61092361098d565b60015460405163ba1b5f2360e01b8152600160a01b9091046001600160401b039081166004830152821660248201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ba1b5f23903490604401610894565b5f546001600160a01b031633146104a05760405163118cdaa760e01b81523360048201526024016104d6565b600180546001600160a01b03191690556104e8815f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f60208284031215610a2c575f5ffd5b5035919050565b80356001600160401b0381168114610a49575f5ffd5b919050565b5f60208284031215610a5e575f5ffd5b610a6782610a33565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b60405160a081016001600160401b0381118282101715610aa457610aa4610a6e565b60405290565b604051606081016001600160401b0381118282101715610aa457610aa4610a6e565b604080519081016001600160401b0381118282101715610aa457610aa4610a6e565b604051601f8201601f191681016001600160401b0381118282101715610b1657610b16610a6e565b604052919050565b8035600781900b8114610a49575f5ffd5b5f60208284031215610b3f575f5ffd5b81356001600160401b03811115610b54575f5ffd5b820160a08185031215610b65575f5ffd5b610b6d610a82565b81358152610b7d60208301610a33565b6020820152610b8e60408301610a33565b6040820152606082013560038110610ba4575f5ffd5b606082015260808201356001600160401b03811115610bc1575f5ffd5b919091019060608286031215610bd5575f5ffd5b610bdd610aaa565b610be683610a33565b815260208301356001600160401b03811115610c00575f5ffd5b8301601f81018713610c10575f5ffd5b80356001600160401b03811115610c2957610c29610a6e565b610c3860208260051b01610aee565b8082825260208201915060208360061b850101925089831115610c59575f5ffd5b6020840193505b82841015610ca9576040848b031215610c77575f5ffd5b610c7f610acc565b84358152610c8f60208601610a33565b602082015280835250602082019150604084019350610c60565b602085015250610cbe91505060408401610b1e565b60408201526080820152949350505050565b6001600160a01b03811681146104e8575f5ffd5b5f60208284031215610cf4575f5ffd5b8135610a6781610cd0565b5f60208284031215610d0f575f5ffd5b8151610a6781610cd0565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220b6998a540b07685692bb5d1229af2ed3a508254bd209daca63f4f5e5bbc3fd9164736f6c634300081b0033000000000000000000000000d82330754b620ab91a2979de39e854721fbf27aa00000000000000000000000086fda4ed3492d1f1da4ff52cf0c2352b64922fc3

Deployed Bytecode

0x6080604052600436106100e4575f3560e01c8063853828b611610087578063d0e30db011610057578063d0e30db0146102a3578063e30c3978146102ab578063f2fde38b146102c8578063fc7e4746146102e7575f5ffd5b8063853828b6146102165780638da5cb5b1461022a578063a79c8c0914610246578063bb5114f914610284575f5ffd5b80636a5d9b59116100c25780636a5d9b5914610184578063715018a6146101cf57806379ba5097146101e35780637b30d813146101f7575f5ffd5b80632e1a7d4d146100e857806351b42b001461010957806360846bc61461011d575b5f5ffd5b3480156100f3575f5ffd5b50610107610102366004610a1c565b6102fa565b005b348015610114575f5ffd5b506101076103fe565b348015610128575f5ffd5b5061015d610137366004610a1c565b60026020525f90815260409020546001600160401b03811690600160401b900460070b82565b604080516001600160401b03909316835260079190910b6020830152015b60405180910390f35b34801561018f575f5ffd5b506101b77f000000000000000000000000d82330754b620ab91a2979de39e854721fbf27aa81565b6040516001600160a01b03909116815260200161017b565b3480156101da575f5ffd5b5061010761048f565b3480156101ee575f5ffd5b506101076104a2565b348015610202575f5ffd5b50610107610211366004610a4e565b6104eb565b348015610221575f5ffd5b50610107610520565b348015610235575f5ffd5b505f546001600160a01b03166101b7565b348015610251575f5ffd5b5060015461026c90600160a01b90046001600160401b031681565b6040516001600160401b03909116815260200161017b565b34801561028f575f5ffd5b5061010761029e366004610b2f565b61061c565b6101076107cd565b3480156102b6575f5ffd5b506001546001600160a01b03166101b7565b3480156102d3575f5ffd5b506101076102e2366004610ce4565b6108ab565b6101076102f5366004610a4e565b61091b565b61030261098d565b5f7f000000000000000000000000d82330754b620ab91a2979de39e854721fbf27aa6001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035f573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103839190610cff565b60015460405163349b2b8f60e21b8152600160a01b9091046001600160401b03166004820152336024820152604481018490529091506001600160a01b0382169063d26cae3c906064015f604051808303815f87803b1580156103e4575f5ffd5b505af11580156103f6573d5f5f3e3d5ffd5b505050505050565b61040661098d565b6001546040516343ba231760e11b8152600160a01b9091046001600160401b031660048201527f000000000000000000000000d82330754b620ab91a2979de39e854721fbf27aa6001600160a01b031690638774462e906024015f604051808303815f87803b158015610477575f5ffd5b505af1158015610489573d5f5f3e3d5ffd5b50505050565b61049761098d565b6104a05f6109b9565b565b60015433906001600160a01b031681146104df5760405163118cdaa760e01b81526001600160a01b03821660048201526024015b60405180910390fd5b6104e8816109b9565b50565b6104f361098d565b600180546001600160401b03909216600160a01b0267ffffffffffffffff60a01b19909216919091179055565b61052861098d565b5f7f000000000000000000000000d82330754b620ab91a2979de39e854721fbf27aa6001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610585573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a99190610cff565b60015460405163fc7a1c2960e01b8152600160a01b9091046001600160401b031660048201523360248201529091506001600160a01b0382169063fc7a1c29906044015f604051808303815f87803b158015610603575f5ffd5b505af1158015610615573d5f5f3e3d5ffd5b5050505050565b336001600160a01b037f000000000000000000000000d82330754b620ab91a2979de39e854721fbf27aa161461066557604051636e96d7e160e11b815260040160405180910390fd5b60808101515f5b8160200151518110156107c85760405180604001604052808360200151838151811061069a5761069a610d1a565b6020026020010151602001516001600160401b03168152602001836040015160070b81525060025f846020015184815181106106d8576106d8610d1a565b602090810291909101810151518252818101929092526040015f2082518154938301516001600160401b03908116600160401b026fffffffffffffffffffffffffffffffff199095169116179290921790915582015180518290811061074057610740610d1a565b60200260200101515f01517fa623627c34311a71b36da152b44076ede51861d701868671c9a6dfdd0f5da00a8360200151838151811061078257610782610d1a565b60200260200101516020015184604001516040516107b89291906001600160401b0392909216825260070b602082015260400190565b60405180910390a260010161066c565b505050565b5f7f000000000000000000000000d82330754b620ab91a2979de39e854721fbf27aa6001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561082a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061084e9190610cff565b60015460405163576bcd2f60e01b8152600160a01b9091046001600160401b031660048201523060248201529091506001600160a01b0382169063576bcd2f9034906044015b5f604051808303818588803b1580156103e4575f5ffd5b6108b361098d565b600180546001600160a01b0383166001600160a01b031990911681179091556108e35f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b61092361098d565b60015460405163ba1b5f2360e01b8152600160a01b9091046001600160401b039081166004830152821660248201527f000000000000000000000000d82330754b620ab91a2979de39e854721fbf27aa6001600160a01b03169063ba1b5f23903490604401610894565b5f546001600160a01b031633146104a05760405163118cdaa760e01b81523360048201526024016104d6565b600180546001600160a01b03191690556104e8815f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f60208284031215610a2c575f5ffd5b5035919050565b80356001600160401b0381168114610a49575f5ffd5b919050565b5f60208284031215610a5e575f5ffd5b610a6782610a33565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b60405160a081016001600160401b0381118282101715610aa457610aa4610a6e565b60405290565b604051606081016001600160401b0381118282101715610aa457610aa4610a6e565b604080519081016001600160401b0381118282101715610aa457610aa4610a6e565b604051601f8201601f191681016001600160401b0381118282101715610b1657610b16610a6e565b604052919050565b8035600781900b8114610a49575f5ffd5b5f60208284031215610b3f575f5ffd5b81356001600160401b03811115610b54575f5ffd5b820160a08185031215610b65575f5ffd5b610b6d610a82565b81358152610b7d60208301610a33565b6020820152610b8e60408301610a33565b6040820152606082013560038110610ba4575f5ffd5b606082015260808201356001600160401b03811115610bc1575f5ffd5b919091019060608286031215610bd5575f5ffd5b610bdd610aaa565b610be683610a33565b815260208301356001600160401b03811115610c00575f5ffd5b8301601f81018713610c10575f5ffd5b80356001600160401b03811115610c2957610c29610a6e565b610c3860208260051b01610aee565b8082825260208201915060208360061b850101925089831115610c59575f5ffd5b6020840193505b82841015610ca9576040848b031215610c77575f5ffd5b610c7f610acc565b84358152610c8f60208601610a33565b602082015280835250602082019150604084019350610c60565b602085015250610cbe91505060408401610b1e565b60408201526080820152949350505050565b6001600160a01b03811681146104e8575f5ffd5b5f60208284031215610cf4575f5ffd5b8135610a6781610cd0565b5f60208284031215610d0f575f5ffd5b8151610a6781610cd0565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220b6998a540b07685692bb5d1229af2ed3a508254bd209daca63f4f5e5bbc3fd9164736f6c634300081b0033

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

000000000000000000000000d82330754b620ab91a2979de39e854721fbf27aa00000000000000000000000086fda4ed3492d1f1da4ff52cf0c2352b64922fc3

-----Decoded View---------------
Arg [0] : tunnelRouter_ (address): 0xd82330754B620AB91A2979dE39e854721fbf27aA
Arg [1] : initialOwner (address): 0x86FdA4Ed3492D1F1Da4Ff52Cf0c2352b64922fC3

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000d82330754b620ab91a2979de39e854721fbf27aa
Arg [1] : 00000000000000000000000086fda4ed3492d1f1da4ff52cf0c2352b64922fc3


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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