More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 26 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Execute Proposal | 126276886 | 135 days ago | IN | 0 ETH | 0.000003399843 | ||||
Queue Proposal | 126233629 | 136 days ago | IN | 0 ETH | 0.000002327288 | ||||
Execute Proposal | 126054927 | 140 days ago | IN | 0 ETH | 0.000006799023 | ||||
Queue Proposal | 126011655 | 141 days ago | IN | 0 ETH | 0.000003671333 | ||||
Execute Proposal | 125103557 | 162 days ago | IN | 0 ETH | 0.000010441724 | ||||
Queue Proposal | 125060296 | 163 days ago | IN | 0 ETH | 0.000029546908 | ||||
Execute Proposal | 124861621 | 167 days ago | IN | 0 ETH | 0.000000962963 | ||||
Execute Proposal | 124861606 | 167 days ago | IN | 0 ETH | 0.000000912842 | ||||
Queue Proposal | 124860855 | 167 days ago | IN | 0 ETH | 0.000000208403 | ||||
Queue Proposal | 124816009 | 168 days ago | IN | 0 ETH | 0.000017036718 | ||||
Queue Proposal | 124815888 | 168 days ago | IN | 0 ETH | 0.000029924473 | ||||
Execute Proposal | 123949689 | 189 days ago | IN | 0 ETH | 0.00000085657 | ||||
Execute Proposal | 123949655 | 189 days ago | IN | 0 ETH | 0.000000908332 | ||||
Queue Proposal | 123905351 | 190 days ago | IN | 0 ETH | 0.000015141985 | ||||
Queue Proposal | 123904761 | 190 days ago | IN | 0 ETH | 0.000020914795 | ||||
Execute Proposal | 123872582 | 190 days ago | IN | 0 ETH | 0.000000516405 | ||||
Execute Proposal | 123866074 | 190 days ago | IN | 0 ETH | 0.000000900187 | ||||
Queue Proposal | 123828983 | 191 days ago | IN | 0 ETH | 0.000015444811 | ||||
Queue Proposal | 123821153 | 191 days ago | IN | 0 ETH | 0.000000868299 | ||||
Queue Proposal | 123821126 | 191 days ago | IN | 0 ETH | 0.000000508369 | ||||
Execute Proposal | 123345308 | 203 days ago | IN | 0 ETH | 0.000003828126 | ||||
Execute Proposal | 123345187 | 203 days ago | IN | 0 ETH | 0.000001211671 | ||||
Queue Proposal | 123301715 | 204 days ago | IN | 0 ETH | 0.00000039816 | ||||
Queue Proposal | 123301679 | 204 days ago | IN | 0 ETH | 0.000000506407 | ||||
Transfer Ownersh... | 122531511 | 221 days ago | IN | 0 ETH | 0.000000035635 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
TemporalGovernor
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 1 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.19; import {EnumerableSet} from "@openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol"; import {Pausable} from "@openzeppelin-contracts/contracts/security/Pausable.sol"; import {Ownable} from "@openzeppelin-contracts/contracts/access/Ownable.sol"; import {IWormhole} from "@protocol/wormhole/IWormhole.sol"; import {ITemporalGovernor} from "@protocol/governance/ITemporalGovernor.sol"; /// @notice contract that governs the Base deployment of moonwell leveraging the wormhole bridge /// as the source of truth. Wormhole will be fed in actions from the moonbeam chain and this contract /// will execute them on base. /// There are a few assumptions that are made in this contract: /// 1. Wormhole is secure and will not send malicious messages or be deactivated. /// 2. Moonbeam is secure. /// 3. Governance on Moonbeam cannot be compromised. /// if 1. is untrue and wormhole is deactivated, then this contract will be unable to upgrade the base instance /// if 1. is untrue and wormhole sends malicious messages, then this contract will be paused, and the guardian /// will have to fast track a proposal to hand ownership to a new governor, and wormhole will have to revoke /// the permissions on the compromised validator set. /// if 2. is untrue, then this contract will be paused until moonbeam is restored /// if 3. is untrue, then this contract will be paused until moonbeam governance is restored, if gov control /// cannot be restored, then this governance will be compromised. contract TemporalGovernor is ITemporalGovernor, Ownable, Pausable { using EnumerableSet for EnumerableSet.Bytes32Set; /// ----------- IMMUTABLES ----------- /// @notice reference to the wormhole bridge IWormhole public immutable wormholeBridge; /// @notice returns the amount of time a proposal must wait before being processed. uint256 public immutable proposalDelay; /// @notice returns the amount of time until this contract can be unpaused permissionlessly uint256 public immutable permissionlessUnpauseTime; /// ----------- SINGLE STORAGE SLOT ----------- /// @notice last paused time uint248 public lastPauseTime; /// @notice returns whether or not the guardian can pause. /// starts true and then is turned false when the guardian pauses /// governance can then reactivate it. bool public guardianPauseAllowed = true; /// ----------- MAPPINGS ----------- /// @notice Map of chain id => trusted sender mapping(uint16 => EnumerableSet.Bytes32Set) private trustedSenders; /// @notice Record of processed messages to prevent replaying /// and enforce time limits are respected mapping(bytes32 => ProposalInfo) public queuedTransactions; constructor( address wormholeCore, uint256 _proposalDelay, uint256 _permissionlessUnpauseTime, TrustedSender[] memory _trustedSenders ) Ownable() { wormholeBridge = IWormhole(wormholeCore); proposalDelay = _proposalDelay; permissionlessUnpauseTime = _permissionlessUnpauseTime; // Using https://book.wormhole.com/reference/contracts.html#testnet chain ids and local contracts // Mark 0xf16165f1046f1b3cdb37da25e835b986e696313a as trusted to emit from eth mainnet // Establish a list of trusted emitters from eash chain for (uint256 i = 0; i < _trustedSenders.length; i++) { trustedSenders[_trustedSenders[i].chainId].add( addressToBytes(_trustedSenders[i].addr) ); } } /// ------------- VIEW ONLY API ------------- /// @notice returns whether or not the address is in the trusted senders list for a given chain /// @param chainId The wormhole chain id to check /// @param addr The address to check function isTrustedSender( uint16 chainId, bytes32 addr ) public view returns (bool) { return trustedSenders[chainId].contains(addr); } /// @notice returns whether or not the address is in the trusted senders list for a given chain /// @param chainId The wormhole chain id to check /// @param addr The address to check function isTrustedSender( uint16 chainId, address addr ) external view returns (bool) { return isTrustedSender(chainId, addressToBytes(addr)); } /// @notice returns the list of trusted senders for a given chain /// @param chainId The wormhole chain id to check /// @return The list of trusted senders function allTrustedSenders( uint16 chainId ) external view override returns (bytes32[] memory) { bytes32[] memory trustedSendersList = new bytes32[]( trustedSenders[chainId].length() ); unchecked { for (uint256 i = 0; i < trustedSendersList.length; i++) { trustedSendersList[i] = trustedSenders[chainId].at(i); } } return trustedSendersList; } /// @notice Wormhole addresses are denominated in 32 byte chunks. Converting the address to a bytes20 /// then to a bytes32 *left* aligns it, so we right shift to get the proper data /// @param addr The address to convert /// @return The address as a bytes32 function addressToBytes(address addr) public pure returns (bytes32) { return bytes32(bytes20(addr)) >> 96; } /// @notice only callable through a governance proposal /// @dev Updates the list of trusted senders /// @param _trustedSenders The list of trusted senders, allowing one /// trusted sender per chain id function setTrustedSenders( TrustedSender[] calldata _trustedSenders ) external { require( msg.sender == address(this), "TemporalGovernor: Only this contract can update trusted senders" ); unchecked { for (uint256 i = 0; i < _trustedSenders.length; i++) { trustedSenders[_trustedSenders[i].chainId].add( addressToBytes(_trustedSenders[i].addr) ); emit TrustedSenderUpdated( _trustedSenders[i].chainId, _trustedSenders[i].addr, true /// added to list ); } } } /// @notice only callable through a governance proposal /// @dev Removes trusted senders from the list /// @param _trustedSenders The list of trusted senders, allowing multiple /// trusted sender per chain id function unSetTrustedSenders( TrustedSender[] calldata _trustedSenders ) external { require( msg.sender == address(this), "TemporalGovernor: Only this contract can update trusted senders" ); unchecked { for (uint256 i = 0; i < _trustedSenders.length; i++) { trustedSenders[_trustedSenders[i].chainId].remove( addressToBytes(_trustedSenders[i].addr) ); emit TrustedSenderUpdated( _trustedSenders[i].chainId, _trustedSenders[i].addr, false /// removed from list ); } } } /// @notice grant the guardians the pause ability function grantGuardiansPause() external { require( msg.sender == address(this), "TemporalGovernor: Only this contract can update grant guardian pause" ); guardianPauseAllowed = true; lastPauseTime = 0; emit GuardianPauseGranted(block.timestamp); } /// @notice callable only via a gov proposal (governance) /// this transfers the guardian to a new address /// @param newGuardian The new guardian address function changeGuardian(address newGuardian) external { require( msg.sender == address(this), "TemporalGovernor: cannot change guardian" ); _transferOwnership(newGuardian); guardianPauseAllowed = true; lastPauseTime = 0; emit GuardianChanged(newGuardian); } /// ------------- GUARDIAN / GOVERNOR ONLY API ------------- /// @notice callable only via a gov proposal (governance) or by the guardian /// this revokes guardian's ability, no more pausing or fast tracking and /// unpauses the contract if paused function revokeGuardian() external { address oldGuardian = owner(); require( msg.sender == oldGuardian || msg.sender == address(this), "TemporalGovernor: cannot revoke guardian" ); _transferOwnership(address(0)); guardianPauseAllowed = false; lastPauseTime = 0; if (paused()) { _unpause(); } emit GuardianRevoked(oldGuardian); } /// ------------- PERMISSIONLESS APIs ------------- /// @notice We explicitly don't care who is relaying this, as long /// as the VAA is only processed once AND, critically, intended for this contract. /// @param VAA The signed Verified Action Approval to process /// @dev callable only when unpaused function queueProposal(bytes memory VAA) external whenNotPaused { _queueProposal(VAA); } /// @notice Taken mostly from the best practices docs from wormhole. /// We explicitly don't care who is relaying this, as long /// as the VAA is only processed once AND, critically, intended for this contract. /// @param VAA The signed Verified Action Approval to process function executeProposal(bytes memory VAA) public payable whenNotPaused { _executeProposal(VAA, false); } /// @notice unpauses the contract, and blocks the guardian from pausing again until governance reapproves them function permissionlessUnpause() external whenPaused { /// lastPauseTime cannot be equal to 0 at this point because /// block.timstamp on a real chain will always be gt 0 and /// toggle pause will set lastPauseTime to block.timestamp /// which means if the contract is paused on a live network, /// its lastPauseTime cannot be 0 require( lastPauseTime + permissionlessUnpauseTime <= block.timestamp, "TemporalGovernor: not past pause window" ); lastPauseTime = 0; _unpause(); emit PermissionlessUnpaused(block.timestamp); } /// @notice Allow the guardian to process a VAA when the /// Temporal Governor is paused this is only for use during /// periods of emergency when the governance on moonbeam is /// compromised and we need to stop additional proposals from going through. /// @param VAA The signed Verified Action Approval to process function fastTrackProposalExecution( bytes memory VAA ) external payable onlyOwner whenPaused { _executeProposal(VAA, true); /// override timestamp checks and execute } /// @notice Allow the guardian to pause the contract /// removes the guardians ability to call pause again until governance reaaproves them /// starts the timer for the permissionless unpause /// cannot call this function if guardian is revoked function togglePause() external onlyOwner { if (paused()) { _unpause(); } else { require( guardianPauseAllowed, "TemporalGovernor: guardian pause not allowed" ); guardianPauseAllowed = false; lastPauseTime = uint248(block.timestamp); _pause(); } } /// ------------- HELPER FUNCTIONS ------------- /// queue a proposal function _queueProposal(bytes memory VAA) private { /// Checks // This call accepts single VAAs and headless VAAs ( IWormhole.VM memory vm, bool valid, string memory reason ) = wormholeBridge.parseAndVerifyVM(VAA); // Ensure VAA parsing verification succeeded. require(valid, reason); address intendedRecipient; address[] memory targets; /// contracts to call uint256[] memory values; /// native token amount to send bytes[] memory calldatas; /// calldata to send (intendedRecipient, targets, values, calldatas) = abi.decode( vm.payload, (address, address[], uint256[], bytes[]) ); _sanityCheckPayload(targets, values, calldatas); // Very important to check to make sure that the VAA we're processing is specifically designed // to be sent to this contract require( intendedRecipient == address(this), "TemporalGovernor: Incorrect destination" ); // Ensure the emitterAddress of this VAA is a trusted address require( trustedSenders[vm.emitterChainId].contains(vm.emitterAddress), /// allow multiple per chainid "TemporalGovernor: Invalid Emitter Address" ); /// Check that the VAA hasn't already been processed (replay protection) require( queuedTransactions[vm.hash].queueTime == 0, "TemporalGovernor: Message already queued" ); /// Effect // Add the VAA to queued messages so that it can't be replayed queuedTransactions[vm.hash].queueTime = uint248(block.timestamp); emit QueuedTransaction(intendedRecipient, targets, values, calldatas); } function _executeProposal(bytes memory VAA, bool overrideDelay) private { // This call accepts single VAAs and headless VAAs ( IWormhole.VM memory vm, bool valid, string memory reason ) = wormholeBridge.parseAndVerifyVM(VAA); require(valid, reason); /// ensure VAA parsing verification succeeded if (!overrideDelay) { require( queuedTransactions[vm.hash].queueTime != 0, "TemporalGovernor: tx not queued" ); require( queuedTransactions[vm.hash].queueTime + proposalDelay <= block.timestamp, "TemporalGovernor: timelock not finished" ); } else if (queuedTransactions[vm.hash].queueTime == 0) { /// if queue time is 0 due to fast track execution, set it to current block timestamp queuedTransactions[vm.hash].queueTime = uint248(block.timestamp); } // Ensure the emitterAddress of this VAA is a trusted address require( trustedSenders[vm.emitterChainId].contains(vm.emitterAddress), /// allow multiple per chainid "TemporalGovernor: Invalid Emitter Address" ); require( !queuedTransactions[vm.hash].executed, "TemporalGovernor: tx already executed" ); queuedTransactions[vm.hash].executed = true; address[] memory targets; /// contracts to call uint256[] memory values; /// native token amount to send bytes[] memory calldatas; /// calldata to send (, targets, values, calldatas) = abi.decode( vm.payload, (address, address[], uint256[], bytes[]) ); /// Interaction (s) _sanityCheckPayload(targets, values, calldatas); for (uint256 i = 0; i < targets.length; i++) { address target = targets[i]; uint256 value = values[i]; bytes memory data = calldatas[i]; // Go make our call, and if it is not successful revert with the error bubbling up (bool success, bytes memory returnData) = target.call{value: value}( data ); /// revert on failure with error message if any require(success, string(returnData)); emit ExecutedTransaction(target, value, data); } } /// @notice arity check for payload function _sanityCheckPayload( address[] memory targets, uint256[] memory values, bytes[] memory calldatas ) private pure { require(targets.length != 0, "TemporalGovernor: Empty proposal"); require( targets.length == values.length && targets.length == calldatas.length, "TemporalGovernor: Arity mismatch for payload" ); } /// @notice function to receive Ether receive() external payable {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableSet.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. pragma solidity ^0.8.0; /** * @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 of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @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._indexes[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 read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 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 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[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._indexes[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; /// @solidity memory-safe-assembly assembly { 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; /// @solidity memory-safe-assembly assembly { 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; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../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. * * By default, the owner account will be the one that deploys the contract. 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; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @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 { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @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 { require(newOwner != address(0), "Ownable: new owner is the zero address"); _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: Apache 2 pragma solidity 0.8.19; interface IWormhole { struct GuardianSet { address[] keys; uint32 expirationTime; } struct Signature { bytes32 r; bytes32 s; uint8 v; uint8 guardianIndex; } struct VM { uint8 version; uint32 timestamp; uint32 nonce; uint16 emitterChainId; bytes32 emitterAddress; uint64 sequence; uint8 consistencyLevel; bytes payload; uint32 guardianSetIndex; Signature[] signatures; bytes32 hash; } struct ContractUpgrade { bytes32 module; uint8 action; uint16 chain; address newContract; } struct GuardianSetUpgrade { bytes32 module; uint8 action; uint16 chain; GuardianSet newGuardianSet; uint32 newGuardianSetIndex; } struct SetMessageFee { bytes32 module; uint8 action; uint16 chain; uint256 messageFee; } struct TransferFees { bytes32 module; uint8 action; uint16 chain; uint256 amount; bytes32 recipient; } struct RecoverChainId { bytes32 module; uint8 action; uint256 evmChainId; uint16 newChainId; } event LogMessagePublished( address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel ); event ContractUpgraded( address indexed oldContract, address indexed newContract ); event GuardianSetAdded(uint32 indexed index); function publishMessage( uint32 nonce, bytes memory payload, uint8 consistencyLevel ) external payable returns (uint64 sequence); function initialize() external; function parseAndVerifyVM( bytes calldata encodedVM ) external view returns (VM memory vm, bool valid, string memory reason); function verifyVM( VM memory vm ) external view returns (bool valid, string memory reason); function verifySignatures( bytes32 hash, Signature[] memory signatures, GuardianSet memory guardianSet ) external pure returns (bool valid, string memory reason); function parseVM( bytes memory encodedVM ) external pure returns (VM memory vm); function quorum( uint numGuardians ) external pure returns (uint numSignaturesRequiredForQuorum); function getGuardianSet( uint32 index ) external view returns (GuardianSet memory); function getCurrentGuardianSetIndex() external view returns (uint32); function getGuardianSetExpiry() external view returns (uint32); function governanceActionIsConsumed( bytes32 hash ) external view returns (bool); function isInitialized(address impl) external view returns (bool); function chainId() external view returns (uint16); function isFork() external view returns (bool); function governanceChainId() external view returns (uint16); function governanceContract() external view returns (bytes32); function messageFee() external view returns (uint256); function evmChainId() external view returns (uint256); function nextSequence(address emitter) external view returns (uint64); function parseContractUpgrade( bytes memory encodedUpgrade ) external pure returns (ContractUpgrade memory cu); function parseGuardianSetUpgrade( bytes memory encodedUpgrade ) external pure returns (GuardianSetUpgrade memory gsu); function parseSetMessageFee( bytes memory encodedSetMessageFee ) external pure returns (SetMessageFee memory smf); function parseTransferFees( bytes memory encodedTransferFees ) external pure returns (TransferFees memory tf); function parseRecoverChainId( bytes memory encodedRecoverChainId ) external pure returns (RecoverChainId memory rci); function submitContractUpgrade(bytes memory _vm) external; function submitSetMessageFee(bytes memory _vm) external; function submitNewGuardianSet(bytes memory _vm) external; function submitTransferFees(bytes memory _vm) external; function submitRecoverChainId(bytes memory _vm) external; }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.8.19; import {IWormhole} from "@protocol/wormhole/IWormhole.sol"; /// @notice interface for the Temporal Governor Contract interface ITemporalGovernor { /// ------------- STATE VARIABLES ------------- /// @notice reference to the wormhole bridge function wormholeBridge() external view returns (IWormhole); /// @notice Map of chain id => trusted sender function allTrustedSenders(uint16) external view returns (bytes32[] memory); /// @notice returns whether or not the guardian can pause. /// starts true and then is turned false when the guardian pauses /// governance can then reactivate it. function guardianPauseAllowed() external view returns (bool); /// @notice list of transactions queued and awaiting execution function queuedTransactions(bytes32) external view returns (bool, uint248); /// @notice returns the amount of time a proposal must wait before being processed. function proposalDelay() external view returns (uint256); struct ProposalInfo { bool executed; uint248 queueTime; } /// ------------- STRUCTS ------------- /// @notice A trusted sender is a contract that is allowed to emit VAAs struct TrustedSender { uint16 chainId; address addr; } /// ------------- EVENTS ------------- /// @notice Emitted when a VAA is decoded event QueuedTransaction( address intendedRecipient, address[] targets, uint256[] values, bytes[] calldatas ); /// @notice Emitted when a transaction is executed event ExecutedTransaction(address target, uint256 value, bytes data); /// @notice Emitted when a trusted sender is updated event TrustedSenderUpdated(uint16 chainId, address addr, bool added); /// @notice Emitted when a trusted guardian is revoked event GuardianRevoked(address indexed guardian); /// @notice Emitted when guardian is changed through a governance proposal event GuardianChanged(address indexed guardian); /// @notice emitted when guardian pause is granted event GuardianPauseGranted(uint256 indexed timestamp); /// @notice emitted when contract is trustlessly unpaused event PermissionlessUnpaused(uint256 indexed timestamp); // Wormhole addresses are denominated in 32 byte chunks. Converting the address to a bytes20 // then to a bytes32 *left* aligns it, so we right shift to get the proper data function addressToBytes(address addr) external pure returns (bytes32); /// ------------- PERMISSIONLESS APIs ------------- /// @notice Taken mostly from the best practices docs from wormhole. /// We explicitly don't care who is relaying this, as long /// as the VAA is only processed once AND, critically, intended for this contract. /// @param VAA The signed Verified Action Approval to process /// @dev callable only when unpaused function queueProposal(bytes memory VAA) external; /// @notice permissionless function to execute a queued VAA /// @param VAA The signed Verified Action Approval to process /// @dev callable only when unpaused function executeProposal(bytes memory VAA) external payable; /// @notice unpauses the contract, and blocks the guardian from pausing again until governance reapproves them function permissionlessUnpause() external; /// ------------- GUARDIAN ONLY APIs ------------- /// @notice Allow the guardian to pause the contract function togglePause() external; /// @notice fast track execution of a VAA as a VAA, ignoring any waiting times and pauses function fastTrackProposalExecution(bytes memory VAA) external payable; /// ------------- GOVERNOR ONLY APIs ------------- /// @notice grant the guardians the pause ability function grantGuardiansPause() external; /// @notice only callable through a governance proposal /// @dev Updates the list of trusted senders /// @param _trustedSenders The list of trusted senders, allowing multiple /// trusted sender per chain id function setTrustedSenders( TrustedSender[] calldata _trustedSenders ) external; /// @notice only callable through a governance proposal /// @dev Removes trusted senders from the list /// @param _trustedSenders The list of trusted senders, allowing multiple /// trusted sender per chain id function unSetTrustedSenders( TrustedSender[] calldata _trustedSenders ) external; /// ------------- GUARDIAN / GOVERNOR ONLY APIs ------------- /// @notice callable only via a gov proposal (governance) or by the guardian /// this revokes guardian's ability, no more pausing or fast tracking and /// unpauses the contract if paused function revokeGuardian() external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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; } }
{ "remappings": [ "@forge-std/=lib/forge-std/src/", "@openzeppelin-contracts/=lib/openzeppelin-contracts/", "@openzeppelin/=lib/openzeppelin-contracts/", "@openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "@wormhole/=lib/wormhole/ethereum/contracts/", "@protocol/=src/", "@test/=test/", "@proposals/=src/proposals/", "@utils/=src/utils/", "@zelt/=lib/zelt/", "@zelt-src/=lib/zelt/src/", "@zelt-test/=lib/zelt/test/", "ds-test/=lib/solmate/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/", "solmate/=lib/solmate/src/", "wormhole/=lib/wormhole/", "zelt/=lib/zelt/src/" ], "optimizer": { "enabled": true, "runs": 1 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"wormholeCore","type":"address"},{"internalType":"uint256","name":"_proposalDelay","type":"uint256"},{"internalType":"uint256","name":"_permissionlessUnpauseTime","type":"uint256"},{"components":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"address","name":"addr","type":"address"}],"internalType":"struct ITemporalGovernor.TrustedSender[]","name":"_trustedSenders","type":"tuple[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"ExecutedTransaction","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"GuardianPauseGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"guardian","type":"address"}],"name":"GuardianRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"PermissionlessUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"intendedRecipient","type":"address"},{"indexed":false,"internalType":"address[]","name":"targets","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"},{"indexed":false,"internalType":"bytes[]","name":"calldatas","type":"bytes[]"}],"name":"QueuedTransaction","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"chainId","type":"uint16"},{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"added","type":"bool"}],"name":"TrustedSenderUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addressToBytes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId","type":"uint16"}],"name":"allTrustedSenders","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newGuardian","type":"address"}],"name":"changeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"VAA","type":"bytes"}],"name":"executeProposal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"VAA","type":"bytes"}],"name":"fastTrackProposalExecution","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"grantGuardiansPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"guardianPauseAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"address","name":"addr","type":"address"}],"name":"isTrustedSender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"bytes32","name":"addr","type":"bytes32"}],"name":"isTrustedSender","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint248","name":"","type":"uint248"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permissionlessUnpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"permissionlessUnpauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proposalDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"VAA","type":"bytes"}],"name":"queueProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"queuedTransactions","outputs":[{"internalType":"bool","name":"executed","type":"bool"},{"internalType":"uint248","name":"queueTime","type":"uint248"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"address","name":"addr","type":"address"}],"internalType":"struct ITemporalGovernor.TrustedSender[]","name":"_trustedSenders","type":"tuple[]"}],"name":"setTrustedSenders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"address","name":"addr","type":"address"}],"internalType":"struct ITemporalGovernor.TrustedSender[]","name":"_trustedSenders","type":"tuple[]"}],"name":"unSetTrustedSenders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wormholeBridge","outputs":[{"internalType":"contract IWormhole","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e0604052600180546001600160f81b0316600160f81b1790553480156200002657600080fd5b50604051620026c9380380620026c983398101604081905262000049916200026e565b620000543362000118565b6000805460ff60a01b191681556001600160a01b03851660805260a084905260c08390525b81518110156200010d57620000f7620000b8838381518110620000a057620000a062000387565b6020026020010151602001516200016860201b60201c565b60026000858581518110620000d157620000d162000387565b6020908102919091018101515161ffff1682528101919091526040016000209062000174565b508062000104816200039d565b91505062000079565b5050505050620003c5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b031690565b60006200018283836200018b565b90505b92915050565b6000818152600183016020526040812054620001d45750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000185565b50600062000185565b80516001600160a01b0381168114620001f557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715620002355762000235620001fa565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620002665762000266620001fa565b604052919050565b600080600080608085870312156200028557600080fd5b6200029085620001dd565b935060208086015193506040808701519350606087015160018060401b0380821115620002bc57600080fd5b818901915089601f830112620002d157600080fd5b815181811115620002e657620002e6620001fa565b620002f6858260051b016200023b565b818152858101925060069190911b83018501908b8211156200031757600080fd5b928501925b81841015620003775784848d031215620003365760008081fd5b6200034062000210565b845161ffff81168114620003545760008081fd5b815262000363858801620001dd565b81880152835292840192918501916200031c565b989b979a50959850505050505050565b634e487b7160e01b600052603260045260246000fd5b600060018201620003be57634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a05160c0516122b8620004116000396000818161015f01526109ad0152600081816103620152610e5701526000818161023c01528181610d0e015261124e01526122b86000f3fe60806040526004361061011f5760003560e01c80630878d3fb1461012b5780631045e9661461014d5780632fcb4f041461019457806330faa259146101b457806335a2017d146101c75780633f4b28f4146101f75780634a3548911461020a57806352a800851461022a5780635c975abb1461026b57806363c6c6a314610280578063715018a6146102a057806388516742146102b55780638ab9b2e1146102d65780638da5cb5b1461030357806391b4ded914610318578063a78b17cc14610350578063b44be09514610384578063be6a2f0c14610399578063c4ae3168146103ae578063d4f3826b146103c3578063dd310f87146103e3578063ded8454a146103f8578063f2b0653714610418578063f2fde38b1461047757600080fd5b3661012657005b600080fd5b34801561013757600080fd5b5061014b6101463660046117cb565b610497565b005b34801561015957600080fd5b506101817f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101a057600080fd5b5061014b6101af366004611854565b6105c8565b61014b6101c2366004611930565b610670565b3480156101d357600080fd5b506101e76101e23660046119bf565b610686565b604051901515815260200161018b565b61014b610205366004611930565b61069e565b34801561021657600080fd5b5061014b6102253660046117cb565b6106b9565b34801561023657600080fd5b5061025e7f000000000000000000000000000000000000000000000000000000000000000081565b60405161018b91906119f8565b34801561027757600080fd5b506101e76107c4565b34801561028c57600080fd5b5061014b61029b366004611930565b6107d4565b3480156102ac57600080fd5b5061014b6107e5565b3480156102c157600080fd5b506001546101e790600160f81b900460ff1681565b3480156102e257600080fd5b506102f66102f1366004611a0c565b6107f9565b60405161018b9190611a29565b34801561030f57600080fd5b5061025e6108b1565b34801561032457600080fd5b50600154610338906001600160f81b031681565b6040516001600160f81b03909116815260200161018b565b34801561035c57600080fd5b506101817f000000000000000000000000000000000000000000000000000000000000000081565b34801561039057600080fd5b5061014b6108c0565b3480156103a557600080fd5b5061014b61099a565b3480156103ba57600080fd5b5061014b610a7e565b3480156103cf57600080fd5b506101e76103de366004611a6d565b610b1e565b3480156103ef57600080fd5b5061014b610b3b565b34801561040457600080fd5b50610181610413366004611854565b610be1565b34801561042457600080fd5b50610458610433366004611a99565b60036020526000908152604090205460ff81169061010090046001600160f81b031682565b6040805192151583526001600160f81b0390911660208301520161018b565b34801561048357600080fd5b5061014b610492366004611854565b610bed565b3330146104bf5760405162461bcd60e51b81526004016104b690611ab2565b60405180910390fd5b60005b818110156105c3576105406104fa8484848181106104e2576104e2611afd565b90506040020160200160208101906104139190611854565b6002600086868681811061051057610510611afd565b6105269260206040909202019081019150611a0c565b61ffff168152602081019190915260400160002090610c63565b5060008051602061224383398151915283838381811061056257610562611afd565b6105789260206040909202019081019150611a0c565b84848481811061058a5761058a611afd565b90506040020160200160208101906105a29190611854565b60006040516105b393929190611b13565b60405180910390a16001016104c2565b505050565b3330146106285760405162461bcd60e51b815260206004820152602860248201527f54656d706f72616c476f7665726e6f723a2063616e6e6f74206368616e67652060448201526733bab0b93234b0b760c11b60648201526084016104b6565b61063181610c6f565b600160f81b6001556040516001600160a01b038216907f01c6520cf747e4632b43b535b91afe3950ccabc4ab29bbd89e3c1f6b0ba0565590600090a250565b610678610cbf565b610683816000610d07565b50565b6000610695836103de84610be1565b90505b92915050565b6106a6611191565b6106ae6111f0565b610683816001610d07565b3330146106d85760405162461bcd60e51b81526004016104b690611ab2565b60005b818110156105c3576107416106fb8484848181106104e2576104e2611afd565b6002600086868681811061071157610711611afd565b6107279260206040909202019081019150611a0c565b61ffff16815260208101919091526040016000209061123b565b5060008051602061224383398151915283838381811061076357610763611afd565b6107799260206040909202019081019150611a0c565b84848481811061078b5761078b611afd565b90506040020160200160208101906107a39190611854565b60016040516107b493929190611b13565b60405180910390a16001016106db565b600054600160a01b900460ff1690565b6107dc610cbf565b61068381611247565b6107ed611191565b6107f76000610c6f565b565b61ffff8116600090815260026020526040812060609190610819906114d4565b6001600160401b0381111561083057610830611878565b604051908082528060200260200182016040528015610859578160200160208202803683370190505b50905060005b81518110156108aa5761ffff8416600090815260026020526040902061088590826114de565b82828151811061089757610897611afd565b602090810291909101015260010161085f565b5092915050565b6000546001600160a01b031690565b60006108ca6108b1565b9050336001600160a01b03821614806108e257503330145b61093f5760405162461bcd60e51b815260206004820152602860248201527f54656d706f72616c476f7665726e6f723a2063616e6e6f74207265766f6b652060448201526733bab0b93234b0b760c11b60648201526084016104b6565b6109496000610c6f565b60006001556109566107c4565b15610963576109636114ea565b6040516001600160a01b038216907f0c92d12d8037dd6d77aed8d12addd54d5eb2a6801541a1bf87c9822e78eea42190600090a250565b6109a26111f0565b60015442906109db907f0000000000000000000000000000000000000000000000000000000000000000906001600160f81b0316611b50565b1115610a395760405162461bcd60e51b815260206004820152602760248201527f54656d706f72616c476f7665726e6f723a206e6f7420706173742070617573656044820152662077696e646f7760c81b60648201526084016104b6565b600180546001600160f81b0319169055610a516114ea565b60405142907f5607d774129cad49296363738883d35576762c63e621f31b16c5e2214e2c03b490600090a2565b610a86611191565b610a8e6107c4565b15610a9b576107f76114ea565b600154600160f81b900460ff16610b095760405162461bcd60e51b815260206004820152602c60248201527f54656d706f72616c476f7665726e6f723a20677561726469616e20706175736560448201526b081b9bdd08185b1b1bddd95960a21b60648201526084016104b6565b426001600160f81b03166001556107f7611539565b61ffff82166000908152600260205260408120610695908361157c565b333014610bac5760405162461bcd60e51b815260206004820152604460248201819052600080516020612263833981519152908201527f726163742063616e20757064617465206772616e7420677561726469616e20706064820152636175736560e01b608482015260a4016104b6565b600160f81b60015560405142907f309f3735db2677e216920b5dc9d0b76108f0fa9fc1176a6701bd4e77f5065ac190600090a2565b6001600160a01b031690565b610bf5611191565b6001600160a01b038116610c5a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104b6565b61068381610c6f565b60006106958383611588565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610cc76107c4565b156107f75760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016104b6565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c0fd8bde866040518263ffffffff1660e01b8152600401610d589190611bb3565b600060405180830381865afa158015610d75573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d9d9190810190611d3e565b925092509250818190610dc35760405162461bcd60e51b81526004016104b69190611bb3565b5083610eed5761014083015160009081526003602052604081205461010090046001600160f81b03169003610e3a5760405162461bcd60e51b815260206004820152601f60248201527f54656d706f72616c476f7665726e6f723a207478206e6f74207175657565640060448201526064016104b6565b6101408301516000908152600360205260409020544290610e8a907f00000000000000000000000000000000000000000000000000000000000000009061010090046001600160f81b0316611b50565b1115610ee85760405162461bcd60e51b815260206004820152602760248201527f54656d706f72616c476f7665726e6f723a2074696d656c6f636b206e6f7420666044820152661a5b9a5cda195960ca1b60648201526084016104b6565b610f41565b61014083015160009081526003602052604081205461010090046001600160f81b03169003610f41576101408301516000908152600360205260409020805460ff16610100426001600160f81b0316021790555b6080830151606084015161ffff166000908152600260205260409020610f669161157c565b610f825760405162461bcd60e51b81526004016104b690611e95565b61014083015160009081526003602052604090205460ff1615610ff55760405162461bcd60e51b815260206004820152602560248201527f54656d706f72616c476f7665726e6f723a20747820616c72656164792065786560448201526418dd5d195960da1b60648201526084016104b6565b6101408301516000908152600360209081526040909120805460ff1916600117905560e08401518051606092839283926110359290820181019101611fb8565b91955093509150611049905083838361167b565b60005b835181101561118657600084828151811061106957611069611afd565b60200260200101519050600084838151811061108757611087611afd565b6020026020010151905060008484815181106110a5576110a5611afd565b60200260200101519050600080846001600160a01b031684846040516110cb91906120b5565b60006040518083038185875af1925050503d8060008114611108576040519150601f19603f3d011682016040523d82523d6000602084013e61110d565b606091505b50915091508181906111325760405162461bcd60e51b81526004016104b69190611bb3565b507faf022f6b53b11c364e2dfc0aea08eb9416c94f2661451ea82ead8831385617a6858585604051611166939291906120d1565b60405180910390a15050505050808061117e90612101565b91505061104c565b505050505050505050565b3361119a6108b1565b6001600160a01b0316146107f75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104b6565b6111f86107c4565b6107f75760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016104b6565b6000610695838361173f565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c0fd8bde856040518263ffffffff1660e01b81526004016112989190611bb3565b600060405180830381865afa1580156112b5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112dd9190810190611d3e565b9250925092508181906113035760405162461bcd60e51b81526004016104b69190611bb3565b50600060608060608660e001518060200190518101906113239190611fb8565b9296509094509250905061133883838361167b565b6001600160a01b03841630146113a05760405162461bcd60e51b815260206004820152602760248201527f54656d706f72616c476f7665726e6f723a20496e636f7272656374206465737460448201526634b730ba34b7b760c91b60648201526084016104b6565b6080870151606088015161ffff1660009081526002602052604090206113c59161157c565b6113e15760405162461bcd60e51b81526004016104b690611e95565b61014087015160009081526003602052604090205461010090046001600160f81b0316156114625760405162461bcd60e51b815260206004820152602860248201527f54656d706f72616c476f7665726e6f723a204d65737361676520616c726561646044820152671e481c5d595d595960c21b60648201526084016104b6565b61014087015160009081526003602052604090819020805460ff16610100426001600160f81b031602179055517fc486294e67e6b98e19d854bb8a606f314e248d45e842a98b09a51be7b13ce2a5906114c2908690869086908690612172565b60405180910390a15050505050505050565b6000610698825490565b60006106958383611789565b6114f26111f0565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405161152f91906119f8565b60405180910390a1565b611541610cbf565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586115223390565b600061069583836117b3565b600081815260018301602052604081205480156116715760006115ac600183612219565b85549091506000906115c090600190612219565b90508181146116255760008660000182815481106115e0576115e0611afd565b906000526020600020015490508087600001848154811061160357611603611afd565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806116365761163661222c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610698565b6000915050610698565b82516000036116cc5760405162461bcd60e51b815260206004820181905260248201527f54656d706f72616c476f7665726e6f723a20456d7074792070726f706f73616c60448201526064016104b6565b815183511480156116de575080518351145b6105c35760405162461bcd60e51b815260206004820152602c60248201527f54656d706f72616c476f7665726e6f723a204172697479206d69736d6174636860448201526b08199bdc881c185e5b1bd85960a21b60648201526084016104b6565b600061174b83836117b3565b61178157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610698565b506000610698565b60008260000182815481106117a0576117a0611afd565b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b600080602083850312156117de57600080fd5b82356001600160401b03808211156117f557600080fd5b818501915085601f83011261180957600080fd5b81358181111561181857600080fd5b8660208260061b850101111561182d57600080fd5b60209290920196919550909350505050565b6001600160a01b038116811461068357600080fd5b60006020828403121561186657600080fd5b81356118718161183f565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156118b0576118b0611878565b60405290565b60405161016081016001600160401b03811182821017156118b0576118b0611878565b604051601f8201601f191681016001600160401b038111828210171561190157611901611878565b604052919050565b60006001600160401b0382111561192257611922611878565b50601f01601f191660200190565b60006020828403121561194257600080fd5b81356001600160401b0381111561195857600080fd5b8201601f8101841361196957600080fd5b803561197c61197782611909565b6118d9565b81815285602083850101111561199157600080fd5b81602084016020830137600091810160200191909152949350505050565b61ffff8116811461068357600080fd5b600080604083850312156119d257600080fd5b82356119dd816119af565b915060208301356119ed8161183f565b809150509250929050565b6001600160a01b0391909116815260200190565b600060208284031215611a1e57600080fd5b8135611871816119af565b6020808252825182820181905260009190848201906040850190845b81811015611a6157835183529284019291840191600101611a45565b50909695505050505050565b60008060408385031215611a8057600080fd5b8235611a8b816119af565b946020939093013593505050565b600060208284031215611aab57600080fd5b5035919050565b6020808252603f9082015260008051602061226383398151915260408201527f726163742063616e2075706461746520747275737465642073656e6465727300606082015260800190565b634e487b7160e01b600052603260045260246000fd5b61ffff9390931683526001600160a01b039190911660208301521515604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8082018082111561069857610698611b3a565b60005b83811015611b7e578181015183820152602001611b66565b50506000910152565b60008151808452611b9f816020860160208601611b63565b601f01601f19169290920160200192915050565b6020815260006106956020830184611b87565b805160ff81168114611bd757600080fd5b919050565b805163ffffffff81168114611bd757600080fd5b8051611bd7816119af565b80516001600160401b0381168114611bd757600080fd5b600082601f830112611c2357600080fd5b8151611c3161197782611909565b818152846020838601011115611c4657600080fd5b611c57826020830160208701611b63565b949350505050565b60006001600160401b03821115611c7857611c78611878565b5060051b60200190565b600082601f830112611c9357600080fd5b81516020611ca361197783611c5f565b82815260079290921b84018101918181019086841115611cc257600080fd5b8286015b84811015611d235760808189031215611cdf5760008081fd5b611ce761188e565b8151815284820151858201526040611d00818401611bc6565b908201526060611d11838201611bc6565b90820152835291830191608001611cc6565b509695505050505050565b80518015158114611bd757600080fd5b600080600060608486031215611d5357600080fd5b83516001600160401b0380821115611d6a57600080fd5b908501906101608288031215611d7f57600080fd5b611d876118b6565b611d9083611bc6565b8152611d9e60208401611bdc565b6020820152611daf60408401611bdc565b6040820152611dc060608401611bf0565b606082015260808301516080820152611ddb60a08401611bfb565b60a0820152611dec60c08401611bc6565b60c082015260e083015182811115611e0357600080fd5b611e0f89828601611c12565b60e083015250610100611e23818501611bdc565b908201526101208381015183811115611e3b57600080fd5b611e478a828701611c82565b918301919091525061014083810151908201529450611e6860208701611d2e565b93506040860151915080821115611e7e57600080fd5b50611e8b86828701611c12565b9150509250925092565b60208082526029908201527f54656d706f72616c476f7665726e6f723a20496e76616c696420456d6974746560408201526872204164647265737360b81b606082015260800190565b600082601f830112611eef57600080fd5b81516020611eff61197783611c5f565b82815260059290921b84018101918181019086841115611f1e57600080fd5b8286015b84811015611d235780518352918301918301611f22565b600082601f830112611f4a57600080fd5b81516020611f5a61197783611c5f565b82815260059290921b84018101918181019086841115611f7957600080fd5b8286015b84811015611d235780516001600160401b03811115611f9c5760008081fd5b611faa8986838b0101611c12565b845250918301918301611f7d565b60008060008060808587031215611fce57600080fd5b8451611fd98161183f565b602086810151919550906001600160401b0380821115611ff857600080fd5b818801915088601f83011261200c57600080fd5b815161201a61197782611c5f565b81815260059190911b8301840190848101908b83111561203957600080fd5b938501935b828510156120605784516120518161183f565b8252938501939085019061203e565b60408b0151909850945050508083111561207957600080fd5b61208589848a01611ede565b9450606088015192508083111561209b57600080fd5b50506120a987828801611f39565b91505092959194509250565b600082516120c7818460208701611b63565b9190910192915050565b60018060a01b03841681528260208201526060604082015260006120f86060830184611b87565b95945050505050565b60006001820161211357612113611b3a565b5060010190565b600082825180855260208086019550808260051b84010181860160005b8481101561216557601f19868403018952612153838351611b87565b98840198925090830190600101612137565b5090979650505050505050565b6001600160a01b0385811682526080602080840182905286519184018290526000928782019290919060a0860190855b818110156121c05785518516835294830194918301916001016121a2565b5050858103604087015287518082529082019350915080870160005b838110156121f8578151855293820193908201906001016121dc565b50505050828103606084015261220e818561211a565b979650505050505050565b8181038181111561069857610698611b3a565b634e487b7160e01b600052603160045260246000fdfead5ad009fb0380817906297d4db849c9a30b93e0d3761c005ef8c487d923922454656d706f72616c476f7665726e6f723a204f6e6c79207468697320636f6e74a264697066735822122069b0a18183bc03980e928e5109113040d2ad5ea7181a98eac66ff98645ab9fb164736f6c63430008130033000000000000000000000000ee91c335eab126df5fdb3797ea9d6ad93aec972200000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000100000000000000000000000009a8464c4c11cea17e191653deb7cdc1be30f1af4
Deployed Bytecode
0x60806040526004361061011f5760003560e01c80630878d3fb1461012b5780631045e9661461014d5780632fcb4f041461019457806330faa259146101b457806335a2017d146101c75780633f4b28f4146101f75780634a3548911461020a57806352a800851461022a5780635c975abb1461026b57806363c6c6a314610280578063715018a6146102a057806388516742146102b55780638ab9b2e1146102d65780638da5cb5b1461030357806391b4ded914610318578063a78b17cc14610350578063b44be09514610384578063be6a2f0c14610399578063c4ae3168146103ae578063d4f3826b146103c3578063dd310f87146103e3578063ded8454a146103f8578063f2b0653714610418578063f2fde38b1461047757600080fd5b3661012657005b600080fd5b34801561013757600080fd5b5061014b6101463660046117cb565b610497565b005b34801561015957600080fd5b506101817f0000000000000000000000000000000000000000000000000000000000278d0081565b6040519081526020015b60405180910390f35b3480156101a057600080fd5b5061014b6101af366004611854565b6105c8565b61014b6101c2366004611930565b610670565b3480156101d357600080fd5b506101e76101e23660046119bf565b610686565b604051901515815260200161018b565b61014b610205366004611930565b61069e565b34801561021657600080fd5b5061014b6102253660046117cb565b6106b9565b34801561023657600080fd5b5061025e7f000000000000000000000000ee91c335eab126df5fdb3797ea9d6ad93aec972281565b60405161018b91906119f8565b34801561027757600080fd5b506101e76107c4565b34801561028c57600080fd5b5061014b61029b366004611930565b6107d4565b3480156102ac57600080fd5b5061014b6107e5565b3480156102c157600080fd5b506001546101e790600160f81b900460ff1681565b3480156102e257600080fd5b506102f66102f1366004611a0c565b6107f9565b60405161018b9190611a29565b34801561030f57600080fd5b5061025e6108b1565b34801561032457600080fd5b50600154610338906001600160f81b031681565b6040516001600160f81b03909116815260200161018b565b34801561035c57600080fd5b506101817f000000000000000000000000000000000000000000000000000000000001518081565b34801561039057600080fd5b5061014b6108c0565b3480156103a557600080fd5b5061014b61099a565b3480156103ba57600080fd5b5061014b610a7e565b3480156103cf57600080fd5b506101e76103de366004611a6d565b610b1e565b3480156103ef57600080fd5b5061014b610b3b565b34801561040457600080fd5b50610181610413366004611854565b610be1565b34801561042457600080fd5b50610458610433366004611a99565b60036020526000908152604090205460ff81169061010090046001600160f81b031682565b6040805192151583526001600160f81b0390911660208301520161018b565b34801561048357600080fd5b5061014b610492366004611854565b610bed565b3330146104bf5760405162461bcd60e51b81526004016104b690611ab2565b60405180910390fd5b60005b818110156105c3576105406104fa8484848181106104e2576104e2611afd565b90506040020160200160208101906104139190611854565b6002600086868681811061051057610510611afd565b6105269260206040909202019081019150611a0c565b61ffff168152602081019190915260400160002090610c63565b5060008051602061224383398151915283838381811061056257610562611afd565b6105789260206040909202019081019150611a0c565b84848481811061058a5761058a611afd565b90506040020160200160208101906105a29190611854565b60006040516105b393929190611b13565b60405180910390a16001016104c2565b505050565b3330146106285760405162461bcd60e51b815260206004820152602860248201527f54656d706f72616c476f7665726e6f723a2063616e6e6f74206368616e67652060448201526733bab0b93234b0b760c11b60648201526084016104b6565b61063181610c6f565b600160f81b6001556040516001600160a01b038216907f01c6520cf747e4632b43b535b91afe3950ccabc4ab29bbd89e3c1f6b0ba0565590600090a250565b610678610cbf565b610683816000610d07565b50565b6000610695836103de84610be1565b90505b92915050565b6106a6611191565b6106ae6111f0565b610683816001610d07565b3330146106d85760405162461bcd60e51b81526004016104b690611ab2565b60005b818110156105c3576107416106fb8484848181106104e2576104e2611afd565b6002600086868681811061071157610711611afd565b6107279260206040909202019081019150611a0c565b61ffff16815260208101919091526040016000209061123b565b5060008051602061224383398151915283838381811061076357610763611afd565b6107799260206040909202019081019150611a0c565b84848481811061078b5761078b611afd565b90506040020160200160208101906107a39190611854565b60016040516107b493929190611b13565b60405180910390a16001016106db565b600054600160a01b900460ff1690565b6107dc610cbf565b61068381611247565b6107ed611191565b6107f76000610c6f565b565b61ffff8116600090815260026020526040812060609190610819906114d4565b6001600160401b0381111561083057610830611878565b604051908082528060200260200182016040528015610859578160200160208202803683370190505b50905060005b81518110156108aa5761ffff8416600090815260026020526040902061088590826114de565b82828151811061089757610897611afd565b602090810291909101015260010161085f565b5092915050565b6000546001600160a01b031690565b60006108ca6108b1565b9050336001600160a01b03821614806108e257503330145b61093f5760405162461bcd60e51b815260206004820152602860248201527f54656d706f72616c476f7665726e6f723a2063616e6e6f74207265766f6b652060448201526733bab0b93234b0b760c11b60648201526084016104b6565b6109496000610c6f565b60006001556109566107c4565b15610963576109636114ea565b6040516001600160a01b038216907f0c92d12d8037dd6d77aed8d12addd54d5eb2a6801541a1bf87c9822e78eea42190600090a250565b6109a26111f0565b60015442906109db907f0000000000000000000000000000000000000000000000000000000000278d00906001600160f81b0316611b50565b1115610a395760405162461bcd60e51b815260206004820152602760248201527f54656d706f72616c476f7665726e6f723a206e6f7420706173742070617573656044820152662077696e646f7760c81b60648201526084016104b6565b600180546001600160f81b0319169055610a516114ea565b60405142907f5607d774129cad49296363738883d35576762c63e621f31b16c5e2214e2c03b490600090a2565b610a86611191565b610a8e6107c4565b15610a9b576107f76114ea565b600154600160f81b900460ff16610b095760405162461bcd60e51b815260206004820152602c60248201527f54656d706f72616c476f7665726e6f723a20677561726469616e20706175736560448201526b081b9bdd08185b1b1bddd95960a21b60648201526084016104b6565b426001600160f81b03166001556107f7611539565b61ffff82166000908152600260205260408120610695908361157c565b333014610bac5760405162461bcd60e51b815260206004820152604460248201819052600080516020612263833981519152908201527f726163742063616e20757064617465206772616e7420677561726469616e20706064820152636175736560e01b608482015260a4016104b6565b600160f81b60015560405142907f309f3735db2677e216920b5dc9d0b76108f0fa9fc1176a6701bd4e77f5065ac190600090a2565b6001600160a01b031690565b610bf5611191565b6001600160a01b038116610c5a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104b6565b61068381610c6f565b60006106958383611588565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b610cc76107c4565b156107f75760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016104b6565b60008060007f000000000000000000000000ee91c335eab126df5fdb3797ea9d6ad93aec97226001600160a01b031663c0fd8bde866040518263ffffffff1660e01b8152600401610d589190611bb3565b600060405180830381865afa158015610d75573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d9d9190810190611d3e565b925092509250818190610dc35760405162461bcd60e51b81526004016104b69190611bb3565b5083610eed5761014083015160009081526003602052604081205461010090046001600160f81b03169003610e3a5760405162461bcd60e51b815260206004820152601f60248201527f54656d706f72616c476f7665726e6f723a207478206e6f74207175657565640060448201526064016104b6565b6101408301516000908152600360205260409020544290610e8a907f00000000000000000000000000000000000000000000000000000000000151809061010090046001600160f81b0316611b50565b1115610ee85760405162461bcd60e51b815260206004820152602760248201527f54656d706f72616c476f7665726e6f723a2074696d656c6f636b206e6f7420666044820152661a5b9a5cda195960ca1b60648201526084016104b6565b610f41565b61014083015160009081526003602052604081205461010090046001600160f81b03169003610f41576101408301516000908152600360205260409020805460ff16610100426001600160f81b0316021790555b6080830151606084015161ffff166000908152600260205260409020610f669161157c565b610f825760405162461bcd60e51b81526004016104b690611e95565b61014083015160009081526003602052604090205460ff1615610ff55760405162461bcd60e51b815260206004820152602560248201527f54656d706f72616c476f7665726e6f723a20747820616c72656164792065786560448201526418dd5d195960da1b60648201526084016104b6565b6101408301516000908152600360209081526040909120805460ff1916600117905560e08401518051606092839283926110359290820181019101611fb8565b91955093509150611049905083838361167b565b60005b835181101561118657600084828151811061106957611069611afd565b60200260200101519050600084838151811061108757611087611afd565b6020026020010151905060008484815181106110a5576110a5611afd565b60200260200101519050600080846001600160a01b031684846040516110cb91906120b5565b60006040518083038185875af1925050503d8060008114611108576040519150601f19603f3d011682016040523d82523d6000602084013e61110d565b606091505b50915091508181906111325760405162461bcd60e51b81526004016104b69190611bb3565b507faf022f6b53b11c364e2dfc0aea08eb9416c94f2661451ea82ead8831385617a6858585604051611166939291906120d1565b60405180910390a15050505050808061117e90612101565b91505061104c565b505050505050505050565b3361119a6108b1565b6001600160a01b0316146107f75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104b6565b6111f86107c4565b6107f75760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016104b6565b6000610695838361173f565b60008060007f000000000000000000000000ee91c335eab126df5fdb3797ea9d6ad93aec97226001600160a01b031663c0fd8bde856040518263ffffffff1660e01b81526004016112989190611bb3565b600060405180830381865afa1580156112b5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112dd9190810190611d3e565b9250925092508181906113035760405162461bcd60e51b81526004016104b69190611bb3565b50600060608060608660e001518060200190518101906113239190611fb8565b9296509094509250905061133883838361167b565b6001600160a01b03841630146113a05760405162461bcd60e51b815260206004820152602760248201527f54656d706f72616c476f7665726e6f723a20496e636f7272656374206465737460448201526634b730ba34b7b760c91b60648201526084016104b6565b6080870151606088015161ffff1660009081526002602052604090206113c59161157c565b6113e15760405162461bcd60e51b81526004016104b690611e95565b61014087015160009081526003602052604090205461010090046001600160f81b0316156114625760405162461bcd60e51b815260206004820152602860248201527f54656d706f72616c476f7665726e6f723a204d65737361676520616c726561646044820152671e481c5d595d595960c21b60648201526084016104b6565b61014087015160009081526003602052604090819020805460ff16610100426001600160f81b031602179055517fc486294e67e6b98e19d854bb8a606f314e248d45e842a98b09a51be7b13ce2a5906114c2908690869086908690612172565b60405180910390a15050505050505050565b6000610698825490565b60006106958383611789565b6114f26111f0565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405161152f91906119f8565b60405180910390a1565b611541610cbf565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586115223390565b600061069583836117b3565b600081815260018301602052604081205480156116715760006115ac600183612219565b85549091506000906115c090600190612219565b90508181146116255760008660000182815481106115e0576115e0611afd565b906000526020600020015490508087600001848154811061160357611603611afd565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806116365761163661222c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610698565b6000915050610698565b82516000036116cc5760405162461bcd60e51b815260206004820181905260248201527f54656d706f72616c476f7665726e6f723a20456d7074792070726f706f73616c60448201526064016104b6565b815183511480156116de575080518351145b6105c35760405162461bcd60e51b815260206004820152602c60248201527f54656d706f72616c476f7665726e6f723a204172697479206d69736d6174636860448201526b08199bdc881c185e5b1bd85960a21b60648201526084016104b6565b600061174b83836117b3565b61178157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610698565b506000610698565b60008260000182815481106117a0576117a0611afd565b9060005260206000200154905092915050565b60009081526001919091016020526040902054151590565b600080602083850312156117de57600080fd5b82356001600160401b03808211156117f557600080fd5b818501915085601f83011261180957600080fd5b81358181111561181857600080fd5b8660208260061b850101111561182d57600080fd5b60209290920196919550909350505050565b6001600160a01b038116811461068357600080fd5b60006020828403121561186657600080fd5b81356118718161183f565b9392505050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b03811182821017156118b0576118b0611878565b60405290565b60405161016081016001600160401b03811182821017156118b0576118b0611878565b604051601f8201601f191681016001600160401b038111828210171561190157611901611878565b604052919050565b60006001600160401b0382111561192257611922611878565b50601f01601f191660200190565b60006020828403121561194257600080fd5b81356001600160401b0381111561195857600080fd5b8201601f8101841361196957600080fd5b803561197c61197782611909565b6118d9565b81815285602083850101111561199157600080fd5b81602084016020830137600091810160200191909152949350505050565b61ffff8116811461068357600080fd5b600080604083850312156119d257600080fd5b82356119dd816119af565b915060208301356119ed8161183f565b809150509250929050565b6001600160a01b0391909116815260200190565b600060208284031215611a1e57600080fd5b8135611871816119af565b6020808252825182820181905260009190848201906040850190845b81811015611a6157835183529284019291840191600101611a45565b50909695505050505050565b60008060408385031215611a8057600080fd5b8235611a8b816119af565b946020939093013593505050565b600060208284031215611aab57600080fd5b5035919050565b6020808252603f9082015260008051602061226383398151915260408201527f726163742063616e2075706461746520747275737465642073656e6465727300606082015260800190565b634e487b7160e01b600052603260045260246000fd5b61ffff9390931683526001600160a01b039190911660208301521515604082015260600190565b634e487b7160e01b600052601160045260246000fd5b8082018082111561069857610698611b3a565b60005b83811015611b7e578181015183820152602001611b66565b50506000910152565b60008151808452611b9f816020860160208601611b63565b601f01601f19169290920160200192915050565b6020815260006106956020830184611b87565b805160ff81168114611bd757600080fd5b919050565b805163ffffffff81168114611bd757600080fd5b8051611bd7816119af565b80516001600160401b0381168114611bd757600080fd5b600082601f830112611c2357600080fd5b8151611c3161197782611909565b818152846020838601011115611c4657600080fd5b611c57826020830160208701611b63565b949350505050565b60006001600160401b03821115611c7857611c78611878565b5060051b60200190565b600082601f830112611c9357600080fd5b81516020611ca361197783611c5f565b82815260079290921b84018101918181019086841115611cc257600080fd5b8286015b84811015611d235760808189031215611cdf5760008081fd5b611ce761188e565b8151815284820151858201526040611d00818401611bc6565b908201526060611d11838201611bc6565b90820152835291830191608001611cc6565b509695505050505050565b80518015158114611bd757600080fd5b600080600060608486031215611d5357600080fd5b83516001600160401b0380821115611d6a57600080fd5b908501906101608288031215611d7f57600080fd5b611d876118b6565b611d9083611bc6565b8152611d9e60208401611bdc565b6020820152611daf60408401611bdc565b6040820152611dc060608401611bf0565b606082015260808301516080820152611ddb60a08401611bfb565b60a0820152611dec60c08401611bc6565b60c082015260e083015182811115611e0357600080fd5b611e0f89828601611c12565b60e083015250610100611e23818501611bdc565b908201526101208381015183811115611e3b57600080fd5b611e478a828701611c82565b918301919091525061014083810151908201529450611e6860208701611d2e565b93506040860151915080821115611e7e57600080fd5b50611e8b86828701611c12565b9150509250925092565b60208082526029908201527f54656d706f72616c476f7665726e6f723a20496e76616c696420456d6974746560408201526872204164647265737360b81b606082015260800190565b600082601f830112611eef57600080fd5b81516020611eff61197783611c5f565b82815260059290921b84018101918181019086841115611f1e57600080fd5b8286015b84811015611d235780518352918301918301611f22565b600082601f830112611f4a57600080fd5b81516020611f5a61197783611c5f565b82815260059290921b84018101918181019086841115611f7957600080fd5b8286015b84811015611d235780516001600160401b03811115611f9c5760008081fd5b611faa8986838b0101611c12565b845250918301918301611f7d565b60008060008060808587031215611fce57600080fd5b8451611fd98161183f565b602086810151919550906001600160401b0380821115611ff857600080fd5b818801915088601f83011261200c57600080fd5b815161201a61197782611c5f565b81815260059190911b8301840190848101908b83111561203957600080fd5b938501935b828510156120605784516120518161183f565b8252938501939085019061203e565b60408b0151909850945050508083111561207957600080fd5b61208589848a01611ede565b9450606088015192508083111561209b57600080fd5b50506120a987828801611f39565b91505092959194509250565b600082516120c7818460208701611b63565b9190910192915050565b60018060a01b03841681528260208201526060604082015260006120f86060830184611b87565b95945050505050565b60006001820161211357612113611b3a565b5060010190565b600082825180855260208086019550808260051b84010181860160005b8481101561216557601f19868403018952612153838351611b87565b98840198925090830190600101612137565b5090979650505050505050565b6001600160a01b0385811682526080602080840182905286519184018290526000928782019290919060a0860190855b818110156121c05785518516835294830194918301916001016121a2565b5050858103604087015287518082529082019350915080870160005b838110156121f8578151855293820193908201906001016121dc565b50505050828103606084015261220e818561211a565b979650505050505050565b8181038181111561069857610698611b3a565b634e487b7160e01b600052603160045260246000fdfead5ad009fb0380817906297d4db849c9a30b93e0d3761c005ef8c487d923922454656d706f72616c476f7665726e6f723a204f6e6c79207468697320636f6e74a264697066735822122069b0a18183bc03980e928e5109113040d2ad5ea7181a98eac66ff98645ab9fb164736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ee91c335eab126df5fdb3797ea9d6ad93aec972200000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000278d000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000100000000000000000000000009a8464c4c11cea17e191653deb7cdc1be30f1af4
-----Decoded View---------------
Arg [0] : wormholeCore (address): 0xEe91C335eab126dF5fDB3797EA9d6aD93aeC9722
Arg [1] : _proposalDelay (uint256): 86400
Arg [2] : _permissionlessUnpauseTime (uint256): 2592000
Arg [3] : _trustedSenders (tuple[]): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000ee91c335eab126df5fdb3797ea9d6ad93aec9722
Arg [1] : 0000000000000000000000000000000000000000000000000000000000015180
Arg [2] : 0000000000000000000000000000000000000000000000000000000000278d00
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000010
Arg [6] : 0000000000000000000000009a8464c4c11cea17e191653deb7cdc1be30f1af4
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
OP | 30.44% | $96,007 | 0.00005681 | $5.45 | |
OP | 25.44% | $0.072474 | 62.8765 | $4.56 | |
OP | 10.74% | $3,010.61 | 0.00063907 | $1.92 | |
OP | 9.84% | $2,757.52 | 0.000639 | $1.76 | |
OP | 5.44% | $3,287.29 | 0.00029644 | $0.9744 | |
OP | 5.42% | $1.18 | 0.822 | $0.9714 | |
OP | 5.40% | $3,103.23 | 0.00031153 | $0.9667 | |
OP | 4.72% | $0.072474 | 11.6578 | $0.8448 | |
OP | 0.86% | $0.999793 | 0.1539 | $0.1538 | |
OP | 0.86% | $0.99991 | 0.1538 | $0.1537 | |
OP | 0.85% | $1 | 0.1532 | $0.1531 |
[ 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.