S Price: $0.551718 (-2.01%)

Contract

0xd9E3a8Ba9Be55919C5C0De6694e3103F5a35820E

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Nominate Owner24736672025-01-04 14:16:0559 days ago1736000165IN
0xd9E3a8Ba...F5a35820E
0 S0.000031661.155
Nominate Owner24733482025-01-04 14:12:5759 days ago1735999977IN
0xd9E3a8Ba...F5a35820E
0 S0.000054531.155

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SwitchboardSimulator

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion
File 1 of 9 : SwitchboardSimulator.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.19;

import "../../interfaces/ISignatureVerifier.sol";
import "../../interfaces/ISocket.sol";

import "../../utils/AccessControlExtended.sol";
import {WATCHER_ROLE} from "../../utils/AccessRoles.sol";

contract SwitchboardSimulator is AccessControlExtended {
    // dstChainSlug => totalWatchers registered
    mapping(uint32 => uint256) public totalWatchers;

    // used to track which watcher have attested a root
    // watcher => root => isAttested
    mapping(address => mapping(bytes32 => bool)) public isAttested;

    // used to detect when enough attestations are reached
    // root => attestationCount
    mapping(bytes32 => uint256) public attestations;

    // mapping to store if root is valid
    // marked when all watchers have attested for a root
    // root => isValid
    mapping(bytes32 => bool) public isRootValid;

    ISignatureVerifier public immutable signatureVerifier__;

    // socket contract
    ISocket public immutable socket__;

    // chain slug of deployed chain
    uint32 public immutable chainSlug;

    // timeout after which packets become valid
    // optimistic switchboard: this is the wait time to validate packet
    // fast switchboard: this makes packets valid even if all watchers have not attested
    //      used to make the system work when watchers are inactive due to infra etc problems
    // this is only applicable if none of the trips are triggered
    uint256 public immutable timeoutInSeconds;

    // variable to pause the switchboard completely, to be used only in case of smart contract bug
    // trip can be done by TRIP_ROLE holders
    // untrip can be done by UN_TRIP_ROLE holders
    bool public isGlobalTipped;

    // pause all proposals coming from given chain.
    // to be used if a transmitter has gone rogue and needs to be kicked to resume normal functioning
    // trip can be done by WATCHER_ROLE holders
    // untrip can be done by UN_TRIP_ROLE holders
    // sourceChain => isPaused
    mapping(uint32 => bool) public isPathTripped;

    // block execution of single proposal
    // to be used if transmitter proposes wrong packet root single time
    // trip can be done by WATCHER_ROLE holders
    // untrip not possible, but same root can be proposed again at next proposalCount
    // isProposalTripped(packetId => proposalCount => isTripped)
    mapping(bytes32 => mapping(uint256 => bool)) public isProposalTripped;
    mapping(uint32 => uint256) public initialPacketCount;

    // incrementing nonce for each signer
    // watcher => nextNonce
    mapping(address => uint256) public nextNonce;

    // Event emitted when a proposal is attested
    event ProposalAttested(
        bytes32 packetId,
        uint256 proposalCount,
        bytes32 root,
        address watcher,
        uint256 attestationsCount
    );

    // Error emitted when a watcher is not found while attesting or while revoking role
    error WatcherNotFound();

    // Error emitted when a root is already attested by a specific watcher.
    // This is hit even if they are attesting a new proposalCount with same root.
    error AlreadyAttested();

    // Error emitted while attesting if root is zero or it doesn't match the root on socket for given proposal
    // helps in cases where attest tx has been sent but root changes on socket due to reorgs.
    error InvalidRoot();

    /**
     * @dev Constructor function for the FastSwitchboard contract
     * @param owner_ Address of the owner of the contract
     * @param socket_ Address of the socket contract
     * @param chainSlug_ Chain slug of the chain where the contract is deployed
     * @param timeoutInSeconds_ Timeout in seconds after which proposals become valid if not tripped
     * @param signatureVerifier_ The address of the signature verifier contract
     */
    constructor(
        address owner_,
        address socket_,
        uint32 chainSlug_,
        uint256 timeoutInSeconds_,
        ISignatureVerifier signatureVerifier_
    ) AccessControlExtended(owner_) {
        signatureVerifier__ = signatureVerifier_;
        socket__ = ISocket(socket_);
        chainSlug = chainSlug_;
        timeoutInSeconds = timeoutInSeconds_;
    }

    /**
     * @dev Function to attest a packet
     * @param packetId_ Packet ID
     * @param proposalCount_ Proposal count
     * @param root_ Root of the packet
     * @param signature_ Signature of the watcher
     * @notice we are attesting a root uniquely identified with packetId and proposalCount. However,
     * there can be multiple proposals for same root. To avoid need to re-attest for different proposals
     *  with same root, we are storing attestations against root instead of packetId and proposalCount.
     */
    function attest(
        bytes32 packetId_,
        uint256 proposalCount_,
        bytes32 root_,
        bytes calldata signature_
    ) external onlyOwner {
        uint32 srcChainSlug = uint32(uint256(packetId_) >> 224);

        bytes32 root = socket__.packetIdRoots(
            packetId_,
            proposalCount_,
            address(this)
        );
        if (root_ == bytes32(0)) revert InvalidRoot();
        if (root_ == bytes32(0)) revert InvalidRoot();

        address watcher = signatureVerifier__.recoverSigner(
            keccak256(
                abi.encode(
                    address(this),
                    chainSlug,
                    packetId_,
                    proposalCount_,
                    root_
                )
            ),
            signature_
        );

        if (isAttested[watcher][root]) revert AlreadyAttested();
        if (_hasRoleWithSlug(WATCHER_ROLE, srcChainSlug, watcher))
            revert WatcherNotFound();

        isAttested[watcher][root] = true;
        ++attestations[root];

        if (attestations[root] >= totalWatchers[srcChainSlug])
            isRootValid[root] = true;

        emit ProposalAttested(
            packetId_,
            proposalCount_,
            root,
            watcher,
            attestations[root]
        );
    }

    function allowPacket(
        bytes32 root_,
        bytes32 packetId_,
        uint256 proposalCount_,
        uint32 srcChainSlug_,
        uint256 proposeTime_
    ) external view returns (bool) {
        uint64 packetCount = uint64(uint256(packetId_));

        // any relevant trips triggered or invalid packet count.
        if (
            isGlobalTipped ||
            isPathTripped[srcChainSlug_] ||
            isProposalTripped[packetId_][proposalCount_] ||
            packetCount < initialPacketCount[srcChainSlug_]
        ) return false;

        // root has enough attestations
        if (!isRootValid[root_]) return true;

        // this makes packets valid even if all watchers have not attested
        // used to make the system work when watchers are inactive due to infra etc problems
        if (block.timestamp - proposeTime_ < timeoutInSeconds) return true;

        // not enough attestations and timeout not hit
        return false;
    }
}

File 2 of 9 : IExecutionManager.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.19;

/**
 * @title Execution Manager Interface
 * @dev This interface defines the functions for managing and executing transactions on external chains
 * @dev It is also responsible for collecting all the socket fees, which can then be pulled by others
 */
interface IExecutionManager {
    struct ExecutionFeesParam {
        // for calculating perGasCost * gasLimit
        uint80 perGasCost;
        // for calculating cost for executing payload (needed for rollups)
        uint80 perByteCost;
        // additional cost (differs based on chain)
        uint80 overhead;
    }

    /**
     * @notice Returns the executor of the packed message and whether the executor is authorized
     * @param packedMessage The message packed with payload, fees and config
     * @param sig The signature of the message
     * @return The address of the executor and a boolean indicating if the executor is authorized
     */
    function isExecutor(
        bytes32 packedMessage,
        bytes memory sig
    ) external view returns (address, bool);

    /**
     * @notice Pays the fees for executing a transaction on the external chain
     * @dev This function is payable and assumes the socket is going to send correct amount of fees.
     * @param minMsgGasLimit_ The minimum gas limit for the transaction
     * @param payloadSize_ The payload size in bytes
     * @param executionParams_ Extra params for execution
     * @param transmissionParams_ Extra params for transmission
     * @param siblingChainSlug_ Sibling chain identifier
     * @param switchboardFees_ fee charged by switchboard for processing transaction
     * @param verificationOverheadFees_ fee charged for verifying transaction
     * @param transmitManager_ The transmitManager address
     * @param switchboard_ The switchboard address
     * @param maxPacketLength_ The maxPacketLength for the capacitor
     */
    function payAndCheckFees(
        uint256 minMsgGasLimit_,
        uint256 payloadSize_,
        bytes32 executionParams_,
        bytes32 transmissionParams_,
        uint32 siblingChainSlug_,
        uint128 switchboardFees_,
        uint128 verificationOverheadFees_,
        address transmitManager_,
        address switchboard_,
        uint256 maxPacketLength_
    ) external payable returns (uint128, uint128);

    /**
     * @notice Returns the minimum fees required for executing a transaction on the external chain
     * @param minMsgGasLimit_ minMsgGasLimit_
     * @param siblingChainSlug_ The destination slug
     * @return The minimum fees required for executing the transaction
     */
    function getMinFees(
        uint256 minMsgGasLimit_,
        uint256 payloadSize_,
        bytes32 executionParams_,
        uint32 siblingChainSlug_
    ) external view returns (uint128);

    /**
     * @notice function for getting the minimum fees required for executing and transmitting a cross-chain transaction
     * @dev this function is called at source to calculate the execution cost.
     * @param payloadSize_ byte length of payload. Currently only used to check max length, later on will be used for fees calculation.
     * @param executionParams_ Can be used for providing extra information. Currently used for msgValue
     * @param siblingChainSlug_ Sibling chain identifier
     * @return minExecutionFee : Minimum fees required for executing the transaction
     */
    function getExecutionTransmissionMinFees(
        uint256 minMsgGasLimit_,
        uint256 payloadSize_,
        bytes32 executionParams_,
        bytes32 transmissionParams_,
        uint32 siblingChainSlug_,
        address transmitManager_
    ) external view returns (uint128, uint128);

    /**
     * @notice Updates the execution fees for an executor and message ID
     * @param executor The executor address
     * @param executionFees The execution fees to update
     * @param msgId The ID of the message
     */
    function updateExecutionFees(
        address executor,
        uint128 executionFees,
        bytes32 msgId
    ) external;

    /**
     * @notice updates the transmission fee
     * @param remoteChainSlug_ sibling chain identifier
     * @param transmitMinFees_ transmission fees collected
     */
    function setTransmissionMinFees(
        uint32 remoteChainSlug_,
        uint128 transmitMinFees_
    ) external;

    /**
     * @notice sets the minimum execution fees required for executing at `siblingChainSlug_`
     * @dev this function currently sets the price for a constant msg gas limit and payload size
     * @param nonce_ incremental id to prevent signature replay
     * @param siblingChainSlug_ sibling chain identifier
     * @param executionFees_ total fees where price in destination native token is converted to source native tokens
     * @param signature_ signature of fee updater
     */
    function setExecutionFees(
        uint256 nonce_,
        uint32 siblingChainSlug_,
        ExecutionFeesParam calldata executionFees_,
        bytes calldata signature_
    ) external;

    /**
     * @notice sets the min limit for msg value for `siblingChainSlug_`
     * @param nonce_ incremental id to prevent signature replay
     * @param siblingChainSlug_ sibling chain identifier
     * @param msgValueMinThreshold_ min msg value
     * @param signature_ signature of fee updater
     */
    function setMsgValueMinThreshold(
        uint256 nonce_,
        uint32 siblingChainSlug_,
        uint256 msgValueMinThreshold_,
        bytes calldata signature_
    ) external;

    /**
     * @notice sets the max limit for msg value for `siblingChainSlug_`
     * @param nonce_ incremental id to prevent signature replay
     * @param siblingChainSlug_ sibling chain identifier
     * @param msgValueMaxThreshold_ max msg value
     * @param signature_ signature of fee updater
     */
    function setMsgValueMaxThreshold(
        uint256 nonce_,
        uint32 siblingChainSlug_,
        uint256 msgValueMaxThreshold_,
        bytes calldata signature_
    ) external;

    /**
     * @notice sets the relative token price for `siblingChainSlug_`
     * @dev this function is expected to be called frequently to match the original prices
     * @param nonce_ incremental id to prevent signature replay
     * @param siblingChainSlug_ sibling chain identifier
     * @param relativeNativeTokenPrice_ relative price
     * @param signature_ signature of fee updater
     */
    function setRelativeNativeTokenPrice(
        uint256 nonce_,
        uint32 siblingChainSlug_,
        uint256 relativeNativeTokenPrice_,
        bytes calldata signature_
    ) external;

    /**
     * @notice called by socket while executing message to validate if the msg value provided is enough
     * @param executionParams_ a bytes32 string where first byte gives param type (if value is 0 or not)
     * and remaining bytes give the msg value needed
     * @param msgValue_ msg.value to be sent with inbound
     */
    function verifyParams(
        bytes32 executionParams_,
        uint256 msgValue_
    ) external view;

    /**
     * @notice withdraws switchboard fees from contract
     * @param siblingChainSlug_ withdraw fees corresponding to this slug
     * @param amount_ withdraw amount
     */
    function withdrawSwitchboardFees(
        uint32 siblingChainSlug_,
        address switchboard_,
        uint128 amount_
    ) external;

    /**
     * @dev this function gets the transmitManager address from the socket contract. If it is ever upgraded in socket,
     * @dev remove the fees from executionManager first, and then upgrade address at socket.
     * @notice withdraws transmission fees from contract
     * @param siblingChainSlug_ withdraw fees corresponding to this slug
     * @param amount_ withdraw amount
     */
    function withdrawTransmissionFees(
        uint32 siblingChainSlug_,
        uint128 amount_
    ) external;
}

File 3 of 9 : ISignatureVerifier.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.19;

/**
 * @title Signature Verifier
 * @notice Verifies the signatures and returns the address of signer recovered from the input signature or digest.
 */
interface ISignatureVerifier {
    /**
     * @notice returns the address of signer recovered from input signature and digest
     */
    function recoverSigner(
        bytes32 digest_,
        bytes memory signature_
    ) external pure returns (address signer);
}

File 4 of 9 : ISocket.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.19;

import "./ITransmitManager.sol";
import "./IExecutionManager.sol";

/**
 * @title ISocket
 * @notice An interface for a cross-chain communication contract
 * @dev This interface provides methods for transmitting and executing messages between chains,
 * connecting a plug to a remote chain and setting up switchboards for the message transmission
 * This interface also emits events for important operations such as message transmission, execution status,
 * and plug connection
 */
interface ISocket {
    /**
     * @notice A struct containing fees required for message transmission and execution
     * @param transmissionFees fees needed for transmission
     * @param switchboardFees fees needed by switchboard
     * @param executionFee fees needed for execution
     */
    struct Fees {
        uint128 transmissionFees;
        uint128 executionFee;
        uint128 switchboardFees;
    }

    /**
     * @title MessageDetails
     * @dev This struct defines the details of a message to be executed in a Decapacitor contract.
     */
    struct MessageDetails {
        // A unique identifier for the message.
        bytes32 msgId;
        // The fee to be paid for executing the message.
        uint256 executionFee;
        // The min amount of gas that can be used to execute the message.
        uint256 minMsgGasLimit;
        // The extra params which might provide msg value and additional info needed for message exec
        bytes32 executionParams;
        // The payload data to be executed in the message.
        bytes payload;
    }

    /**
     * @title ExecutionDetails
     * @dev This struct defines the execution details
     */
    struct ExecutionDetails {
        // packet id
        bytes32 packetId;
        // proposal count
        uint256 proposalCount;
        // gas limit needed to execute inbound
        uint256 executionGasLimit;
        // proof data required by the Decapacitor contract to verify the message's authenticity
        bytes decapacitorProof;
        // signature of executor
        bytes signature;
    }

    /**
     * @notice emits the status of message after inbound call
     * @param msgId msg id which is executed
     */
    event ExecutionSuccess(bytes32 msgId);

    /**
     * @notice emits the config set by a plug for a remoteChainSlug
     * @param plug address of plug on current chain
     * @param siblingChainSlug sibling chain slug
     * @param siblingPlug address of plug on sibling chain
     * @param inboundSwitchboard inbound switchboard (select from registered options)
     * @param outboundSwitchboard outbound switchboard (select from registered options)
     * @param capacitor capacitor selected based on outbound switchboard
     * @param decapacitor decapacitor selected based on inbound switchboard
     */
    event PlugConnected(
        address plug,
        uint32 siblingChainSlug,
        address siblingPlug,
        address inboundSwitchboard,
        address outboundSwitchboard,
        address capacitor,
        address decapacitor
    );

    /**
     * @notice registers a message
     * @dev Packs the message and includes it in a packet with capacitor
     * @param remoteChainSlug_ the remote chain slug
     * @param minMsgGasLimit_ the gas limit needed to execute the payload on remote
     * @param payload_ the data which is needed by plug at inbound call on remote
     */
    function outbound(
        uint32 remoteChainSlug_,
        uint256 minMsgGasLimit_,
        bytes32 executionParams_,
        bytes32 transmissionParams_,
        bytes calldata payload_
    ) external payable returns (bytes32 msgId);

    /**
     * @notice executes a message
     * @param executionDetails_ the packet details, proof and signature needed for message execution
     * @param messageDetails_ the message details
     */
    function execute(
        ISocket.ExecutionDetails calldata executionDetails_,
        ISocket.MessageDetails calldata messageDetails_
    ) external payable;

    /**
     * @notice seals data in capacitor for specific batchSize
     * @param batchSize_ size of batch to be sealed
     * @param capacitorAddress_ address of capacitor
     * @param signature_ signed Data needed for verification
     */
    function seal(
        uint256 batchSize_,
        address capacitorAddress_,
        bytes calldata signature_
    ) external payable;

    /**
     * @notice proposes a packet
     * @param packetId_ packet id
     * @param root_ root data
     * @param switchboard_ The address of switchboard for which this packet is proposed
     * @param signature_ signed Data needed for verification
     */
    function proposeForSwitchboard(
        bytes32 packetId_,
        bytes32 root_,
        address switchboard_,
        bytes calldata signature_
    ) external payable;

    /**
     * @notice sets the config specific to the plug
     * @param siblingChainSlug_ the sibling chain slug
     * @param siblingPlug_ address of plug present at sibling chain to call inbound
     * @param inboundSwitchboard_ the address of switchboard to use for receiving messages
     * @param outboundSwitchboard_ the address of switchboard to use for sending messages
     */
    function connect(
        uint32 siblingChainSlug_,
        address siblingPlug_,
        address inboundSwitchboard_,
        address outboundSwitchboard_
    ) external;

    /**
     * @notice deploy capacitor and decapacitor for a switchboard with a specified max packet length, sibling chain slug, and capacitor type.
     * @param siblingChainSlug_ The slug of the sibling chain that the switchboard is registered with.
     * @param maxPacketLength_ The maximum length of a packet allowed by the switchboard.
     * @param capacitorType_ The type of capacitor that the switchboard uses.
     * @param siblingSwitchboard_ The switchboard address deployed on `siblingChainSlug_`
     */
    function registerSwitchboardForSibling(
        uint32 siblingChainSlug_,
        uint256 maxPacketLength_,
        uint256 capacitorType_,
        address siblingSwitchboard_
    ) external returns (address capacitor, address decapacitor);

    /**
     * @notice Emits the sibling switchboard for given `siblingChainSlug_`.
     * @dev This function is expected to be only called by switchboard.
     * @dev the event emitted is tracked by transmitters to decide which switchboard a packet should be proposed on
     * @param siblingChainSlug_ The slug of the sibling chain
     * @param siblingSwitchboard_ The switchboard address deployed on `siblingChainSlug_`
     */
    function useSiblingSwitchboard(
        uint32 siblingChainSlug_,
        address siblingSwitchboard_
    ) external;

    /**
     * @notice Retrieves the packet id roots for a specified packet id.
     * @param packetId_ The packet id for which to retrieve the root.
     * @param proposalCount_ The proposal id for packetId_ for which to retrieve the root.
     * @param switchboard_ The address of switchboard for which this packet is proposed
     * @return The packet id roots for the specified packet id.
     */
    function packetIdRoots(
        bytes32 packetId_,
        uint256 proposalCount_,
        address switchboard_
    ) external view returns (bytes32);

    /**
     * @notice Retrieves the latest proposalCount for a packet id.
     * @return The proposal count for the specified packet id.
     */
    function proposalCount(bytes32 packetId_) external view returns (uint256);

    /**
     * @notice Retrieves the minimum fees required for a message with a specified gas limit and destination chain.
     * @param minMsgGasLimit_ The gas limit of the message.
     * @param remoteChainSlug_ The slug of the destination chain for the message.
     * @param plug_ The address of the plug through which the message is sent.
     * @return totalFees The minimum fees required for the specified message.
     */
    function getMinFees(
        uint256 minMsgGasLimit_,
        uint256 payloadSize_,
        bytes32 executionParams_,
        bytes32 transmissionParams_,
        uint32 remoteChainSlug_,
        address plug_
    ) external view returns (uint256 totalFees);

    /// return instance of transmit manager
    function transmitManager__() external view returns (ITransmitManager);

    /// return instance of execution manager
    function executionManager__() external view returns (IExecutionManager);
}

File 5 of 9 : ITransmitManager.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.19;

/**
 * @title ITransmitManager
 * @dev The interface for a transmit manager contract
 */
interface ITransmitManager {
    /**
     * @notice Checks if a given transmitter is authorized to send transactions to the destination chain.
     * @param siblingSlug The unique identifier for the sibling chain.
     * @param digest The digest of the message being signed.
     * @param signature The signature of the message being signed.
     * @return The address of the transmitter and a boolean indicating whether the transmitter is authorized or not.
     */
    function checkTransmitter(
        uint32 siblingSlug,
        bytes32 digest,
        bytes calldata signature
    ) external view returns (address, bool);

    /**
     * @notice sets the transmission fee needed to transmit message to given `siblingSlug_`
     * @dev recovered address should add have feeUpdater role for `siblingSlug_`
     * @param nonce_ The incremental nonce to prevent signature replay
     * @param siblingSlug_ sibling id for which fee updater is registered
     * @param transmissionFees_ digest which is signed by transmitter
     * @param signature_ signature
     */
    function setTransmissionFees(
        uint256 nonce_,
        uint32 siblingSlug_,
        uint128 transmissionFees_,
        bytes calldata signature_
    ) external;

    /**
     * @notice receives fees from Execution manager
     * @dev this function can be used to keep track of fees received for each slug
     * @param siblingSlug_ sibling id for which fee updater is registered
     */
    function receiveFees(uint32 siblingSlug_) external payable;
}

File 6 of 9 : AccessControl.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.19;

import "./Ownable.sol";

/**
 * @title AccessControl
 * @dev This abstract contract implements access control mechanism based on roles.
 * Each role can have one or more addresses associated with it, which are granted
 * permission to execute functions with the onlyRole modifier.
 */
abstract contract AccessControl is Ownable {
    /**
     * @dev A mapping of roles to a mapping of addresses to boolean values indicating whether or not they have the role.
     */
    mapping(bytes32 => mapping(address => bool)) private _permits;

    /**
     * @dev Emitted when a role is granted to an address.
     */
    event RoleGranted(bytes32 indexed role, address indexed grantee);

    /**
     * @dev Emitted when a role is revoked from an address.
     */
    event RoleRevoked(bytes32 indexed role, address indexed revokee);

    /**
     * @dev Error message thrown when an address does not have permission to execute a function with onlyRole modifier.
     */
    error NoPermit(bytes32 role);

    /**
     * @dev Constructor that sets the owner of the contract.
     */
    constructor(address owner_) Ownable(owner_) {}

    /**
     * @dev Modifier that restricts access to addresses having roles
     * Throws an error if the caller do not have permit
     */
    modifier onlyRole(bytes32 role) {
        if (!_permits[role][msg.sender]) revert NoPermit(role);
        _;
    }

    /**
     * @dev Checks and reverts if an address do not have a specific role.
     * @param role_ The role to check.
     * @param address_ The address to check.
     */
    function _checkRole(bytes32 role_, address address_) internal virtual {
        if (!_hasRole(role_, address_)) revert NoPermit(role_);
    }

    /**
     * @dev Grants a role to a given address.
     * @param role_ The role to grant.
     * @param grantee_ The address to grant the role to.
     * Emits a RoleGranted event.
     * Can only be called by the owner of the contract.
     */
    function grantRole(
        bytes32 role_,
        address grantee_
    ) external virtual onlyOwner {
        _grantRole(role_, grantee_);
    }

    /**
     * @dev Revokes a role from a given address.
     * @param role_ The role to revoke.
     * @param revokee_ The address to revoke the role from.
     * Emits a RoleRevoked event.
     * Can only be called by the owner of the contract.
     */
    function revokeRole(
        bytes32 role_,
        address revokee_
    ) external virtual onlyOwner {
        _revokeRole(role_, revokee_);
    }

    /**
     * @dev Internal function to grant a role to a given address.
     * @param role_ The role to grant.
     * @param grantee_ The address to grant the role to.
     * Emits a RoleGranted event.
     */
    function _grantRole(bytes32 role_, address grantee_) internal {
        _permits[role_][grantee_] = true;
        emit RoleGranted(role_, grantee_);
    }

    /**
     * @dev Internal function to revoke a role from a given address.
     * @param role_ The role to revoke.
     * @param revokee_ The address to revoke the role from.
     * Emits a RoleRevoked event.
     */
    function _revokeRole(bytes32 role_, address revokee_) internal {
        _permits[role_][revokee_] = false;
        emit RoleRevoked(role_, revokee_);
    }

    /**
     * @dev Checks whether an address has a specific role.
     * @param role_ The role to check.
     * @param address_ The address to check.
     * @return A boolean value indicating whether or not the address has the role.
     */
    function hasRole(
        bytes32 role_,
        address address_
    ) external view returns (bool) {
        return _hasRole(role_, address_);
    }

    function _hasRole(
        bytes32 role_,
        address address_
    ) internal view returns (bool) {
        return _permits[role_][address_];
    }
}

File 7 of 9 : AccessControlExtended.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.19;

import "./AccessControl.sol";

/**
 * @title AccessControlExtended
 * @dev This contract extends the functionality of the AccessControl contract by adding
 * the ability to grant and revoke roles based on a combination of role name and a chain slug.
 * It also provides batch operations for granting and revoking roles.
 */
contract AccessControlExtended is AccessControl {
    /**
     * @dev Constructor that sets the owner of the contract.
     */
    constructor(address owner_) AccessControl(owner_) {}

    /**
     * @dev thrown when array lengths are not equal
     */
    error UnequalArrayLengths();

    /**
     * @dev Checks if an address has the role.
     * @param roleName_ The name of the role.
     * @param chainSlug_ The chain slug associated with the role.
     * @param address_ The address to be granted the role.
     */
    function _checkRoleWithSlug(
        bytes32 roleName_,
        uint256 chainSlug_,
        address address_
    ) internal virtual {
        bytes32 roleHash = keccak256(abi.encode(roleName_, chainSlug_));
        if (!_hasRole(roleHash, address_)) revert NoPermit(roleHash);
    }

    /**
     * @dev Grants a role to an address based on the role name and chain slug.
     * @param roleName_ The name of the role.
     * @param chainSlug_ The chain slug associated with the role.
     * @param grantee_ The address to be granted the role.
     */
    function grantRoleWithSlug(
        bytes32 roleName_,
        uint32 chainSlug_,
        address grantee_
    ) external virtual onlyOwner {
        _grantRoleWithSlug(roleName_, chainSlug_, grantee_);
    }

    /**
     * @dev Grants multiple roles to multiple addresses in batch.
     * @param roleNames_ The names of the roles to grant.
     * @param slugs_ The slugs for chain specific roles. For roles which are not chain-specific, we can use slug = 0
     * @param grantees_ The addresses to be granted the roles.
     */
    function grantBatchRole(
        bytes32[] calldata roleNames_,
        uint32[] calldata slugs_,
        address[] calldata grantees_
    ) external virtual onlyOwner {
        if (
            roleNames_.length != grantees_.length ||
            roleNames_.length != slugs_.length
        ) revert UnequalArrayLengths();
        uint256 totalRoles = roleNames_.length;
        for (uint256 index = 0; index < totalRoles; ) {
            if (slugs_[index] > 0)
                _grantRoleWithSlug(
                    roleNames_[index],
                    slugs_[index],
                    grantees_[index]
                );
            else _grantRole(roleNames_[index], grantees_[index]);

            // inputs are controlled by owner
            unchecked {
                ++index;
            }
        }
    }

    /**
     * @dev Revokes multiple roles from multiple addresses in batch.
     * @param roleNames_ The names of the roles to revoke.
     * @param slugs_ The slugs for chain specific roles. For roles which are not chain-specific, we can use slug = 0
     * @param grantees_ The addresses to be revoked the roles.
     */
    function revokeBatchRole(
        bytes32[] calldata roleNames_,
        uint32[] calldata slugs_,
        address[] calldata grantees_
    ) external virtual onlyOwner {
        if (
            roleNames_.length != grantees_.length ||
            roleNames_.length != slugs_.length
        ) revert UnequalArrayLengths();
        uint256 totalRoles = roleNames_.length;
        for (uint256 index = 0; index < totalRoles; ) {
            if (slugs_[index] > 0)
                _revokeRoleWithSlug(
                    roleNames_[index],
                    slugs_[index],
                    grantees_[index]
                );
            else _revokeRole(roleNames_[index], grantees_[index]);

            // inputs are controlled by owner
            unchecked {
                ++index;
            }
        }
    }

    function _grantRoleWithSlug(
        bytes32 roleName_,
        uint32 chainSlug_,
        address grantee_
    ) internal {
        _grantRole(keccak256(abi.encode(roleName_, chainSlug_)), grantee_);
    }

    /**
     * @dev Checks if an address has a role based on the role name and chain slug.
     * @param roleName_ The name of the role.
     * @param chainSlug_ The chain slug associated with the role.
     * @param address_ The address to check for the role.
     * @return A boolean indicating whether the address has the specified role.
     */
    function hasRoleWithSlug(
        bytes32 roleName_,
        uint32 chainSlug_,
        address address_
    ) external view returns (bool) {
        return _hasRoleWithSlug(roleName_, chainSlug_, address_);
    }

    function _hasRoleWithSlug(
        bytes32 roleName_,
        uint32 chainSlug_,
        address address_
    ) internal view returns (bool) {
        return _hasRole(keccak256(abi.encode(roleName_, chainSlug_)), address_);
    }

    /**
     * @dev Revokes roles from an address
     * @param roleName_ The names of the roles to revoke.
     * @param chainSlug_ The chain slug associated with the role.
     * @param grantee_ The addresses to be revoked the roles.
     */
    function revokeRoleWithSlug(
        bytes32 roleName_,
        uint32 chainSlug_,
        address grantee_
    ) external virtual onlyOwner {
        _revokeRoleWithSlug(roleName_, chainSlug_, grantee_);
    }

    function _revokeRoleWithSlug(
        bytes32 roleName_,
        uint32 chainSlug_,
        address revokee_
    ) internal {
        _revokeRole(keccak256(abi.encode(roleName_, chainSlug_)), revokee_);
    }
}

File 8 of 9 : AccessRoles.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.19;

// contains role hashes used in socket dl for various different operations

// used to rescue funds
bytes32 constant RESCUE_ROLE = keccak256("RESCUE_ROLE");
// used to withdraw fees
bytes32 constant WITHDRAW_ROLE = keccak256("WITHDRAW_ROLE");
// used to trip switchboards
bytes32 constant TRIP_ROLE = keccak256("TRIP_ROLE");
// used to un trip switchboards
bytes32 constant UN_TRIP_ROLE = keccak256("UN_TRIP_ROLE");
// used by governance
bytes32 constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE");
//used by executors which executes message at destination
bytes32 constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
// used by transmitters who seal and propose packets in socket
bytes32 constant TRANSMITTER_ROLE = keccak256("TRANSMITTER_ROLE");
// used by switchboard watchers who work against transmitters
bytes32 constant WATCHER_ROLE = keccak256("WATCHER_ROLE");
// used by fee updaters responsible for updating fees at switchboards, transmit manager and execution manager
bytes32 constant FEES_UPDATER_ROLE = keccak256("FEES_UPDATER_ROLE");

File 9 of 9 : Ownable.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.19;

/**
 * @title Ownable
 * @dev The Ownable contract provides a simple way to manage ownership of a contract
 * and allows for ownership to be transferred to a nominated address.
 */
abstract contract Ownable {
    address private _owner;
    address private _nominee;

    event OwnerNominated(address indexed nominee);
    event OwnerClaimed(address indexed claimer);

    error OnlyOwner();
    error OnlyNominee();

    /**
     * @dev Sets the contract's owner to the address that is passed to the constructor.
     */
    constructor(address owner_) {
        _claimOwner(owner_);
    }

    /**
     * @dev Modifier that restricts access to only the contract's owner.
     * Throws an error if the caller is not the owner.
     */
    modifier onlyOwner() {
        if (msg.sender != _owner) revert OnlyOwner();
        _;
    }

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

    /**
     * @dev Returns the current nominee for ownership of the contract.
     */
    function nominee() external view returns (address) {
        return _nominee;
    }

    /**
     * @dev Allows the current owner to nominate a new owner for the contract.
     * Throws an error if the caller is not the owner.
     * Emits an `OwnerNominated` event with the address of the nominee.
     */
    function nominateOwner(address nominee_) external {
        if (msg.sender != _owner) revert OnlyOwner();
        _nominee = nominee_;
        emit OwnerNominated(_nominee);
    }

    /**
     * @dev Allows the nominated owner to claim ownership of the contract.
     * Throws an error if the caller is not the nominee.
     * Sets the nominated owner as the new owner of the contract.
     * Emits an `OwnerClaimed` event with the address of the new owner.
     */
    function claimOwner() external {
        if (msg.sender != _nominee) revert OnlyNominee();
        _claimOwner(msg.sender);
    }

    /**
     * @dev Internal function that sets the owner of the contract to the specified address
     * and sets the nominee to address(0).
     */
    function _claimOwner(address claimer_) internal {
        _owner = claimer_;
        _nominee = address(0);
        emit OwnerClaimed(claimer_);
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 999999
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"socket_","type":"address"},{"internalType":"uint32","name":"chainSlug_","type":"uint32"},{"internalType":"uint256","name":"timeoutInSeconds_","type":"uint256"},{"internalType":"contract ISignatureVerifier","name":"signatureVerifier_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyAttested","type":"error"},{"inputs":[],"name":"InvalidRoot","type":"error"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"NoPermit","type":"error"},{"inputs":[],"name":"OnlyNominee","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"UnequalArrayLengths","type":"error"},{"inputs":[],"name":"WatcherNotFound","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"}],"name":"OwnerClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nominee","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"packetId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"proposalCount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"root","type":"bytes32"},{"indexed":false,"internalType":"address","name":"watcher","type":"address"},{"indexed":false,"internalType":"uint256","name":"attestationsCount","type":"uint256"}],"name":"ProposalAttested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"grantee","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"revokee","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[{"internalType":"bytes32","name":"root_","type":"bytes32"},{"internalType":"bytes32","name":"packetId_","type":"bytes32"},{"internalType":"uint256","name":"proposalCount_","type":"uint256"},{"internalType":"uint32","name":"srcChainSlug_","type":"uint32"},{"internalType":"uint256","name":"proposeTime_","type":"uint256"}],"name":"allowPacket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"packetId_","type":"bytes32"},{"internalType":"uint256","name":"proposalCount_","type":"uint256"},{"internalType":"bytes32","name":"root_","type":"bytes32"},{"internalType":"bytes","name":"signature_","type":"bytes"}],"name":"attest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"attestations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chainSlug","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"roleNames_","type":"bytes32[]"},{"internalType":"uint32[]","name":"slugs_","type":"uint32[]"},{"internalType":"address[]","name":"grantees_","type":"address[]"}],"name":"grantBatchRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"grantee_","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"roleName_","type":"bytes32"},{"internalType":"uint32","name":"chainSlug_","type":"uint32"},{"internalType":"address","name":"grantee_","type":"address"}],"name":"grantRoleWithSlug","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"address_","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"roleName_","type":"bytes32"},{"internalType":"uint32","name":"chainSlug_","type":"uint32"},{"internalType":"address","name":"address_","type":"address"}],"name":"hasRoleWithSlug","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"initialPacketCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"isAttested","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isGlobalTipped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"isPathTripped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"isProposalTripped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"isRootValid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nextNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nominee_","type":"address"}],"name":"nominateOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"roleNames_","type":"bytes32[]"},{"internalType":"uint32[]","name":"slugs_","type":"uint32[]"},{"internalType":"address[]","name":"grantees_","type":"address[]"}],"name":"revokeBatchRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"revokee_","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"roleName_","type":"bytes32"},{"internalType":"uint32","name":"chainSlug_","type":"uint32"},{"internalType":"address","name":"grantee_","type":"address"}],"name":"revokeRoleWithSlug","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signatureVerifier__","outputs":[{"internalType":"contract ISignatureVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"socket__","outputs":[{"internalType":"contract ISocket","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timeoutInSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"totalWatchers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

6101006040523480156200001257600080fd5b506040516200197e3803806200197e8339810160408190526200003591620000da565b84808062000043816200006e565b5050506001600160a01b039081166080529290921660a05263ffffffff1660c05260e0525062000156565b600080546001600160a01b0383166001600160a01b0319918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b6001600160a01b0381168114620000d757600080fd5b50565b600080600080600060a08688031215620000f357600080fd5b85516200010081620000c1565b60208701519095506200011381620000c1565b604087015190945063ffffffff811681146200012e57600080fd5b6060870151608088015191945092506200014881620000c1565b809150509295509295909350565b60805160a05160c05160e0516117d2620001ac600039600081816104b70152610a5c0152600081816103c40152610d370152600081816104230152610c3701526000818161047d0152610db601526117d26000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80638da5cb5b116100f9578063c877930811610097578063d5b8da7311610071578063d5b8da7314610478578063ecb974841461049f578063efec6cd4146104b2578063f37f3e37146104d957600080fd5b8063c877930814610445578063d2883fbe14610452578063d547741f1461046557600080fd5b8063aac96557116100d3578063aac9655714610391578063b349ba65146103bf578063b947aac6146103fb578063c6a261d21461041e57600080fd5b80638da5cb5b1461034057806391d148541461035e578063940992a31461037157600080fd5b806330ef41b41161016657806343fa97ca1161014057806343fa97ca146102e75780634c408180146102fa5780635b94db271461030d5780637c1388141461032057600080fd5b806330ef41b41461027e57806331d1e063146102b15780633bd1adec146102df57600080fd5b806320f99c0a1161019757806320f99c0a146102195780632e7eb258146102585780632f2ff15d1461026b57600080fd5b80630cd55abf146101be5780631ba8e484146101f15780631e86731114610206575b600080fd5b6101de6101cc366004611380565b600b6020526000908152604090205481565b6040519081526020015b60405180910390f35b6102046101ff3660046113bd565b6104f9565b005b610204610214366004611449565b61055a565b60015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e8565b6102046102663660046113bd565b610700565b6102046102793660046114e3565b61075c565b6102a161028c366004611513565b60066020526000908152604090205460ff1681565b60405190151581526020016101e8565b6102a16102bf36600461152c565b600460209081526000928352604080842090915290825290205460ff1681565b6102046107bb565b6102046102f5366004611449565b610817565b6102a1610308366004611558565b6109b3565b61020461031b366004611380565b610aa4565b6101de61032e36600461159f565b600a6020526000908152604090205481565b60005473ffffffffffffffffffffffffffffffffffffffff16610233565b6102a161036c3660046114e3565b610b64565b6101de61037f366004611513565b60056020526000908152604090205481565b6102a161039f3660046115ba565b600960209081526000928352604080842090915290825290205460ff1681565b6103e67f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101e8565b6102a161040936600461159f565b60086020526000908152604090205460ff1681565b6102337f000000000000000000000000000000000000000000000000000000000000000081565b6007546102a19060ff1681565b6102046104603660046115dc565b610ba1565b6102046104733660046114e3565b611062565b6102337f000000000000000000000000000000000000000000000000000000000000000081565b6102a16104ad3660046113bd565b6110bd565b6101de7f000000000000000000000000000000000000000000000000000000000000000081565b6101de6104e736600461159f565b60036020526000908152604090205481565b60005473ffffffffffffffffffffffffffffffffffffffff16331461054a576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105558383836110d2565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ab576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84811415806105ba5750848314155b156105f1576040517f11e86f7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460005b818110156106f657600086868381811061061157610611611669565b9050602002016020810190610626919061159f565b63ffffffff1611156106a6576106a188888381811061064757610647611669565b9050602002013587878481811061066057610660611669565b9050602002016020810190610675919061159f565b86868581811061068757610687611669565b905060200201602081019061069c9190611380565b6110d2565b6106ee565b6106ee8888838181106106bb576106bb611669565b905060200201358585848181106106d4576106d4611669565b90506020020160208101906106e99190611380565b61110f565b6001016105f5565b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610751576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610555838383611192565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107ad576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107b782826111cf565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461080c576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61081533611255565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610868576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84811415806108775750848314155b156108ae576040517f11e86f7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460005b818110156106f65760008686838181106108ce576108ce611669565b90506020020160208101906108e3919061159f565b63ffffffff1611156109635761095e88888381811061090457610904611669565b9050602002013587878481811061091d5761091d611669565b9050602002016020810190610932919061159f565b86868581811061094457610944611669565b90506020020160208101906109599190611380565b611192565b6109ab565b6109ab88888381811061097857610978611669565b9050602002013585858481811061099157610991611669565b90506020020160208101906109a69190611380565b6111cf565b6001016108b2565b600754600090859060ff16806109de575063ffffffff841660009081526008602052604090205460ff165b80610a025750600086815260096020908152604080832088845290915290205460ff165b80610a2b575063ffffffff84166000908152600a602052604090205467ffffffffffffffff8216105b15610a3a576000915050610a9b565b60008781526006602052604090205460ff16610a5a576001915050610a9b565b7f0000000000000000000000000000000000000000000000000000000000000000610a8584426116c7565b1015610a95576001915050610a9b565b60009150505b95945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610af5576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bf2576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f4ad701bc000000000000000000000000000000000000000000000000000000008152600481018690526024810185905230604482015260e086901c906000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690634ad701bc90606401602060405180830381865afa158015610c93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb791906116da565b905084610cf0576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84610d27576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051306020808301919091527f000000000000000000000000000000000000000000000000000000000000000063ffffffff1682840152606082018a90526080820189905260a08083018990528351808403909101815260c083019384905280519101207f97aba7f9000000000000000000000000000000000000000000000000000000009092526000917f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16916397aba7f991610e02918990899060c4016116f3565b602060405180830381865afa158015610e1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e439190611747565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832086845290915290205490915060ff1615610eb1576040517f35d9080500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610edc7f2125d1e225cadc5c8296e2cc1f96ee607770bf4a4a16131e62f6819937437c8984836112cd565b15610f13576040517fa278e4ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600460209081526040808320858452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600590915281208054909190610f8190611764565b9091555063ffffffff831660009081526003602090815260408083205485845260059092529091205410610fe757600082815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b6000828152600560209081526040918290205482518b81529182018a905281830185905273ffffffffffffffffffffffffffffffffffffffff84166060830152608082015290517f8cfaedaacfb148cee9ec5ed036100285c6f3ede20c1637a618733cbd631e92079181900360a00190a15050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146110b3576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107b7828261110f565b60006110ca8484846112cd565b949350505050565b61055583836040516020016110f792919091825263ffffffff16602082015260400190565b60405160208183030381529060405280519060200120825b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b61055583836040516020016111b792919091825263ffffffff16602082015260400190565b60405160208183030381529060405280519060200120825b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b60006110ca84846040516020016112f492919091825263ffffffff16602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009081526002835281812073ffffffffffffffffffffffffffffffffffffffff8716825290925290205460ff1690565b73ffffffffffffffffffffffffffffffffffffffff8116811461137d57600080fd5b50565b60006020828403121561139257600080fd5b813561139d8161135b565b9392505050565b803563ffffffff811681146113b857600080fd5b919050565b6000806000606084860312156113d257600080fd5b833592506113e2602085016113a4565b915060408401356113f28161135b565b809150509250925092565b60008083601f84011261140f57600080fd5b50813567ffffffffffffffff81111561142757600080fd5b6020830191508360208260051b850101111561144257600080fd5b9250929050565b6000806000806000806060878903121561146257600080fd5b863567ffffffffffffffff8082111561147a57600080fd5b6114868a838b016113fd565b9098509650602089013591508082111561149f57600080fd5b6114ab8a838b016113fd565b909650945060408901359150808211156114c457600080fd5b506114d189828a016113fd565b979a9699509497509295939492505050565b600080604083850312156114f657600080fd5b8235915060208301356115088161135b565b809150509250929050565b60006020828403121561152557600080fd5b5035919050565b6000806040838503121561153f57600080fd5b823561154a8161135b565b946020939093013593505050565b600080600080600060a0868803121561157057600080fd5b85359450602086013593506040860135925061158e606087016113a4565b949793965091946080013592915050565b6000602082840312156115b157600080fd5b610b98826113a4565b600080604083850312156115cd57600080fd5b50508035926020909101359150565b6000806000806000608086880312156115f457600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff8082111561162157600080fd5b818801915088601f83011261163557600080fd5b81358181111561164457600080fd5b89602082850101111561165657600080fd5b9699959850939650602001949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610b9b57610b9b611698565b6000602082840312156116ec57600080fd5b5051919050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b60006020828403121561175957600080fd5b815161139d8161135b565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361179557611795611698565b506001019056fea264697066735822122002727649fe6ffd98c1d89bc1bec9778a825498e6fec779ce36f433d11b2fd24e64736f6c63430008130033000000000000000000000000b0bbff6311b7f245761a7846d3ce7b1b100c1836000000000000000000000000525a6489a1df5ff1ae077faf628e43b7f52298ef000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000003e8000000000000000000000000c8a4d2fd77c155fd52e65ab07f337abf84495ead

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101b95760003560e01c80638da5cb5b116100f9578063c877930811610097578063d5b8da7311610071578063d5b8da7314610478578063ecb974841461049f578063efec6cd4146104b2578063f37f3e37146104d957600080fd5b8063c877930814610445578063d2883fbe14610452578063d547741f1461046557600080fd5b8063aac96557116100d3578063aac9655714610391578063b349ba65146103bf578063b947aac6146103fb578063c6a261d21461041e57600080fd5b80638da5cb5b1461034057806391d148541461035e578063940992a31461037157600080fd5b806330ef41b41161016657806343fa97ca1161014057806343fa97ca146102e75780634c408180146102fa5780635b94db271461030d5780637c1388141461032057600080fd5b806330ef41b41461027e57806331d1e063146102b15780633bd1adec146102df57600080fd5b806320f99c0a1161019757806320f99c0a146102195780632e7eb258146102585780632f2ff15d1461026b57600080fd5b80630cd55abf146101be5780631ba8e484146101f15780631e86731114610206575b600080fd5b6101de6101cc366004611380565b600b6020526000908152604090205481565b6040519081526020015b60405180910390f35b6102046101ff3660046113bd565b6104f9565b005b610204610214366004611449565b61055a565b60015473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e8565b6102046102663660046113bd565b610700565b6102046102793660046114e3565b61075c565b6102a161028c366004611513565b60066020526000908152604090205460ff1681565b60405190151581526020016101e8565b6102a16102bf36600461152c565b600460209081526000928352604080842090915290825290205460ff1681565b6102046107bb565b6102046102f5366004611449565b610817565b6102a1610308366004611558565b6109b3565b61020461031b366004611380565b610aa4565b6101de61032e36600461159f565b600a6020526000908152604090205481565b60005473ffffffffffffffffffffffffffffffffffffffff16610233565b6102a161036c3660046114e3565b610b64565b6101de61037f366004611513565b60056020526000908152604090205481565b6102a161039f3660046115ba565b600960209081526000928352604080842090915290825290205460ff1681565b6103e67f000000000000000000000000000000000000000000000000000000000000009281565b60405163ffffffff90911681526020016101e8565b6102a161040936600461159f565b60086020526000908152604090205460ff1681565b6102337f000000000000000000000000525a6489a1df5ff1ae077faf628e43b7f52298ef81565b6007546102a19060ff1681565b6102046104603660046115dc565b610ba1565b6102046104733660046114e3565b611062565b6102337f000000000000000000000000c8a4d2fd77c155fd52e65ab07f337abf84495ead81565b6102a16104ad3660046113bd565b6110bd565b6101de7f00000000000000000000000000000000000000000000000000000000000003e881565b6101de6104e736600461159f565b60036020526000908152604090205481565b60005473ffffffffffffffffffffffffffffffffffffffff16331461054a576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105558383836110d2565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105ab576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84811415806105ba5750848314155b156105f1576040517f11e86f7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460005b818110156106f657600086868381811061061157610611611669565b9050602002016020810190610626919061159f565b63ffffffff1611156106a6576106a188888381811061064757610647611669565b9050602002013587878481811061066057610660611669565b9050602002016020810190610675919061159f565b86868581811061068757610687611669565b905060200201602081019061069c9190611380565b6110d2565b6106ee565b6106ee8888838181106106bb576106bb611669565b905060200201358585848181106106d4576106d4611669565b90506020020160208101906106e99190611380565b61110f565b6001016105f5565b5050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610751576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610555838383611192565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107ad576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107b782826111cf565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461080c576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61081533611255565b565b60005473ffffffffffffffffffffffffffffffffffffffff163314610868576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84811415806108775750848314155b156108ae576040517f11e86f7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8460005b818110156106f65760008686838181106108ce576108ce611669565b90506020020160208101906108e3919061159f565b63ffffffff1611156109635761095e88888381811061090457610904611669565b9050602002013587878481811061091d5761091d611669565b9050602002016020810190610932919061159f565b86868581811061094457610944611669565b90506020020160208101906109599190611380565b611192565b6109ab565b6109ab88888381811061097857610978611669565b9050602002013585858481811061099157610991611669565b90506020020160208101906109a69190611380565b6111cf565b6001016108b2565b600754600090859060ff16806109de575063ffffffff841660009081526008602052604090205460ff165b80610a025750600086815260096020908152604080832088845290915290205460ff165b80610a2b575063ffffffff84166000908152600a602052604090205467ffffffffffffffff8216105b15610a3a576000915050610a9b565b60008781526006602052604090205460ff16610a5a576001915050610a9b565b7f00000000000000000000000000000000000000000000000000000000000003e8610a8584426116c7565b1015610a95576001915050610a9b565b60009150505b95945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610af5576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610bf2576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f4ad701bc000000000000000000000000000000000000000000000000000000008152600481018690526024810185905230604482015260e086901c906000907f000000000000000000000000525a6489a1df5ff1ae077faf628e43b7f52298ef73ffffffffffffffffffffffffffffffffffffffff1690634ad701bc90606401602060405180830381865afa158015610c93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb791906116da565b905084610cf0576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84610d27576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051306020808301919091527f000000000000000000000000000000000000000000000000000000000000009263ffffffff1682840152606082018a90526080820189905260a08083018990528351808403909101815260c083019384905280519101207f97aba7f9000000000000000000000000000000000000000000000000000000009092526000917f000000000000000000000000c8a4d2fd77c155fd52e65ab07f337abf84495ead73ffffffffffffffffffffffffffffffffffffffff16916397aba7f991610e02918990899060c4016116f3565b602060405180830381865afa158015610e1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e439190611747565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832086845290915290205490915060ff1615610eb1576040517f35d9080500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610edc7f2125d1e225cadc5c8296e2cc1f96ee607770bf4a4a16131e62f6819937437c8984836112cd565b15610f13576040517fa278e4ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600460209081526040808320858452825280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055600590915281208054909190610f8190611764565b9091555063ffffffff831660009081526003602090815260408083205485845260059092529091205410610fe757600082815260066020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555b6000828152600560209081526040918290205482518b81529182018a905281830185905273ffffffffffffffffffffffffffffffffffffffff84166060830152608082015290517f8cfaedaacfb148cee9ec5ed036100285c6f3ede20c1637a618733cbd631e92079181900360a00190a15050505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146110b3576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6107b7828261110f565b60006110ca8484846112cd565b949350505050565b61055583836040516020016110f792919091825263ffffffff16602082015260400190565b60405160208183030381529060405280519060200120825b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b61055583836040516020016111b792919091825263ffffffff16602082015260400190565b60405160208183030381529060405280519060200120825b600082815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8791a250565b60006110ca84846040516020016112f492919091825263ffffffff16602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009081526002835281812073ffffffffffffffffffffffffffffffffffffffff8716825290925290205460ff1690565b73ffffffffffffffffffffffffffffffffffffffff8116811461137d57600080fd5b50565b60006020828403121561139257600080fd5b813561139d8161135b565b9392505050565b803563ffffffff811681146113b857600080fd5b919050565b6000806000606084860312156113d257600080fd5b833592506113e2602085016113a4565b915060408401356113f28161135b565b809150509250925092565b60008083601f84011261140f57600080fd5b50813567ffffffffffffffff81111561142757600080fd5b6020830191508360208260051b850101111561144257600080fd5b9250929050565b6000806000806000806060878903121561146257600080fd5b863567ffffffffffffffff8082111561147a57600080fd5b6114868a838b016113fd565b9098509650602089013591508082111561149f57600080fd5b6114ab8a838b016113fd565b909650945060408901359150808211156114c457600080fd5b506114d189828a016113fd565b979a9699509497509295939492505050565b600080604083850312156114f657600080fd5b8235915060208301356115088161135b565b809150509250929050565b60006020828403121561152557600080fd5b5035919050565b6000806040838503121561153f57600080fd5b823561154a8161135b565b946020939093013593505050565b600080600080600060a0868803121561157057600080fd5b85359450602086013593506040860135925061158e606087016113a4565b949793965091946080013592915050565b6000602082840312156115b157600080fd5b610b98826113a4565b600080604083850312156115cd57600080fd5b50508035926020909101359150565b6000806000806000608086880312156115f457600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff8082111561162157600080fd5b818801915088601f83011261163557600080fd5b81358181111561164457600080fd5b89602082850101111561165657600080fd5b9699959850939650602001949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610b9b57610b9b611698565b6000602082840312156116ec57600080fd5b5051919050565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b60006020828403121561175957600080fd5b815161139d8161135b565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361179557611795611698565b506001019056fea264697066735822122002727649fe6ffd98c1d89bc1bec9778a825498e6fec779ce36f433d11b2fd24e64736f6c63430008130033

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

000000000000000000000000b0bbff6311b7f245761a7846d3ce7b1b100c1836000000000000000000000000525a6489a1df5ff1ae077faf628e43b7f52298ef000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000003e8000000000000000000000000c8a4d2fd77c155fd52e65ab07f337abf84495ead

-----Decoded View---------------
Arg [0] : owner_ (address): 0xB0BBff6311B7F245761A7846d3Ce7B1b100C1836
Arg [1] : socket_ (address): 0x525a6489a1df5fF1ae077fAf628E43b7F52298eF
Arg [2] : chainSlug_ (uint32): 146
Arg [3] : timeoutInSeconds_ (uint256): 1000
Arg [4] : signatureVerifier_ (address): 0xc8a4D2fd77c155fd52e65Ab07F337aBF84495Ead

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000b0bbff6311b7f245761a7846d3ce7b1b100c1836
Arg [1] : 000000000000000000000000525a6489a1df5ff1ae077faf628e43b7f52298ef
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000092
Arg [3] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [4] : 000000000000000000000000c8a4d2fd77c155fd52e65ab07f337abf84495ead


Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.