Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
SwitchboardSimulator
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// 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; } }
// 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; }
// 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); }
// 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); }
// 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; }
// 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_]; } }
// 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_); } }
// 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");
// 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_); } }
{ "optimizer": { "enabled": true, "runs": 999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
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"}]
Contract Creation Code
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
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.