Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
7281312 | 12 days ago | Contract Creation | 0 S |
Loading...
Loading
Contract Name:
GranularGuardianAccessControl
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.8; import {ICrossChainForwarder} from '../interfaces/ICrossChainForwarder.sol'; import {ICrossChainControllerWithEmergencyMode} from '../interfaces/ICrossChainControllerWithEmergencyMode.sol'; import {IGranularGuardianAccessControl, Envelope, ICrossChainReceiver} from './IGranularGuardianAccessControl.sol'; import {AccessControlEnumerable} from 'openzeppelin-contracts/contracts/access/extensions/AccessControlEnumerable.sol'; import {IWithGuardian} from 'solidity-utils/contracts/access-control/OwnableWithGuardian.sol'; import {ICrossChainControllerWithEmergencyModeDeprecated} from '../interfaces/ICrossChainControllerWithEmergencyModeDeprecated.sol'; /** * @title GranularGuardianAccessControl * @author BGD Labs * @notice Contract to manage a granular access to the methods safeguarded by guardian on CrossChainController */ contract GranularGuardianAccessControl is AccessControlEnumerable, IGranularGuardianAccessControl { /// @inheritdoc IGranularGuardianAccessControl address public immutable CROSS_CHAIN_CONTROLLER; /// @inheritdoc IGranularGuardianAccessControl bytes32 public constant SOLVE_EMERGENCY_ROLE = keccak256('SOLVE_EMERGENCY_ROLE'); /// @inheritdoc IGranularGuardianAccessControl bytes32 public constant RETRY_ROLE = keccak256('RETRY_ROLE'); /** * @param initialGuardians object with the initial guardians to assign the roles to * @param crossChainController address of the CrossChainController */ constructor(InitialGuardians memory initialGuardians, address crossChainController) { if (crossChainController == address(0)) { revert CrossChainControllerCantBe0(); } if (initialGuardians.defaultAdmin == address(0)) { revert DefaultAdminCantBe0(); } CROSS_CHAIN_CONTROLLER = crossChainController; _grantRole(DEFAULT_ADMIN_ROLE, initialGuardians.defaultAdmin); if (initialGuardians.solveEmergencyGuardian != address(0)) { _grantRole(SOLVE_EMERGENCY_ROLE, initialGuardians.solveEmergencyGuardian); } if (initialGuardians.retryGuardian != address(0)) { _grantRole(RETRY_ROLE, initialGuardians.retryGuardian); } } /// @inheritdoc IGranularGuardianAccessControl function retryEnvelope( Envelope memory envelope, uint256 gasLimit ) external onlyRole(RETRY_ROLE) returns (bytes32) { return ICrossChainForwarder(CROSS_CHAIN_CONTROLLER).retryEnvelope(envelope, gasLimit); } /// @inheritdoc IGranularGuardianAccessControl function retryTransaction( bytes memory encodedTransaction, uint256 gasLimit, address[] memory bridgeAdaptersToRetry ) external onlyRole(RETRY_ROLE) { ICrossChainForwarder(CROSS_CHAIN_CONTROLLER).retryTransaction( encodedTransaction, gasLimit, bridgeAdaptersToRetry ); } /// @inheritdoc IGranularGuardianAccessControl function solveEmergency( ICrossChainReceiver.ConfirmationInput[] memory newConfirmations, ICrossChainReceiver.ValidityTimestampInput[] memory newValidityTimestamp, ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToAllow, ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToDisallow, address[] memory sendersToApprove, address[] memory sendersToRemove, ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable, ICrossChainForwarder.BridgeAdapterToDisable[] memory forwarderBridgeAdaptersToDisable, ICrossChainForwarder.OptimalBandwidthByChain[] memory optimalBandwidthByChain ) external onlyRole(SOLVE_EMERGENCY_ROLE) { ICrossChainControllerWithEmergencyMode(CROSS_CHAIN_CONTROLLER).solveEmergency( newConfirmations, newValidityTimestamp, receiverBridgeAdaptersToAllow, receiverBridgeAdaptersToDisallow, sendersToApprove, sendersToRemove, forwarderBridgeAdaptersToEnable, forwarderBridgeAdaptersToDisable, optimalBandwidthByChain ); } /// @inheritdoc IGranularGuardianAccessControl function solveEmergencyDeprecated( ICrossChainReceiver.ConfirmationInput[] memory newConfirmations, ICrossChainReceiver.ValidityTimestampInput[] memory newValidityTimestamp, ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToAllow, ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToDisallow, address[] memory sendersToApprove, address[] memory sendersToRemove, ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable, ICrossChainForwarder.BridgeAdapterToDisable[] memory forwarderBridgeAdaptersToDisable ) external onlyRole(SOLVE_EMERGENCY_ROLE) { ICrossChainControllerWithEmergencyModeDeprecated(CROSS_CHAIN_CONTROLLER).solveEmergency( newConfirmations, newValidityTimestamp, receiverBridgeAdaptersToAllow, receiverBridgeAdaptersToDisallow, sendersToApprove, sendersToRemove, forwarderBridgeAdaptersToEnable, forwarderBridgeAdaptersToDisable ); } /// @inheritdoc IGranularGuardianAccessControl function updateGuardian( address newCrossChainControllerGuardian ) external onlyRole(DEFAULT_ADMIN_ROLE) { if (newCrossChainControllerGuardian == address(0)) { revert NewGuardianCantBe0(); } IWithGuardian(CROSS_CHAIN_CONTROLLER).updateGuardian(newCrossChainControllerGuardian); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import {Transaction, Envelope} from '../libs/EncodingUtils.sol'; /** * @title ICrossChainForwarder * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the CrossChainForwarder contract */ interface ICrossChainForwarder { /** * @notice Object containing the optimal bandwidth for communication with a receiver chain id * @param chainId id of the receiver chain * @param optimalBandwidth optimal number of bridge adapters to use to send a message to receiver chain */ struct OptimalBandwidthByChain { uint256 chainId; uint256 optimalBandwidth; } /** * @notice object storing the connected pair of bridge adapters, on current and destination chain * @param destinationBridgeAdapter address of the bridge adapter on the destination chain * @param currentChainBridgeAdapter address of the bridge adapter deployed on current network */ struct ChainIdBridgeConfig { address destinationBridgeAdapter; address currentChainBridgeAdapter; } /** * @notice object with the necessary information to remove bridge adapters * @param bridgeAdapter address of the bridge adapter to remove * @param chainIds array of chain ids where the bridge adapter connects */ struct BridgeAdapterToDisable { address bridgeAdapter; uint256[] chainIds; } /** * @notice object storing the pair bridgeAdapter (current deployed chain) destination chain bridge adapter configuration * @param currentChainBridgeAdapter address of the bridge adapter deployed on current chain * @param destinationBridgeAdapter address of the bridge adapter on the destination chain * @param destinationChainId id of the destination chain using our own nomenclature */ struct ForwarderBridgeAdapterConfigInput { address currentChainBridgeAdapter; address destinationBridgeAdapter; uint256 destinationChainId; } /** * @notice emitted when a transaction is successfully forwarded through a bridge adapter * @param envelopeId internal id of the envelope * @param envelope the Envelope type data */ event EnvelopeRegistered(bytes32 indexed envelopeId, Envelope envelope); /** * @notice emitted when a transaction forwarding is attempted through a bridge adapter * @param transactionId id of the forwarded transaction * @param envelopeId internal id of the envelope * @param encodedTransaction object intended to be bridged * @param destinationChainId id of the destination chain in our notation * @param bridgeAdapter address of the bridge adapter that failed (deployed on current network) * @param destinationBridgeAdapter address of the connected bridge adapter on destination chain * @param adapterSuccessful adapter was able to forward the message * @param returnData bytes with error information */ event TransactionForwardingAttempted( bytes32 transactionId, bytes32 indexed envelopeId, bytes encodedTransaction, uint256 destinationChainId, address indexed bridgeAdapter, address destinationBridgeAdapter, bool indexed adapterSuccessful, bytes returnData ); /** * @notice emitted when a bridge adapter has been added to the allowed list * @param destinationChainId id of the destination chain in our notation * @param bridgeAdapter address of the bridge adapter added (deployed on current network) * @param destinationBridgeAdapter address of the connected bridge adapter on destination chain * @param allowed boolean indicating if the bridge adapter is allowed or disallowed */ event BridgeAdapterUpdated( uint256 indexed destinationChainId, address indexed bridgeAdapter, address destinationBridgeAdapter, bool indexed allowed ); /** * @notice emitted when the optimal bandwidth is updated for a specified receiver chain * @param chainId id of the receiver chain that gets the new optimal bandwidth * @param optimalBandwidth optimal number of adapters to use for sending a message to a receiver chain */ event OptimalBandwidthUpdated(uint256 indexed chainId, uint256 optimalBandwidth); /** * @notice emitted when a sender has been updated * @param sender address of the updated sender * @param isApproved boolean that indicates if the sender has been approved or removed */ event SenderUpdated(address indexed sender, bool indexed isApproved); /** * @notice method to get the current valid envelope nonce * @return the current valid envelope nonce */ function getCurrentEnvelopeNonce() external view returns (uint256); /** * @notice method to get the current valid transaction nonce * @return the current valid transaction nonce */ function getCurrentTransactionNonce() external view returns (uint256); /** * @notice method to check if a envelope has been previously forwarded. * @param envelope the Envelope type data * @return boolean indicating if the envelope has been registered */ function isEnvelopeRegistered(Envelope memory envelope) external view returns (bool); /** * @notice method to check if a envelope has been previously forwarded. * @param envelopeId the hashed id of the envelope * @return boolean indicating if the envelope has been registered */ function isEnvelopeRegistered(bytes32 envelopeId) external view returns (bool); /** * @notice method to get if a transaction has been forwarded * @param transaction the Transaction type data * @return flag indicating if a transaction has been forwarded */ function isTransactionForwarded(Transaction memory transaction) external view returns (bool); /** * @notice method to get if a transaction has been forwarded * @param transactionId hashed id of the transaction * @return flag indicating if a transaction has been forwarded */ function isTransactionForwarded(bytes32 transactionId) external view returns (bool); /** * @notice method called to initiate message forwarding to other networks. * @param destinationChainId id of the destination chain where the message needs to be bridged * @param destination address where the message is intended for * @param gasLimit gas cost on receiving side of the message * @param message bytes that need to be bridged * @return internal id of the envelope and transaction */ function forwardMessage( uint256 destinationChainId, address destination, uint256 gasLimit, bytes memory message ) external returns (bytes32, bytes32); /** * @notice method called to re forward a previously sent envelope. * @param envelope the Envelope type data * @param gasLimit gas cost on receiving side of the message * @return the transaction id that has the retried envelope * @dev This method will send an existing Envelope using a new Transaction. * @dev This method should be used when the intention is to send the Envelope as if it was a new message. This way on the Receiver side it will start from 0 to count for the required confirmations. (usual use case would be for when an envelope has been invalidated on Receiver side, and needs to be retried as a new message) */ function retryEnvelope(Envelope memory envelope, uint256 gasLimit) external returns (bytes32); /** * @notice method to retry forwarding an already forwarded transaction * @param encodedTransaction the encoded Transaction data * @param gasLimit limit of gas to spend on forwarding per bridge * @param bridgeAdaptersToRetry list of bridge adapters to be used for the transaction forwarding retry * @dev This method will send an existing Transaction with its Envelope to the specified adapters. * @dev Should be used when some of the bridges on the initial forwarding did not work (out of gas), and we want the Transaction with Envelope to still account for the required confirmations on the Receiver side */ function retryTransaction( bytes memory encodedTransaction, uint256 gasLimit, address[] memory bridgeAdaptersToRetry ) external; /** * @notice method to enable bridge adapters * @param bridgeAdapters array of new bridge adapter configurations */ function enableBridgeAdapters(ForwarderBridgeAdapterConfigInput[] memory bridgeAdapters) external; /** * @notice method to disable bridge adapters * @param bridgeAdapters array of bridge adapter addresses to disable */ function disableBridgeAdapters(BridgeAdapterToDisable[] memory bridgeAdapters) external; /** * @notice method to remove sender addresses * @param senders list of addresses to remove */ function removeSenders(address[] memory senders) external; /** * @notice method to approve new sender addresses * @param senders list of addresses to approve */ function approveSenders(address[] memory senders) external; /** * @notice method to get all the forwarder bridge adapters of a chain * @param chainId id of the chain we want to get the adapters from * @return an array of chain configurations where the bridge adapter can communicate */ function getForwarderBridgeAdaptersByChain( uint256 chainId ) external view returns (ChainIdBridgeConfig[] memory); /** * @notice method to get if a sender is approved * @param sender address that we want to check if approved * @return boolean indicating if the address has been approved as sender */ function isSenderApproved(address sender) external view returns (bool); /** * @notice method to update the optimal bandwidth for communication with a receiver chain * @param optimalBandwidthByChain array of objects containing the optimal bandwidth for a specified receiver chain id */ function updateOptimalBandwidthByChain( OptimalBandwidthByChain[] memory optimalBandwidthByChain ) external; /** * @notice method to get the optimal bandwidth for communication with the receiver chain * @param chainId id of the receiver chain to get the optimal bandwidth from * @return optimal bandwidth of the receiver chain */ function getOptimalBandwidthByChain(uint256 chainId) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import './IBaseCrossChainController.sol'; import '../emergency/interfaces/IEmergencyConsumer.sol'; /** * @title ICrossChainControllerWithEmergencyMode * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the CrossChainControllerWithEmergencyMode contract */ interface ICrossChainControllerWithEmergencyMode is IBaseCrossChainController, IEmergencyConsumer { /** * @notice method called to initialize the proxy * @param owner address of the owner of the cross chain controller * @param guardian address of the guardian of the cross chain controller * @param clEmergencyOracle address of the chainlink emergency oracle * @param initialRequiredConfirmations number of confirmations the messages need to be accepted as valid * @param receiverBridgeAdaptersToAllow array of addresses of the bridge adapters that can receive messages * @param forwarderBridgeAdaptersToEnable array specifying for every bridgeAdapter, the destinations it can have * @param sendersToApprove array of addresses to allow as forwarders * @param optimalBandwidthByChain array of optimal numbers of bridge adapters to use to send a message to receiver chain */ function initialize( address owner, address guardian, address clEmergencyOracle, ConfirmationInput[] memory initialRequiredConfirmations, ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToAllow, ForwarderBridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable, address[] memory sendersToApprove, OptimalBandwidthByChain[] memory optimalBandwidthByChain ) external; /** * @notice method to solve an emergency. This method is only callable by the guardian * @param newConfirmations number of confirmations necessary for a message to be routed to destination * @param newValidityTimestamp timestamp in seconds indicating the point to where not confirmed messages will be * invalidated. * @param receiverBridgeAdaptersToAllow list of bridge adapter addresses to be allowed to receive messages * @param receiverBridgeAdaptersToDisallow list of bridge adapter addresses to be disallowed * @param sendersToApprove list of addresses to be approved as senders * @param sendersToRemove list of sender addresses to be removed * @param forwarderBridgeAdaptersToEnable list of bridge adapters to be enabled to send messages * @param forwarderBridgeAdaptersToDisable list of bridge adapters to be disabled * @param optimalBandwidthByChain array of optimal numbers of bridge adapters to use to send a message to receiver chain */ function solveEmergency( ConfirmationInput[] memory newConfirmations, ValidityTimestampInput[] memory newValidityTimestamp, ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToAllow, ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToDisallow, address[] memory sendersToApprove, address[] memory sendersToRemove, ForwarderBridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable, BridgeAdapterToDisable[] memory forwarderBridgeAdaptersToDisable, OptimalBandwidthByChain[] memory optimalBandwidthByChain ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import {Envelope} from '../libs/EncodingUtils.sol'; import {ICrossChainReceiver} from '../interfaces/ICrossChainReceiver.sol'; import {ICrossChainForwarder} from '../interfaces/ICrossChainForwarder.sol'; /** * @title IGranularGuardianAccessControl * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the GranularGuardianAccessControl contract */ interface IGranularGuardianAccessControl { /// @dev default admin address can not be address 0 error DefaultAdminCantBe0(); /// @dev CrossChainController address can not be address 0 error CrossChainControllerCantBe0(); /// @dev new Guardian address can not be address 0 error NewGuardianCantBe0(); /** * @param defaultAdmin address that will have control of the default admin * @param retryGuardian address to be added to the retry role * @param solveEmergencyGuardian address to be added to the solve emergency role */ struct InitialGuardians { address defaultAdmin; address retryGuardian; address solveEmergencyGuardian; } /** * @notice method called to re forward a previously sent envelope. This method is only callable by the accounts holding the RETRY_ROLE role * @param envelope the Envelope type data * @param gasLimit gas cost on receiving side of the message * @return the transaction id that has the retried envelope * @dev This method will send an existing Envelope using a new Transaction. * @dev This method should be used when the intention is to send the Envelope as if it was a new message. This way on the Receiver side it will start from 0 to count for the required confirmations. (usual use case would be for when an envelope has been invalidated on Receiver side, and needs to be retried as a new message) */ function retryEnvelope(Envelope memory envelope, uint256 gasLimit) external returns (bytes32); /** * @notice method to retry forwarding an already forwarded transaction. This method is only callable by the accounts holding the RETRY_ROLE role * @param encodedTransaction the encoded Transaction data * @param gasLimit limit of gas to spend on forwarding per bridge * @param bridgeAdaptersToRetry list of bridge adapters to be used for the transaction forwarding retry * @dev This method will send an existing Transaction with its Envelope to the specified adapters. * @dev Should be used when some of the bridges on the initial forwarding did not work (out of gas), and we want the Transaction with Envelope to still account for the required confirmations on the Receiver side */ function retryTransaction( bytes memory encodedTransaction, uint256 gasLimit, address[] memory bridgeAdaptersToRetry ) external; /** * @notice method to solve an emergency. This method is only callable by the accounts holding the SOLVE_EMERGENCY_ROLE role * @param newConfirmations number of confirmations necessary for a message to be routed to destination * @param newValidityTimestamp timestamp in seconds indicating the point to where not confirmed messages will be * invalidated. * @param receiverBridgeAdaptersToAllow list of bridge adapter addresses to be allowed to receive messages * @param receiverBridgeAdaptersToDisallow list of bridge adapter addresses to be disallowed * @param sendersToApprove list of addresses to be approved as senders * @param sendersToRemove list of sender addresses to be removed * @param forwarderBridgeAdaptersToEnable list of bridge adapters to be enabled to send messages * @param forwarderBridgeAdaptersToDisable list of bridge adapters to be disabled * @param optimalBandwidthByChain array of optimal numbers of bridge adapters to use to send a message to receiver chain */ function solveEmergency( ICrossChainReceiver.ConfirmationInput[] memory newConfirmations, ICrossChainReceiver.ValidityTimestampInput[] memory newValidityTimestamp, ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToAllow, ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToDisallow, address[] memory sendersToApprove, address[] memory sendersToRemove, ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable, ICrossChainForwarder.BridgeAdapterToDisable[] memory forwarderBridgeAdaptersToDisable, ICrossChainForwarder.OptimalBandwidthByChain[] memory optimalBandwidthByChain ) external; /** * @notice method to solve an emergency on a CrossChainController with Revision 2 or older interface. This method is only callable by the accounts holding the SOLVE_EMERGENCY_ROLE role * @param newConfirmations number of confirmations necessary for a message to be routed to destination * @param newValidityTimestamp timestamp in seconds indicating the point to where not confirmed messages will be * invalidated. * @param receiverBridgeAdaptersToAllow list of bridge adapter addresses to be allowed to receive messages * @param receiverBridgeAdaptersToDisallow list of bridge adapter addresses to be disallowed * @param sendersToApprove list of addresses to be approved as senders * @param sendersToRemove list of sender addresses to be removed * @param forwarderBridgeAdaptersToEnable list of bridge adapters to be enabled to send messages * @param forwarderBridgeAdaptersToDisable list of bridge adapters to be disabled */ function solveEmergencyDeprecated( ICrossChainReceiver.ConfirmationInput[] memory newConfirmations, ICrossChainReceiver.ValidityTimestampInput[] memory newValidityTimestamp, ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToAllow, ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToDisallow, address[] memory sendersToApprove, address[] memory sendersToRemove, ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable, ICrossChainForwarder.BridgeAdapterToDisable[] memory forwarderBridgeAdaptersToDisable ) external; /** * @notice method to update the CrossChainController guardian when this contract has been set as guardian */ function updateGuardian(address newCrossChainControllerGuardian) external; /** * @notice method to get the address of the CrossChainController where the contract points to * @return the address of the CrossChainController */ function CROSS_CHAIN_CONTROLLER() external view returns (address); /** * @notice method to get the solve emergency role * @return the solve emergency role id */ function SOLVE_EMERGENCY_ROLE() external view returns (bytes32); /** * @notice method to get the retry role * @return the retry role id */ function RETRY_ROLE() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (access/extensions/AccessControlEnumerable.sol) pragma solidity ^0.8.20; import {IAccessControlEnumerable} from "./IAccessControlEnumerable.sol"; import {AccessControl} from "../AccessControl.sol"; import {EnumerableSet} from "../../utils/structs/EnumerableSet.sol"; /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl { using EnumerableSet for EnumerableSet.AddressSet; mapping(bytes32 role => EnumerableSet.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view virtual returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view virtual returns (uint256) { return _roleMembers[role].length(); } /** * @dev Return all accounts that have `role` * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function getRoleMembers(bytes32 role) public view virtual returns (address[] memory) { return _roleMembers[role].values(); } /** * @dev Overload {AccessControl-_grantRole} to track enumerable memberships */ function _grantRole(bytes32 role, address account) internal virtual override returns (bool) { bool granted = super._grantRole(role, account); if (granted) { _roleMembers[role].add(account); } return granted; } /** * @dev Overload {AccessControl-_revokeRole} to track enumerable memberships */ function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) { bool revoked = super._revokeRole(role, account); if (revoked) { _roleMembers[role].remove(account); } return revoked; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import {Ownable} from 'openzeppelin-contracts/contracts/access/Ownable.sol'; import {IWithGuardian} from './interfaces/IWithGuardian.sol'; abstract contract OwnableWithGuardian is Ownable, IWithGuardian { address private _guardian; constructor(address initialOwner, address initialGuardian) Ownable(initialOwner) { _updateGuardian(initialGuardian); } modifier onlyGuardian() { _checkGuardian(); _; } modifier onlyOwnerOrGuardian() { _checkOwnerOrGuardian(); _; } function guardian() public view override returns (address) { return _guardian; } /// @inheritdoc IWithGuardian function updateGuardian(address newGuardian) external override onlyOwnerOrGuardian { _updateGuardian(newGuardian); } /** * @dev method to update the guardian * @param newGuardian the new guardian address */ function _updateGuardian(address newGuardian) internal { address oldGuardian = _guardian; _guardian = newGuardian; emit GuardianUpdated(oldGuardian, newGuardian); } function _checkGuardian() internal view { if (guardian() != _msgSender()) revert OnlyGuardianInvalidCaller(_msgSender()); } function _checkOwnerOrGuardian() internal view { if (_msgSender() != owner() && _msgSender() != guardian()) revert OnlyGuardianOrOwnerInvalidCaller(_msgSender()); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import './IBaseCrossChainController.sol'; import '../emergency/interfaces/IEmergencyConsumer.sol'; /** * @title ICrossChainControllerWithEmergencyModeRev2 * @author BGD Labs. Interface containing the solveEmergency interface of the CrossChainController of Revision 2 or older */ interface ICrossChainControllerWithEmergencyModeDeprecated is IBaseCrossChainController, IEmergencyConsumer { /** * @notice method to solve an emergency. This method is only callable by the guardian * @param newConfirmations number of confirmations necessary for a message to be routed to destination * @param newValidityTimestamp timestamp in seconds indicating the point to where not confirmed messages will be * invalidated. * @param receiverBridgeAdaptersToAllow list of bridge adapter addresses to be allowed to receive messages * @param receiverBridgeAdaptersToDisallow list of bridge adapter addresses to be disallowed * @param sendersToApprove list of addresses to be approved as senders * @param sendersToRemove list of sender addresses to be removed * @param forwarderBridgeAdaptersToEnable list of bridge adapters to be enabled to send messages * @param forwarderBridgeAdaptersToDisable list of bridge adapters to be disabled */ function solveEmergency( ConfirmationInput[] memory newConfirmations, ValidityTimestampInput[] memory newValidityTimestamp, ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToAllow, ReceiverBridgeAdapterConfigInput[] memory receiverBridgeAdaptersToDisallow, address[] memory sendersToApprove, address[] memory sendersToRemove, ForwarderBridgeAdapterConfigInput[] memory forwarderBridgeAdaptersToEnable, BridgeAdapterToDisable[] memory forwarderBridgeAdaptersToDisable ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; using EnvelopeUtils for Envelope global; using TransactionUtils for Transaction global; /** * @notice Object with the necessary information to define a unique envelope * @param nonce sequential (unique) numeric indicator of the Envelope creation * @param origin address that originated the bridging of a message * @param destination address where the message needs to be sent * @param originChainId id of the chain where the message originated * @param destinationChainId id of the chain where the message needs to be bridged * @param message bytes that needs to be bridged */ struct Envelope { uint256 nonce; address origin; address destination; uint256 originChainId; uint256 destinationChainId; bytes message; } /** * @notice Object containing the information of an envelope for internal usage * @param data bytes of the encoded envelope * @param id hash of the encoded envelope */ struct EncodedEnvelope { bytes data; bytes32 id; } /** * @title EnvelopeUtils library * @author BGD Labs * @notice Defines utility functions for Envelopes */ library EnvelopeUtils { /** * @notice method that encodes an Envelope and generates its id * @param envelope object with the routing information necessary to send a message to a destination chain * @return object containing the encoded envelope and the envelope id */ function encode(Envelope memory envelope) internal pure returns (EncodedEnvelope memory) { EncodedEnvelope memory encodedEnvelope; encodedEnvelope.data = abi.encode(envelope); encodedEnvelope.id = getId(encodedEnvelope.data); return encodedEnvelope; } /** * @notice method to decode and encoded envelope to its raw parameters * @param envelope bytes with the encoded envelope data * @return object with the decoded envelope information */ function decode(bytes memory envelope) internal pure returns (Envelope memory) { return abi.decode(envelope, (Envelope)); } /** * @notice method to get an envelope's id * @param envelope object with the routing information necessary to send a message to a destination chain * @return hash id of the envelope */ function getId(Envelope memory envelope) internal pure returns (bytes32) { EncodedEnvelope memory encodedEnvelope = encode(envelope); return encodedEnvelope.id; } /** * @notice method to get an envelope's id * @param envelope bytes with the encoded envelope data * @return hash id of the envelope */ function getId(bytes memory envelope) internal pure returns (bytes32) { return keccak256(envelope); } } /** * @notice Object with the necessary information to send an envelope to a bridge * @param nonce sequential (unique) numeric indicator of the Transaction creation * @param encodedEnvelope bytes of an encoded envelope object */ struct Transaction { uint256 nonce; bytes encodedEnvelope; } /** * @notice Object containing the information of a transaction for internal usage * @param data bytes of the encoded transaction * @param id hash of the encoded transaction */ struct EncodedTransaction { bytes data; bytes32 id; } /** * @title TransactionUtils library * @author BGD Labs * @notice Defines utility functions for Transactions */ library TransactionUtils { /** * @notice method that encodes a Transaction and generates its id * @param transaction object with the information necessary to send an envelope to a bridge * @return object containing the encoded transaction and the transaction id */ function encode( Transaction memory transaction ) internal pure returns (EncodedTransaction memory) { EncodedTransaction memory encodedTransaction; encodedTransaction.data = abi.encode(transaction); encodedTransaction.id = getId(encodedTransaction.data); return encodedTransaction; } /** * @notice method that decodes an encoded transaction (bytes) into a Transaction object * @param transaction encoded transaction object * @return object containing the decoded Transaction object */ function decode(bytes memory transaction) internal pure returns (Transaction memory) { return abi.decode(transaction, (Transaction)); } /** * @notice method to get a transaction id * @param transaction object with the information necessary to send an envelope to a bridge * @return hash id of the transaction */ function getId(Transaction memory transaction) internal pure returns (bytes32) { EncodedTransaction memory encodedTransaction = encode(transaction); return encodedTransaction.id; } /** * @notice method to get a transaction id * @param transaction encoded transaction object * @return hash id of the transaction */ function getId(bytes memory transaction) internal pure returns (bytes32) { return keccak256(transaction); } /** * @notice method to get the envelope information from the transaction object * @param transaction object with the information necessary to send an envelope to a bridge * @return object with decoded information of the envelope in the transaction */ function getEnvelope(Transaction memory transaction) internal pure returns (Envelope memory) { return EnvelopeUtils.decode(transaction.encodedEnvelope); } /** * @notice method to get the envelope id from the transaction object * @param transaction object with the information necessary to send an envelope to a bridge * @return hash id of the envelope on a transaction */ function getEnvelopeId(Transaction memory transaction) internal pure returns (bytes32) { return EnvelopeUtils.getId(transaction.encodedEnvelope); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import './ICrossChainForwarder.sol'; import './ICrossChainReceiver.sol'; import {IRescuable} from 'solidity-utils/contracts/utils/interfaces/IRescuable.sol'; /** * @title IBaseCrossChainController * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the CrossChainController contract */ interface IBaseCrossChainController is IRescuable, ICrossChainForwarder, ICrossChainReceiver { }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IEmergencyConsumer { /** * @dev emitted when chainlink emergency oracle gets updated * @param chainlinkEmergencyOracle address of the new oracle */ event CLEmergencyOracleUpdated(address indexed chainlinkEmergencyOracle); /** * @dev emitted when the emergency is solved * @param emergencyCount number of emergencies solved. Used to check if a new emergency is active. */ event EmergencySolved(uint256 emergencyCount); /** * @notice method that returns the last emergency solved * @return the current emergency count */ function getEmergencyCount() external view returns (uint256); /** * @notice method that returns the address of the current chainlink emergency oracle * @return the Chainlink emergency oracle address */ function getChainlinkEmergencyOracle() external view returns (address); /** * @dev method to update the chainlink emergency mode address. * This method is made virtual as it is expected to have access control, but this way it is delegated to implementation. * It should call _updateCLEmergencyOracle when implemented * @param chainlinkEmergencyOracle address of the new chainlink emergency mode oracle */ function updateCLEmergencyOracle(address chainlinkEmergencyOracle) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import {EnumerableSet} from 'openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol'; import {Transaction, Envelope} from '../libs/EncodingUtils.sol'; /** * @title ICrossChainReceiver * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the CrossChainReceiver contract */ interface ICrossChainReceiver { /** * @notice object with information to set new required confirmations * @param chainId id of the origin chain * @param requiredConfirmations required confirmations to set a message as confirmed */ struct ConfirmationInput { uint256 chainId; uint8 requiredConfirmations; } /** * @notice object with information to set new validity timestamp * @param chainId id of the origin chain * @param validityTimestamp new timestamp in seconds to set as validity point */ struct ValidityTimestampInput { uint256 chainId; uint120 validityTimestamp; } /** * @notice object with necessary information to configure bridge adapters * @param bridgeAdapter address of the bridge adapter to configure * @param chainIds array of ids of the chains the adapter receives messages from */ struct ReceiverBridgeAdapterConfigInput { address bridgeAdapter; uint256[] chainIds; } /** * @notice object containing the receiver configuration * @param requiredConfirmation number of bridges that are needed to make a bridged message valid from origin chain * @param validityTimestamp all messages originated but not finally confirmed before this timestamp per origin chain, are invalid */ struct ReceiverConfiguration { uint8 requiredConfirmation; uint120 validityTimestamp; } /** * @notice object with full information of the receiver configuration for a chain * @param configuration object containing the specifications of the receiver for a chain * @param allowedBridgeAdapters stores if a bridge adapter is allowed for a chain */ struct ReceiverConfigurationFull { ReceiverConfiguration configuration; EnumerableSet.AddressSet allowedBridgeAdapters; } /** * @notice object that stores the internal information of the transaction * @param confirmations number of times that this transaction has been bridged * @param firstBridgedAt timestamp in seconds indicating the first time a transaction was received */ struct TransactionStateWithoutAdapters { uint8 confirmations; uint120 firstBridgedAt; } /** * @notice object that stores the internal information of the transaction with bridge adapters state * @param confirmations number of times that this transactions has been bridged * @param firstBridgedAt timestamp in seconds indicating the first time a transaction was received * @param bridgedByAdapter list of bridge adapters that have bridged the message */ struct TransactionState { uint8 confirmations; uint120 firstBridgedAt; mapping(address => bool) bridgedByAdapter; } /** * @notice object with the current state of an envelope * @param confirmed boolean indicating if the bridged message has been confirmed by the infrastructure * @param delivered boolean indicating if the bridged message has been delivered to the destination */ enum EnvelopeState { None, Confirmed, Delivered } /** * @notice emitted when a transaction has been received successfully * @param transactionId id of the transaction * @param envelopeId id of the envelope * @param originChainId id of the chain where the envelope originated * @param transaction the Transaction type data * @param bridgeAdapter address of the bridge adapter who received the message (deployed on current network) * @param confirmations number of current confirmations for this message */ event TransactionReceived( bytes32 transactionId, bytes32 indexed envelopeId, uint256 indexed originChainId, Transaction transaction, address indexed bridgeAdapter, uint8 confirmations ); /** * @notice emitted when an envelope has been delivery attempted * @param envelopeId id of the envelope * @param envelope the Envelope type data * @param isDelivered flag indicating if the message has been delivered successfully */ event EnvelopeDeliveryAttempted(bytes32 envelopeId, Envelope envelope, bool isDelivered); /** * @notice emitted when a bridge adapter gets updated (allowed or disallowed) * @param bridgeAdapter address of the updated bridge adapter * @param allowed boolean indicating if the bridge adapter has been allowed or disallowed * @param chainId id of the chain updated */ event ReceiverBridgeAdaptersUpdated( address indexed bridgeAdapter, bool indexed allowed, uint256 indexed chainId ); /** * @notice emitted when number of confirmations needed to validate a message changes * @param newConfirmations number of new confirmations needed for a message to be valid * @param chainId id of the chain updated */ event ConfirmationsUpdated(uint8 newConfirmations, uint256 indexed chainId); /** * @notice emitted when a new timestamp for invalidations gets set * @param invalidTimestamp timestamp to invalidate previous messages * @param chainId id of the chain updated */ event NewInvalidation(uint256 invalidTimestamp, uint256 indexed chainId); /** * @notice method to get the current allowed receiver bridge adapters for a chain * @param chainId id of the chain to get the allowed bridge adapter list * @return the list of allowed bridge adapters */ function getReceiverBridgeAdaptersByChain( uint256 chainId ) external view returns (address[] memory); /** * @notice method to get the current supported chains (at least one allowed bridge adapter) * @return list of supported chains */ function getSupportedChains() external view returns (uint256[] memory); /** * @notice method to get the current configuration of a chain * @param chainId id of the chain to get the configuration from * @return the specified chain configuration object */ function getConfigurationByChain( uint256 chainId ) external view returns (ReceiverConfiguration memory); /** * @notice method to get if a bridge adapter is allowed * @param bridgeAdapter address of the bridge adapter to check * @param chainId id of the chain to check * @return boolean indicating if bridge adapter is allowed */ function isReceiverBridgeAdapterAllowed( address bridgeAdapter, uint256 chainId ) external view returns (bool); /** * @notice method to get the current state of a transaction * @param transactionId the id of transaction * @return number of confirmations of internal message identified by the transactionId and the updated timestamp */ function getTransactionState( bytes32 transactionId ) external view returns (TransactionStateWithoutAdapters memory); /** * @notice method to get the internal transaction information * @param transaction Transaction type data * @return number of confirmations of internal message identified by internalId and the updated timestamp */ function getTransactionState( Transaction memory transaction ) external view returns (TransactionStateWithoutAdapters memory); /** * @notice method to get the internal state of an envelope * @param envelope the Envelope type data * @return the envelope current state, containing if it has been confirmed and delivered */ function getEnvelopeState(Envelope memory envelope) external view returns (EnvelopeState); /** * @notice method to get the internal state of an envelope * @param envelopeId id of the envelope * @return the envelope current state, containing if it has been confirmed and delivered */ function getEnvelopeState(bytes32 envelopeId) external view returns (EnvelopeState); /** * @notice method to get if transaction has been received by bridge adapter * @param transactionId id of the transaction as stored internally * @param bridgeAdapter address of the bridge adapter to check if it has bridged the message * @return boolean indicating if the message has been received */ function isTransactionReceivedByAdapter( bytes32 transactionId, address bridgeAdapter ) external view returns (bool); /** * @notice method to set a new timestamp from where the messages will be valid. * @param newValidityTimestamp array of objects containing the chain and timestamp where all the previous unconfirmed messages must be invalidated. */ function updateMessagesValidityTimestamp( ValidityTimestampInput[] memory newValidityTimestamp ) external; /** * @notice method to update the number of confirmations necessary for the messages to be accepted as valid * @param newConfirmations array of objects with the chainId and the new number of needed confirmations */ function updateConfirmations(ConfirmationInput[] memory newConfirmations) external; /** * @notice method that receives a bridged transaction and tries to deliver the contents to destination if possible * @param encodedTransaction bytes containing the bridged information * @param originChainId id of the chain where the transaction originated */ function receiveCrossChainMessage( bytes memory encodedTransaction, uint256 originChainId ) external; /** * @notice method to deliver an envelope to its destination * @param envelope the Envelope typed data * @dev to deliver an envelope, it needs to have been previously confirmed and not delivered */ function deliverEnvelope(Envelope memory envelope) external; /** * @notice method to add bridge adapters to the allowed list * @param bridgeAdaptersInput array of objects with the new bridge adapters and supported chains */ function allowReceiverBridgeAdapters( ReceiverBridgeAdapterConfigInput[] memory bridgeAdaptersInput ) external; /** * @notice method to remove bridge adapters from the allowed list * @param bridgeAdaptersInput array of objects with the bridge adapters and supported chains to disallow */ function disallowReceiverBridgeAdapters( ReceiverBridgeAdapterConfigInput[] memory bridgeAdaptersInput ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (access/extensions/IAccessControlEnumerable.sol) pragma solidity ^0.8.20; import {IAccessControl} from "../IAccessControl.sol"; /** * @dev External interface of AccessControlEnumerable declared to support ERC-165 detection. */ interface IAccessControlEnumerable is IAccessControl { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol) pragma solidity ^0.8.20; import {IAccessControl} from "./IAccessControl.sol"; import {Context} from "../utils/Context.sol"; import {ERC165} from "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address account => bool) hasRole; bytes32 adminRole; } mapping(bytes32 role => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with an {AccessControlUnauthorizedAccount} error including the required role. */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual returns (bool) { return _roles[role].hasRole[account]; } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()` * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier. */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account` * is missing `role`. */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert AccessControlUnauthorizedAccount(account, role); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address callerConfirmation) public virtual { if (callerConfirmation != _msgSender()) { revert AccessControlBadConfirmation(); } _revokeRole(role, callerConfirmation); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual returns (bool) { if (!hasRole(role, account)) { _roles[role].hasRole[account] = true; emit RoleGranted(role, account, _msgSender()); return true; } else { return false; } } /** * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual returns (bool) { if (hasRole(role, account)) { _roles[role].hasRole[account] = false; emit RoleRevoked(role, account, _msgSender()); return true; } else { return false; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.20; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure * unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableSet. * ==== */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position is the index of the value in the `values` array plus 1. // Position 0 is used to mean a value is not in the set. mapping(bytes32 value => uint256) _positions; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._positions[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We cache the value's position to prevent multiple reads from the same storage slot uint256 position = set._positions[value]; if (position != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 valueIndex = position - 1; uint256 lastIndex = set._values.length - 1; if (valueIndex != lastIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the lastValue to the index where the value to delete is set._values[valueIndex] = lastValue; // Update the tracked position of the lastValue (that was just moved) set._positions[lastValue] = position; } // Delete the slot where the moved value was stored set._values.pop(); // Delete the tracked position for the deleted slot delete set._positions[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._positions[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { bytes32[] memory store = _values(set._inner); bytes32[] memory result; assembly ("memory-safe") { result := store } return result; } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly ("memory-safe") { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values in the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly ("memory-safe") { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; interface IWithGuardian { /** * @dev Event emitted when guardian gets updated * @param oldGuardian address of previous guardian * @param newGuardian address of the new guardian */ event GuardianUpdated(address oldGuardian, address newGuardian); /** * @dev The caller account is not authorized to perform an operation. */ error OnlyGuardianInvalidCaller(address account); /** * @dev The caller account is not authorized to perform an operation. */ error OnlyGuardianOrOwnerInvalidCaller(address account); /** * @dev get guardian address; */ function guardian() external view returns (address); /** * @dev method to update the guardian * @param newGuardian the new guardian address */ function updateGuardian(address newGuardian) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import {IRescuableBase} from './IRescuableBase.sol'; /** * @title IRescuable * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the Rescuable contract */ interface IRescuable is IRescuableBase { error OnlyRescueGuardian(); /** * @notice method called to rescue tokens sent erroneously to the contract. Only callable by owner * @param erc20Token address of the token to rescue * @param to address to send the tokens * @param amount of tokens to rescue */ function emergencyTokenTransfer(address erc20Token, address to, uint256 amount) external; /** * @notice method called to rescue ether sent erroneously to the contract. Only callable by owner * @param to address to send the eth * @param amount of eth to rescue */ function emergencyEtherTransfer(address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC-165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role). * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title IRescuableBase * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the RescuableBase contract */ interface IRescuableBase { error EthTransferFailed(); /** * @notice emitted when erc20 tokens get rescued * @param caller address that triggers the rescue * @param token address of the rescued token * @param to address that will receive the rescued tokens * @param amount quantity of tokens rescued */ event ERC20Rescued( address indexed caller, address indexed token, address indexed to, uint256 amount ); /** * @notice emitted when native tokens get rescued * @param caller address that triggers the rescue * @param to address that will receive the rescued tokens * @param amount quantity of tokens rescued */ event NativeTokensRescued(address indexed caller, address indexed to, uint256 amount); /** * @notice method that defined the maximum amount rescuable for any given asset. * @dev there's currently no way to limit the rescuable "native asset", as we assume erc20s as intended underlying. * @return the maximum amount of */ function maxRescue(address erc20Token) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "remappings": [ "solidity-utils/=lib/aave-delivery-infrastructure/lib/solidity-utils/src/", "forge-std/=lib/aave-helpers/lib/forge-std/src/", "openzeppelin-contracts/=lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/", "aave-helpers/=lib/aave-helpers/src/", "aave-address-book/=lib/aave-helpers/lib/aave-address-book/src/", "adi/=lib/aave-delivery-infrastructure/src/contracts/", "adi-scripts/=lib/aave-delivery-infrastructure/scripts/", "adi-tests/=lib/aave-delivery-infrastructure/tests/", "aave-v3-origin/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src/", "@openzeppelin/=lib/aave-delivery-infrastructure/lib/openzeppelin-contracts/", "@openzeppelin/contracts-upgradeable/=lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/", "aave-delivery-infrastructure/=lib/aave-delivery-infrastructure/", "aave-v3-origin-tests/=lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/tests/", "ds-test/=lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "halmos-cheatcodes/=lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/", "hyperlane-monorepo/=lib/aave-delivery-infrastructure/lib/hyperlane-monorepo/solidity/contracts/", "openzeppelin-contracts-upgradeable/=lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "shanghai", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"components":[{"internalType":"address","name":"defaultAdmin","type":"address"},{"internalType":"address","name":"retryGuardian","type":"address"},{"internalType":"address","name":"solveEmergencyGuardian","type":"address"}],"internalType":"struct IGranularGuardianAccessControl.InitialGuardians","name":"initialGuardians","type":"tuple"},{"internalType":"address","name":"crossChainController","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"CrossChainControllerCantBe0","type":"error"},{"inputs":[],"name":"DefaultAdminCantBe0","type":"error"},{"inputs":[],"name":"NewGuardianCantBe0","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"CROSS_CHAIN_CONTROLLER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RETRY_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SOLVE_EMERGENCY_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMembers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"origin","type":"address"},{"internalType":"address","name":"destination","type":"address"},{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"}],"internalType":"struct Envelope","name":"envelope","type":"tuple"},{"internalType":"uint256","name":"gasLimit","type":"uint256"}],"name":"retryEnvelope","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedTransaction","type":"bytes"},{"internalType":"uint256","name":"gasLimit","type":"uint256"},{"internalType":"address[]","name":"bridgeAdaptersToRetry","type":"address[]"}],"name":"retryTransaction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"uint8","name":"requiredConfirmations","type":"uint8"}],"internalType":"struct ICrossChainReceiver.ConfirmationInput[]","name":"newConfirmations","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"uint120","name":"validityTimestamp","type":"uint120"}],"internalType":"struct ICrossChainReceiver.ValidityTimestampInput[]","name":"newValidityTimestamp","type":"tuple[]"},{"components":[{"internalType":"address","name":"bridgeAdapter","type":"address"},{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"}],"internalType":"struct ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[]","name":"receiverBridgeAdaptersToAllow","type":"tuple[]"},{"components":[{"internalType":"address","name":"bridgeAdapter","type":"address"},{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"}],"internalType":"struct ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[]","name":"receiverBridgeAdaptersToDisallow","type":"tuple[]"},{"internalType":"address[]","name":"sendersToApprove","type":"address[]"},{"internalType":"address[]","name":"sendersToRemove","type":"address[]"},{"components":[{"internalType":"address","name":"currentChainBridgeAdapter","type":"address"},{"internalType":"address","name":"destinationBridgeAdapter","type":"address"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"}],"internalType":"struct ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[]","name":"forwarderBridgeAdaptersToEnable","type":"tuple[]"},{"components":[{"internalType":"address","name":"bridgeAdapter","type":"address"},{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"}],"internalType":"struct ICrossChainForwarder.BridgeAdapterToDisable[]","name":"forwarderBridgeAdaptersToDisable","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"uint256","name":"optimalBandwidth","type":"uint256"}],"internalType":"struct ICrossChainForwarder.OptimalBandwidthByChain[]","name":"optimalBandwidthByChain","type":"tuple[]"}],"name":"solveEmergency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"uint8","name":"requiredConfirmations","type":"uint8"}],"internalType":"struct ICrossChainReceiver.ConfirmationInput[]","name":"newConfirmations","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"uint120","name":"validityTimestamp","type":"uint120"}],"internalType":"struct ICrossChainReceiver.ValidityTimestampInput[]","name":"newValidityTimestamp","type":"tuple[]"},{"components":[{"internalType":"address","name":"bridgeAdapter","type":"address"},{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"}],"internalType":"struct ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[]","name":"receiverBridgeAdaptersToAllow","type":"tuple[]"},{"components":[{"internalType":"address","name":"bridgeAdapter","type":"address"},{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"}],"internalType":"struct ICrossChainReceiver.ReceiverBridgeAdapterConfigInput[]","name":"receiverBridgeAdaptersToDisallow","type":"tuple[]"},{"internalType":"address[]","name":"sendersToApprove","type":"address[]"},{"internalType":"address[]","name":"sendersToRemove","type":"address[]"},{"components":[{"internalType":"address","name":"currentChainBridgeAdapter","type":"address"},{"internalType":"address","name":"destinationBridgeAdapter","type":"address"},{"internalType":"uint256","name":"destinationChainId","type":"uint256"}],"internalType":"struct ICrossChainForwarder.ForwarderBridgeAdapterConfigInput[]","name":"forwarderBridgeAdaptersToEnable","type":"tuple[]"},{"components":[{"internalType":"address","name":"bridgeAdapter","type":"address"},{"internalType":"uint256[]","name":"chainIds","type":"uint256[]"}],"internalType":"struct ICrossChainForwarder.BridgeAdapterToDisable[]","name":"forwarderBridgeAdaptersToDisable","type":"tuple[]"}],"name":"solveEmergencyDeprecated","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newCrossChainControllerGuardian","type":"address"}],"name":"updateGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a060405234801562000010575f80fd5b5060405162001ce038038062001ce0833981016040819052620000339162000299565b6001600160a01b0381166200005b57604051639c9ea1e760e01b815260040160405180910390fd5b81516001600160a01b0316620000835760405162d11f8960e11b815260040160405180910390fd5b6001600160a01b03811660805281516200009f905f9062000140565b5060408201516001600160a01b031615620000ec57620000ea7ff4cdc679c22cbf47d6de8e836ce79ffdae51f38408dcde3f0645de7634fa607d83604001516200014060201b60201c565b505b60208201516001600160a01b0316156200013857620001367fc448b9502bbdf9850cc39823b6ea40cfe96d3ac63008e89edd2b8e98c6cc0af383602001516200014060201b60201c565b505b505062000339565b5f806200014e84846200017b565b9050801562000172575f84815260016020526040902062000170908462000226565b505b90505b92915050565b5f828152602081815260408083206001600160a01b038516845290915281205460ff166200021e575f838152602081815260408083206001600160a01b03861684529091529020805460ff19166001179055620001d53390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a450600162000175565b505f62000175565b5f62000172836001600160a01b0384165f8181526001830160205260408120546200021e57508154600181810184555f84815260208082209093018490558454848252828601909352604090209190915562000175565b80516001600160a01b038116811462000294575f80fd5b919050565b5f808284036080811215620002ac575f80fd5b6060811215620002ba575f80fd5b50604051606081016001600160401b0381118282101715620002ea57634e487b7160e01b5f52604160045260245ffd5b604052620002f8846200027d565b815262000308602085016200027d565b60208201526200031b604085016200027d565b6040820152915062000330606084016200027d565b90509250929050565b60805161196b620003755f395f81816102860152818161035f0152818161048001528181610574015281816106960152610732015261196b5ff3fe608060405234801561000f575f80fd5b5060043610610111575f3560e01c806391d148541161009e578063c49563661161006e578063c495636614610281578063ca15c873146102a8578063d547741f146102bb578063fc525395146102ce578063fea15fae146102e1575f80fd5b806391d1485414610234578063a217fddf14610247578063a25d38921461024e578063a3246ad314610261575f80fd5b80632f2ff15d116100e45780632f2ff15d146101a957806336568abe146101bc5780633eb59f60146101cf5780637655914a146101e25780639010d07c14610209575f80fd5b806301ffc9a7146101155780631bb94c011461013d578063248a9ca3146101525780632559e40a14610182575b5f80fd5b610128610123366004610b74565b6102f4565b60405190151581526020015b60405180910390f35b61015061014b36600461103e565b61031e565b005b610174610160366004611194565b5f9081526020819052604090206001015490565b604051908152602001610134565b6101747fc448b9502bbdf9850cc39823b6ea40cfe96d3ac63008e89edd2b8e98c6cc0af381565b6101506101b73660046111ab565b6103dd565b6101506101ca3660046111ab565b610407565b6101506101dd366004611241565b61043f565b6101747ff4cdc679c22cbf47d6de8e836ce79ffdae51f38408dcde3f0645de7634fa607d81565b61021c6102173660046112a9565b6104ec565b6040516001600160a01b039091168152602001610134565b6101286102423660046111ab565b61050a565b6101745f81565b61017461025c3660046112c9565b610532565b61027461026f366004611194565b6105f3565b60405161013491906113bc565b61021c7f000000000000000000000000000000000000000000000000000000000000000081565b6101746102b6366004611194565b61060c565b6101506102c93660046111ab565b610622565b6101506102dc3660046113ce565b610646565b6101506102ef3660046113e7565b6106f1565b5f6001600160e01b03198216635a05180f60e01b14806103185750610318826107ad565b92915050565b7ff4cdc679c22cbf47d6de8e836ce79ffdae51f38408dcde3f0645de7634fa607d610348816107e1565b604051631bb94c0160e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631bb94c01906103a4908d908d908d908d908d908d908d908d908d9060040161167a565b5f604051808303815f87803b1580156103bb575f80fd5b505af11580156103cd573d5f803e3d5ffd5b5050505050505050505050505050565b5f828152602081905260409020600101546103f7816107e1565b61040183836107ee565b50505050565b6001600160a01b03811633146104305760405163334bd91960e11b815260040160405180910390fd5b61043a8282610821565b505050565b7fc448b9502bbdf9850cc39823b6ea40cfe96d3ac63008e89edd2b8e98c6cc0af3610469816107e1565b6040516301f5acfb60e51b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633eb59f60906104b9908790879087906004016117b2565b5f604051808303815f87803b1580156104d0575f80fd5b505af11580156104e2573d5f803e3d5ffd5b5050505050505050565b5f828152600160205260408120610503908361084c565b9392505050565b5f918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b5f7fc448b9502bbdf9850cc39823b6ea40cfe96d3ac63008e89edd2b8e98c6cc0af361055d816107e1565b60405163512e9c4960e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063a25d3892906105ab90879087906004016117e6565b6020604051808303815f875af11580156105c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105eb9190611852565b949350505050565b5f81815260016020526040902060609061031890610857565b5f81815260016020526040812061031890610863565b5f8281526020819052604090206001015461063c816107e1565b6104018383610821565b5f610650816107e1565b6001600160a01b03821661067757604051632f000de560e21b815260040160405180910390fd5b60405163fc52539560e01b81526001600160a01b0383811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063fc525395906024015f604051808303815f87803b1580156106d7575f80fd5b505af11580156106e9573d5f803e3d5ffd5b505050505050565b7ff4cdc679c22cbf47d6de8e836ce79ffdae51f38408dcde3f0645de7634fa607d61071b816107e1565b604051630c5ca18360e41b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c5ca183090610775908c908c908c908c908c908c908c908c90600401611869565b5f604051808303815f87803b15801561078c575f80fd5b505af115801561079e573d5f803e3d5ffd5b50505050505050505050505050565b5f6001600160e01b03198216637965db0b60e01b148061031857506301ffc9a760e01b6001600160e01b0319831614610318565b6107eb813361086c565b50565b5f806107fa84846108ad565b90508015610503575f848152600160205260409020610819908461093c565b509392505050565b5f8061082d8484610950565b90508015610503575f84815260016020526040902061081990846109b9565b5f61050383836109cd565b60605f610503836109f3565b5f610318825490565b610876828261050a565b6108a95760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440160405180910390fd5b5050565b5f6108b8838361050a565b610935575f838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556108ed3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610318565b505f610318565b5f610503836001600160a01b038416610a4c565b5f61095b838361050a565b15610935575f838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610318565b5f610503836001600160a01b038416610a91565b5f825f0182815481106109e2576109e2611917565b905f5260205f200154905092915050565b6060815f01805480602002602001604051908101604052809291908181526020018280548015610a4057602002820191905f5260205f20905b815481526020019060010190808311610a2c575b50505050509050919050565b5f81815260018301602052604081205461093557508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610318565b5f8181526001830160205260408120548015610b6b575f610ab360018361192b565b85549091505f90610ac69060019061192b565b9050808214610b25575f865f018281548110610ae457610ae4611917565b905f5260205f200154905080875f018481548110610b0457610b04611917565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080610b3657610b3661194a565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610318565b5f915050610318565b5f60208284031215610b84575f80fd5b81356001600160e01b031981168114610503575f80fd5b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715610bd257610bd2610b9b565b60405290565b6040516060810167ffffffffffffffff81118282101715610bd257610bd2610b9b565b60405160c0810167ffffffffffffffff81118282101715610bd257610bd2610b9b565b604051601f8201601f1916810167ffffffffffffffff81118282101715610c4757610c47610b9b565b604052919050565b5f67ffffffffffffffff821115610c6857610c68610b9b565b5060051b60200190565b5f82601f830112610c81575f80fd5b81356020610c96610c9183610c4f565b610c1e565b82815260069290921b84018101918181019086841115610cb4575f80fd5b8286015b84811015610cff5760408189031215610ccf575f80fd5b610cd7610baf565b813581528482013560ff81168114610ced575f80fd5b81860152835291830191604001610cb8565b509695505050505050565b5f82601f830112610d19575f80fd5b81356020610d29610c9183610c4f565b82815260069290921b84018101918181019086841115610d47575f80fd5b8286015b84811015610cff5760408189031215610d62575f80fd5b610d6a610baf565b81358152848201356001600160781b0381168114610d86575f80fd5b81860152835291830191604001610d4b565b80356001600160a01b0381168114610dae575f80fd5b919050565b5f82601f830112610dc2575f80fd5b81356020610dd2610c9183610c4f565b828152600592831b8501820192828201919087851115610df0575f80fd5b8387015b85811015610ec457803567ffffffffffffffff80821115610e13575f80fd5b908901906040828c03601f1901811315610e2b575f80fd5b610e33610baf565b610e3e898501610d98565b81528184013583811115610e50575f80fd5b8085019450508c603f850112610e64575f80fd5b888401359250610e76610c9184610c4f565b83815292861b8401820192898101908e851115610e91575f80fd5b948301945b84861015610eaf5785358252948a0194908a0190610e96565b828b0152508752505050928401928401610df4565b5090979650505050505050565b5f82601f830112610ee0575f80fd5b81356020610ef0610c9183610c4f565b8083825260208201915060208460051b870101935086841115610f11575f80fd5b602086015b84811015610cff57610f2781610d98565b8352918301918301610f16565b5f82601f830112610f43575f80fd5b81356020610f53610c9183610c4f565b82815260609283028501820192828201919087851115610f71575f80fd5b8387015b85811015610ec45781818a031215610f8b575f80fd5b610f93610bd8565b610f9c82610d98565b8152610fa9868301610d98565b81870152604082810135908201528452928401928101610f75565b5f82601f830112610fd3575f80fd5b81356020610fe3610c9183610c4f565b82815260069290921b84018101918181019086841115611001575f80fd5b8286015b84811015610cff576040818903121561101c575f80fd5b611024610baf565b813581528482013585820152835291830191604001611005565b5f805f805f805f805f6101208a8c031215611057575f80fd5b893567ffffffffffffffff8082111561106e575f80fd5b61107a8d838e01610c72565b9a5060208c013591508082111561108f575f80fd5b61109b8d838e01610d0a565b995060408c01359150808211156110b0575f80fd5b6110bc8d838e01610db3565b985060608c01359150808211156110d1575f80fd5b6110dd8d838e01610db3565b975060808c01359150808211156110f2575f80fd5b6110fe8d838e01610ed1565b965060a08c0135915080821115611113575f80fd5b61111f8d838e01610ed1565b955060c08c0135915080821115611134575f80fd5b6111408d838e01610f34565b945060e08c0135915080821115611155575f80fd5b6111618d838e01610db3565b93506101008c0135915080821115611177575f80fd5b506111848c828d01610fc4565b9150509295985092959850929598565b5f602082840312156111a4575f80fd5b5035919050565b5f80604083850312156111bc575f80fd5b823591506111cc60208401610d98565b90509250929050565b5f82601f8301126111e4575f80fd5b813567ffffffffffffffff8111156111fe576111fe610b9b565b611211601f8201601f1916602001610c1e565b818152846020838601011115611225575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f60608486031215611253575f80fd5b833567ffffffffffffffff8082111561126a575f80fd5b611276878388016111d5565b9450602086013593506040860135915080821115611292575f80fd5b5061129f86828701610ed1565b9150509250925092565b5f80604083850312156112ba575f80fd5b50508035926020909101359150565b5f80604083850312156112da575f80fd5b823567ffffffffffffffff808211156112f1575f80fd5b9084019060c08287031215611304575f80fd5b61130c610bfb565b8235815261131c60208401610d98565b602082015261132d60408401610d98565b6040820152606083013560608201526080830135608082015260a083013582811115611357575f80fd5b611363888286016111d5565b60a0830152509660209590950135955050505050565b5f815180845260208085019450602084015f5b838110156113b15781516001600160a01b03168752958201959082019060010161138c565b509495945050505050565b602081525f6105036020830184611379565b5f602082840312156113de575f80fd5b61050382610d98565b5f805f805f805f80610100898b0312156113ff575f80fd5b883567ffffffffffffffff80821115611416575f80fd5b6114228c838d01610c72565b995060208b0135915080821115611437575f80fd5b6114438c838d01610d0a565b985060408b0135915080821115611458575f80fd5b6114648c838d01610db3565b975060608b0135915080821115611479575f80fd5b6114858c838d01610db3565b965060808b013591508082111561149a575f80fd5b6114a68c838d01610ed1565b955060a08b01359150808211156114bb575f80fd5b6114c78c838d01610ed1565b945060c08b01359150808211156114dc575f80fd5b6114e88c838d01610f34565b935060e08b01359150808211156114fd575f80fd5b5061150a8b828c01610db3565b9150509295985092959890939650565b5f815180845260208085019450602084015f5b838110156113b15781518051885283015160ff16838801526040909601959082019060010161152d565b5f815180845260208085019450602084015f5b838110156113b1578151805188528301516001600160781b0316838801526040909601959082019060010161156a565b5f82825180855260208086019550808260051b8401018186015f5b84811015610ec457858303601f19018952815180516001600160a01b03168452840151604085850181905281519085018190529085019060608501905f905b8082101561161457835183529287019291870191600191909101906115f4565b505099850199935050908301906001016115b5565b5f815180845260208085019450602084015f5b838110156113b157815180516001600160a01b039081168952848201511684890152604090810151908801526060909601959082019060010161163c565b5f61012080835261168d8184018d61151a565b90506020838203818501526116a2828d611557565b9150604084830360408601526116b8838d61159a565b925084830360608601526116cc838c61159a565b925084830360808601526116e0838b611379565b925084830360a08601526116f4838a611379565b925084830360c08601526117088389611629565b925084830360e086015261171c838861159a565b85810361010087015286518082528388019450908301905f5b8181101561175a57855180518452850151858401529484019491830191600101611735565b50909f9e505050505050505050505050505050565b5f81518084525f5b8181101561179357602081850181015186830182015201611777565b505f602082860101526020601f19601f83011685010191505092915050565b606081525f6117c4606083018661176f565b84602084015282810360408401526117dc8185611379565b9695505050505050565b60408152825160408201525f602084015160018060a01b0380821660608501528060408701511660808501525050606084015160a0830152608084015160c083015260a084015160c060e084015261184261010084018261176f565b9150508260208301529392505050565b5f60208284031215611862575f80fd5b5051919050565b5f61010080835261187c8184018c61151a565b90508281036020840152611890818b611557565b905082810360408401526118a4818a61159a565b905082810360608401526118b8818961159a565b905082810360808401526118cc8188611379565b905082810360a08401526118e08187611379565b905082810360c08401526118f48186611629565b905082810360e0840152611908818561159a565b9b9a5050505050505050505050565b634e487b7160e01b5f52603260045260245ffd5b8181038181111561031857634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603160045260245ffdfea164736f6c6343000816000a0000000000000000000000007b62461a3570c6ac8a9f8330421576e417b71ee70000000000000000000000007837d7a167732ae41627a3b829871d9e32e2e7f200000000000000000000000063c4422d6cc849549daeb600b7ece52bd18fad7f00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610111575f3560e01c806391d148541161009e578063c49563661161006e578063c495636614610281578063ca15c873146102a8578063d547741f146102bb578063fc525395146102ce578063fea15fae146102e1575f80fd5b806391d1485414610234578063a217fddf14610247578063a25d38921461024e578063a3246ad314610261575f80fd5b80632f2ff15d116100e45780632f2ff15d146101a957806336568abe146101bc5780633eb59f60146101cf5780637655914a146101e25780639010d07c14610209575f80fd5b806301ffc9a7146101155780631bb94c011461013d578063248a9ca3146101525780632559e40a14610182575b5f80fd5b610128610123366004610b74565b6102f4565b60405190151581526020015b60405180910390f35b61015061014b36600461103e565b61031e565b005b610174610160366004611194565b5f9081526020819052604090206001015490565b604051908152602001610134565b6101747fc448b9502bbdf9850cc39823b6ea40cfe96d3ac63008e89edd2b8e98c6cc0af381565b6101506101b73660046111ab565b6103dd565b6101506101ca3660046111ab565b610407565b6101506101dd366004611241565b61043f565b6101747ff4cdc679c22cbf47d6de8e836ce79ffdae51f38408dcde3f0645de7634fa607d81565b61021c6102173660046112a9565b6104ec565b6040516001600160a01b039091168152602001610134565b6101286102423660046111ab565b61050a565b6101745f81565b61017461025c3660046112c9565b610532565b61027461026f366004611194565b6105f3565b60405161013491906113bc565b61021c7f00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c81565b6101746102b6366004611194565b61060c565b6101506102c93660046111ab565b610622565b6101506102dc3660046113ce565b610646565b6101506102ef3660046113e7565b6106f1565b5f6001600160e01b03198216635a05180f60e01b14806103185750610318826107ad565b92915050565b7ff4cdc679c22cbf47d6de8e836ce79ffdae51f38408dcde3f0645de7634fa607d610348816107e1565b604051631bb94c0160e01b81526001600160a01b037f00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c1690631bb94c01906103a4908d908d908d908d908d908d908d908d908d9060040161167a565b5f604051808303815f87803b1580156103bb575f80fd5b505af11580156103cd573d5f803e3d5ffd5b5050505050505050505050505050565b5f828152602081905260409020600101546103f7816107e1565b61040183836107ee565b50505050565b6001600160a01b03811633146104305760405163334bd91960e11b815260040160405180910390fd5b61043a8282610821565b505050565b7fc448b9502bbdf9850cc39823b6ea40cfe96d3ac63008e89edd2b8e98c6cc0af3610469816107e1565b6040516301f5acfb60e51b81526001600160a01b037f00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c1690633eb59f60906104b9908790879087906004016117b2565b5f604051808303815f87803b1580156104d0575f80fd5b505af11580156104e2573d5f803e3d5ffd5b5050505050505050565b5f828152600160205260408120610503908361084c565b9392505050565b5f918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b5f7fc448b9502bbdf9850cc39823b6ea40cfe96d3ac63008e89edd2b8e98c6cc0af361055d816107e1565b60405163512e9c4960e11b81526001600160a01b037f00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c169063a25d3892906105ab90879087906004016117e6565b6020604051808303815f875af11580156105c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105eb9190611852565b949350505050565b5f81815260016020526040902060609061031890610857565b5f81815260016020526040812061031890610863565b5f8281526020819052604090206001015461063c816107e1565b6104018383610821565b5f610650816107e1565b6001600160a01b03821661067757604051632f000de560e21b815260040160405180910390fd5b60405163fc52539560e01b81526001600160a01b0383811660048301527f00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c169063fc525395906024015f604051808303815f87803b1580156106d7575f80fd5b505af11580156106e9573d5f803e3d5ffd5b505050505050565b7ff4cdc679c22cbf47d6de8e836ce79ffdae51f38408dcde3f0645de7634fa607d61071b816107e1565b604051630c5ca18360e41b81526001600160a01b037f00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c169063c5ca183090610775908c908c908c908c908c908c908c908c90600401611869565b5f604051808303815f87803b15801561078c575f80fd5b505af115801561079e573d5f803e3d5ffd5b50505050505050505050505050565b5f6001600160e01b03198216637965db0b60e01b148061031857506301ffc9a760e01b6001600160e01b0319831614610318565b6107eb813361086c565b50565b5f806107fa84846108ad565b90508015610503575f848152600160205260409020610819908461093c565b509392505050565b5f8061082d8484610950565b90508015610503575f84815260016020526040902061081990846109b9565b5f61050383836109cd565b60605f610503836109f3565b5f610318825490565b610876828261050a565b6108a95760405163e2517d3f60e01b81526001600160a01b03821660048201526024810183905260440160405180910390fd5b5050565b5f6108b8838361050a565b610935575f838152602081815260408083206001600160a01b03861684529091529020805460ff191660011790556108ed3390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610318565b505f610318565b5f610503836001600160a01b038416610a4c565b5f61095b838361050a565b15610935575f838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610318565b5f610503836001600160a01b038416610a91565b5f825f0182815481106109e2576109e2611917565b905f5260205f200154905092915050565b6060815f01805480602002602001604051908101604052809291908181526020018280548015610a4057602002820191905f5260205f20905b815481526020019060010190808311610a2c575b50505050509050919050565b5f81815260018301602052604081205461093557508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610318565b5f8181526001830160205260408120548015610b6b575f610ab360018361192b565b85549091505f90610ac69060019061192b565b9050808214610b25575f865f018281548110610ae457610ae4611917565b905f5260205f200154905080875f018481548110610b0457610b04611917565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080610b3657610b3661194a565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610318565b5f915050610318565b5f60208284031215610b84575f80fd5b81356001600160e01b031981168114610503575f80fd5b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715610bd257610bd2610b9b565b60405290565b6040516060810167ffffffffffffffff81118282101715610bd257610bd2610b9b565b60405160c0810167ffffffffffffffff81118282101715610bd257610bd2610b9b565b604051601f8201601f1916810167ffffffffffffffff81118282101715610c4757610c47610b9b565b604052919050565b5f67ffffffffffffffff821115610c6857610c68610b9b565b5060051b60200190565b5f82601f830112610c81575f80fd5b81356020610c96610c9183610c4f565b610c1e565b82815260069290921b84018101918181019086841115610cb4575f80fd5b8286015b84811015610cff5760408189031215610ccf575f80fd5b610cd7610baf565b813581528482013560ff81168114610ced575f80fd5b81860152835291830191604001610cb8565b509695505050505050565b5f82601f830112610d19575f80fd5b81356020610d29610c9183610c4f565b82815260069290921b84018101918181019086841115610d47575f80fd5b8286015b84811015610cff5760408189031215610d62575f80fd5b610d6a610baf565b81358152848201356001600160781b0381168114610d86575f80fd5b81860152835291830191604001610d4b565b80356001600160a01b0381168114610dae575f80fd5b919050565b5f82601f830112610dc2575f80fd5b81356020610dd2610c9183610c4f565b828152600592831b8501820192828201919087851115610df0575f80fd5b8387015b85811015610ec457803567ffffffffffffffff80821115610e13575f80fd5b908901906040828c03601f1901811315610e2b575f80fd5b610e33610baf565b610e3e898501610d98565b81528184013583811115610e50575f80fd5b8085019450508c603f850112610e64575f80fd5b888401359250610e76610c9184610c4f565b83815292861b8401820192898101908e851115610e91575f80fd5b948301945b84861015610eaf5785358252948a0194908a0190610e96565b828b0152508752505050928401928401610df4565b5090979650505050505050565b5f82601f830112610ee0575f80fd5b81356020610ef0610c9183610c4f565b8083825260208201915060208460051b870101935086841115610f11575f80fd5b602086015b84811015610cff57610f2781610d98565b8352918301918301610f16565b5f82601f830112610f43575f80fd5b81356020610f53610c9183610c4f565b82815260609283028501820192828201919087851115610f71575f80fd5b8387015b85811015610ec45781818a031215610f8b575f80fd5b610f93610bd8565b610f9c82610d98565b8152610fa9868301610d98565b81870152604082810135908201528452928401928101610f75565b5f82601f830112610fd3575f80fd5b81356020610fe3610c9183610c4f565b82815260069290921b84018101918181019086841115611001575f80fd5b8286015b84811015610cff576040818903121561101c575f80fd5b611024610baf565b813581528482013585820152835291830191604001611005565b5f805f805f805f805f6101208a8c031215611057575f80fd5b893567ffffffffffffffff8082111561106e575f80fd5b61107a8d838e01610c72565b9a5060208c013591508082111561108f575f80fd5b61109b8d838e01610d0a565b995060408c01359150808211156110b0575f80fd5b6110bc8d838e01610db3565b985060608c01359150808211156110d1575f80fd5b6110dd8d838e01610db3565b975060808c01359150808211156110f2575f80fd5b6110fe8d838e01610ed1565b965060a08c0135915080821115611113575f80fd5b61111f8d838e01610ed1565b955060c08c0135915080821115611134575f80fd5b6111408d838e01610f34565b945060e08c0135915080821115611155575f80fd5b6111618d838e01610db3565b93506101008c0135915080821115611177575f80fd5b506111848c828d01610fc4565b9150509295985092959850929598565b5f602082840312156111a4575f80fd5b5035919050565b5f80604083850312156111bc575f80fd5b823591506111cc60208401610d98565b90509250929050565b5f82601f8301126111e4575f80fd5b813567ffffffffffffffff8111156111fe576111fe610b9b565b611211601f8201601f1916602001610c1e565b818152846020838601011115611225575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f60608486031215611253575f80fd5b833567ffffffffffffffff8082111561126a575f80fd5b611276878388016111d5565b9450602086013593506040860135915080821115611292575f80fd5b5061129f86828701610ed1565b9150509250925092565b5f80604083850312156112ba575f80fd5b50508035926020909101359150565b5f80604083850312156112da575f80fd5b823567ffffffffffffffff808211156112f1575f80fd5b9084019060c08287031215611304575f80fd5b61130c610bfb565b8235815261131c60208401610d98565b602082015261132d60408401610d98565b6040820152606083013560608201526080830135608082015260a083013582811115611357575f80fd5b611363888286016111d5565b60a0830152509660209590950135955050505050565b5f815180845260208085019450602084015f5b838110156113b15781516001600160a01b03168752958201959082019060010161138c565b509495945050505050565b602081525f6105036020830184611379565b5f602082840312156113de575f80fd5b61050382610d98565b5f805f805f805f80610100898b0312156113ff575f80fd5b883567ffffffffffffffff80821115611416575f80fd5b6114228c838d01610c72565b995060208b0135915080821115611437575f80fd5b6114438c838d01610d0a565b985060408b0135915080821115611458575f80fd5b6114648c838d01610db3565b975060608b0135915080821115611479575f80fd5b6114858c838d01610db3565b965060808b013591508082111561149a575f80fd5b6114a68c838d01610ed1565b955060a08b01359150808211156114bb575f80fd5b6114c78c838d01610ed1565b945060c08b01359150808211156114dc575f80fd5b6114e88c838d01610f34565b935060e08b01359150808211156114fd575f80fd5b5061150a8b828c01610db3565b9150509295985092959890939650565b5f815180845260208085019450602084015f5b838110156113b15781518051885283015160ff16838801526040909601959082019060010161152d565b5f815180845260208085019450602084015f5b838110156113b1578151805188528301516001600160781b0316838801526040909601959082019060010161156a565b5f82825180855260208086019550808260051b8401018186015f5b84811015610ec457858303601f19018952815180516001600160a01b03168452840151604085850181905281519085018190529085019060608501905f905b8082101561161457835183529287019291870191600191909101906115f4565b505099850199935050908301906001016115b5565b5f815180845260208085019450602084015f5b838110156113b157815180516001600160a01b039081168952848201511684890152604090810151908801526060909601959082019060010161163c565b5f61012080835261168d8184018d61151a565b90506020838203818501526116a2828d611557565b9150604084830360408601526116b8838d61159a565b925084830360608601526116cc838c61159a565b925084830360808601526116e0838b611379565b925084830360a08601526116f4838a611379565b925084830360c08601526117088389611629565b925084830360e086015261171c838861159a565b85810361010087015286518082528388019450908301905f5b8181101561175a57855180518452850151858401529484019491830191600101611735565b50909f9e505050505050505050505050505050565b5f81518084525f5b8181101561179357602081850181015186830182015201611777565b505f602082860101526020601f19601f83011685010191505092915050565b606081525f6117c4606083018661176f565b84602084015282810360408401526117dc8185611379565b9695505050505050565b60408152825160408201525f602084015160018060a01b0380821660608501528060408701511660808501525050606084015160a0830152608084015160c083015260a084015160c060e084015261184261010084018261176f565b9150508260208301529392505050565b5f60208284031215611862575f80fd5b5051919050565b5f61010080835261187c8184018c61151a565b90508281036020840152611890818b611557565b905082810360408401526118a4818a61159a565b905082810360608401526118b8818961159a565b905082810360808401526118cc8188611379565b905082810360a08401526118e08187611379565b905082810360c08401526118f48186611629565b905082810360e0840152611908818561159a565b9b9a5050505050505050505050565b634e487b7160e01b5f52603260045260245ffd5b8181038181111561031857634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603160045260245ffdfea164736f6c6343000816000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007b62461a3570c6ac8a9f8330421576e417b71ee70000000000000000000000007837d7a167732ae41627a3b829871d9e32e2e7f200000000000000000000000063c4422d6cc849549daeb600b7ece52bd18fad7f00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c
-----Decoded View---------------
Arg [0] : initialGuardians (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [1] : crossChainController (address): 0x58e003a3C6f2Aeed6a2a6Bc77B504566523cb15c
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000007b62461a3570c6ac8a9f8330421576e417b71ee7
Arg [1] : 0000000000000000000000007837d7a167732ae41627a3b829871d9e32e2e7f2
Arg [2] : 00000000000000000000000063c4422d6cc849549daeb600b7ece52bd18fad7f
Arg [3] : 00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c
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.