Contract
0x2a3e72ed893b5958690e16c3bbe1bd92137b6250
9
Contract Overview
Balance:
0 AVAX
AVAX Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0xa2b2b170641b2d6ccc84f6384fddbff27f5bcc9644431f13de1fd6b787325297 | Initialize | 15530401 | 482 days 19 hrs ago | 0xb779daead6031ef189cad4ac438c991efe7635a7 | IN | 0x2a3e72ed893b5958690e16c3bbe1bd92137b6250 | 0 AVAX | 0.003115059702 | |
0xbdd942d5f435d70b6f3ab28f101881e3b529ef52428ae60dc85143df256240da | 0x60806040 | 11904998 | 568 days 2 hrs ago | 0xd6f0dabbbccd143f7d526a82ca176b5395ccc844 | IN | Create: SignatureVerifier | 0 AVAX | 0.057743912914 |
[ Download CSV Export ]
Contract Name:
SignatureVerifier
Compiler Version
v0.8.7+commit.e28d00a7
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.7; import "./OraclesManager.sol"; import "../interfaces/ISignatureVerifier.sol"; import "../libraries/SignatureUtil.sol"; /// @dev It's used to verify that a transfer is signed by oracles. contract SignatureVerifier is OraclesManager, ISignatureVerifier { using SignatureUtil for bytes; using SignatureUtil for bytes32; /* ========== STATE VARIABLES ========== */ /// @dev Number of required confirmations per block after the extra check is enabled uint8 public confirmationThreshold; /// @dev submissions count in current block uint40 public submissionsInBlock; /// @dev Current block uint40 public currentBlock; /// @dev Debridge gate address address public debridgeAddress; /* ========== ERRORS ========== */ error DeBridgeGateBadRole(); error NotConfirmedByRequiredOracles(); error NotConfirmedThreshold(); error SubmissionNotConfirmed(); error DuplicateSignatures(); /* ========== MODIFIERS ========== */ modifier onlyDeBridgeGate() { if (msg.sender != debridgeAddress) revert DeBridgeGateBadRole(); _; } /* ========== CONSTRUCTOR ========== */ /// @dev Constructor that initializes the most important configurations. /// @param _minConfirmations Common confirmations count. /// @param _confirmationThreshold Confirmations per block after the extra check is enabled. /// @param _excessConfirmations Confirmations count in case of excess activity. function initialize( uint8 _minConfirmations, uint8 _confirmationThreshold, uint8 _excessConfirmations, address _debridgeAddress ) public initializer { OraclesManager.initialize(_minConfirmations, _excessConfirmations); confirmationThreshold = _confirmationThreshold; debridgeAddress = _debridgeAddress; } /// @inheritdoc ISignatureVerifier function submit( bytes32 _submissionId, bytes memory _signatures, uint8 _excessConfirmations ) external override onlyDeBridgeGate { //Need confirmation to confirm submission uint8 needConfirmations = _excessConfirmations > minConfirmations ? _excessConfirmations : minConfirmations; // Count of required(DSRM) oracles confirmation uint256 currentRequiredOraclesCount; // stack variable to aggregate confirmations and write to storage once uint8 confirmations; uint256 signaturesCount = _countSignatures(_signatures); address[] memory validators = new address[](signaturesCount); for (uint256 i = 0; i < signaturesCount; i++) { (bytes32 r, bytes32 s, uint8 v) = _signatures.parseSignature(i * 65); address oracle = ecrecover(_submissionId.getUnsignedMsg(), v, r, s); if (getOracleInfo[oracle].isValid) { for (uint256 k = 0; k < i; k++) { if (validators[k] == oracle) revert DuplicateSignatures(); } validators[i] = oracle; confirmations += 1; emit Confirmed(_submissionId, oracle); if (getOracleInfo[oracle].required) { currentRequiredOraclesCount += 1; } if ( confirmations >= needConfirmations && currentRequiredOraclesCount >= requiredOraclesCount ) { break; } } } if (currentRequiredOraclesCount != requiredOraclesCount) revert NotConfirmedByRequiredOracles(); if (confirmations >= minConfirmations) { if (currentBlock == uint40(block.number)) { submissionsInBlock += 1; } else { currentBlock = uint40(block.number); submissionsInBlock = 1; } emit SubmissionApproved(_submissionId); } if (submissionsInBlock > confirmationThreshold) { if (confirmations < excessConfirmations) revert NotConfirmedThreshold(); } if (confirmations < needConfirmations) revert SubmissionNotConfirmed(); } /* ========== ADMIN ========== */ /// @dev Sets minimal required confirmations. /// @param _confirmationThreshold Confirmation info. function setThreshold(uint8 _confirmationThreshold) external onlyAdmin { if (_confirmationThreshold == 0) revert WrongArgument(); confirmationThreshold = _confirmationThreshold; } /// @dev Sets core debridge conrtact address. /// @param _debridgeAddress Debridge address. function setDebridgeAddress(address _debridgeAddress) external onlyAdmin { debridgeAddress = _debridgeAddress; } /* ========== VIEW ========== */ /// @dev Check is valid signature /// @param _submissionId Submission identifier. /// @param _signature signature by oracle. function isValidSignature(bytes32 _submissionId, bytes memory _signature) external view returns (bool) { (bytes32 r, bytes32 s, uint8 v) = _signature.splitSignature(); address oracle = ecrecover(_submissionId.getUnsignedMsg(), v, r, s); return getOracleInfo[oracle].isValid; } /* ========== INTERNAL ========== */ function _countSignatures(bytes memory _signatures) internal pure returns (uint256) { return _signatures.length % 65 == 0 ? _signatures.length / 65 : 0; } // ============ Version Control ============ /// @dev Get this contract's version function version() external pure returns (uint256) { return 201; // 2.0.1 } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.7; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "../interfaces/IOraclesManager.sol"; /// @dev The base contract for oracles management. Allows adding/removing oracles, /// managing the minimal required amount of confirmations. contract OraclesManager is Initializable, AccessControlUpgradeable, IOraclesManager { /* ========== STATE VARIABLES ========== */ /// @dev Minimal required confirmations uint8 public minConfirmations; /// @dev Minimal required confirmations in case of too many confirmations uint8 public excessConfirmations; /// @dev Count of required oracles uint8 public requiredOraclesCount; /// @dev Oracle addresses address[] public oracleAddresses; /// @dev Maps an oracle address to the oracle details mapping(address => OracleInfo) public getOracleInfo; /* ========== ERRORS ========== */ error AdminBadRole(); error OracleBadRole(); error OracleAlreadyExist(); error OracleNotFound(); error WrongArgument(); error LowMinConfirmations(); /* ========== MODIFIERS ========== */ modifier onlyAdmin() { if (!hasRole(DEFAULT_ADMIN_ROLE, msg.sender)) revert AdminBadRole(); _; } modifier onlyOracle() { if (!getOracleInfo[msg.sender].isValid) revert OracleBadRole(); _; } /* ========== CONSTRUCTOR ========== */ /// @dev Constructor that initializes the most important configurations. /// @param _minConfirmations Minimal required confirmations. /// @param _excessConfirmations Minimal required confirmations in case of too many confirmations. function initialize(uint8 _minConfirmations, uint8 _excessConfirmations) internal { if (_minConfirmations == 0 || _excessConfirmations < _minConfirmations) revert LowMinConfirmations(); minConfirmations = _minConfirmations; excessConfirmations = _excessConfirmations; _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); } /* ========== ADMIN ========== */ /// @dev Sets minimal required confirmations. /// @param _minConfirmations Minimal required confirmations. function setMinConfirmations(uint8 _minConfirmations) external onlyAdmin { if (_minConfirmations < oracleAddresses.length / 2 + 1) revert LowMinConfirmations(); minConfirmations = _minConfirmations; } /// @dev Sets minimal required confirmations in case of too many confirmations. /// @param _excessConfirmations Minimal required confirmations in case of too many confirmations. function setExcessConfirmations(uint8 _excessConfirmations) external onlyAdmin { if (_excessConfirmations < minConfirmations) revert LowMinConfirmations(); excessConfirmations = _excessConfirmations; } /// @dev Add oracles. /// @param _oracles Oracles' addresses. /// @param _required A transfer will not be confirmed without oracles having required set to true, function addOracles( address[] memory _oracles, bool[] memory _required ) external onlyAdmin { if (_oracles.length != _required.length) revert WrongArgument(); if (minConfirmations < (oracleAddresses.length + _oracles.length) / 2 + 1) revert LowMinConfirmations(); for (uint256 i = 0; i < _oracles.length; i++) { OracleInfo storage oracleInfo = getOracleInfo[_oracles[i]]; if (oracleInfo.exist) revert OracleAlreadyExist(); oracleAddresses.push(_oracles[i]); if (_required[i]) { requiredOraclesCount += 1; } oracleInfo.exist = true; oracleInfo.isValid = true; oracleInfo.required = _required[i]; emit AddOracle(_oracles[i], _required[i]); } } /// @dev Update an oracle. /// @param _oracle An oracle address. /// @param _isValid Is this oracle valid, i.e. should it be treated as an oracle. /// @param _required If set to true a transfer will not be confirmed without this oracle. function updateOracle( address _oracle, bool _isValid, bool _required ) external onlyAdmin { //If oracle is invalid, it must be not required if (!_isValid && _required) revert WrongArgument(); OracleInfo storage oracleInfo = getOracleInfo[_oracle]; if (!oracleInfo.exist) revert OracleNotFound(); if (oracleInfo.required && !_required) { requiredOraclesCount -= 1; } else if (!oracleInfo.required && _required) { requiredOraclesCount += 1; } if (oracleInfo.isValid && !_isValid) { // remove oracle from oracleAddresses array without keeping an order for (uint256 i = 0; i < oracleAddresses.length; i++) { if (oracleAddresses[i] == _oracle) { oracleAddresses[i] = oracleAddresses[oracleAddresses.length - 1]; oracleAddresses.pop(); break; } } } else if (!oracleInfo.isValid && _isValid) { if (minConfirmations < (oracleAddresses.length + 1) / 2 + 1) revert LowMinConfirmations(); oracleAddresses.push(_oracle); } oracleInfo.isValid = _isValid; oracleInfo.required = _required; emit UpdateOracle(_oracle, _required, _isValid); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.7; interface ISignatureVerifier { /* ========== EVENTS ========== */ /// @dev Emitted once the submission is confirmed by one oracle. event Confirmed(bytes32 submissionId, address operator); /// @dev Emitted once the submission is confirmed by min required amount of oracles. event DeployConfirmed(bytes32 deployId, address operator); /* ========== FUNCTIONS ========== */ /// @dev Check confirmation (validate signatures) for the transfer request. /// @param _submissionId Submission identifier. /// @param _signatures Array of signatures by oracles. /// @param _excessConfirmations override min confirmations count function submit( bytes32 _submissionId, bytes memory _signatures, uint8 _excessConfirmations ) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.7; library SignatureUtil { /* ========== ERRORS ========== */ error WrongArgumentLength(); error SignatureInvalidLength(); error SignatureInvalidV(); /// @dev Prepares raw msg that was signed by the oracle. /// @param _submissionId Submission identifier. function getUnsignedMsg(bytes32 _submissionId) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _submissionId)); } /// @dev Splits signature bytes to r,s,v components. /// @param _signature Signature bytes in format r+s+v. function splitSignature(bytes memory _signature) internal pure returns ( bytes32 r, bytes32 s, uint8 v ) { if (_signature.length != 65) revert SignatureInvalidLength(); return parseSignature(_signature, 0); } function parseSignature(bytes memory _signatures, uint256 offset) internal pure returns ( bytes32 r, bytes32 s, uint8 v ) { assembly { r := mload(add(_signatures, add(32, offset))) s := mload(add(_signatures, add(64, offset))) v := and(mload(add(_signatures, add(65, offset))), 0xff) } if (v < 27) v += 27; if (v != 27 && v != 28) revert SignatureInvalidV(); } function toUint256(bytes memory _bytes, uint256 _offset) internal pure returns (uint256 result) { if (_bytes.length < _offset + 32) revert WrongArgumentLength(); assembly { result := mload(add(add(_bytes, 0x20), _offset)) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControlUpgradeable.sol"; import "../utils/ContextUpgradeable.sol"; import "../utils/StringsUpgradeable.sol"; import "../utils/introspection/ERC165Upgradeable.sol"; import "../proxy/utils/Initializable.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: * * ``` * 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}: * * ``` * 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. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal initializer { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal initializer { } struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(uint160(account), 20), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @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 override 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. */ function grantRole(bytes32 role, address account) public virtual override 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. */ function revokeRole(bytes32 role, address account) public virtual override 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 `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @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 Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.7; interface IOraclesManager { /* ========== STRUCTS ========== */ struct OracleInfo { bool exist; // exist oracle bool isValid; // is valid oracle bool required; // without this oracle (DSRM), the transfer will not be confirmed } /* ========== EVENTS ========== */ /// @dev Emitted when an oracle is added /// @param oracle Address of an added oracle /// @param required Is this oracle's signature required for every transfer event AddOracle(address oracle, bool required); /// @dev Emitted when an oracle is updated /// @param oracle Address of an updated oracle /// @param required Is this oracle's signature required for every transfer /// @param isValid Is this oracle valid, i.e. should it be treated as an oracle event UpdateOracle(address oracle, bool required, bool isValid); /// @dev Emitted once the submission is confirmed by min required amount of oracles event DeployApproved(bytes32 deployId); /// @dev Emitted once the submission is confirmed by min required amount of oracles event SubmissionApproved(bytes32 submissionId); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @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. * * _Available since v3.1._ */ 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, an admin role * bearer except when using {AccessControl-_setupRole}. */ 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 `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 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); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal initializer { __ERC165_init_unchained(); } function __ERC165_init_unchained() internal initializer { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @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[EIP 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); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
[{"inputs":[],"name":"AdminBadRole","type":"error"},{"inputs":[],"name":"DeBridgeGateBadRole","type":"error"},{"inputs":[],"name":"DuplicateSignatures","type":"error"},{"inputs":[],"name":"LowMinConfirmations","type":"error"},{"inputs":[],"name":"NotConfirmedByRequiredOracles","type":"error"},{"inputs":[],"name":"NotConfirmedThreshold","type":"error"},{"inputs":[],"name":"OracleAlreadyExist","type":"error"},{"inputs":[],"name":"OracleBadRole","type":"error"},{"inputs":[],"name":"OracleNotFound","type":"error"},{"inputs":[],"name":"SignatureInvalidLength","type":"error"},{"inputs":[],"name":"SignatureInvalidV","type":"error"},{"inputs":[],"name":"SubmissionNotConfirmed","type":"error"},{"inputs":[],"name":"WrongArgument","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"bool","name":"required","type":"bool"}],"name":"AddOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"submissionId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"Confirmed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"deployId","type":"bytes32"}],"name":"DeployApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"deployId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"DeployConfirmed","type":"event"},{"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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"submissionId","type":"bytes32"}],"name":"SubmissionApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"bool","name":"required","type":"bool"},{"indexed":false,"internalType":"bool","name":"isValid","type":"bool"}],"name":"UpdateOracle","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_oracles","type":"address[]"},{"internalType":"bool[]","name":"_required","type":"bool[]"}],"name":"addOracles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confirmationThreshold","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentBlock","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debridgeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"excessConfirmations","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"getOracleInfo","outputs":[{"internalType":"bool","name":"exist","type":"bool"},{"internalType":"bool","name":"isValid","type":"bool"},{"internalType":"bool","name":"required","type":"bool"}],"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":"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":"uint8","name":"_minConfirmations","type":"uint8"},{"internalType":"uint8","name":"_confirmationThreshold","type":"uint8"},{"internalType":"uint8","name":"_excessConfirmations","type":"uint8"},{"internalType":"address","name":"_debridgeAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_submissionId","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minConfirmations","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"oracleAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requiredOraclesCount","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_debridgeAddress","type":"address"}],"name":"setDebridgeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_excessConfirmations","type":"uint8"}],"name":"setExcessConfirmations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_minConfirmations","type":"uint8"}],"name":"setMinConfirmations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_confirmationThreshold","type":"uint8"}],"name":"setThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"submissionsInBlock","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_submissionId","type":"bytes32"},{"internalType":"bytes","name":"_signatures","type":"bytes"},{"internalType":"uint8","name":"_excessConfirmations","type":"uint8"}],"name":"submit","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":"_oracle","type":"address"},{"internalType":"bool","name":"_isValid","type":"bool"},{"internalType":"bool","name":"_required","type":"bool"}],"name":"updateOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50611e46806100206000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c806391d14854116100de578063c4e7337711610097578063e12ed13c11610071578063e12ed13c146103de578063e5a98603146103f6578063e7c4393e14610409578063fceb17eb1461041657600080fd5b8063c4e7337714610386578063d547741f146103b8578063dc4bfb85146103cb57600080fd5b806391d14854146102de578063965d0a64146102f1578063a217fddf14610304578063b50492261461030c578063b9b556521461031f578063bfdb6b041461033157600080fd5b806332ea039a1161014b57806354fd4d501161012557806354fd4d501461028c578063698efb9514610293578063794a9c29146102a65780637c533fd3146102b957600080fd5b806332ea039a1461025357806336568abe146102665780634425bd9a1461027957600080fd5b806301ffc9a714610193578063140c0b1e146101bb5780631626ba7e146101d0578063248a9ca3146101e35780632f2ff15d146102145780632fa3ab6314610227575b600080fd5b6101a66101a1366004611ac3565b610423565b60405190151581526020015b60405180910390f35b6101ce6101c9366004611aed565b61045a565b005b6101a66101de366004611a38565b6104c8565b6102066101f13660046119f3565b60009081526065602052604090206001015490565b6040519081526020016101b2565b6101ce610222366004611a0c565b61056c565b609a5461023d90610100900464ffffffffff1681565b60405164ffffffffff90911681526020016101b2565b6101ce610261366004611aed565b610597565b6101ce610274366004611a0c565b610612565b6101ce61028736600461192c565b610695565b60c9610206565b6101ce6102a1366004611b08565b610917565b6101ce6102b43660046118e9565b610a18565b6097546102cc9062010000900460ff1681565b60405160ff90911681526020016101b2565b6101a66102ec366004611a0c565b610d9f565b6101ce6102ff366004611a75565b610dca565b610206600081565b6101ce61031a3660046118ce565b611210565b6097546102cc90610100900460ff1681565b61036761033f3660046118ce565b60996020526000908152604090205460ff808216916101008104821691620100009091041683565b60408051931515845291151560208401521515908201526060016101b2565b609a546103a090600160581b90046001600160a01b031681565b6040516001600160a01b0390911681526020016101b2565b6101ce6103c6366004611a0c565b611279565b6103a06103d93660046119f3565b61129f565b609a5461023d90600160301b900464ffffffffff1681565b6101ce610404366004611aed565b6112c9565b6097546102cc9060ff1681565b609a546102cc9060ff1681565b60006001600160e01b03198216637965db0b60e01b148061045457506301ffc9a760e01b6001600160e01b03198316145b92915050565b610465600033610d9f565b61048257604051636f4720fd60e11b815260040160405180910390fd5b60975460ff90811690821610156104ac5760405163412f84c160e11b815260040160405180910390fd5b6097805460ff9092166101000261ff0019909216919091179055565b6000806000806104d785611328565b925092509250600060016104ea88611367565b6040805160008152602081018083529290925260ff851690820152606081018690526080810185905260a0016020604051602081039080840390855afa158015610538573d6000803e3d6000fd5b505060408051601f1901516001600160a01b0316600090815260996020522054610100900460ff1698975050505050505050565b60008281526065602052604090206001015461058881336113ba565b610592838361141e565b505050565b6105a2600033610d9f565b6105bf57604051636f4720fd60e11b815260040160405180910390fd5b6098546105ce90600290611cbf565b6105d9906001611c59565b8160ff1610156105fc5760405163412f84c160e11b815260040160405180910390fd5b6097805460ff191660ff92909216919091179055565b6001600160a01b03811633146106875760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b61069182826114a4565b5050565b6106a0600033610d9f565b6106bd57604051636f4720fd60e11b815260040160405180910390fd5b80518251146106df57604051634668624160e01b815260040160405180910390fd5b81516098546002916106f091611c59565b6106fa9190611cbf565b610705906001611c59565b60975460ff16101561072a5760405163412f84c160e11b815260040160405180910390fd5b60005b82518110156105925760006099600085848151811061074e5761074e611de4565b6020908102919091018101516001600160a01b03168252810191909152604001600020805490915060ff161561079757604051633ad24c0760e11b815260040160405180910390fd5b60988483815181106107ab576107ab611de4565b60209081029190910181015182546001810184556000938452919092200180546001600160a01b0319166001600160a01b0390921691909117905582518390839081106107fa576107fa611de4565b60200260200101511561083f576001609760028282829054906101000a900460ff166108269190611c9a565b92506101000a81548160ff021916908360ff1602179055505b805461ffff1916610101178155825183908390811061086057610860611de4565b60209081029190910101518154901515620100000262ff00001990911617815583517fe755f450de2082b1e2a5be83219122e863839acc705c368b6e119432edfc360e908590849081106108b6576108b6611de4565b60200260200101518484815181106108d0576108d0611de4565b60200260200101516040516108fc9291906001600160a01b039290921682521515602082015260400190565b60405180910390a1508061090f81611d73565b91505061072d565b600054610100900460ff1680610930575060005460ff16155b6109935760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161067e565b600054610100900460ff161580156109b5576000805461ffff19166101011790555b6109bf858461150b565b609a80546001600160a01b038416600160581b027fff0000000000000000000000000000000000000000ffffffffffffffffffff0090911660ff8716171790558015610a11576000805461ff00191690555b5050505050565b610a23600033610d9f565b610a4057604051636f4720fd60e11b815260040160405180910390fd5b81158015610a4b5750805b15610a6957604051634668624160e01b815260040160405180910390fd5b6001600160a01b0383166000908152609960205260409020805460ff16610aa357604051630b0a0e0d60e21b815260040160405180910390fd5b805462010000900460ff168015610ab8575081155b15610af9576001609760028282829054906101000a900460ff16610adc9190611d09565b92506101000a81548160ff021916908360ff160217905550610b4b565b805462010000900460ff16158015610b0e5750815b15610b4b576001609760028282829054906101000a900460ff16610b329190611c9a565b92506101000a81548160ff021916908360ff1602179055505b8054610100900460ff168015610b5f575082155b15610c735760005b609854811015610c6d57846001600160a01b031660988281548110610b8e57610b8e611de4565b6000918252602090912001546001600160a01b03161415610c5b5760988054610bb990600190611cf2565b81548110610bc957610bc9611de4565b600091825260209091200154609880546001600160a01b039092169183908110610bf557610bf5611de4565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506098805480610c3457610c34611dce565b600082815260209020810160001990810180546001600160a01b0319169055019055610c6d565b80610c6581611d73565b915050610b67565b50610d23565b8054610100900460ff16158015610c875750825b15610d2357609854600290610c9d906001611c59565b610ca79190611cbf565b610cb2906001611c59565b60975460ff161015610cd75760405163412f84c160e11b815260040160405180910390fd5b609880546001810182556000919091527f2237a976fa961f5921fd19f2b03c925c725d77b20ce8f790c19709c03de4d8140180546001600160a01b0319166001600160a01b0386161790555b805462ffff00191661010084151590810262ff000019169190911762010000841515908102919091178355604080516001600160a01b038816815260208101929092528101919091527fd0a47d00eff59bee6da649bbe44f1e639db18f184bb4a80783cf8afd2a41e4609060600160405180910390a150505050565b60009182526065602090815260408084206001600160a01b0393909316845291905290205460ff1690565b609a54600160581b90046001600160a01b03163314610dfc576040516388a38fa160e01b815260040160405180910390fd5b60975460009060ff90811690831611610e1a5760975460ff16610e1c565b815b90506000806000610e2c86611564565b905060008167ffffffffffffffff811115610e4957610e49611dfa565b604051908082528060200260200182016040528015610e72578160200160208202803683370190505b50905060005b8281101561108f5760008080610e99610e92856041611cd3565b8c9061158e565b92509250925060006001610eac8e611367565b6040805160008152602081018083529290925260ff851690820152606081018690526080810185905260a0016020604051602081039080840390855afa158015610efa573d6000803e3d6000fd5b505060408051601f1901516001600160a01b038116600090815260996020529190912054909250610100900460ff161590506110785760005b85811015610f9957816001600160a01b0316878281518110610f5757610f57611de4565b60200260200101516001600160a01b03161415610f87576040516317ab4f2360e11b815260040160405180910390fd5b80610f9181611d73565b915050610f33565b5080868681518110610fad57610fad611de4565b6001600160a01b0390921660209283029190910190910152610fd0600189611c9a565b604080518f81526001600160a01b03841660208201529199507fd4964a7cd99f5c1fa8f2420fb5e1d3bd26eadf16e2658cf2e29a67dfda38601e910160405180910390a16001600160a01b03811660009081526099602052604090205462010000900460ff16156110495761104660018a611c59565b98505b8960ff168860ff161015801561106a575060975462010000900460ff168910155b15611078575050505061108f565b50505050808061108790611d73565b915050610e78565b5060975462010000900460ff1684146110bb576040516382635e4d60e01b815260040160405180910390fd5b60975460ff9081169084161061119657609a544364ffffffffff908116600160301b90920416141561112f576001609a60018282829054906101000a900464ffffffffff1661110a9190611c71565b92506101000a81548164ffffffffff021916908364ffffffffff160217905550611162565b609a805465ffffffffff001964ffffffffff4316600160301b02166affffffffffffffffffff0019909116176101001790555b6040518881527f2a6b4960c287d4d53a338f9c9a9f830f37e7b66e67a0a958f68be89a4eeb939d9060200160405180910390a15b609a5460ff811661010090910464ffffffffff1611156111df5760975460ff610100909104811690841610156111df576040516323d8dc8760e01b815260040160405180910390fd5b8460ff168360ff161015611206576040516374bb49d560e01b815260040160405180910390fd5b5050505050505050565b61121b600033610d9f565b61123857604051636f4720fd60e11b815260040160405180910390fd5b609a80546001600160a01b03909216600160581b027fff0000000000000000000000000000000000000000ffffffffffffffffffffff909216919091179055565b60008281526065602052604090206001015461129581336113ba565b61059283836114a4565b609881815481106112af57600080fd5b6000918252602090912001546001600160a01b0316905081565b6112d4600033610d9f565b6112f157604051636f4720fd60e11b815260040160405180910390fd5b60ff811661131257604051634668624160e01b815260040160405180910390fd5b609a805460ff191660ff92909216919091179055565b6000806000835160411461134f5760405163bb5ee95b60e01b815260040160405180910390fd5b61135a84600061158e565b9250925092509193909250565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b6113c48282610d9f565b610691576113dc816001600160a01b031660146115fb565b6113e78360206115fb565b6040516020016113f8929190611b5c565b60408051601f198184030181529082905262461bcd60e51b825261067e91600401611bd1565b6114288282610d9f565b6106915760008281526065602090815260408083206001600160a01b03851684529091529020805460ff191660011790556114603390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6114ae8282610d9f565b156106915760008281526065602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60ff8216158061152057508160ff168160ff16105b1561153e5760405163412f84c160e11b815260040160405180910390fd5b6097805460ff8381166101000261ffff199092169085161717905561069160003361179e565b6000604182516115749190611d8e565b15611580576000610454565b604182516104549190611cbf565b8181016020810151604082015160419092015190919060ff16601b8110156115be576115bb601b82611c9a565b90505b8060ff16601b141580156115d657508060ff16601c14155b156115f457604051630633a0a560e21b815260040160405180910390fd5b9250925092565b6060600061160a836002611cd3565b611615906002611c59565b67ffffffffffffffff81111561162d5761162d611dfa565b6040519080825280601f01601f191660200182016040528015611657576020820181803683370190505b509050600360fc1b8160008151811061167257611672611de4565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106116a1576116a1611de4565b60200101906001600160f81b031916908160001a90535060006116c5846002611cd3565b6116d0906001611c59565b90505b6001811115611748576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061170457611704611de4565b1a60f81b82828151811061171a5761171a611de4565b60200101906001600160f81b031916908160001a90535060049490941c9361174181611d5c565b90506116d3565b5083156117975760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161067e565b9392505050565b610691828261141e565b80356001600160a01b03811681146117bf57600080fd5b919050565b600082601f8301126117d557600080fd5b813560206117ea6117e583611c35565b611c04565b80838252828201915082860187848660051b890101111561180a57600080fd5b60005b858110156118305761181e8261183d565b8452928401929084019060010161180d565b5090979650505050505050565b803580151581146117bf57600080fd5b600082601f83011261185e57600080fd5b813567ffffffffffffffff81111561187857611878611dfa565b61188b601f8201601f1916602001611c04565b8181528460208386010111156118a057600080fd5b816020850160208301376000918101602001919091529392505050565b803560ff811681146117bf57600080fd5b6000602082840312156118e057600080fd5b611797826117a8565b6000806000606084860312156118fe57600080fd5b611907846117a8565b92506119156020850161183d565b91506119236040850161183d565b90509250925092565b6000806040838503121561193f57600080fd5b823567ffffffffffffffff8082111561195757600080fd5b818501915085601f83011261196b57600080fd5b8135602061197b6117e583611c35565b8083825282820191508286018a848660051b890101111561199b57600080fd5b600096505b848710156119c5576119b1816117a8565b8352600196909601959183019183016119a0565b50965050860135925050808211156119dc57600080fd5b506119e9858286016117c4565b9150509250929050565b600060208284031215611a0557600080fd5b5035919050565b60008060408385031215611a1f57600080fd5b82359150611a2f602084016117a8565b90509250929050565b60008060408385031215611a4b57600080fd5b82359150602083013567ffffffffffffffff811115611a6957600080fd5b6119e98582860161184d565b600080600060608486031215611a8a57600080fd5b83359250602084013567ffffffffffffffff811115611aa857600080fd5b611ab48682870161184d565b925050611923604085016118bd565b600060208284031215611ad557600080fd5b81356001600160e01b03198116811461179757600080fd5b600060208284031215611aff57600080fd5b611797826118bd565b60008060008060808587031215611b1e57600080fd5b611b27856118bd565b9350611b35602086016118bd565b9250611b43604086016118bd565b9150611b51606086016117a8565b905092959194509250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611b94816017850160208801611d2c565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611bc5816028840160208801611d2c565b01602801949350505050565b6020815260008251806020840152611bf0816040850160208701611d2c565b601f01601f19169190910160400192915050565b604051601f8201601f1916810167ffffffffffffffff81118282101715611c2d57611c2d611dfa565b604052919050565b600067ffffffffffffffff821115611c4f57611c4f611dfa565b5060051b60200190565b60008219821115611c6c57611c6c611da2565b500190565b600064ffffffffff808316818516808303821115611c9157611c91611da2565b01949350505050565b600060ff821660ff84168060ff03821115611cb757611cb7611da2565b019392505050565b600082611cce57611cce611db8565b500490565b6000816000190483118215151615611ced57611ced611da2565b500290565b600082821015611d0457611d04611da2565b500390565b600060ff821660ff841680821015611d2357611d23611da2565b90039392505050565b60005b83811015611d47578181015183820152602001611d2f565b83811115611d56576000848401525b50505050565b600081611d6b57611d6b611da2565b506000190190565b6000600019821415611d8757611d87611da2565b5060010190565b600082611d9d57611d9d611db8565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea2646970667358221220f9760b135eaaddb7ba8149166dcb4c51f3416673392a0c426438ec72a4163faf64736f6c63430008070033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.