Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Smol
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0; import {TransparentUpgradeableProxy} from "@hyperlane-xyz/core/contracts/upgrade/TransparentUpgradeableProxy.sol"; import {TokenRouter} from "@hyperlane-xyz/core/contracts/token/libs/TokenRouter.sol"; import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import {ERC20VotesUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol"; import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {Message} from "@hyperlane-xyz/core/contracts/libs/Message.sol"; import {TokenMessage} from "@hyperlane-xyz/core/contracts/token/libs/TokenMessage.sol"; import {TypeCasts} from "@hyperlane-xyz/core/contracts/libs/TypeCasts.sol"; contract Smol is ERC20Upgradeable, ERC20PermitUpgradeable, ERC20VotesUpgradeable, OwnableUpgradeable, TokenRouter { using Math for uint256; using TypeCasts for bytes32; using TypeCasts for address; using TokenMessage for bytes; uint256 private constant REDUCTION_RATIO = 1666; error TransferToBlockedChainNotAllowed(); uint32 public immutable blockedChain; constructor(address _mailbox, uint32 _blockedChain) TokenRouter(_mailbox) { blockedChain = _blockedChain; _disableInitializers(); } function initialize( string memory _name, string memory _symbol, address _hook, address _interchainSecurityModule, address _owner ) external initializer { __ERC20_init(_name, _symbol); __ERC20Permit_init(_name); __ERC20Votes_init(); __Ownable_init(); _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); _transferOwnership(_owner); } function mint(address to, uint256 amount) external onlyOwner { _mint(to, amount); } function balanceOf( address _account ) public view virtual override(TokenRouter, ERC20Upgradeable) returns (uint256) { return ERC20Upgradeable.balanceOf(_account); } function _transferFromSender(uint256 _amount) internal override returns (bytes memory) { _burn(msg.sender, _amount); return bytes(""); } function _transferTo( address _recipient, uint256 _amount, bytes calldata ) internal virtual override { _mint(_recipient, _amount); } function _transferRemote( uint32 _destination, bytes32 _recipient, uint256 _amountOrId, uint256 _value, bytes memory _hookMetadata, address _hook ) internal virtual override returns (bytes32 messageId) { if (_destination == blockedChain) revert TransferToBlockedChainNotAllowed(); return super._transferRemote( _destination, _recipient, _amountOrId, _value, _hookMetadata, _hook ); } // Required overrides for ERC20Votes function _afterTokenTransfer( address from, address to, uint256 amount ) internal override(ERC20Upgradeable, ERC20VotesUpgradeable) { super._afterTokenTransfer(from, to, amount); } function _mint( address to, uint256 amount ) internal override(ERC20Upgradeable, ERC20VotesUpgradeable) { super._mint(to, amount); } function _burn( address account, uint256 amount ) internal override(ERC20Upgradeable, ERC20VotesUpgradeable) { super._burn(account, amount); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; /*@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@ HYPERLANE @@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@*/ // ============ Internal Imports ============ import {Router} from "./Router.sol"; import {StandardHookMetadata} from "../hooks/libs/StandardHookMetadata.sol"; abstract contract GasRouter is Router { event GasSet(uint32 domain, uint256 gas); // ============ Mutable Storage ============ mapping(uint32 => uint256) public destinationGas; struct GasRouterConfig { uint32 domain; uint256 gas; } constructor(address _mailbox) Router(_mailbox) {} /** * @notice Sets the gas amount dispatched for each configured domain. * @param gasConfigs The array of GasRouterConfig structs */ function setDestinationGas( GasRouterConfig[] calldata gasConfigs ) external onlyOwner { for (uint256 i = 0; i < gasConfigs.length; i += 1) { _setDestinationGas(gasConfigs[i].domain, gasConfigs[i].gas); } } /** * @notice Sets the gas amount dispatched for each configured domain. * @param domain The destination domain ID * @param gas The gas limit */ function setDestinationGas(uint32 domain, uint256 gas) external onlyOwner { _setDestinationGas(domain, gas); } /** * @notice Returns the gas payment required to dispatch a message to the given domain's router. * @param _destinationDomain The domain of the router. * @return _gasPayment Payment computed by the registered InterchainGasPaymaster. */ function quoteGasPayment( uint32 _destinationDomain ) external view returns (uint256) { return _GasRouter_quoteDispatch(_destinationDomain, "", address(hook)); } function _GasRouter_hookMetadata( uint32 _destination ) internal view returns (bytes memory) { return StandardHookMetadata.overrideGasLimit(destinationGas[_destination]); } function _setDestinationGas(uint32 domain, uint256 gas) internal { destinationGas[domain] = gas; emit GasSet(domain, gas); } function _GasRouter_dispatch( uint32 _destination, uint256 _value, bytes memory _messageBody, address _hook ) internal returns (bytes32) { return _Router_dispatch( _destination, _value, _messageBody, _GasRouter_hookMetadata(_destination), _hook ); } function _GasRouter_quoteDispatch( uint32 _destination, bytes memory _messageBody, address _hook ) internal view returns (uint256) { return _Router_quoteDispatch( _destination, _messageBody, _GasRouter_hookMetadata(_destination), _hook ); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; /*@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@ HYPERLANE @@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@*/ // ============ Internal Imports ============ import {IMailbox} from "../interfaces/IMailbox.sol"; import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol"; import {IInterchainSecurityModule} from "../interfaces/IInterchainSecurityModule.sol"; import {Message} from "../libs/Message.sol"; import {PackageVersioned} from "../PackageVersioned.sol"; // ============ External Imports ============ import {Address} from "@openzeppelin/contracts/utils/Address.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; abstract contract MailboxClient is OwnableUpgradeable, PackageVersioned { using Message for bytes; event HookSet(address _hook); event IsmSet(address _ism); IMailbox public immutable mailbox; uint32 public immutable localDomain; IPostDispatchHook public hook; IInterchainSecurityModule public interchainSecurityModule; uint256[48] private __GAP; // gap for upgrade safety // ============ Modifiers ============ modifier onlyContract(address _contract) { require( Address.isContract(_contract), "MailboxClient: invalid mailbox" ); _; } modifier onlyContractOrNull(address _contract) { require( Address.isContract(_contract) || _contract == address(0), "MailboxClient: invalid contract setting" ); _; } /** * @notice Only accept messages from a Hyperlane Mailbox contract */ modifier onlyMailbox() { require( msg.sender == address(mailbox), "MailboxClient: sender not mailbox" ); _; } constructor(address _mailbox) onlyContract(_mailbox) { mailbox = IMailbox(_mailbox); localDomain = mailbox.localDomain(); _transferOwnership(msg.sender); } /** * @notice Sets the address of the application's custom hook. * @param _hook The address of the hook contract. */ function setHook( address _hook ) public virtual onlyContractOrNull(_hook) onlyOwner { hook = IPostDispatchHook(_hook); emit HookSet(_hook); } /** * @notice Sets the address of the application's custom interchain security module. * @param _module The address of the interchain security module contract. */ function setInterchainSecurityModule( address _module ) public onlyContractOrNull(_module) onlyOwner { interchainSecurityModule = IInterchainSecurityModule(_module); emit IsmSet(_module); } // ======== Initializer ========= function _MailboxClient_initialize( address _hook, address _interchainSecurityModule, address _owner ) internal onlyInitializing { __Ownable_init(); setHook(_hook); setInterchainSecurityModule(_interchainSecurityModule); _transferOwnership(_owner); } function _isLatestDispatched(bytes32 id) internal view returns (bool) { return mailbox.latestDispatchedId() == id; } function _isDelivered(bytes32 id) internal view returns (bool) { return mailbox.delivered(id); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; // ============ Internal Imports ============ import {IMessageRecipient} from "../interfaces/IMessageRecipient.sol"; import {IPostDispatchHook} from "../interfaces/hooks/IPostDispatchHook.sol"; import {IInterchainSecurityModule} from "../interfaces/IInterchainSecurityModule.sol"; import {MailboxClient} from "./MailboxClient.sol"; import {EnumerableMapExtended} from "../libs/EnumerableMapExtended.sol"; // ============ External Imports ============ import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; abstract contract Router is MailboxClient, IMessageRecipient { using EnumerableMapExtended for EnumerableMapExtended.UintToBytes32Map; using Strings for uint32; // ============ Mutable Storage ============ EnumerableMapExtended.UintToBytes32Map internal _routers; uint256[48] private __GAP; // gap for upgrade safety constructor(address _mailbox) MailboxClient(_mailbox) {} // ============ External functions ============ function domains() external view returns (uint32[] memory) { return _routers.uint32Keys(); } /** * @notice Returns the address of the Router contract for the given domain * @param _domain The remote domain ID. * @dev Returns 0 address if no router is enrolled for the given domain * @return router The address of the Router contract for the given domain */ function routers(uint32 _domain) public view virtual returns (bytes32) { (, bytes32 _router) = _routers.tryGet(_domain); return _router; } /** * @notice Unregister the domain * @param _domain The domain of the remote Application Router */ function unenrollRemoteRouter(uint32 _domain) external virtual onlyOwner { _unenrollRemoteRouter(_domain); } /** * @notice Register the address of a Router contract for the same Application on a remote chain * @param _domain The domain of the remote Application Router * @param _router The address of the remote Application Router */ function enrollRemoteRouter( uint32 _domain, bytes32 _router ) external virtual onlyOwner { _enrollRemoteRouter(_domain, _router); } /** * @notice Batch version of `enrollRemoteRouter` * @param _domains The domains of the remote Application Routers * @param _addresses The addresses of the remote Application Routers */ function enrollRemoteRouters( uint32[] calldata _domains, bytes32[] calldata _addresses ) external virtual onlyOwner { require(_domains.length == _addresses.length, "!length"); uint256 length = _domains.length; for (uint256 i = 0; i < length; i += 1) { _enrollRemoteRouter(_domains[i], _addresses[i]); } } /** * @notice Batch version of `unenrollRemoteRouter` * @param _domains The domains of the remote Application Routers */ function unenrollRemoteRouters( uint32[] calldata _domains ) external virtual onlyOwner { uint256 length = _domains.length; for (uint256 i = 0; i < length; i += 1) { _unenrollRemoteRouter(_domains[i]); } } /** * @notice Handles an incoming message * @param _origin The origin domain * @param _sender The sender address * @param _message The message */ function handle( uint32 _origin, bytes32 _sender, bytes calldata _message ) external payable virtual override onlyMailbox { bytes32 _router = _mustHaveRemoteRouter(_origin); require(_router == _sender, "Enrolled router does not match sender"); _handle(_origin, _sender, _message); } // ============ Virtual functions ============ function _handle( uint32 _origin, bytes32 _sender, bytes calldata _message ) internal virtual; // ============ Internal functions ============ /** * @notice Set the router for a given domain * @param _domain The domain * @param _address The new router */ function _enrollRemoteRouter( uint32 _domain, bytes32 _address ) internal virtual { _routers.set(_domain, _address); } /** * @notice Remove the router for a given domain * @param _domain The domain */ function _unenrollRemoteRouter(uint32 _domain) internal virtual { require(_routers.remove(_domain), _domainNotFoundError(_domain)); } /** * @notice Return true if the given domain / router is the address of a remote Application Router * @param _domain The domain of the potential remote Application Router * @param _address The address of the potential remote Application Router */ function _isRemoteRouter( uint32 _domain, bytes32 _address ) internal view returns (bool) { return routers(_domain) == _address; } /** * @notice Assert that the given domain has an Application Router registered and return its address * @param _domain The domain of the chain for which to get the Application Router * @return _router The address of the remote Application Router on _domain */ function _mustHaveRemoteRouter( uint32 _domain ) internal view returns (bytes32) { (bool contained, bytes32 _router) = _routers.tryGet(_domain); if (contained) { return _router; } revert(_domainNotFoundError(_domain)); } function _domainNotFoundError( uint32 _domain ) internal pure returns (string memory) { return string.concat( "No router enrolled for domain: ", _domain.toString() ); } function _Router_dispatch( uint32 _destinationDomain, uint256 _value, bytes memory _messageBody, bytes memory _hookMetadata, address _hook ) internal returns (bytes32) { bytes32 _router = _mustHaveRemoteRouter(_destinationDomain); return mailbox.dispatch{value: _value}( _destinationDomain, _router, _messageBody, _hookMetadata, IPostDispatchHook(_hook) ); } /** * DEPRECATED: Use `_Router_dispatch` instead * @dev For backward compatibility with v2 client contracts */ function _dispatch( uint32 _destinationDomain, bytes memory _messageBody ) internal returns (bytes32) { return _Router_dispatch( _destinationDomain, msg.value, _messageBody, "", address(hook) ); } function _Router_quoteDispatch( uint32 _destinationDomain, bytes memory _messageBody, bytes memory _hookMetadata, address _hook ) internal view returns (uint256) { bytes32 _router = _mustHaveRemoteRouter(_destinationDomain); return mailbox.quoteDispatch( _destinationDomain, _router, _messageBody, _hookMetadata, IPostDispatchHook(_hook) ); } /** * DEPRECATED: Use `_Router_quoteDispatch` instead * @dev For backward compatibility with v2 client contracts */ function _quoteDispatch( uint32 _destinationDomain, bytes memory _messageBody ) internal view returns (uint256) { return _Router_quoteDispatch( _destinationDomain, _messageBody, "", address(hook) ); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; /*@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@ HYPERLANE @@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@*/ /** * Format of metadata: * * [0:2] variant * [2:34] msg.value * [34:66] Gas limit for message (IGP) * [66:86] Refund address for message (IGP) * [86:] Custom metadata */ library StandardHookMetadata { struct Metadata { uint16 variant; uint256 msgValue; uint256 gasLimit; address refundAddress; } uint8 private constant VARIANT_OFFSET = 0; uint8 private constant MSG_VALUE_OFFSET = 2; uint8 private constant GAS_LIMIT_OFFSET = 34; uint8 private constant REFUND_ADDRESS_OFFSET = 66; uint256 private constant MIN_METADATA_LENGTH = 86; uint16 public constant VARIANT = 1; /** * @notice Returns the variant of the metadata. * @param _metadata ABI encoded standard hook metadata. * @return variant of the metadata as uint8. */ function variant(bytes calldata _metadata) internal pure returns (uint16) { if (_metadata.length < VARIANT_OFFSET + 2) return 0; return uint16(bytes2(_metadata[VARIANT_OFFSET:VARIANT_OFFSET + 2])); } /** * @notice Returns the specified value for the message. * @param _metadata ABI encoded standard hook metadata. * @param _default Default fallback value. * @return Value for the message as uint256. */ function msgValue( bytes calldata _metadata, uint256 _default ) internal pure returns (uint256) { if (_metadata.length < MSG_VALUE_OFFSET + 32) return _default; return uint256(bytes32(_metadata[MSG_VALUE_OFFSET:MSG_VALUE_OFFSET + 32])); } /** * @notice Returns the specified gas limit for the message. * @param _metadata ABI encoded standard hook metadata. * @param _default Default fallback gas limit. * @return Gas limit for the message as uint256. */ function gasLimit( bytes calldata _metadata, uint256 _default ) internal pure returns (uint256) { if (_metadata.length < GAS_LIMIT_OFFSET + 32) return _default; return uint256(bytes32(_metadata[GAS_LIMIT_OFFSET:GAS_LIMIT_OFFSET + 32])); } /** * @notice Returns the specified refund address for the message. * @param _metadata ABI encoded standard hook metadata. * @param _default Default fallback refund address. * @return Refund address for the message as address. */ function refundAddress( bytes calldata _metadata, address _default ) internal pure returns (address) { if (_metadata.length < REFUND_ADDRESS_OFFSET + 20) return _default; return address( bytes20( _metadata[REFUND_ADDRESS_OFFSET:REFUND_ADDRESS_OFFSET + 20] ) ); } /** * @notice Returns any custom metadata. * @param _metadata ABI encoded standard hook metadata. * @return Custom metadata. */ function getCustomMetadata( bytes calldata _metadata ) internal pure returns (bytes calldata) { if (_metadata.length < MIN_METADATA_LENGTH) return _metadata[0:0]; return _metadata[MIN_METADATA_LENGTH:]; } /** * @notice Formats the specified gas limit and refund address into standard hook metadata. * @param _msgValue msg.value for the message. * @param _gasLimit Gas limit for the message. * @param _refundAddress Refund address for the message. * @param _customMetadata Additional metadata to include in the standard hook metadata. * @return ABI encoded standard hook metadata. */ function formatMetadata( uint256 _msgValue, uint256 _gasLimit, address _refundAddress, bytes memory _customMetadata ) internal pure returns (bytes memory) { return abi.encodePacked( VARIANT, _msgValue, _gasLimit, _refundAddress, _customMetadata ); } /** * @notice Formats the specified gas limit and refund address into standard hook metadata. * @param _msgValue msg.value for the message. * @return ABI encoded standard hook metadata. */ function overrideMsgValue( uint256 _msgValue ) internal view returns (bytes memory) { return formatMetadata(_msgValue, uint256(0), msg.sender, ""); } /** * @notice Formats the specified gas limit and refund address into standard hook metadata. * @param _gasLimit Gas limit for the message. * @return ABI encoded standard hook metadata. */ function overrideGasLimit( uint256 _gasLimit ) internal view returns (bytes memory) { return formatMetadata(uint256(0), _gasLimit, msg.sender, ""); } /** * @notice Formats the specified refund address into standard hook metadata. * @param _refundAddress Refund address for the message. * @return ABI encoded standard hook metadata. */ function overrideRefundAddress( address _refundAddress ) internal pure returns (bytes memory) { return formatMetadata(uint256(0), uint256(0), _refundAddress, ""); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; /*@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@ HYPERLANE @@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@@ @@@@@@@@*/ interface IPostDispatchHook { enum Types { UNUSED, ROUTING, AGGREGATION, MERKLE_TREE, INTERCHAIN_GAS_PAYMASTER, FALLBACK_ROUTING, ID_AUTH_ISM, PAUSABLE, PROTOCOL_FEE, LAYER_ZERO_V1, RATE_LIMITED, ARB_L2_TO_L1, OP_L2_TO_L1 } /** * @notice Returns an enum that represents the type of hook */ function hookType() external view returns (uint8); /** * @notice Returns whether the hook supports metadata * @param metadata metadata * @return Whether the hook supports metadata */ function supportsMetadata( bytes calldata metadata ) external view returns (bool); /** * @notice Post action after a message is dispatched via the Mailbox * @param metadata The metadata required for the hook * @param message The message passed from the Mailbox.dispatch() call */ function postDispatch( bytes calldata metadata, bytes calldata message ) external payable; /** * @notice Compute the payment required by the postDispatch call * @param metadata The metadata required for the hook * @param message The message passed from the Mailbox.dispatch() call * @return Quoted payment for the postDispatch call */ function quoteDispatch( bytes calldata metadata, bytes calldata message ) external view returns (uint256); }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; interface IInterchainSecurityModule { enum Types { UNUSED, ROUTING, AGGREGATION, LEGACY_MULTISIG, MERKLE_ROOT_MULTISIG, MESSAGE_ID_MULTISIG, NULL, // used with relayer carrying no metadata CCIP_READ, ARB_L2_TO_L1, WEIGHTED_MERKLE_ROOT_MULTISIG, WEIGHTED_MESSAGE_ID_MULTISIG, OP_L2_TO_L1 } /** * @notice Returns an enum that represents the type of security model * encoded by this ISM. * @dev Relayers infer how to fetch and format metadata. */ function moduleType() external view returns (uint8); /** * @notice Defines a security model responsible for verifying interchain * messages based on the provided metadata. * @param _metadata Off-chain metadata provided by a relayer, specific to * the security model encoded by the module (e.g. validator signatures) * @param _message Hyperlane encoded interchain message * @return True if the message was verified */ function verify( bytes calldata _metadata, bytes calldata _message ) external returns (bool); } interface ISpecifiesInterchainSecurityModule { function interchainSecurityModule() external view returns (IInterchainSecurityModule); }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; import {IInterchainSecurityModule} from "./IInterchainSecurityModule.sol"; import {IPostDispatchHook} from "./hooks/IPostDispatchHook.sol"; interface IMailbox { // ============ Events ============ /** * @notice Emitted when a new message is dispatched via Hyperlane * @param sender The address that dispatched the message * @param destination The destination domain of the message * @param recipient The message recipient address on `destination` * @param message Raw bytes of message */ event Dispatch( address indexed sender, uint32 indexed destination, bytes32 indexed recipient, bytes message ); /** * @notice Emitted when a new message is dispatched via Hyperlane * @param messageId The unique message identifier */ event DispatchId(bytes32 indexed messageId); /** * @notice Emitted when a Hyperlane message is processed * @param messageId The unique message identifier */ event ProcessId(bytes32 indexed messageId); /** * @notice Emitted when a Hyperlane message is delivered * @param origin The origin domain of the message * @param sender The message sender address on `origin` * @param recipient The address that handled the message */ event Process( uint32 indexed origin, bytes32 indexed sender, address indexed recipient ); function localDomain() external view returns (uint32); function delivered(bytes32 messageId) external view returns (bool); function defaultIsm() external view returns (IInterchainSecurityModule); function defaultHook() external view returns (IPostDispatchHook); function requiredHook() external view returns (IPostDispatchHook); function latestDispatchedId() external view returns (bytes32); function dispatch( uint32 destinationDomain, bytes32 recipientAddress, bytes calldata messageBody ) external payable returns (bytes32 messageId); function quoteDispatch( uint32 destinationDomain, bytes32 recipientAddress, bytes calldata messageBody ) external view returns (uint256 fee); function dispatch( uint32 destinationDomain, bytes32 recipientAddress, bytes calldata body, bytes calldata defaultHookMetadata ) external payable returns (bytes32 messageId); function quoteDispatch( uint32 destinationDomain, bytes32 recipientAddress, bytes calldata messageBody, bytes calldata defaultHookMetadata ) external view returns (uint256 fee); function dispatch( uint32 destinationDomain, bytes32 recipientAddress, bytes calldata body, bytes calldata customHookMetadata, IPostDispatchHook customHook ) external payable returns (bytes32 messageId); function quoteDispatch( uint32 destinationDomain, bytes32 recipientAddress, bytes calldata messageBody, bytes calldata customHookMetadata, IPostDispatchHook customHook ) external view returns (uint256 fee); function process( bytes calldata metadata, bytes calldata message ) external payable; function recipientIsm( address recipient ) external view returns (IInterchainSecurityModule module); }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; interface IMessageRecipient { function handle( uint32 _origin, bytes32 _sender, bytes calldata _message ) external payable; }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; // ============ External Imports ============ import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; // extends EnumerableMap with uint256 => bytes32 type // modelled after https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.0/contracts/utils/structs/EnumerableMap.sol library EnumerableMapExtended { using EnumerableMap for EnumerableMap.Bytes32ToBytes32Map; using EnumerableSet for EnumerableSet.Bytes32Set; struct UintToBytes32Map { EnumerableMap.Bytes32ToBytes32Map _inner; } // ============ Library Functions ============ function keys( UintToBytes32Map storage map ) internal view returns (uint256[] memory _keys) { uint256 _length = map._inner.length(); _keys = new uint256[](_length); for (uint256 i = 0; i < _length; i++) { _keys[i] = uint256(map._inner._keys.at(i)); } } function uint32Keys( UintToBytes32Map storage map ) internal view returns (uint32[] memory _keys) { uint256[] memory uint256keys = keys(map); _keys = new uint32[](uint256keys.length); for (uint256 i = 0; i < uint256keys.length; i++) { _keys[i] = uint32(uint256keys[i]); } } function set( UintToBytes32Map storage map, uint256 key, bytes32 value ) internal { map._inner.set(bytes32(key), value); } function get( UintToBytes32Map storage map, uint256 key ) internal view returns (bytes32) { return map._inner.get(bytes32(key)); } function tryGet( UintToBytes32Map storage map, uint256 key ) internal view returns (bool, bytes32) { return map._inner.tryGet(bytes32(key)); } function remove( UintToBytes32Map storage map, uint256 key ) internal returns (bool) { return map._inner.remove(bytes32(key)); } function contains( UintToBytes32Map storage map, uint256 key ) internal view returns (bool) { return map._inner.contains(bytes32(key)); } function length( UintToBytes32Map storage map ) internal view returns (uint256) { return map._inner.length(); } function at( UintToBytes32Map storage map, uint256 index ) internal view returns (uint256, bytes32) { (bytes32 key, bytes32 value) = map._inner.at(index); return (uint256(key), value); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; import {TypeCasts} from "./TypeCasts.sol"; /** * @title Hyperlane Message Library * @notice Library for formatted messages used by Mailbox **/ library Message { using TypeCasts for bytes32; uint256 private constant VERSION_OFFSET = 0; uint256 private constant NONCE_OFFSET = 1; uint256 private constant ORIGIN_OFFSET = 5; uint256 private constant SENDER_OFFSET = 9; uint256 private constant DESTINATION_OFFSET = 41; uint256 private constant RECIPIENT_OFFSET = 45; uint256 private constant BODY_OFFSET = 77; /** * @notice Returns formatted (packed) Hyperlane message with provided fields * @dev This function should only be used in memory message construction. * @param _version The version of the origin and destination Mailboxes * @param _nonce A nonce to uniquely identify the message on its origin chain * @param _originDomain Domain of origin chain * @param _sender Address of sender as bytes32 * @param _destinationDomain Domain of destination chain * @param _recipient Address of recipient on destination chain as bytes32 * @param _messageBody Raw bytes of message body * @return Formatted message */ function formatMessage( uint8 _version, uint32 _nonce, uint32 _originDomain, bytes32 _sender, uint32 _destinationDomain, bytes32 _recipient, bytes calldata _messageBody ) internal pure returns (bytes memory) { return abi.encodePacked( _version, _nonce, _originDomain, _sender, _destinationDomain, _recipient, _messageBody ); } /** * @notice Returns the message ID. * @param _message ABI encoded Hyperlane message. * @return ID of `_message` */ function id(bytes memory _message) internal pure returns (bytes32) { return keccak256(_message); } /** * @notice Returns the message version. * @param _message ABI encoded Hyperlane message. * @return Version of `_message` */ function version(bytes calldata _message) internal pure returns (uint8) { return uint8(bytes1(_message[VERSION_OFFSET:NONCE_OFFSET])); } /** * @notice Returns the message nonce. * @param _message ABI encoded Hyperlane message. * @return Nonce of `_message` */ function nonce(bytes calldata _message) internal pure returns (uint32) { return uint32(bytes4(_message[NONCE_OFFSET:ORIGIN_OFFSET])); } /** * @notice Returns the message origin domain. * @param _message ABI encoded Hyperlane message. * @return Origin domain of `_message` */ function origin(bytes calldata _message) internal pure returns (uint32) { return uint32(bytes4(_message[ORIGIN_OFFSET:SENDER_OFFSET])); } /** * @notice Returns the message sender as bytes32. * @param _message ABI encoded Hyperlane message. * @return Sender of `_message` as bytes32 */ function sender(bytes calldata _message) internal pure returns (bytes32) { return bytes32(_message[SENDER_OFFSET:DESTINATION_OFFSET]); } /** * @notice Returns the message sender as address. * @param _message ABI encoded Hyperlane message. * @return Sender of `_message` as address */ function senderAddress( bytes calldata _message ) internal pure returns (address) { return sender(_message).bytes32ToAddress(); } /** * @notice Returns the message destination domain. * @param _message ABI encoded Hyperlane message. * @return Destination domain of `_message` */ function destination( bytes calldata _message ) internal pure returns (uint32) { return uint32(bytes4(_message[DESTINATION_OFFSET:RECIPIENT_OFFSET])); } /** * @notice Returns the message recipient as bytes32. * @param _message ABI encoded Hyperlane message. * @return Recipient of `_message` as bytes32 */ function recipient( bytes calldata _message ) internal pure returns (bytes32) { return bytes32(_message[RECIPIENT_OFFSET:BODY_OFFSET]); } /** * @notice Returns the message recipient as address. * @param _message ABI encoded Hyperlane message. * @return Recipient of `_message` as address */ function recipientAddress( bytes calldata _message ) internal pure returns (address) { return recipient(_message).bytes32ToAddress(); } /** * @notice Returns the message body. * @param _message ABI encoded Hyperlane message. * @return Body of `_message` */ function body( bytes calldata _message ) internal pure returns (bytes calldata) { return bytes(_message[BODY_OFFSET:]); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; library TypeCasts { // alignment preserving cast function addressToBytes32(address _addr) internal pure returns (bytes32) { return bytes32(uint256(uint160(_addr))); } // alignment preserving cast function bytes32ToAddress(bytes32 _buf) internal pure returns (address) { require( uint256(_buf) <= uint256(type(uint160).max), "TypeCasts: bytes32ToAddress overflow" ); return address(uint160(uint256(_buf))); } }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; /** * @title PackageVersioned * @notice Package version getter for contracts **/ abstract contract PackageVersioned { // GENERATED CODE - DO NOT EDIT string public constant PACKAGE_VERSION = "5.9.1"; }
// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; library TokenMessage { function format( bytes32 _recipient, uint256 _amount, bytes memory _metadata ) internal pure returns (bytes memory) { return abi.encodePacked(_recipient, _amount, _metadata); } function recipient(bytes calldata message) internal pure returns (bytes32) { return bytes32(message[0:32]); } function amount(bytes calldata message) internal pure returns (uint256) { return uint256(bytes32(message[32:64])); } // alias for ERC721 function tokenId(bytes calldata message) internal pure returns (uint256) { return amount(message); } function metadata( bytes calldata message ) internal pure returns (bytes calldata) { return message[64:]; } }
// SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0; import {IPostDispatchHook} from "../../interfaces/hooks/IPostDispatchHook.sol"; import {GasRouter} from "../../client/GasRouter.sol"; import {MailboxClient} from "../../client/MailboxClient.sol"; import {TypeCasts} from "../../libs/TypeCasts.sol"; import {TokenMessage} from "./TokenMessage.sol"; /** * @title Hyperlane Token Router that extends Router with abstract token (ERC20/ERC721) remote transfer functionality. * @author Abacus Works */ abstract contract TokenRouter is GasRouter { using TypeCasts for bytes32; using TypeCasts for address; using TokenMessage for bytes; /** * @dev Emitted on `transferRemote` when a transfer message is dispatched. * @param destination The identifier of the destination chain. * @param recipient The address of the recipient on the destination chain. * @param amount The amount of tokens burnt on the origin chain. */ event SentTransferRemote( uint32 indexed destination, bytes32 indexed recipient, uint256 amount ); /** * @dev Emitted on `_handle` when a transfer message is processed. * @param origin The identifier of the origin chain. * @param recipient The address of the recipient on the destination chain. * @param amount The amount of tokens minted on the destination chain. */ event ReceivedTransferRemote( uint32 indexed origin, bytes32 indexed recipient, uint256 amount ); constructor(address _mailbox) GasRouter(_mailbox) {} /** * @notice Transfers `_amountOrId` token to `_recipient` on `_destination` domain. * @dev Delegates transfer logic to `_transferFromSender` implementation. * @dev Emits `SentTransferRemote` event on the origin chain. * @param _destination The identifier of the destination chain. * @param _recipient The address of the recipient on the destination chain. * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient. * @return messageId The identifier of the dispatched message. */ function transferRemote( uint32 _destination, bytes32 _recipient, uint256 _amountOrId ) external payable virtual returns (bytes32 messageId) { return _transferRemote(_destination, _recipient, _amountOrId, msg.value); } /** * @notice Transfers `_amountOrId` token to `_recipient` on `_destination` domain with a specified hook * @dev Delegates transfer logic to `_transferFromSender` implementation. * @dev The metadata is the token metadata, and is DIFFERENT than the hook metadata. * @dev Emits `SentTransferRemote` event on the origin chain. * @param _destination The identifier of the destination chain. * @param _recipient The address of the recipient on the destination chain. * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient. * @param _hookMetadata The metadata passed into the hook * @param _hook The post dispatch hook to be called by the Mailbox * @return messageId The identifier of the dispatched message. */ function transferRemote( uint32 _destination, bytes32 _recipient, uint256 _amountOrId, bytes calldata _hookMetadata, address _hook ) external payable virtual returns (bytes32 messageId) { return _transferRemote( _destination, _recipient, _amountOrId, msg.value, _hookMetadata, _hook ); } function _transferRemote( uint32 _destination, bytes32 _recipient, uint256 _amountOrId, uint256 _value ) internal returns (bytes32 messageId) { return _transferRemote( _destination, _recipient, _amountOrId, _value, _GasRouter_hookMetadata(_destination), address(hook) ); } function _transferRemote( uint32 _destination, bytes32 _recipient, uint256 _amountOrId, uint256 _value, bytes memory _hookMetadata, address _hook ) internal virtual returns (bytes32 messageId) { bytes memory _tokenMetadata = _transferFromSender(_amountOrId); bytes memory _tokenMessage = TokenMessage.format( _recipient, _amountOrId, _tokenMetadata ); messageId = _Router_dispatch( _destination, _value, _tokenMessage, _hookMetadata, _hook ); emit SentTransferRemote(_destination, _recipient, _amountOrId); } /** * @dev Should transfer `_amountOrId` of tokens from `msg.sender` to this token router. * @dev Called by `transferRemote` before message dispatch. * @dev Optionally returns `metadata` associated with the transfer to be passed in message. */ function _transferFromSender( uint256 _amountOrId ) internal virtual returns (bytes memory metadata); /** * @notice Returns the balance of `account` on this token router. * @param account The address to query the balance of. * @return The balance of `account`. */ function balanceOf(address account) external virtual returns (uint256); /** * @dev Mints tokens to recipient when router receives transfer message. * @dev Emits `ReceivedTransferRemote` event on the destination chain. * @param _origin The identifier of the origin chain. * @param _message The encoded remote transfer message containing the recipient address and amount. */ function _handle( uint32 _origin, bytes32, bytes calldata _message ) internal virtual override { bytes32 recipient = _message.recipient(); uint256 amount = _message.amount(); bytes calldata metadata = _message.metadata(); _transferTo(recipient.bytes32ToAddress(), amount, metadata); emit ReceivedTransferRemote(_origin, recipient, amount); } /** * @dev Should transfer `_amountOrId` of tokens from this token router to `_recipient`. * @dev Called by `handle` after message decoding. * @dev Optionally handles `metadata` associated with transfer passed in message. */ function _transferTo( address _recipient, uint256 _amountOrId, bytes calldata metadata ) internal virtual; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/transparent/TransparentUpgradeableProxy.sol) pragma solidity ^0.8.0; import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _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); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (governance/utils/IVotes.sol) pragma solidity ^0.8.0; /** * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts. * * _Available since v4.5._ */ interface IVotesUpgradeable { /** * @dev Emitted when an account changes their delegate. */ event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /** * @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of votes. */ event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); /** * @dev Returns the current amount of votes that `account` has. */ function getVotes(address account) external view returns (uint256); /** * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. */ function getPastVotes(address account, uint256 timepoint) external view returns (uint256); /** * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is * configured to use block numbers, this will return the value at the end of the corresponding block. * * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. * Votes that have not been delegated are still part of total supply, even though they would not participate in a * vote. */ function getPastTotalSupply(uint256 timepoint) external view returns (uint256); /** * @dev Returns the delegate that `account` has chosen. */ function delegates(address account) external view returns (address); /** * @dev Delegates votes from the sender to `delegatee`. */ function delegate(address delegatee) external; /** * @dev Delegates votes from signer to `delegatee`. */ function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.0; interface IERC5267Upgradeable { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5805.sol) pragma solidity ^0.8.0; import "../governance/utils/IVotesUpgradeable.sol"; import "./IERC6372Upgradeable.sol"; interface IERC5805Upgradeable is IERC6372Upgradeable, IVotesUpgradeable {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC6372.sol) pragma solidity ^0.8.0; interface IERC6372Upgradeable { /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() external view returns (uint48); /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @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 proxied contracts do not make use of 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. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * 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 prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20Upgradeable.sol"; import "./extensions/IERC20MetadataUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import {Initializable} from "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer(address from, address to, uint256 amount) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _balances[to] += amount; } emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _balances[account] += amount; } emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; // Overflow not possible: amount <= accountBalance <= totalSupply. _totalSupply -= amount; } emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[45] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/ERC20Permit.sol) pragma solidity ^0.8.0; import "./IERC20PermitUpgradeable.sol"; import "../ERC20Upgradeable.sol"; import "../../../utils/cryptography/ECDSAUpgradeable.sol"; import "../../../utils/cryptography/EIP712Upgradeable.sol"; import "../../../utils/CountersUpgradeable.sol"; import {Initializable} from "../../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * _Available since v3.4._ * * @custom:storage-size 51 */ abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable { using CountersUpgradeable for CountersUpgradeable.Counter; mapping(address => CountersUpgradeable.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private constant _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev In previous versions `_PERMIT_TYPEHASH` was declared as `immutable`. * However, to ensure consistency with the upgradeable transpiler, we will continue * to reserve a slot. * @custom:oz-renamed-from _PERMIT_TYPEHASH */ // solhint-disable-next-line var-name-mixedcase bytes32 private _PERMIT_TYPEHASH_DEPRECATED_SLOT; /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ function __ERC20Permit_init(string memory name) internal onlyInitializing { __EIP712_init_unchained(name, "1"); } function __ERC20Permit_init_unchained(string memory) internal onlyInitializing {} /** * @inheritdoc IERC20PermitUpgradeable */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSAUpgradeable.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @inheritdoc IERC20PermitUpgradeable */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @inheritdoc IERC20PermitUpgradeable */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. * * _Available since v4.1._ */ function _useNonce(address owner) internal virtual returns (uint256 current) { CountersUpgradeable.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Votes.sol) pragma solidity ^0.8.0; import "./ERC20PermitUpgradeable.sol"; import "../../../interfaces/IERC5805Upgradeable.sol"; import "../../../utils/math/MathUpgradeable.sol"; import "../../../utils/math/SafeCastUpgradeable.sol"; import "../../../utils/cryptography/ECDSAUpgradeable.sol"; import {Initializable} from "../../../proxy/utils/Initializable.sol"; /** * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's, * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1. * * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module. * * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting * power can be queried through the public accessors {getVotes} and {getPastVotes}. * * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked. * * _Available since v4.2._ */ abstract contract ERC20VotesUpgradeable is Initializable, ERC20PermitUpgradeable, IERC5805Upgradeable { struct Checkpoint { uint32 fromBlock; uint224 votes; } bytes32 private constant _DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); mapping(address => address) private _delegates; mapping(address => Checkpoint[]) private _checkpoints; Checkpoint[] private _totalSupplyCheckpoints; function __ERC20Votes_init() internal onlyInitializing { } function __ERC20Votes_init_unchained() internal onlyInitializing { } /** * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting). */ function clock() public view virtual override returns (uint48) { return SafeCastUpgradeable.toUint48(block.number); } /** * @dev Description of the clock */ // solhint-disable-next-line func-name-mixedcase function CLOCK_MODE() public view virtual override returns (string memory) { // Check that the clock was not modified require(clock() == block.number, "ERC20Votes: broken clock mode"); return "mode=blocknumber&from=default"; } /** * @dev Get the `pos`-th checkpoint for `account`. */ function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) { return _checkpoints[account][pos]; } /** * @dev Get number of checkpoints for `account`. */ function numCheckpoints(address account) public view virtual returns (uint32) { return SafeCastUpgradeable.toUint32(_checkpoints[account].length); } /** * @dev Get the address `account` is currently delegating to. */ function delegates(address account) public view virtual override returns (address) { return _delegates[account]; } /** * @dev Gets the current votes balance for `account` */ function getVotes(address account) public view virtual override returns (uint256) { uint256 pos = _checkpoints[account].length; unchecked { return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes; } } /** * @dev Retrieve the number of votes for `account` at the end of `timepoint`. * * Requirements: * * - `timepoint` must be in the past */ function getPastVotes(address account, uint256 timepoint) public view virtual override returns (uint256) { require(timepoint < clock(), "ERC20Votes: future lookup"); return _checkpointsLookup(_checkpoints[account], timepoint); } /** * @dev Retrieve the `totalSupply` at the end of `timepoint`. Note, this value is the sum of all balances. * It is NOT the sum of all the delegated votes! * * Requirements: * * - `timepoint` must be in the past */ function getPastTotalSupply(uint256 timepoint) public view virtual override returns (uint256) { require(timepoint < clock(), "ERC20Votes: future lookup"); return _checkpointsLookup(_totalSupplyCheckpoints, timepoint); } /** * @dev Lookup a value in a list of (sorted) checkpoints. */ function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 timepoint) private view returns (uint256) { // We run a binary search to look for the last (most recent) checkpoint taken before (or at) `timepoint`. // // Initially we check if the block is recent to narrow the search range. // During the loop, the index of the wanted checkpoint remains in the range [low-1, high). // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant. // - If the middle checkpoint is after `timepoint`, we look in [low, mid) // - If the middle checkpoint is before or equal to `timepoint`, we look in [mid+1, high) // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not // out of bounds (in which case we're looking too far in the past and the result is 0). // Note that if the latest checkpoint available is exactly for `timepoint`, we end up with an index that is // past the end of the array, so we technically don't find a checkpoint after `timepoint`, but it works out // the same. uint256 length = ckpts.length; uint256 low = 0; uint256 high = length; if (length > 5) { uint256 mid = length - MathUpgradeable.sqrt(length); if (_unsafeAccess(ckpts, mid).fromBlock > timepoint) { high = mid; } else { low = mid + 1; } } while (low < high) { uint256 mid = MathUpgradeable.average(low, high); if (_unsafeAccess(ckpts, mid).fromBlock > timepoint) { high = mid; } else { low = mid + 1; } } unchecked { return high == 0 ? 0 : _unsafeAccess(ckpts, high - 1).votes; } } /** * @dev Delegate votes from the sender to `delegatee`. */ function delegate(address delegatee) public virtual override { _delegate(_msgSender(), delegatee); } /** * @dev Delegates votes from signer to `delegatee` */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= expiry, "ERC20Votes: signature expired"); address signer = ECDSAUpgradeable.recover( _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), v, r, s ); require(nonce == _useNonce(signer), "ERC20Votes: invalid nonce"); _delegate(signer, delegatee); } /** * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1). */ function _maxSupply() internal view virtual returns (uint224) { return type(uint224).max; } /** * @dev Snapshots the totalSupply after it has been increased. */ function _mint(address account, uint256 amount) internal virtual override { super._mint(account, amount); require(totalSupply() <= _maxSupply(), "ERC20Votes: total supply risks overflowing votes"); _writeCheckpoint(_totalSupplyCheckpoints, _add, amount); } /** * @dev Snapshots the totalSupply after it has been decreased. */ function _burn(address account, uint256 amount) internal virtual override { super._burn(account, amount); _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount); } /** * @dev Move voting power when tokens are transferred. * * Emits a {IVotes-DelegateVotesChanged} event. */ function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual override { super._afterTokenTransfer(from, to, amount); _moveVotingPower(delegates(from), delegates(to), amount); } /** * @dev Change delegation for `delegator` to `delegatee`. * * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}. */ function _delegate(address delegator, address delegatee) internal virtual { address currentDelegate = delegates(delegator); uint256 delegatorBalance = balanceOf(delegator); _delegates[delegator] = delegatee; emit DelegateChanged(delegator, currentDelegate, delegatee); _moveVotingPower(currentDelegate, delegatee, delegatorBalance); } function _moveVotingPower(address src, address dst, uint256 amount) private { if (src != dst && amount > 0) { if (src != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount); emit DelegateVotesChanged(src, oldWeight, newWeight); } if (dst != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount); emit DelegateVotesChanged(dst, oldWeight, newWeight); } } } function _writeCheckpoint( Checkpoint[] storage ckpts, function(uint256, uint256) view returns (uint256) op, uint256 delta ) private returns (uint256 oldWeight, uint256 newWeight) { uint256 pos = ckpts.length; unchecked { Checkpoint memory oldCkpt = pos == 0 ? Checkpoint(0, 0) : _unsafeAccess(ckpts, pos - 1); oldWeight = oldCkpt.votes; newWeight = op(oldWeight, delta); if (pos > 0 && oldCkpt.fromBlock == clock()) { _unsafeAccess(ckpts, pos - 1).votes = SafeCastUpgradeable.toUint224(newWeight); } else { ckpts.push(Checkpoint({fromBlock: SafeCastUpgradeable.toUint32(clock()), votes: SafeCastUpgradeable.toUint224(newWeight)})); } } } function _add(uint256 a, uint256 b) private pure returns (uint256) { return a + b; } function _subtract(uint256 a, uint256 b) private pure returns (uint256) { return a - b; } /** * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds. */ function _unsafeAccess(Checkpoint[] storage ckpts, uint256 pos) private pure returns (Checkpoint storage result) { assembly { mstore(0, ckpts.slot) result.slot := add(keccak256(0, 0x20), pos) } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[47] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "../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 onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library CountersUpgradeable { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; import "../StringsUpgradeable.sol"; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSAUpgradeable { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV // Deprecated in v4.8 } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 message) { // 32 is the length in bytes of hash, // enforced by the type signature above /// @solidity memory-safe-assembly assembly { mstore(0x00, "\x19Ethereum Signed Message:\n32") mstore(0x1c, hash) message := keccak256(0x00, 0x3c) } } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) data := keccak256(ptr, 0x42) } } /** * @dev Returns an Ethereum Signed Data with intended validator, created from a * `validator` and `data` according to the version 0 of EIP-191. * * See {recover}. */ function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x00", validator, data)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol) pragma solidity ^0.8.8; import "./ECDSAUpgradeable.sol"; import "../../interfaces/IERC5267Upgradeable.sol"; import {Initializable} from "../../proxy/utils/Initializable.sol"; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain * separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. * * _Available since v3.4._ * * @custom:storage-size 52 */ abstract contract EIP712Upgradeable is Initializable, IERC5267Upgradeable { bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); /// @custom:oz-renamed-from _HASHED_NAME bytes32 private _hashedName; /// @custom:oz-renamed-from _HASHED_VERSION bytes32 private _hashedVersion; string private _name; string private _version; /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ function __EIP712_init(string memory name, string memory version) internal onlyInitializing { __EIP712_init_unchained(name, version); } function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing { _name = name; _version = version; // Reset prior values in storage if upgrading _hashedName = 0; _hashedVersion = 0; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { return _buildDomainSeparator(); } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev See {EIP-5267}. * * _Available since v4.9._ */ function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized // and the EIP712 domain is not reliable, as it will be missing name and version. require(_hashedName == 0 && _hashedVersion == 0, "EIP712: Uninitialized"); return ( hex"0f", // 01111 _EIP712Name(), _EIP712Version(), block.chainid, address(this), bytes32(0), new uint256[](0) ); } /** * @dev The name parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712Name() internal virtual view returns (string memory) { return _name; } /** * @dev The version parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712Version() internal virtual view returns (string memory) { return _version; } /** * @dev The hash of the name parameter for the EIP712 domain. * * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead. */ function _EIP712NameHash() internal view returns (bytes32) { string memory name = _EIP712Name(); if (bytes(name).length > 0) { return keccak256(bytes(name)); } else { // If the name is empty, the contract may have been upgraded without initializing the new storage. // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design. bytes32 hashedName = _hashedName; if (hashedName != 0) { return hashedName; } else { return keccak256(""); } } } /** * @dev The hash of the version parameter for the EIP712 domain. * * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead. */ function _EIP712VersionHash() internal view returns (bytes32) { string memory version = _EIP712Version(); if (bytes(version).length > 0) { return keccak256(bytes(version)); } else { // If the version is empty, the contract may have been upgraded without initializing the new storage. // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design. bytes32 hashedVersion = _hashedVersion; if (hashedVersion != 0) { return hashedVersion; } else { return keccak256(""); } } } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[48] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCastUpgradeable { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMathUpgradeable { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/MathUpgradeable.sol"; import "./math/SignedMathUpgradeable.sol"; /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = MathUpgradeable.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, MathUpgradeable.log256(value) + 1); } } /** * @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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822Proxiable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol) pragma solidity ^0.8.0; /** * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC. * * _Available since v4.8.3._ */ interface IERC1967 { /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Emitted when the beacon is changed. */ event BeaconUpgraded(address indexed beacon); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeacon { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol) pragma solidity ^0.8.0; import "../Proxy.sol"; import "./ERC1967Upgrade.sol"; /** * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an * implementation address that can be changed. This address is stored in storage in the location specified by * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the * implementation behind the proxy. */ contract ERC1967Proxy is Proxy, ERC1967Upgrade { /** * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. * * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded * function call, and allows initializing the storage of the proxy like a Solidity constructor. */ constructor(address _logic, bytes memory _data) payable { _upgradeToAndCall(_logic, _data, false); } /** * @dev Returns the current implementation address. */ function _implementation() internal view virtual override returns (address impl) { return ERC1967Upgrade._getImplementation(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeacon.sol"; import "../../interfaces/IERC1967.sol"; import "../../interfaces/draft-IERC1822.sol"; import "../../utils/Address.sol"; import "../../utils/StorageSlot.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ */ abstract contract ERC1967Upgrade is IERC1967 { // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { Address.functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlot.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( Address.isContract(IBeacon(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overridden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/transparent/TransparentUpgradeableProxy.sol) pragma solidity ^0.8.0; import "../ERC1967/ERC1967Proxy.sol"; /** * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy} * does not implement this interface directly, and some of its functions are implemented by an internal dispatch * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not * include them in the ABI so this interface must be used to interact with it. */ interface ITransparentUpgradeableProxy is IERC1967 { function admin() external view returns (address); function implementation() external view returns (address); function changeAdmin(address) external; function upgradeTo(address) external; function upgradeToAndCall(address, bytes memory) external payable; } /** * @dev This contract implements a proxy that is upgradeable by an admin. * * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector * clashing], which can potentially be used in an attack, this contract uses the * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two * things that go hand in hand: * * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if * that call matches one of the admin functions exposed by the proxy itself. * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the * implementation. If the admin tries to call a function on the implementation it will fail with an error that says * "admin cannot fallback to proxy target". * * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due * to sudden errors when trying to call a function from the proxy implementation. * * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, * you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy. * * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not * inherit from that interface, and instead the admin functions are implicitly implemented using a custom dispatch * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the * implementation. * * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the compiler * will not check that there are no selector conflicts, due to the note above. A selector clash between any new function * and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This could * render the admin operations inaccessible, which could prevent upgradeability. Transparency may also be compromised. */ contract TransparentUpgradeableProxy is ERC1967Proxy { /** * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. */ constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) { _changeAdmin(admin_); } /** * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. * * CAUTION: This modifier is deprecated, as it could cause issues if the modified function has arguments, and the * implementation provides a function with the same selector. */ modifier ifAdmin() { if (msg.sender == _getAdmin()) { _; } else { _fallback(); } } /** * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior */ function _fallback() internal virtual override { if (msg.sender == _getAdmin()) { bytes memory ret; bytes4 selector = msg.sig; if (selector == ITransparentUpgradeableProxy.upgradeTo.selector) { ret = _dispatchUpgradeTo(); } else if (selector == ITransparentUpgradeableProxy.upgradeToAndCall.selector) { ret = _dispatchUpgradeToAndCall(); } else if (selector == ITransparentUpgradeableProxy.changeAdmin.selector) { ret = _dispatchChangeAdmin(); } else if (selector == ITransparentUpgradeableProxy.admin.selector) { ret = _dispatchAdmin(); } else if (selector == ITransparentUpgradeableProxy.implementation.selector) { ret = _dispatchImplementation(); } else { revert("TransparentUpgradeableProxy: admin cannot fallback to proxy target"); } assembly { return(add(ret, 0x20), mload(ret)) } } else { super._fallback(); } } /** * @dev Returns the current admin. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` */ function _dispatchAdmin() private returns (bytes memory) { _requireZeroValue(); address admin = _getAdmin(); return abi.encode(admin); } /** * @dev Returns the current implementation. * * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` */ function _dispatchImplementation() private returns (bytes memory) { _requireZeroValue(); address implementation = _implementation(); return abi.encode(implementation); } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _dispatchChangeAdmin() private returns (bytes memory) { _requireZeroValue(); address newAdmin = abi.decode(msg.data[4:], (address)); _changeAdmin(newAdmin); return ""; } /** * @dev Upgrade the implementation of the proxy. */ function _dispatchUpgradeTo() private returns (bytes memory) { _requireZeroValue(); address newImplementation = abi.decode(msg.data[4:], (address)); _upgradeToAndCall(newImplementation, bytes(""), false); return ""; } /** * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the * proxied contract. */ function _dispatchUpgradeToAndCall() private returns (bytes memory) { (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes)); _upgradeToAndCall(newImplementation, data, true); return ""; } /** * @dev Returns the current admin. * * CAUTION: This function is deprecated. Use {ERC1967Upgrade-_getAdmin} instead. */ function _admin() internal view virtual returns (address) { return _getAdmin(); } /** * @dev To keep this contract fully transparent, all `ifAdmin` functions must be payable. This helper is here to * emulate some proxy functions being non-payable while still allowing value to pass through. */ function _requireZeroValue() private { require(msg.value == 0); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) // This file was procedurally generated from scripts/generate/templates/StorageSlot.js. pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ```solidity * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._ * _Available since v4.9 for `string`, `bytes`._ */ library StorageSlot { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } struct StringSlot { string value; } struct BytesSlot { bytes value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` with member `value` located at `slot`. */ function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `StringSlot` representation of the string storage pointer `store`. */ function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } /** * @dev Returns an `BytesSlot` with member `value` located at `slot`. */ function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. */ function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := store.slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/EnumerableMap.sol) // This file was procedurally generated from scripts/generate/templates/EnumerableMap.js. pragma solidity ^0.8.0; import "./EnumerableSet.sol"; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ```solidity * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * The following map types are supported: * * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0 * - `address -> uint256` (`AddressToUintMap`) since v4.6.0 * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0 * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0 * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0 * * [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 EnumerableMap, you can either remove all elements one by one or create a fresh instance using an * array of EnumerableMap. * ==== */ library EnumerableMap { using EnumerableSet for EnumerableSet.Bytes32Set; // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct Bytes32ToBytes32Map { // Storage of keys EnumerableSet.Bytes32Set _keys; mapping(bytes32 => bytes32) _values; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) { map._values[key] = value; return map._keys.add(key); } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { delete map._values[key]; return map._keys.remove(key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { return map._keys.contains(key); } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { return map._keys.length(); } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) { bytes32 key = map._keys.at(index); return (key, map._values[key]); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) { bytes32 value = map._values[key]; if (value == bytes32(0)) { return (contains(map, key), bytes32(0)); } else { return (true, value); } } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key"); return value; } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( Bytes32ToBytes32Map storage map, bytes32 key, string memory errorMessage ) internal view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || contains(map, key), errorMessage); return value; } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) { return map._keys.values(); } // UintToUintMap struct UintToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) { return set(map._inner, bytes32(key), bytes32(value)); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToUintMap storage map, uint256 key) internal returns (bool) { return remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) { return contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) { (bytes32 key, bytes32 value) = at(map._inner, index); return (uint256(key), uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) { (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) { return uint256(get(map._inner, bytes32(key))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get(UintToUintMap storage map, uint256 key, string memory errorMessage) internal view returns (uint256) { return uint256(get(map._inner, bytes32(key), errorMessage)); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(UintToUintMap storage map) internal view returns (uint256[] memory) { bytes32[] memory store = keys(map._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintToAddressMap struct UintToAddressMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { return set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( UintToAddressMap storage map, uint256 key, string memory errorMessage ) internal view returns (address) { return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage)))); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) { bytes32[] memory store = keys(map._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // AddressToUintMap struct AddressToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) { return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(AddressToUintMap storage map, address key) internal returns (bool) { return remove(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(AddressToUintMap storage map, address key) internal view returns (bool) { return contains(map._inner, bytes32(uint256(uint160(key)))); } /** * @dev Returns the number of elements in the map. O(1). */ function length(AddressToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { (bytes32 key, bytes32 value) = at(map._inner, index); return (address(uint160(uint256(key))), uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key)))); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(AddressToUintMap storage map, address key) internal view returns (uint256) { return uint256(get(map._inner, bytes32(uint256(uint160(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( AddressToUintMap storage map, address key, string memory errorMessage ) internal view returns (uint256) { return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage)); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(AddressToUintMap storage map) internal view returns (address[] memory) { bytes32[] memory store = keys(map._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // Bytes32ToUintMap struct Bytes32ToUintMap { Bytes32ToBytes32Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) { return set(map._inner, key, bytes32(value)); } /** * @dev Removes a value from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) { return remove(map._inner, key); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) { return contains(map._inner, key); } /** * @dev Returns the number of elements in the map. O(1). */ function length(Bytes32ToUintMap storage map) internal view returns (uint256) { return length(map._inner); } /** * @dev Returns the element stored at position `index` in the map. 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(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) { (bytes32 key, bytes32 value) = at(map._inner, index); return (key, uint256(value)); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) { (bool success, bytes32 value) = tryGet(map._inner, key); return (success, uint256(value)); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) { return uint256(get(map._inner, key)); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( Bytes32ToUintMap storage map, bytes32 key, string memory errorMessage ) internal view returns (uint256) { return uint256(get(map._inner, key, errorMessage)); } /** * @dev Return the an array containing all the keys * * 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 map grows to a point where copying to memory consumes too much gas to fit in a block. */ function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) { bytes32[] memory store = keys(map._inner); bytes32[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// 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; } }
{ "optimizer": { "enabled": true, "runs": 800 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_mailbox","type":"address"},{"internalType":"uint32","name":"_blockedChain","type":"uint32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"TransferToBlockedChainNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegator","type":"address"},{"indexed":true,"internalType":"address","name":"fromDelegate","type":"address"},{"indexed":true,"internalType":"address","name":"toDelegate","type":"address"}],"name":"DelegateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"delegate","type":"address"},{"indexed":false,"internalType":"uint256","name":"previousBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBalance","type":"uint256"}],"name":"DelegateVotesChanged","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"domain","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"gas","type":"uint256"}],"name":"GasSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_hook","type":"address"}],"name":"HookSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_ism","type":"address"}],"name":"IsmSet","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":true,"internalType":"uint32","name":"origin","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"recipient","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReceivedTransferRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"destination","type":"uint32"},{"indexed":true,"internalType":"bytes32","name":"recipient","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SentTransferRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"CLOCK_MODE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PACKAGE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockedChain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint32","name":"pos","type":"uint32"}],"name":"checkpoints","outputs":[{"components":[{"internalType":"uint32","name":"fromBlock","type":"uint32"},{"internalType":"uint224","name":"votes","type":"uint224"}],"internalType":"struct ERC20VotesUpgradeable.Checkpoint","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"clock","outputs":[{"internalType":"uint48","name":"","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"delegateBySig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"delegates","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"destinationGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"domains","outputs":[{"internalType":"uint32[]","name":"","type":"uint32[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"},{"internalType":"bytes32","name":"_router","type":"bytes32"}],"name":"enrollRemoteRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_domains","type":"uint32[]"},{"internalType":"bytes32[]","name":"_addresses","type":"bytes32[]"}],"name":"enrollRemoteRouters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getPastTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timepoint","type":"uint256"}],"name":"getPastVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_origin","type":"uint32"},{"internalType":"bytes32","name":"_sender","type":"bytes32"},{"internalType":"bytes","name":"_message","type":"bytes"}],"name":"handle","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"hook","outputs":[{"internalType":"contract IPostDispatchHook","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_hook","type":"address"},{"internalType":"address","name":"_interchainSecurityModule","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"interchainSecurityModule","outputs":[{"internalType":"contract IInterchainSecurityModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"localDomain","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mailbox","outputs":[{"internalType":"contract IMailbox","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destinationDomain","type":"uint32"}],"name":"quoteGasPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"}],"name":"routers","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"domain","type":"uint32"},{"internalType":"uint256","name":"gas","type":"uint256"}],"name":"setDestinationGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"domain","type":"uint32"},{"internalType":"uint256","name":"gas","type":"uint256"}],"internalType":"struct GasRouter.GasRouterConfig[]","name":"gasConfigs","type":"tuple[]"}],"name":"setDestinationGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_hook","type":"address"}],"name":"setHook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_module","type":"address"}],"name":"setInterchainSecurityModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destination","type":"uint32"},{"internalType":"bytes32","name":"_recipient","type":"bytes32"},{"internalType":"uint256","name":"_amountOrId","type":"uint256"},{"internalType":"bytes","name":"_hookMetadata","type":"bytes"},{"internalType":"address","name":"_hook","type":"address"}],"name":"transferRemote","outputs":[{"internalType":"bytes32","name":"messageId","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_destination","type":"uint32"},{"internalType":"bytes32","name":"_recipient","type":"bytes32"},{"internalType":"uint256","name":"_amountOrId","type":"uint256"}],"name":"transferRemote","outputs":[{"internalType":"bytes32","name":"messageId","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_domain","type":"uint32"}],"name":"unenrollRemoteRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_domains","type":"uint32[]"}],"name":"unenrollRemoteRouters","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e060405234801561001057600080fd5b5060405161491038038061491083398101604081905261002f91610254565b81808080806001600160a01b0381163b6100905760405162461bcd60e51b815260206004820152601e60248201527f4d61696c626f78436c69656e743a20696e76616c6964206d61696c626f78000060448201526064015b60405180910390fd5b6001600160a01b03821660808190526040805163234d8e3d60e21b81529051638d3638f4916004808201926020929091908290030181865afa1580156100da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fe9190610295565b63ffffffff1660a0526101103361012e565b5050505063ffffffff821660c05250610127610180565b50506102b7565b60fe80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600054610100900460ff16156101e85760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608401610087565b60005460ff90811614610239576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b805163ffffffff8116811461024f57600080fd5b919050565b6000806040838503121561026757600080fd5b82516001600160a01b038116811461027e57600080fd5b915061028c6020840161023b565b90509250929050565b6000602082840312156102a757600080fd5b6102b08261023b565b9392505050565b60805160a05160c05161460e610302600039600081816108560152611ffe015260006106fa01526000818161090a01528181610f210152818161301e01526134d8015261460e6000f3fe6080604052600436106103345760003560e01c80637f5a7c7b116101b0578063b1bd6436116100ec578063dd62ed3e11610095578063efae508a1161006f578063efae508a146109d3578063f1127ed8146109f3578063f2ed8c5314610a3d578063f2fde38b14610a5d57600080fd5b8063dd62ed3e1461094c578063de523cf314610992578063e9198bf9146109b357600080fd5b8063d505accf116100c6578063d505accf146108d8578063d5438eae146108f8578063db0ed6a01461092c57600080fd5b8063b1bd643614610878578063b49c53a714610898578063c3cda520146108b857600080fd5b806391ddadf4116101595780639ab24eb0116101335780639ab24eb0146107e4578063a457c2d714610804578063a9059cbb14610824578063ab5d420b1461084457600080fd5b806391ddadf41461075a57806393c448471461078657806395d89b41146107cf57600080fd5b80638d3638f41161018a5780638d3638f4146106e85780638da5cb5b1461071c5780638e539e8c1461073a57600080fd5b80637f5a7c7b1461068c57806381b4e8b4146106ad57806384b0196e146106c057600080fd5b8063440df4f41161027f5780635c19a95c11610228578063715018a611610202578063715018a61461060957806371a15b381461061e578063775313a11461063e5780637ecebe001461066c57600080fd5b80635c19a95c146105945780636fcfff45146105b457806370a08231146105e957600080fd5b806351debffc1161025957806351debffc1461051d57806356d5d47514610530578063587cde1e1461054357600080fd5b8063440df4f4146104c657806349d462ef146104e85780634bf5d7e91461050857600080fd5b8063313ce567116102e15780633a46b1a8116102bb5780633a46b1a8146104665780633dfd38731461048657806340c10f19146104a657600080fd5b8063313ce567146104155780633644e51514610431578063395093511461044657600080fd5b806318160ddd1161031257806318160ddd146103b657806323b872dd146103d55780632ead72f6146103f557600080fd5b806306fdde0314610339578063095ea7b3146103645780630e72cc0614610394575b600080fd5b34801561034557600080fd5b5061034e610a7d565b60405161035b9190613b5b565b60405180910390f35b34801561037057600080fd5b5061038461037f366004613b8a565b610b0f565b604051901515815260200161035b565b3480156103a057600080fd5b506103b46103af366004613bb4565b610b29565b005b3480156103c257600080fd5b506035545b60405190815260200161035b565b3480156103e157600080fd5b506103846103f0366004613bcf565b610c09565b34801561040157600080fd5b506103c7610410366004613c20565b610c2d565b34801561042157600080fd5b506040516012815260200161035b565b34801561043d57600080fd5b506103c7610c4d565b34801561045257600080fd5b50610384610461366004613b8a565b610c5c565b34801561047257600080fd5b506103c7610481366004613b8a565b610c9b565b34801561049257600080fd5b506103b46104a1366004613bb4565b610d24565b3480156104b257600080fd5b506103b46104c1366004613b8a565b610df7565b3480156104d257600080fd5b506104db610e0d565b60405161035b9190613c3b565b3480156104f457600080fd5b506103b4610503366004613c84565b610e1a565b34801561051457600080fd5b5061034e610e2c565b6103c761052b366004613ce2565b610ec4565b6103b461053e366004613d59565b610f16565b34801561054f57600080fd5b5061057c61055e366004613bb4565b6001600160a01b03908116600090815260cc60205260409020541690565b6040516001600160a01b03909116815260200161035b565b3480156105a057600080fd5b506103b46105af366004613bb4565b61102d565b3480156105c057600080fd5b506105d46105cf366004613bb4565b61103a565b60405163ffffffff909116815260200161035b565b3480156105f557600080fd5b506103c7610604366004613bb4565b61105c565b34801561061557600080fd5b506103b461107a565b34801561062a57600080fd5b506103b4610639366004613df8565b61108e565b34801561064a57600080fd5b506103c7610659366004613c20565b6101956020526000908152604090205481565b34801561067857600080fd5b506103c7610687366004613bb4565b6110e9565b34801561069857600080fd5b506101305461057c906001600160a01b031681565b6103c76106bb366004613e3a565b611107565b3480156106cc57600080fd5b506106d5611115565b60405161035b9796959493929190613e6d565b3480156106f457600080fd5b506105d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561072857600080fd5b5060fe546001600160a01b031661057c565b34801561074657600080fd5b506103c7610755366004613f05565b6111bb565b34801561076657600080fd5b5061076f611226565b60405165ffffffffffff909116815260200161035b565b34801561079257600080fd5b5061034e6040518060400160405280600581526020017f352e392e3100000000000000000000000000000000000000000000000000000081525081565b3480156107db57600080fd5b5061034e611231565b3480156107f057600080fd5b506103c76107ff366004613bb4565b611240565b34801561081057600080fd5b5061038461081f366004613b8a565b6112c2565b34801561083057600080fd5b5061038461083f366004613b8a565b61136c565b34801561085057600080fd5b506105d47f000000000000000000000000000000000000000000000000000000000000000081565b34801561088457600080fd5b506103b4610893366004613f1e565b61137a565b3480156108a457600080fd5b506103b46108b3366004613c84565b6113f0565b3480156108c457600080fd5b506103b46108d3366004613fa6565b611402565b3480156108e457600080fd5b506103b46108f3366004613ffe565b611538565b34801561090457600080fd5b5061057c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561093857600080fd5b506103b461094736600461410e565b61169c565b34801561095857600080fd5b506103c76109673660046141a9565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b34801561099e57600080fd5b506101315461057c906001600160a01b031681565b3480156109bf57600080fd5b506103b46109ce3660046141dc565b6117f0565b3480156109df57600080fd5b506103b46109ee366004613c20565b6118ad565b3480156109ff57600080fd5b50610a13610a0e366004614241565b6118be565b60408051825163ffffffff1681526020928301516001600160e01b0316928101929092520161035b565b348015610a4957600080fd5b506103c7610a58366004613c20565b611942565b348015610a6957600080fd5b506103b4610a78366004613bb4565b61196d565b606060368054610a8c9061426b565b80601f0160208091040260200160405190810160405280929190818152602001828054610ab89061426b565b8015610b055780601f10610ada57610100808354040283529160200191610b05565b820191906000526020600020905b815481529060010190602001808311610ae857829003601f168201915b5050505050905090565b600033610b1d8185856119fa565b60019150505b92915050565b806001600160a01b0381163b151580610b4957506001600160a01b038116155b610baa5760405162461bcd60e51b815260206004820152602760248201527f4d61696c626f78436c69656e743a20696e76616c696420636f6e74726163742060448201526673657474696e6760c81b60648201526084015b60405180910390fd5b610bb2611b1e565b61013180546001600160a01b0319166001600160a01b0384169081179091556040519081527fc47cbcc588c67679e52261c45cc315e56562f8d0ccaba16facb9093ff9498799906020015b60405180910390a15050565b600033610c17858285611b78565b610c22858585611c04565b506001949350505050565b600080610c4561016263ffffffff80861690611de416565b949350505050565b6000610c57611dfd565b905090565b3360008181526034602090815260408083206001600160a01b0387168452909152812054909190610b1d9082908690610c969087906142b5565b6119fa565b6000610ca5611226565b65ffffffffffff168210610cfb5760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20667574757265206c6f6f6b7570000000000000006044820152606401610ba1565b6001600160a01b038316600090815260cd60205260409020610d1d9083611e07565b9392505050565b806001600160a01b0381163b151580610d4457506001600160a01b038116155b610da05760405162461bcd60e51b815260206004820152602760248201527f4d61696c626f78436c69656e743a20696e76616c696420636f6e74726163742060448201526673657474696e6760c81b6064820152608401610ba1565b610da8611b1e565b61013080546001600160a01b0319166001600160a01b0384169081179091556040519081527f4eab7b127c764308788622363ad3e9532de3dfba7845bd4f84c125a22544255a90602001610bfd565b610dff611b1e565b610e098282611ef0565b5050565b6060610c57610162611efa565b610e22611b1e565b610e098282611fab565b606043610e37611226565b65ffffffffffff1614610e8c5760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a2062726f6b656e20636c6f636b206d6f64650000006044820152606401610ba1565b5060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b6000610f0b8787873488888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9250611ffa915050565b979650505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610f985760405162461bcd60e51b815260206004820152602160248201527f4d61696c626f78436c69656e743a2073656e646572206e6f74206d61696c626f6044820152600f60fb1b6064820152608401610ba1565b6000610fa385612056565b905083811461101a5760405162461bcd60e51b815260206004820152602560248201527f456e726f6c6c656420726f7574657220646f6573206e6f74206d61746368207360448201527f656e6465720000000000000000000000000000000000000000000000000000006064820152608401610ba1565b611026858585856120a2565b5050505050565b611037338261212e565b50565b6001600160a01b038116600090815260cd6020526040812054610b23906121bd565b6001600160a01b038116600090815260336020526040812054610b23565b611082611b1e565b61108c600061223d565b565b611096611b1e565b8060005b818110156110e3576110d18484838181106110b7576110b76142c8565b90506020020160208101906110cc9190613c20565b61228f565b6110dc6001826142b5565b905061109a565b50505050565b6001600160a01b038116600090815260996020526040812054610b23565b6000610c45848484346122cb565b6000606080600080600060606065546000801b1480156111355750606654155b6111815760405162461bcd60e51b815260206004820152601560248201527f4549503731323a20556e696e697469616c697a656400000000000000000000006044820152606401610ba1565b6111896122f8565b611191612307565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b60006111c5611226565b65ffffffffffff16821061121b5760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20667574757265206c6f6f6b7570000000000000006044820152606401610ba1565b610b2360ce83611e07565b6000610c5743612316565b606060378054610a8c9061426b565b6001600160a01b038116600090815260cd602052604081205480156112af576001600160a01b038316600090815260cd602052604090208054600019830190811061128d5761128d6142c8565b60009182526020909120015464010000000090046001600160e01b03166112b2565b60005b6001600160e01b03169392505050565b3360008181526034602090815260408083206001600160a01b03871684529091528120549091908381101561135f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610ba1565b610c2282868684036119fa565b600033610b1d818585611c04565b611382611b1e565b60005b818110156113eb576113d98383838181106113a2576113a26142c8565b6113b89260206040909202019081019150613c20565b8484848181106113ca576113ca6142c8565b90506040020160200135611fab565b6113e46001826142b5565b9050611385565b505050565b6113f8611b1e565b610e098282612394565b834211156114525760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e617475726520657870697265640000006044820152606401610ba1565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b0388169181019190915260608101869052608081018590526000906114cc906114c49060a001604051602081830303815290604052805190602001206123ab565b8585856123d8565b90506114d781612400565b86146115255760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e6365000000000000006044820152606401610ba1565b61152f818861212e565b50505050505050565b834211156115885760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610ba1565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886115b78c612400565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000611612826123ab565b90506000611622828787876123d8565b9050896001600160a01b0316816001600160a01b0316146116855760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610ba1565b6116908a8a8a6119fa565b50505050505050505050565b600054610100900460ff16158080156116bc5750600054600160ff909116105b806116d65750303b1580156116d6575060005460ff166001145b6117485760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610ba1565b6000805460ff19166001179055801561176b576000805461ff0019166101001790555b6117758686612428565b61177e8661249d565b61178661252b565b61178e612596565b611799848484612609565b6117a28261223d565b80156117e8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6117f8611b1e565b8281146118475760405162461bcd60e51b815260206004820152600760248201527f216c656e677468000000000000000000000000000000000000000000000000006044820152606401610ba1565b8260005b818110156117e85761189b868683818110611868576118686142c8565b905060200201602081019061187d9190613c20565b85858481811061188f5761188f6142c8565b90506020020135612394565b6118a66001826142b5565b905061184b565b6118b5611b1e565b6110378161228f565b60408051808201909152600080825260208201526001600160a01b038316600090815260cd60205260409020805463ffffffff8416908110611902576119026142c8565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b60408051602081019091526000808252610130549091610b23918491906001600160a01b0316612697565b611975611b1e565b6001600160a01b0381166119f15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610ba1565b6110378161223d565b6001600160a01b038316611a5c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610ba1565b6001600160a01b038216611abd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610ba1565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60fe546001600160a01b0316331461108c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ba1565b6001600160a01b0383811660009081526034602090815260408083209386168352929052205460001981146110e35781811015611bf75760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610ba1565b6110e384848484036119fa565b6001600160a01b038316611c805760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610ba1565b6001600160a01b038216611ce25760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610ba1565b6001600160a01b03831660009081526033602052604090205481811015611d715760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610ba1565b6001600160a01b0380851660008181526033602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611dd19086815260200190565b60405180910390a36110e38484846126ad565b600080611df184846126b8565b915091505b9250929050565b6000610c576126f2565b815460009081816005811115611e61576000611e2284612766565b611e2c90856142de565b600088815260209020909150869082015463ffffffff161115611e5157809150611e5f565b611e5c8160016142b5565b92505b505b80821015611eae576000611e75838361284e565b600088815260209020909150869082015463ffffffff161115611e9a57809150611ea8565b611ea58160016142b5565b92505b50611e61565b8015611eda576000868152602090208101600019015464010000000090046001600160e01b0316611edd565b60005b6001600160e01b03169695505050505050565b610e098282612869565b60606000611f0783612900565b9050805167ffffffffffffffff811115611f2357611f23614069565b604051908082528060200260200182016040528015611f4c578160200160208202803683370190505b50915060005b8151811015611fa457818181518110611f6d57611f6d6142c8565b6020026020010151838281518110611f8757611f876142c8565b63ffffffff90921660209283029190910190910152600101611f52565b5050919050565b63ffffffff821660008181526101956020908152604091829020849055815192835282018390527fc3de732a98b24a2b5c6f67e8a7fb057ffc14046b83968a2c73e4148d2fba978b9101610bfd565b60007f000000000000000000000000000000000000000000000000000000000000000063ffffffff168763ffffffff16036120485760405163be45965960e01b815260040160405180910390fd5b610f0b878787878787612991565b6000808061206f61016263ffffffff80871690611de416565b915091508115612080579392505050565b61208984612a0a565b60405162461bcd60e51b8152600401610ba19190613b5b565b60006120ae8383612a41565b905060006120bc8484612a59565b90503660006120cb8686612a69565b915091506120e36120db85612a79565b848484612ade565b838863ffffffff167fba20947a325f450d232530e5f5fce293e7963499d5309a07cee84a269f2f15a68560405161211c91815260200190565b60405180910390a35050505050505050565b6001600160a01b03828116600090815260cc6020526040812054909116906121558461105c565b6001600160a01b03858116600081815260cc602052604080822080546001600160a01b031916898616908117909155905194955093928616927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46110e3828483612ae8565b600063ffffffff8211156122395760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610ba1565b5090565b60fe80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6122a461016263ffffffff80841690612c2516565b6122ad82612a0a565b90610e095760405162461bcd60e51b8152600401610ba19190613b5b565b60006122ef858585856122dd8a612c31565b610130546001600160a01b0316611ffa565b95945050505050565b606060678054610a8c9061426b565b606060688054610a8c9061426b565b600065ffffffffffff8211156122395760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201527f38206269747300000000000000000000000000000000000000000000000000006064820152608401610ba1565b610e0961016263ffffffff808516908490612c5416565b6000610b236123b8611dfd565b8360405161190160f01b8152600281019290925260228201526042902090565b60008060006123e987878787612c5f565b915091506123f681612d23565b5095945050505050565b6001600160a01b03811660009081526099602052604090208054600181018255905b50919050565b600054610100900460ff166124935760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b610e098282612e6d565b600054610100900460ff166125085760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b61103781604051806040016040528060018152602001603160f81b815250612ef1565b600054610100900460ff1661108c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b600054610100900460ff166126015760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b61108c612f84565b600054610100900460ff166126745760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b61267c612596565b61268583610d24565b61268e82610b29565b6113eb8161223d565b6000610c4584846126a787612c31565b85612ff8565b6113eb8383836130a6565b60008181526002830160205260408120548190806126e7576126da85856130d8565b925060009150611df69050565b600192509050611df6565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61271d6130e4565b61272561313d565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60008160000361277857506000919050565b600060016127858461316e565b901c6001901b9050600181848161279e5761279e6142f1565b048201901c905060018184816127b6576127b66142f1565b048201901c905060018184816127ce576127ce6142f1565b048201901c905060018184816127e6576127e66142f1565b048201901c905060018184816127fe576127fe6142f1565b048201901c90506001818481612816576128166142f1565b048201901c9050600181848161282e5761282e6142f1565b048201901c9050610d1d81828581612848576128486142f1565b04613202565b600061285d6002848418614307565b610d1d908484166142b5565b6128738282613218565b6035546001600160e01b0310156128f25760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201527f766572666c6f77696e6720766f746573000000000000000000000000000000006064820152608401610ba1565b6110e360ce6132e1836132ed565b6060600061290d83613462565b90508067ffffffffffffffff81111561292857612928614069565b604051908082528060200260200182016040528015612951578160200160208202803683370190505b50915060005b81811015611fa457612969848261346d565b60001c83828151811061297e5761297e6142c8565b6020908102919091010152600101612957565b60008061299d86613479565b905060006129ac888884613499565b90506129bb89878388886134c8565b9250878963ffffffff167fd229aacb94204188fe8042965fa6b269c62dc5818b21238779ab64bdd17efeec896040516129f691815260200190565b60405180910390a350509695505050505050565b6060612a1b8263ffffffff1661356e565b604051602001612a2b9190614329565b6040516020818303038152906040529050919050565b6000612a50602082848661436e565b610d1d91614398565b6000612a5060406020848661436e565b366000611df1836040818761436e565b60006001600160a01b038211156122395760405162461bcd60e51b8152602060048201526024808201527f5479706543617374733a2062797465733332546f41646472657373206f766572604482015263666c6f7760e01b6064820152608401610ba1565b6110e38484611ef0565b816001600160a01b0316836001600160a01b031614158015612b0a5750600081115b156113eb576001600160a01b03831615612b98576001600160a01b038316600090815260cd602052604081208190612b459061360e856132ed565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612b8d929190918252602082015260400190565b60405180910390a250505b6001600160a01b038216156113eb576001600160a01b038216600090815260cd602052604081208190612bce906132e1856132ed565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612c16929190918252602082015260400190565b60405180910390a25050505050565b6000610d1d838361361a565b63ffffffff811660009081526101956020526040902054606090610b2390613637565b6110e3838383613655565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612c965750600090506003612d1a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612cea573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612d1357600060019250925050612d1a565b9150600090505b94509492505050565b6000816004811115612d3757612d376143b6565b03612d3f5750565b6001816004811115612d5357612d536143b6565b03612da05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610ba1565b6002816004811115612db457612db46143b6565b03612e015760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610ba1565b6003816004811115612e1557612e156143b6565b036110375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610ba1565b600054610100900460ff16612ed85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b6036612ee48382614413565b5060376113eb8282614413565b600054610100900460ff16612f5c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b6067612f688382614413565b506068612f758282614413565b50506000606581905560665550565b600054610100900460ff16612fef5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b61108c3361223d565b60008061300486612056565b6040516381d2ea9560e01b81529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906381d2ea959061305b90899085908a908a908a906004016144d2565b602060405180830381865afa158015613078573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309c9190614525565b9695505050505050565b6001600160a01b03838116600090815260cc60205260408082205485841683529120546113eb92918216911683612ae8565b6000610d1d8383613672565b6000806130ef6122f8565b805190915015613106578051602090910120919050565b60655480156131155792915050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4709250505090565b600080613148612307565b80519091501561315f578051602090910120919050565b60665480156131155792915050565b600080608083901c1561318357608092831c92015b604083901c1561319557604092831c92015b602083901c156131a757602092831c92015b601083901c156131b957601092831c92015b600883901c156131cb57600892831c92015b600483901c156131dd57600492831c92015b600283901c156131ef57600292831c92015b600183901c15610b235760010192915050565b60008183106132115781610d1d565b5090919050565b6001600160a01b03821661326e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610ba1565b806035600082825461328091906142b5565b90915550506001600160a01b0382166000818152603360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610e09600083836126ad565b6000610d1d82846142b5565b8254600090819081811561333a5760008781526020902082016000190160408051808201909152905463ffffffff8116825264010000000090046001600160e01b0316602082015261334f565b60408051808201909152600080825260208201525b905080602001516001600160e01b0316935061336f84868863ffffffff16565b92506000821180156133995750613384611226565b65ffffffffffff16816000015163ffffffff16145b156133de576133a78361368a565b60008881526020902083016000190180546001600160e01b03929092166401000000000263ffffffff909216919091179055613458565b8660405180604001604052806134026133f5611226565b65ffffffffffff166121bd565b63ffffffff1681526020016134168661368a565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b5050935093915050565b6000610b2382613709565b6000610d1d8383613713565b6060613485338361373d565b505060408051602081019091526000815290565b60608383836040516020016134b09392919061453e565b60405160208183030381529060405290509392505050565b6000806134d487612056565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166310b83dc08789848989896040518763ffffffff1660e01b815260040161352b9594939291906144d2565b60206040518083038185885af1158015613549573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610f0b9190614525565b6060600061357b83613747565b600101905060008167ffffffffffffffff81111561359b5761359b614069565b6040519080825280601f01601f1916602001820160405280156135c5576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85049450846135cf57509392505050565b6000610d1d82846142de565b60008181526002830160205260408120819055610d1d8383613829565b6060610b236000833360405180602001604052806000815250613835565b60008281526002840160205260408120829055610c45848461386a565b60008181526001830160205260408120541515610d1d565b60006001600160e01b038211156122395760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f32342062697473000000000000000000000000000000000000000000000000006064820152608401610ba1565b6000610b23825490565b600082600001828154811061372a5761372a6142c8565b9060005260206000200154905092915050565b610e098282613876565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613790577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef810000000083106137bc576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106137da57662386f26fc10000830492506010015b6305f5e10083106137f2576305f5e100830492506008015b612710831061380657612710830492506004015b60648310613818576064830492506002015b600a8310610b235760010192915050565b6000610d1d838361388e565b606060018585858560405160200161385195949392919061456b565b6040516020818303038152906040529050949350505050565b6000610d1d8383613981565b61388082826139d0565b6110e360ce61360e836132ed565b600081815260018301602052604081205480156139775760006138b26001836142de565b85549091506000906138c6906001906142de565b905081811461392b5760008660000182815481106138e6576138e66142c8565b9060005260206000200154905080876000018481548110613909576139096142c8565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061393c5761393c6145c2565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610b23565b6000915050610b23565b60008181526001830160205260408120546139c857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b23565b506000610b23565b6001600160a01b038216613a305760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610ba1565b6001600160a01b03821660009081526033602052604090205481811015613aa45760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610ba1565b6001600160a01b03831660008181526033602090815260408083208686039055603580548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36113eb836000846126ad565b60005b83811015613b26578181015183820152602001613b0e565b50506000910152565b60008151808452613b47816020860160208601613b0b565b601f01601f19169290920160200192915050565b602081526000610d1d6020830184613b2f565b80356001600160a01b0381168114613b8557600080fd5b919050565b60008060408385031215613b9d57600080fd5b613ba683613b6e565b946020939093013593505050565b600060208284031215613bc657600080fd5b610d1d82613b6e565b600080600060608486031215613be457600080fd5b613bed84613b6e565b9250613bfb60208501613b6e565b929592945050506040919091013590565b803563ffffffff81168114613b8557600080fd5b600060208284031215613c3257600080fd5b610d1d82613c0c565b602080825282518282018190526000918401906040840190835b81811015613c7957835163ffffffff16835260209384019390920191600101613c55565b509095945050505050565b60008060408385031215613c9757600080fd5b613ba683613c0c565b60008083601f840112613cb257600080fd5b50813567ffffffffffffffff811115613cca57600080fd5b602083019150836020828501011115611df657600080fd5b60008060008060008060a08789031215613cfb57600080fd5b613d0487613c0c565b95506020870135945060408701359350606087013567ffffffffffffffff811115613d2e57600080fd5b613d3a89828a01613ca0565b9094509250613d4d905060808801613b6e565b90509295509295509295565b60008060008060608587031215613d6f57600080fd5b613d7885613c0c565b935060208501359250604085013567ffffffffffffffff811115613d9b57600080fd5b613da787828801613ca0565b95989497509550505050565b60008083601f840112613dc557600080fd5b50813567ffffffffffffffff811115613ddd57600080fd5b6020830191508360208260051b8501011115611df657600080fd5b60008060208385031215613e0b57600080fd5b823567ffffffffffffffff811115613e2257600080fd5b613e2e85828601613db3565b90969095509350505050565b600080600060608486031215613e4f57600080fd5b613e5884613c0c565b95602085013595506040909401359392505050565b60ff60f81b8816815260e060208201526000613e8c60e0830189613b2f565b8281036040840152613e9e8189613b2f565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501528451808252602080870193509091019060005b81811015613ef4578351835260209384019390920191600101613ed6565b50909b9a5050505050505050505050565b600060208284031215613f1757600080fd5b5035919050565b60008060208385031215613f3157600080fd5b823567ffffffffffffffff811115613f4857600080fd5b8301601f81018513613f5957600080fd5b803567ffffffffffffffff811115613f7057600080fd5b8560208260061b8401011115613f8557600080fd5b6020919091019590945092505050565b803560ff81168114613b8557600080fd5b60008060008060008060c08789031215613fbf57600080fd5b613fc887613b6e565b95506020870135945060408701359350613fe460608801613f95565b9598949750929560808101359460a0909101359350915050565b600080600080600080600060e0888a03121561401957600080fd5b61402288613b6e565b965061403060208901613b6e565b9550604088013594506060880135935061404c60808901613f95565b9699959850939692959460a0840135945060c09093013592915050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261409057600080fd5b813567ffffffffffffffff8111156140aa576140aa614069565b604051601f8201601f19908116603f0116810167ffffffffffffffff811182821017156140d9576140d9614069565b6040528181528382016020018510156140f157600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561412657600080fd5b853567ffffffffffffffff81111561413d57600080fd5b6141498882890161407f565b955050602086013567ffffffffffffffff81111561416657600080fd5b6141728882890161407f565b94505061418160408701613b6e565b925061418f60608701613b6e565b915061419d60808701613b6e565b90509295509295909350565b600080604083850312156141bc57600080fd5b6141c583613b6e565b91506141d360208401613b6e565b90509250929050565b600080600080604085870312156141f257600080fd5b843567ffffffffffffffff81111561420957600080fd5b61421587828801613db3565b909550935050602085013567ffffffffffffffff81111561423557600080fd5b613da787828801613db3565b6000806040838503121561425457600080fd5b61425d83613b6e565b91506141d360208401613c0c565b600181811c9082168061427f57607f821691505b60208210810361242257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610b2357610b2361429f565b634e487b7160e01b600052603260045260246000fd5b81810381811115610b2357610b2361429f565b634e487b7160e01b600052601260045260246000fd5b60008261432457634e487b7160e01b600052601260045260246000fd5b500490565b7f4e6f20726f7574657220656e726f6c6c656420666f7220646f6d61696e3a200081526000825161436181601f850160208701613b0b565b91909101601f0192915050565b6000808585111561437e57600080fd5b8386111561438b57600080fd5b5050820193919092039150565b80356020831015610b2357600019602084900360031b1b1692915050565b634e487b7160e01b600052602160045260246000fd5b601f8211156113eb57806000526020600020601f840160051c810160208510156143f35750805b601f840160051c820191505b8181101561102657600081556001016143ff565b815167ffffffffffffffff81111561442d5761442d614069565b6144418161443b845461426b565b846143cc565b6020601f821160018114614475576000831561445d5750848201515b600019600385901b1c1916600184901b178455611026565b600084815260208120601f198516915b828110156144a55787850151825560209485019460019092019101614485565b50848210156144c35786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b63ffffffff8616815284602082015260a0604082015260006144f760a0830186613b2f565b82810360608401526145098186613b2f565b9150506001600160a01b03831660808301529695505050505050565b60006020828403121561453757600080fd5b5051919050565b8381528260208201526000825161455c816040850160208701613b0b565b91909101604001949350505050565b61ffff60f01b8660f01b1681528460028201528360228201526bffffffffffffffffffffffff198360601b166042820152600082516145b1816056850160208701613b0b565b919091016056019695505050505050565b634e487b7160e01b600052603160045260246000fdfea264697066735822122059457c6da227c99c5ce23bb2213bfb1ec033f78595b7e08a626010ac94f869e664736f6c634300081c0033000000000000000000000000c005dc82818d67af737725bd4bf75435d065d239000000000000000000000000000000000000000000000000000000000000a4b1
Deployed Bytecode
0x6080604052600436106103345760003560e01c80637f5a7c7b116101b0578063b1bd6436116100ec578063dd62ed3e11610095578063efae508a1161006f578063efae508a146109d3578063f1127ed8146109f3578063f2ed8c5314610a3d578063f2fde38b14610a5d57600080fd5b8063dd62ed3e1461094c578063de523cf314610992578063e9198bf9146109b357600080fd5b8063d505accf116100c6578063d505accf146108d8578063d5438eae146108f8578063db0ed6a01461092c57600080fd5b8063b1bd643614610878578063b49c53a714610898578063c3cda520146108b857600080fd5b806391ddadf4116101595780639ab24eb0116101335780639ab24eb0146107e4578063a457c2d714610804578063a9059cbb14610824578063ab5d420b1461084457600080fd5b806391ddadf41461075a57806393c448471461078657806395d89b41146107cf57600080fd5b80638d3638f41161018a5780638d3638f4146106e85780638da5cb5b1461071c5780638e539e8c1461073a57600080fd5b80637f5a7c7b1461068c57806381b4e8b4146106ad57806384b0196e146106c057600080fd5b8063440df4f41161027f5780635c19a95c11610228578063715018a611610202578063715018a61461060957806371a15b381461061e578063775313a11461063e5780637ecebe001461066c57600080fd5b80635c19a95c146105945780636fcfff45146105b457806370a08231146105e957600080fd5b806351debffc1161025957806351debffc1461051d57806356d5d47514610530578063587cde1e1461054357600080fd5b8063440df4f4146104c657806349d462ef146104e85780634bf5d7e91461050857600080fd5b8063313ce567116102e15780633a46b1a8116102bb5780633a46b1a8146104665780633dfd38731461048657806340c10f19146104a657600080fd5b8063313ce567146104155780633644e51514610431578063395093511461044657600080fd5b806318160ddd1161031257806318160ddd146103b657806323b872dd146103d55780632ead72f6146103f557600080fd5b806306fdde0314610339578063095ea7b3146103645780630e72cc0614610394575b600080fd5b34801561034557600080fd5b5061034e610a7d565b60405161035b9190613b5b565b60405180910390f35b34801561037057600080fd5b5061038461037f366004613b8a565b610b0f565b604051901515815260200161035b565b3480156103a057600080fd5b506103b46103af366004613bb4565b610b29565b005b3480156103c257600080fd5b506035545b60405190815260200161035b565b3480156103e157600080fd5b506103846103f0366004613bcf565b610c09565b34801561040157600080fd5b506103c7610410366004613c20565b610c2d565b34801561042157600080fd5b506040516012815260200161035b565b34801561043d57600080fd5b506103c7610c4d565b34801561045257600080fd5b50610384610461366004613b8a565b610c5c565b34801561047257600080fd5b506103c7610481366004613b8a565b610c9b565b34801561049257600080fd5b506103b46104a1366004613bb4565b610d24565b3480156104b257600080fd5b506103b46104c1366004613b8a565b610df7565b3480156104d257600080fd5b506104db610e0d565b60405161035b9190613c3b565b3480156104f457600080fd5b506103b4610503366004613c84565b610e1a565b34801561051457600080fd5b5061034e610e2c565b6103c761052b366004613ce2565b610ec4565b6103b461053e366004613d59565b610f16565b34801561054f57600080fd5b5061057c61055e366004613bb4565b6001600160a01b03908116600090815260cc60205260409020541690565b6040516001600160a01b03909116815260200161035b565b3480156105a057600080fd5b506103b46105af366004613bb4565b61102d565b3480156105c057600080fd5b506105d46105cf366004613bb4565b61103a565b60405163ffffffff909116815260200161035b565b3480156105f557600080fd5b506103c7610604366004613bb4565b61105c565b34801561061557600080fd5b506103b461107a565b34801561062a57600080fd5b506103b4610639366004613df8565b61108e565b34801561064a57600080fd5b506103c7610659366004613c20565b6101956020526000908152604090205481565b34801561067857600080fd5b506103c7610687366004613bb4565b6110e9565b34801561069857600080fd5b506101305461057c906001600160a01b031681565b6103c76106bb366004613e3a565b611107565b3480156106cc57600080fd5b506106d5611115565b60405161035b9796959493929190613e6d565b3480156106f457600080fd5b506105d47f000000000000000000000000000000000000000000000000000000000000000181565b34801561072857600080fd5b5060fe546001600160a01b031661057c565b34801561074657600080fd5b506103c7610755366004613f05565b6111bb565b34801561076657600080fd5b5061076f611226565b60405165ffffffffffff909116815260200161035b565b34801561079257600080fd5b5061034e6040518060400160405280600581526020017f352e392e3100000000000000000000000000000000000000000000000000000081525081565b3480156107db57600080fd5b5061034e611231565b3480156107f057600080fd5b506103c76107ff366004613bb4565b611240565b34801561081057600080fd5b5061038461081f366004613b8a565b6112c2565b34801561083057600080fd5b5061038461083f366004613b8a565b61136c565b34801561085057600080fd5b506105d47f000000000000000000000000000000000000000000000000000000000000a4b181565b34801561088457600080fd5b506103b4610893366004613f1e565b61137a565b3480156108a457600080fd5b506103b46108b3366004613c84565b6113f0565b3480156108c457600080fd5b506103b46108d3366004613fa6565b611402565b3480156108e457600080fd5b506103b46108f3366004613ffe565b611538565b34801561090457600080fd5b5061057c7f000000000000000000000000c005dc82818d67af737725bd4bf75435d065d23981565b34801561093857600080fd5b506103b461094736600461410e565b61169c565b34801561095857600080fd5b506103c76109673660046141a9565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b34801561099e57600080fd5b506101315461057c906001600160a01b031681565b3480156109bf57600080fd5b506103b46109ce3660046141dc565b6117f0565b3480156109df57600080fd5b506103b46109ee366004613c20565b6118ad565b3480156109ff57600080fd5b50610a13610a0e366004614241565b6118be565b60408051825163ffffffff1681526020928301516001600160e01b0316928101929092520161035b565b348015610a4957600080fd5b506103c7610a58366004613c20565b611942565b348015610a6957600080fd5b506103b4610a78366004613bb4565b61196d565b606060368054610a8c9061426b565b80601f0160208091040260200160405190810160405280929190818152602001828054610ab89061426b565b8015610b055780601f10610ada57610100808354040283529160200191610b05565b820191906000526020600020905b815481529060010190602001808311610ae857829003601f168201915b5050505050905090565b600033610b1d8185856119fa565b60019150505b92915050565b806001600160a01b0381163b151580610b4957506001600160a01b038116155b610baa5760405162461bcd60e51b815260206004820152602760248201527f4d61696c626f78436c69656e743a20696e76616c696420636f6e74726163742060448201526673657474696e6760c81b60648201526084015b60405180910390fd5b610bb2611b1e565b61013180546001600160a01b0319166001600160a01b0384169081179091556040519081527fc47cbcc588c67679e52261c45cc315e56562f8d0ccaba16facb9093ff9498799906020015b60405180910390a15050565b600033610c17858285611b78565b610c22858585611c04565b506001949350505050565b600080610c4561016263ffffffff80861690611de416565b949350505050565b6000610c57611dfd565b905090565b3360008181526034602090815260408083206001600160a01b0387168452909152812054909190610b1d9082908690610c969087906142b5565b6119fa565b6000610ca5611226565b65ffffffffffff168210610cfb5760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20667574757265206c6f6f6b7570000000000000006044820152606401610ba1565b6001600160a01b038316600090815260cd60205260409020610d1d9083611e07565b9392505050565b806001600160a01b0381163b151580610d4457506001600160a01b038116155b610da05760405162461bcd60e51b815260206004820152602760248201527f4d61696c626f78436c69656e743a20696e76616c696420636f6e74726163742060448201526673657474696e6760c81b6064820152608401610ba1565b610da8611b1e565b61013080546001600160a01b0319166001600160a01b0384169081179091556040519081527f4eab7b127c764308788622363ad3e9532de3dfba7845bd4f84c125a22544255a90602001610bfd565b610dff611b1e565b610e098282611ef0565b5050565b6060610c57610162611efa565b610e22611b1e565b610e098282611fab565b606043610e37611226565b65ffffffffffff1614610e8c5760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a2062726f6b656e20636c6f636b206d6f64650000006044820152606401610ba1565b5060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b6000610f0b8787873488888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508a9250611ffa915050565b979650505050505050565b336001600160a01b037f000000000000000000000000c005dc82818d67af737725bd4bf75435d065d2391614610f985760405162461bcd60e51b815260206004820152602160248201527f4d61696c626f78436c69656e743a2073656e646572206e6f74206d61696c626f6044820152600f60fb1b6064820152608401610ba1565b6000610fa385612056565b905083811461101a5760405162461bcd60e51b815260206004820152602560248201527f456e726f6c6c656420726f7574657220646f6573206e6f74206d61746368207360448201527f656e6465720000000000000000000000000000000000000000000000000000006064820152608401610ba1565b611026858585856120a2565b5050505050565b611037338261212e565b50565b6001600160a01b038116600090815260cd6020526040812054610b23906121bd565b6001600160a01b038116600090815260336020526040812054610b23565b611082611b1e565b61108c600061223d565b565b611096611b1e565b8060005b818110156110e3576110d18484838181106110b7576110b76142c8565b90506020020160208101906110cc9190613c20565b61228f565b6110dc6001826142b5565b905061109a565b50505050565b6001600160a01b038116600090815260996020526040812054610b23565b6000610c45848484346122cb565b6000606080600080600060606065546000801b1480156111355750606654155b6111815760405162461bcd60e51b815260206004820152601560248201527f4549503731323a20556e696e697469616c697a656400000000000000000000006044820152606401610ba1565b6111896122f8565b611191612307565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b60006111c5611226565b65ffffffffffff16821061121b5760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20667574757265206c6f6f6b7570000000000000006044820152606401610ba1565b610b2360ce83611e07565b6000610c5743612316565b606060378054610a8c9061426b565b6001600160a01b038116600090815260cd602052604081205480156112af576001600160a01b038316600090815260cd602052604090208054600019830190811061128d5761128d6142c8565b60009182526020909120015464010000000090046001600160e01b03166112b2565b60005b6001600160e01b03169392505050565b3360008181526034602090815260408083206001600160a01b03871684529091528120549091908381101561135f5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610ba1565b610c2282868684036119fa565b600033610b1d818585611c04565b611382611b1e565b60005b818110156113eb576113d98383838181106113a2576113a26142c8565b6113b89260206040909202019081019150613c20565b8484848181106113ca576113ca6142c8565b90506040020160200135611fab565b6113e46001826142b5565b9050611385565b505050565b6113f8611b1e565b610e098282612394565b834211156114525760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e617475726520657870697265640000006044820152606401610ba1565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b0388169181019190915260608101869052608081018590526000906114cc906114c49060a001604051602081830303815290604052805190602001206123ab565b8585856123d8565b90506114d781612400565b86146115255760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e6365000000000000006044820152606401610ba1565b61152f818861212e565b50505050505050565b834211156115885760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610ba1565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886115b78c612400565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000611612826123ab565b90506000611622828787876123d8565b9050896001600160a01b0316816001600160a01b0316146116855760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610ba1565b6116908a8a8a6119fa565b50505050505050505050565b600054610100900460ff16158080156116bc5750600054600160ff909116105b806116d65750303b1580156116d6575060005460ff166001145b6117485760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610ba1565b6000805460ff19166001179055801561176b576000805461ff0019166101001790555b6117758686612428565b61177e8661249d565b61178661252b565b61178e612596565b611799848484612609565b6117a28261223d565b80156117e8576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6117f8611b1e565b8281146118475760405162461bcd60e51b815260206004820152600760248201527f216c656e677468000000000000000000000000000000000000000000000000006044820152606401610ba1565b8260005b818110156117e85761189b868683818110611868576118686142c8565b905060200201602081019061187d9190613c20565b85858481811061188f5761188f6142c8565b90506020020135612394565b6118a66001826142b5565b905061184b565b6118b5611b1e565b6110378161228f565b60408051808201909152600080825260208201526001600160a01b038316600090815260cd60205260409020805463ffffffff8416908110611902576119026142c8565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b60408051602081019091526000808252610130549091610b23918491906001600160a01b0316612697565b611975611b1e565b6001600160a01b0381166119f15760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610ba1565b6110378161223d565b6001600160a01b038316611a5c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610ba1565b6001600160a01b038216611abd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610ba1565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60fe546001600160a01b0316331461108c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610ba1565b6001600160a01b0383811660009081526034602090815260408083209386168352929052205460001981146110e35781811015611bf75760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610ba1565b6110e384848484036119fa565b6001600160a01b038316611c805760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610ba1565b6001600160a01b038216611ce25760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610ba1565b6001600160a01b03831660009081526033602052604090205481811015611d715760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610ba1565b6001600160a01b0380851660008181526033602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90611dd19086815260200190565b60405180910390a36110e38484846126ad565b600080611df184846126b8565b915091505b9250929050565b6000610c576126f2565b815460009081816005811115611e61576000611e2284612766565b611e2c90856142de565b600088815260209020909150869082015463ffffffff161115611e5157809150611e5f565b611e5c8160016142b5565b92505b505b80821015611eae576000611e75838361284e565b600088815260209020909150869082015463ffffffff161115611e9a57809150611ea8565b611ea58160016142b5565b92505b50611e61565b8015611eda576000868152602090208101600019015464010000000090046001600160e01b0316611edd565b60005b6001600160e01b03169695505050505050565b610e098282612869565b60606000611f0783612900565b9050805167ffffffffffffffff811115611f2357611f23614069565b604051908082528060200260200182016040528015611f4c578160200160208202803683370190505b50915060005b8151811015611fa457818181518110611f6d57611f6d6142c8565b6020026020010151838281518110611f8757611f876142c8565b63ffffffff90921660209283029190910190910152600101611f52565b5050919050565b63ffffffff821660008181526101956020908152604091829020849055815192835282018390527fc3de732a98b24a2b5c6f67e8a7fb057ffc14046b83968a2c73e4148d2fba978b9101610bfd565b60007f000000000000000000000000000000000000000000000000000000000000a4b163ffffffff168763ffffffff16036120485760405163be45965960e01b815260040160405180910390fd5b610f0b878787878787612991565b6000808061206f61016263ffffffff80871690611de416565b915091508115612080579392505050565b61208984612a0a565b60405162461bcd60e51b8152600401610ba19190613b5b565b60006120ae8383612a41565b905060006120bc8484612a59565b90503660006120cb8686612a69565b915091506120e36120db85612a79565b848484612ade565b838863ffffffff167fba20947a325f450d232530e5f5fce293e7963499d5309a07cee84a269f2f15a68560405161211c91815260200190565b60405180910390a35050505050505050565b6001600160a01b03828116600090815260cc6020526040812054909116906121558461105c565b6001600160a01b03858116600081815260cc602052604080822080546001600160a01b031916898616908117909155905194955093928616927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46110e3828483612ae8565b600063ffffffff8211156122395760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610ba1565b5090565b60fe80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6122a461016263ffffffff80841690612c2516565b6122ad82612a0a565b90610e095760405162461bcd60e51b8152600401610ba19190613b5b565b60006122ef858585856122dd8a612c31565b610130546001600160a01b0316611ffa565b95945050505050565b606060678054610a8c9061426b565b606060688054610a8c9061426b565b600065ffffffffffff8211156122395760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203460448201527f38206269747300000000000000000000000000000000000000000000000000006064820152608401610ba1565b610e0961016263ffffffff808516908490612c5416565b6000610b236123b8611dfd565b8360405161190160f01b8152600281019290925260228201526042902090565b60008060006123e987878787612c5f565b915091506123f681612d23565b5095945050505050565b6001600160a01b03811660009081526099602052604090208054600181018255905b50919050565b600054610100900460ff166124935760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b610e098282612e6d565b600054610100900460ff166125085760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b61103781604051806040016040528060018152602001603160f81b815250612ef1565b600054610100900460ff1661108c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b600054610100900460ff166126015760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b61108c612f84565b600054610100900460ff166126745760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b61267c612596565b61268583610d24565b61268e82610b29565b6113eb8161223d565b6000610c4584846126a787612c31565b85612ff8565b6113eb8383836130a6565b60008181526002830160205260408120548190806126e7576126da85856130d8565b925060009150611df69050565b600192509050611df6565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61271d6130e4565b61272561313d565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b60008160000361277857506000919050565b600060016127858461316e565b901c6001901b9050600181848161279e5761279e6142f1565b048201901c905060018184816127b6576127b66142f1565b048201901c905060018184816127ce576127ce6142f1565b048201901c905060018184816127e6576127e66142f1565b048201901c905060018184816127fe576127fe6142f1565b048201901c90506001818481612816576128166142f1565b048201901c9050600181848161282e5761282e6142f1565b048201901c9050610d1d81828581612848576128486142f1565b04613202565b600061285d6002848418614307565b610d1d908484166142b5565b6128738282613218565b6035546001600160e01b0310156128f25760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201527f766572666c6f77696e6720766f746573000000000000000000000000000000006064820152608401610ba1565b6110e360ce6132e1836132ed565b6060600061290d83613462565b90508067ffffffffffffffff81111561292857612928614069565b604051908082528060200260200182016040528015612951578160200160208202803683370190505b50915060005b81811015611fa457612969848261346d565b60001c83828151811061297e5761297e6142c8565b6020908102919091010152600101612957565b60008061299d86613479565b905060006129ac888884613499565b90506129bb89878388886134c8565b9250878963ffffffff167fd229aacb94204188fe8042965fa6b269c62dc5818b21238779ab64bdd17efeec896040516129f691815260200190565b60405180910390a350509695505050505050565b6060612a1b8263ffffffff1661356e565b604051602001612a2b9190614329565b6040516020818303038152906040529050919050565b6000612a50602082848661436e565b610d1d91614398565b6000612a5060406020848661436e565b366000611df1836040818761436e565b60006001600160a01b038211156122395760405162461bcd60e51b8152602060048201526024808201527f5479706543617374733a2062797465733332546f41646472657373206f766572604482015263666c6f7760e01b6064820152608401610ba1565b6110e38484611ef0565b816001600160a01b0316836001600160a01b031614158015612b0a5750600081115b156113eb576001600160a01b03831615612b98576001600160a01b038316600090815260cd602052604081208190612b459061360e856132ed565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612b8d929190918252602082015260400190565b60405180910390a250505b6001600160a01b038216156113eb576001600160a01b038216600090815260cd602052604081208190612bce906132e1856132ed565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612c16929190918252602082015260400190565b60405180910390a25050505050565b6000610d1d838361361a565b63ffffffff811660009081526101956020526040902054606090610b2390613637565b6110e3838383613655565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612c965750600090506003612d1a565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612cea573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116612d1357600060019250925050612d1a565b9150600090505b94509492505050565b6000816004811115612d3757612d376143b6565b03612d3f5750565b6001816004811115612d5357612d536143b6565b03612da05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610ba1565b6002816004811115612db457612db46143b6565b03612e015760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610ba1565b6003816004811115612e1557612e156143b6565b036110375760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610ba1565b600054610100900460ff16612ed85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b6036612ee48382614413565b5060376113eb8282614413565b600054610100900460ff16612f5c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b6067612f688382614413565b506068612f758282614413565b50506000606581905560665550565b600054610100900460ff16612fef5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610ba1565b61108c3361223d565b60008061300486612056565b6040516381d2ea9560e01b81529091506001600160a01b037f000000000000000000000000c005dc82818d67af737725bd4bf75435d065d23916906381d2ea959061305b90899085908a908a908a906004016144d2565b602060405180830381865afa158015613078573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061309c9190614525565b9695505050505050565b6001600160a01b03838116600090815260cc60205260408082205485841683529120546113eb92918216911683612ae8565b6000610d1d8383613672565b6000806130ef6122f8565b805190915015613106578051602090910120919050565b60655480156131155792915050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4709250505090565b600080613148612307565b80519091501561315f578051602090910120919050565b60665480156131155792915050565b600080608083901c1561318357608092831c92015b604083901c1561319557604092831c92015b602083901c156131a757602092831c92015b601083901c156131b957601092831c92015b600883901c156131cb57600892831c92015b600483901c156131dd57600492831c92015b600283901c156131ef57600292831c92015b600183901c15610b235760010192915050565b60008183106132115781610d1d565b5090919050565b6001600160a01b03821661326e5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610ba1565b806035600082825461328091906142b5565b90915550506001600160a01b0382166000818152603360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610e09600083836126ad565b6000610d1d82846142b5565b8254600090819081811561333a5760008781526020902082016000190160408051808201909152905463ffffffff8116825264010000000090046001600160e01b0316602082015261334f565b60408051808201909152600080825260208201525b905080602001516001600160e01b0316935061336f84868863ffffffff16565b92506000821180156133995750613384611226565b65ffffffffffff16816000015163ffffffff16145b156133de576133a78361368a565b60008881526020902083016000190180546001600160e01b03929092166401000000000263ffffffff909216919091179055613458565b8660405180604001604052806134026133f5611226565b65ffffffffffff166121bd565b63ffffffff1681526020016134168661368a565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b5050935093915050565b6000610b2382613709565b6000610d1d8383613713565b6060613485338361373d565b505060408051602081019091526000815290565b60608383836040516020016134b09392919061453e565b60405160208183030381529060405290509392505050565b6000806134d487612056565b90507f000000000000000000000000c005dc82818d67af737725bd4bf75435d065d2396001600160a01b03166310b83dc08789848989896040518763ffffffff1660e01b815260040161352b9594939291906144d2565b60206040518083038185885af1158015613549573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190610f0b9190614525565b6060600061357b83613747565b600101905060008167ffffffffffffffff81111561359b5761359b614069565b6040519080825280601f01601f1916602001820160405280156135c5576020820181803683370190505b5090508181016020015b600019017f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85049450846135cf57509392505050565b6000610d1d82846142de565b60008181526002830160205260408120819055610d1d8383613829565b6060610b236000833360405180602001604052806000815250613835565b60008281526002840160205260408120829055610c45848461386a565b60008181526001830160205260408120541515610d1d565b60006001600160e01b038211156122395760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f32342062697473000000000000000000000000000000000000000000000000006064820152608401610ba1565b6000610b23825490565b600082600001828154811061372a5761372a6142c8565b9060005260206000200154905092915050565b610e098282613876565b6000807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613790577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef810000000083106137bc576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc1000083106137da57662386f26fc10000830492506010015b6305f5e10083106137f2576305f5e100830492506008015b612710831061380657612710830492506004015b60648310613818576064830492506002015b600a8310610b235760010192915050565b6000610d1d838361388e565b606060018585858560405160200161385195949392919061456b565b6040516020818303038152906040529050949350505050565b6000610d1d8383613981565b61388082826139d0565b6110e360ce61360e836132ed565b600081815260018301602052604081205480156139775760006138b26001836142de565b85549091506000906138c6906001906142de565b905081811461392b5760008660000182815481106138e6576138e66142c8565b9060005260206000200154905080876000018481548110613909576139096142c8565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061393c5761393c6145c2565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610b23565b6000915050610b23565b60008181526001830160205260408120546139c857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610b23565b506000610b23565b6001600160a01b038216613a305760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610ba1565b6001600160a01b03821660009081526033602052604090205481811015613aa45760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610ba1565b6001600160a01b03831660008181526033602090815260408083208686039055603580548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a36113eb836000846126ad565b60005b83811015613b26578181015183820152602001613b0e565b50506000910152565b60008151808452613b47816020860160208601613b0b565b601f01601f19169290920160200192915050565b602081526000610d1d6020830184613b2f565b80356001600160a01b0381168114613b8557600080fd5b919050565b60008060408385031215613b9d57600080fd5b613ba683613b6e565b946020939093013593505050565b600060208284031215613bc657600080fd5b610d1d82613b6e565b600080600060608486031215613be457600080fd5b613bed84613b6e565b9250613bfb60208501613b6e565b929592945050506040919091013590565b803563ffffffff81168114613b8557600080fd5b600060208284031215613c3257600080fd5b610d1d82613c0c565b602080825282518282018190526000918401906040840190835b81811015613c7957835163ffffffff16835260209384019390920191600101613c55565b509095945050505050565b60008060408385031215613c9757600080fd5b613ba683613c0c565b60008083601f840112613cb257600080fd5b50813567ffffffffffffffff811115613cca57600080fd5b602083019150836020828501011115611df657600080fd5b60008060008060008060a08789031215613cfb57600080fd5b613d0487613c0c565b95506020870135945060408701359350606087013567ffffffffffffffff811115613d2e57600080fd5b613d3a89828a01613ca0565b9094509250613d4d905060808801613b6e565b90509295509295509295565b60008060008060608587031215613d6f57600080fd5b613d7885613c0c565b935060208501359250604085013567ffffffffffffffff811115613d9b57600080fd5b613da787828801613ca0565b95989497509550505050565b60008083601f840112613dc557600080fd5b50813567ffffffffffffffff811115613ddd57600080fd5b6020830191508360208260051b8501011115611df657600080fd5b60008060208385031215613e0b57600080fd5b823567ffffffffffffffff811115613e2257600080fd5b613e2e85828601613db3565b90969095509350505050565b600080600060608486031215613e4f57600080fd5b613e5884613c0c565b95602085013595506040909401359392505050565b60ff60f81b8816815260e060208201526000613e8c60e0830189613b2f565b8281036040840152613e9e8189613b2f565b606084018890526001600160a01b038716608085015260a0840186905283810360c08501528451808252602080870193509091019060005b81811015613ef4578351835260209384019390920191600101613ed6565b50909b9a5050505050505050505050565b600060208284031215613f1757600080fd5b5035919050565b60008060208385031215613f3157600080fd5b823567ffffffffffffffff811115613f4857600080fd5b8301601f81018513613f5957600080fd5b803567ffffffffffffffff811115613f7057600080fd5b8560208260061b8401011115613f8557600080fd5b6020919091019590945092505050565b803560ff81168114613b8557600080fd5b60008060008060008060c08789031215613fbf57600080fd5b613fc887613b6e565b95506020870135945060408701359350613fe460608801613f95565b9598949750929560808101359460a0909101359350915050565b600080600080600080600060e0888a03121561401957600080fd5b61402288613b6e565b965061403060208901613b6e565b9550604088013594506060880135935061404c60808901613f95565b9699959850939692959460a0840135945060c09093013592915050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261409057600080fd5b813567ffffffffffffffff8111156140aa576140aa614069565b604051601f8201601f19908116603f0116810167ffffffffffffffff811182821017156140d9576140d9614069565b6040528181528382016020018510156140f157600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a0868803121561412657600080fd5b853567ffffffffffffffff81111561413d57600080fd5b6141498882890161407f565b955050602086013567ffffffffffffffff81111561416657600080fd5b6141728882890161407f565b94505061418160408701613b6e565b925061418f60608701613b6e565b915061419d60808701613b6e565b90509295509295909350565b600080604083850312156141bc57600080fd5b6141c583613b6e565b91506141d360208401613b6e565b90509250929050565b600080600080604085870312156141f257600080fd5b843567ffffffffffffffff81111561420957600080fd5b61421587828801613db3565b909550935050602085013567ffffffffffffffff81111561423557600080fd5b613da787828801613db3565b6000806040838503121561425457600080fd5b61425d83613b6e565b91506141d360208401613c0c565b600181811c9082168061427f57607f821691505b60208210810361242257634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610b2357610b2361429f565b634e487b7160e01b600052603260045260246000fd5b81810381811115610b2357610b2361429f565b634e487b7160e01b600052601260045260246000fd5b60008261432457634e487b7160e01b600052601260045260246000fd5b500490565b7f4e6f20726f7574657220656e726f6c6c656420666f7220646f6d61696e3a200081526000825161436181601f850160208701613b0b565b91909101601f0192915050565b6000808585111561437e57600080fd5b8386111561438b57600080fd5b5050820193919092039150565b80356020831015610b2357600019602084900360031b1b1692915050565b634e487b7160e01b600052602160045260246000fd5b601f8211156113eb57806000526020600020601f840160051c810160208510156143f35750805b601f840160051c820191505b8181101561102657600081556001016143ff565b815167ffffffffffffffff81111561442d5761442d614069565b6144418161443b845461426b565b846143cc565b6020601f821160018114614475576000831561445d5750848201515b600019600385901b1c1916600184901b178455611026565b600084815260208120601f198516915b828110156144a55787850151825560209485019460019092019101614485565b50848210156144c35786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b63ffffffff8616815284602082015260a0604082015260006144f760a0830186613b2f565b82810360608401526145098186613b2f565b9150506001600160a01b03831660808301529695505050505050565b60006020828403121561453757600080fd5b5051919050565b8381528260208201526000825161455c816040850160208701613b0b565b91909101604001949350505050565b61ffff60f01b8660f01b1681528460028201528360228201526bffffffffffffffffffffffff198360601b166042820152600082516145b1816056850160208701613b0b565b919091016056019695505050505050565b634e487b7160e01b600052603160045260246000fdfea264697066735822122059457c6da227c99c5ce23bb2213bfb1ec033f78595b7e08a626010ac94f869e664736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c005dc82818d67af737725bd4bf75435d065d239000000000000000000000000000000000000000000000000000000000000a4b1
-----Decoded View---------------
Arg [0] : _mailbox (address): 0xc005dc82818d67AF737725bD4bf75435d065D239
Arg [1] : _blockedChain (uint32): 42161
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000c005dc82818d67af737725bd4bf75435d065d239
Arg [1] : 000000000000000000000000000000000000000000000000000000000000a4b1
Deployed Bytecode Sourcemap
1024:2851:50:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2516:98:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4802:197;;;;;;;;;;-1:-1:-1;4802:197:21;;;;;:::i;:::-;;:::i;:::-;;;1441:14:51;;1434:22;1416:41;;1404:2;1389:18;4802:197:21;1276:187:51;2771:221:2;;;;;;;;;;-1:-1:-1;2771:221:2;;;;;:::i;:::-;;:::i;:::-;;3613:106:21;;;;;;;;;;-1:-1:-1;3700:12:21;;3613:106;;;1805:25:51;;;1793:2;1778:18;3613:106:21;1659:177:51;5561:256:21;;;;;;;;;;-1:-1:-1;5561:256:21;;;;;:::i;:::-;;:::i;1454:158:3:-;;;;;;;;;;-1:-1:-1;1454:158:3;;;;;:::i;:::-;;:::i;3462:91:21:-;;;;;;;;;;-1:-1:-1;3462:91:21;;3544:2;2901:36:51;;2889:2;2874:18;3462:91:21;2759:184:51;3287:113:23;;;;;;;;;;;;;:::i;6212:234:21:-;;;;;;;;;;-1:-1:-1;6212:234:21;;;;;:::i;:::-;;:::i;3806:248:24:-;;;;;;;;;;-1:-1:-1;3806:248:24;;;;;:::i;:::-;;:::i;2409:174:2:-;;;;;;;;;;-1:-1:-1;2409:174:2;;;;;:::i;:::-;;:::i;2044:95:50:-;;;;;;;;;;-1:-1:-1;2044:95:50;;;;;:::i;:::-;;:::i;1051:104:3:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;1454:122:1:-;;;;;;;;;;-1:-1:-1;1454:122:1;;;;;:::i;:::-;;:::i;2376:254:24:-;;;;;;;;;;;;;:::i;3230:463:13:-;;;;;;:::i;:::-;;:::i;3450:338:3:-;;;;;;:::i;:::-;;:::i;3178:126:24:-;;;;;;;;;;-1:-1:-1;3178:126:24;;;;;:::i;:::-;-1:-1:-1;;;;;3278:19:24;;;3252:7;3278:19;;;:10;:19;;;;;;;;3178:126;;;;-1:-1:-1;;;;;5794:55:51;;;5776:74;;5764:2;5749:18;3178:126:24;5630:226:51;6637:112:24;;;;;;;;;;-1:-1:-1;6637:112:24;;;;;:::i;:::-;;:::i;2930:160::-;;;;;;;;;;-1:-1:-1;2930:160:24;;;;;:::i;:::-;;:::i;:::-;;;6035:10:51;6023:23;;;6005:42;;5993:2;5978:18;2930:160:24;5861:192:51;2145:189:50;;;;;;;;;;-1:-1:-1;2145:189:50;;;;;:::i;:::-;;:::i;2085:101:15:-;;;;;;;;;;;;;:::i;3012:257:3:-;;;;;;;;;;-1:-1:-1;3012:257:3;;;;;:::i;:::-;;:::i;687:48:1:-;;;;;;;;;;-1:-1:-1;687:48:1;;;;;:::i;:::-;;;;;;;;;;;;;;3043:126:23;;;;;;;;;;-1:-1:-1;3043:126:23;;;;;:::i;:::-;;:::i;1226:29:2:-;;;;;;;;;;-1:-1:-1;1226:29:2;;;;-1:-1:-1;;;;;1226:29:2;;;2152:270:13;;;;;;:::i;:::-;;:::i;4521:861:32:-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;1184:35:2:-;;;;;;;;;;;;;;;1462:85:15;;;;;;;;;;-1:-1:-1;1534:6:15;;-1:-1:-1;;;;;1534:6:15;1462:85;;4316:239:24;;;;;;;;;;-1:-1:-1;4316:239:24;;;;;:::i;:::-;;:::i;2135:129::-;;;;;;;;;;;;;:::i;:::-;;;9220:14:51;9208:27;;;9190:46;;9178:2;9163:18;2135:129:24;9046:196:51;234:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2727:102:21;;;;;;;;;;;;;:::i;3383:243:24:-;;;;;;;;;;-1:-1:-1;3383:243:24;;;;;:::i;:::-;;:::i;6933:427:21:-;;;;;;;;;;-1:-1:-1;6933:427:21;;;;;:::i;:::-;;:::i;4098:189::-;;;;;;;;;;-1:-1:-1;4098:189:21;;;;;:::i;:::-;;:::i;1394:36:50:-;;;;;;;;;;;;;;;1029:250:1;;;;;;;;;;-1:-1:-1;1029:250:1;;;;;:::i;:::-;;:::i;2112:164:3:-;;;;;;;;;;-1:-1:-1;2112:164:3;;;;;:::i;:::-;;:::i;6826:585:24:-;;;;;;;;;;-1:-1:-1;6826:585:24;;;;;:::i;:::-;;:::i;2341:637:23:-;;;;;;;;;;-1:-1:-1;2341:637:23;;;;;:::i;:::-;;:::i;1144:33:2:-;;;;;;;;;;;;;;;1594:445:50;;;;;;;;;;-1:-1:-1;1594:445:50;;;;;:::i;:::-;;:::i;4345:149:21:-;;;;;;;;;;-1:-1:-1;4345:149:21;;;;;:::i;:::-;-1:-1:-1;;;;;4460:18:21;;;4434:7;4460:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;4345:149;1262:57:2;;;;;;;;;;-1:-1:-1;1262:57:2;;;;-1:-1:-1;;;;;1262:57:2;;;2493:373:3;;;;;;;;;;-1:-1:-1;2493:373:3;;;;;:::i;:::-;;:::i;1737:120::-;;;;;;;;;;-1:-1:-1;1737:120:3;;;;;:::i;:::-;;:::i;2707:148:24:-;;;;;;;;;;-1:-1:-1;2707:148:24;;;;;:::i;:::-;;:::i;:::-;;;;15575:13:51;;15590:10;15571:30;15553:49;;15662:4;15650:17;;;15644:24;-1:-1:-1;;;;;15640:89:51;15618:20;;;15611:119;;;;15526:18;2707:148:24;15351:385:51;1843:185:1;;;;;;;;;;-1:-1:-1;1843:185:1;;;;;:::i;:::-;;:::i;2335:198:15:-;;;;;;;;;;-1:-1:-1;2335:198:15;;;;;:::i;:::-;;:::i;2516:98:21:-;2570:13;2602:5;2595:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2516:98;:::o;4802:197::-;4885:4;965:10:28;4939:32:21;965:10:28;4955:7:21;4964:6;4939:8;:32::i;:::-;4988:4;4981:11;;;4802:197;;;;;:::o;2771:221:2:-;2865:7;-1:-1:-1;;;;;1702:19:43;;;:23;;1686:56:2;;;-1:-1:-1;;;;;;1719:23:2;;;1686:56;1665:142;;;;-1:-1:-1;;;1665:142:2;;16328:2:51;1665:142:2;;;16310:21:51;16367:2;16347:18;;;16340:30;16406:34;16386:18;;;16379:62;-1:-1:-1;;;16457:18:51;;;16450:37;16504:19;;1665:142:2;;;;;;;;;1355:13:15::1;:11;:13::i;:::-;2894:24:2::2;:61:::0;;-1:-1:-1;;;;;;2894:61:2::2;-1:-1:-1::0;;;;;2894:61:2;::::2;::::0;;::::2;::::0;;;2970:15:::2;::::0;5776:74:51;;;2970:15:2::2;::::0;5764:2:51;5749:18;2970:15:2::2;;;;;;;;2771:221:::0;;:::o;5561:256:21:-;5658:4;965:10:28;5714:38:21;5730:4;965:10:28;5745:6:21;5714:15;:38::i;:::-;5762:27;5772:4;5778:2;5782:6;5762:9;:27::i;:::-;-1:-1:-1;5806:4:21;;5561:256;-1:-1:-1;;;;5561:256:21:o;1454:158:3:-;1516:7;;1557:24;:8;:24;;;;;:15;:24;:::i;:::-;1535:46;1454:158;-1:-1:-1;;;;1454:158:3:o;3287:113:23:-;3347:7;3373:20;:18;:20::i;:::-;3366:27;;3287:113;:::o;6212:234:21:-;965:10:28;6300:4:21;4460:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;4460:27:21;;;;;;;;;;6300:4;;965:10:28;6354:64:21;;965:10:28;;4460:27:21;;6379:38;;6407:10;;6379:38;:::i;:::-;6354:8;:64::i;3806:248:24:-;3902:7;3941;:5;:7::i;:::-;3929:19;;:9;:19;3921:57;;;;-1:-1:-1;;;3921:57:24;;16998:2:51;3921:57:24;;;16980:21:51;17037:2;17017:18;;;17010:30;17076:27;17056:18;;;17049:55;17121:18;;3921:57:24;16796:349:51;3921:57:24;-1:-1:-1;;;;;4014:21:24;;;;;;:12;:21;;;;;3995:52;;4037:9;3995:18;:52::i;:::-;3988:59;3806:248;-1:-1:-1;;;3806:248:24:o;2409:174:2:-;2489:5;-1:-1:-1;;;;;1702:19:43;;;:23;;1686:56:2;;;-1:-1:-1;;;;;;1719:23:2;;;1686:56;1665:142;;;;-1:-1:-1;;;1665:142:2;;16328:2:51;1665:142:2;;;16310:21:51;16367:2;16347:18;;;16340:30;16406:34;16386:18;;;16379:62;-1:-1:-1;;;16457:18:51;;;16450:37;16504:19;;1665:142:2;16126:403:51;1665:142:2;1355:13:15::1;:11;:13::i;:::-;2516:4:2::2;:31:::0;;-1:-1:-1;;;;;;2516:31:2::2;-1:-1:-1::0;;;;;2516:31:2;::::2;::::0;;::::2;::::0;;;2562:14:::2;::::0;5776:74:51;;;2562:14:2::2;::::0;5764:2:51;5749:18;2562:14:2::2;5630:226:51::0;2044:95:50;1355:13:15;:11;:13::i;:::-;2115:17:50::1;2121:2;2125:6;2115:5;:17::i;:::-;2044:95:::0;;:::o;1051:104:3:-;1093:15;1127:21;:8;:19;:21::i;1454:122:1:-;1355:13:15;:11;:13::i;:::-;1538:31:1::1;1557:6;1565:3;1538:18;:31::i;2376:254:24:-:0;2436:13;2529:12;2518:7;:5;:7::i;:::-;:23;;;2510:65;;;;-1:-1:-1;;;2510:65:24;;17352:2:51;2510:65:24;;;17334:21:51;17391:2;17371:18;;;17364:30;17430:31;17410:18;;;17403:59;17479:18;;2510:65:24;17150:353:51;2510:65:24;-1:-1:-1;2585:38:24;;;;;;;;;;;;;;;;;;2376:254::o;3230:463:13:-;3441:17;3489:197;3522:12;3552:10;3580:11;3609:9;3636:13;;3489:197;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3667:5:13;;-1:-1:-1;3489:15:13;;-1:-1:-1;;3489:197:13:i;:::-;3470:216;3230:463;-1:-1:-1;;;;;;;3230:463:13:o;3450:338:3:-;1971:10:2;-1:-1:-1;;;;;1993:7:2;1971:30;;1950:110;;;;-1:-1:-1;;;1950:110:2;;17710:2:51;1950:110:2;;;17692:21:51;17749:2;17729:18;;;17722:30;17788:34;17768:18;;;17761:62;-1:-1:-1;;;17839:18:51;;;17832:31;17880:19;;1950:110:2;17508:397:51;1950:110:2;3610:15:3::1;3628:30;3650:7;3628:21;:30::i;:::-;3610:48;;3687:7;3676;:18;3668:68;;;::::0;-1:-1:-1;;;3668:68:3;;18112:2:51;3668:68:3::1;::::0;::::1;18094:21:51::0;18151:2;18131:18;;;18124:30;18190:34;18170:18;;;18163:62;18261:7;18241:18;;;18234:35;18286:19;;3668:68:3::1;17910:401:51::0;3668:68:3::1;3746:35;3754:7;3763;3772:8;;3746:7;:35::i;:::-;3600:188;3450:338:::0;;;;:::o;6637:112:24:-;6708:34;965:10:28;6732:9:24;6708;:34::i;:::-;6637:112;:::o;2930:160::-;-1:-1:-1;;;;;3054:21:24;;3000:6;3054:21;;;:12;:21;;;;;:28;3025:58;;:28;:58::i;2145:189:50:-;-1:-1:-1;;;;;3877:18:21;;2265:7:50;3877:18:21;;;:9;:18;;;;;;2291:36:50;3777:125:21;2085:101:15;1355:13;:11;:13::i;:::-;2149:30:::1;2176:1;2149:18;:30::i;:::-;2085:101::o:0;3012:257:3:-;1355:13:15;:11;:13::i;:::-;3139:8:3;3122:14:::1;3164:99;3188:6;3184:1;:10;3164:99;;;3218:34;3240:8;;3249:1;3240:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;3218:21;:34::i;:::-;3196:6;3201:1;3196:6:::0;::::1;:::i;:::-;;;3164:99;;;;3112:157;3012:257:::0;;:::o;3043:126:23:-;-1:-1:-1;;;;;3138:14:23;;3112:7;3138:14;;;:7;:14;;;;;929::29;3138:24:23;838:112:29;2152:270:13;2302:17;2350:65;2366:12;2380:10;2392:11;2405:9;2350:15;:65::i;4521:861:32:-;4636:13;4663:18;4695:21;4730:15;4759:25;4798:12;4824:27;5087:11;;5102:1;5087:16;;;:39;;;;-1:-1:-1;5107:14:32;;:19;5087:39;5079:73;;;;-1:-1:-1;;;5079:73:32;;18650:2:51;5079:73:32;;;18632:21:51;18689:2;18669:18;;;18662:30;18728:23;18708:18;;;18701:51;18769:18;;5079:73:32;18448:345:51;5079:73:32;5214:13;:11;:13::i;:::-;5241:16;:14;:16::i;:::-;5349;;;5333:1;5349:16;;;;;;;;;-1:-1:-1;;;5163:212:32;;;-1:-1:-1;5163:212:32;;-1:-1:-1;5271:13:32;;-1:-1:-1;5306:4:32;;-1:-1:-1;5333:1:32;-1:-1:-1;5349:16:32;-1:-1:-1;5163:212:32;-1:-1:-1;4521:861:32:o;4316:239:24:-;4401:7;4440;:5;:7::i;:::-;4428:19;;:9;:19;4420:57;;;;-1:-1:-1;;;4420:57:24;;16998:2:51;4420:57:24;;;16980:21:51;17037:2;17017:18;;;17010:30;17076:27;17056:18;;;17049:55;17121:18;;4420:57:24;16796:349:51;4420:57:24;4494:54;4513:23;4538:9;4494:18;:54::i;2135:129::-;2190:6;2215:42;2244:12;2215:28;:42::i;2727:102:21:-;2783:13;2815:7;2808:14;;;;;:::i;3383:243:24:-;-1:-1:-1;;;;;3489:21:24;;3456:7;3489:21;;;:12;:21;;;;;:28;3558:8;;:51;;-1:-1:-1;;;;;3573:21:24;;;;;;:12;:21;;;;;:30;;-1:-1:-1;;3595:7:24;;;3573:30;;;;;;:::i;:::-;;;;;;;;;;:36;;;;-1:-1:-1;;;;;3573:36:24;3558:51;;;3569:1;3558:51;-1:-1:-1;;;;;3551:58:24;;3383:243;-1:-1:-1;;;3383:243:24:o;6933:427:21:-;965:10:28;7026:4:21;4460:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;4460:27:21;;;;;;;;;;7026:4;;965:10:28;7170:15:21;7150:16;:35;;7142:85;;;;-1:-1:-1;;;7142:85:21;;19000:2:51;7142:85:21;;;18982:21:51;19039:2;19019:18;;;19012:30;19078:34;19058:18;;;19051:62;19149:7;19129:18;;;19122:35;19174:19;;7142:85:21;18798:401:51;7142:85:21;7261:60;7270:5;7277:7;7305:15;7286:16;:34;7261:8;:60::i;4098:189::-;4177:4;965:10:28;4231:28:21;965:10:28;4248:2:21;4252:6;4231:9;:28::i;1029:250:1:-;1355:13:15;:11;:13::i;:::-;1143:9:1::1;1138:135;1158:21:::0;;::::1;1138:135;;;1203:59;1222:10;;1233:1;1222:13;;;;;;;:::i;:::-;:20;::::0;::::1;:13;::::0;;::::1;;:20:::0;;::::1;::::0;-1:-1:-1;1222:20:1::1;:::i;:::-;1244:10;;1255:1;1244:13;;;;;;;:::i;:::-;;;;;;:17;;;1203:18;:59::i;:::-;1181:6;1186:1;1181:6:::0;::::1;:::i;:::-;;;1138:135;;;;1029:250:::0;;:::o;2112:164:3:-;1355:13:15;:11;:13::i;:::-;2232:37:3::1;2252:7;2261;2232:19;:37::i;6826:585:24:-:0;7045:6;7026:15;:25;;7018:67;;;;-1:-1:-1;;;7018:67:24;;19406:2:51;7018:67:24;;;19388:21:51;19445:2;19425:18;;;19418:30;19484:31;19464:18;;;19457:59;19533:18;;7018:67:24;19204:353:51;7018:67:24;7177:58;;;1612:71;7177:58;;;19793:25:51;-1:-1:-1;;;;;19854:55:51;;19834:18;;;19827:83;;;;19926:18;;;19919:34;;;19969:18;;;19962:34;;;7095:14:24;;7112:180;;7150:87;;19765:19:51;;7177:58:24;;;;;;;;;;;;7167:69;;;;;;7150:16;:87::i;:::-;7251:1;7266;7281;7112:24;:180::i;:::-;7095:197;;7319:17;7329:6;7319:9;:17::i;:::-;7310:5;:26;7302:64;;;;-1:-1:-1;;;7302:64:24;;20209:2:51;7302:64:24;;;20191:21:51;20248:2;20228:18;;;20221:30;20287:27;20267:18;;;20260:55;20332:18;;7302:64:24;20007:349:51;7302:64:24;7376:28;7386:6;7394:9;7376;:28::i;:::-;7008:403;6826:585;;;;;;:::o;2341:637:23:-;2576:8;2557:15;:27;;2549:69;;;;-1:-1:-1;;;2549:69:23;;20563:2:51;2549:69:23;;;20545:21:51;20602:2;20582:18;;;20575:30;20641:31;20621:18;;;20614:59;20690:18;;2549:69:23;20361:353:51;2549:69:23;2629:18;1372:95;2689:5;2696:7;2705:5;2712:16;2722:5;2712:9;:16::i;:::-;2660:79;;;;;;21006:25:51;;;;-1:-1:-1;;;;;21067:55:51;;;21047:18;;;21040:83;21159:55;;;;21139:18;;;21132:83;21231:18;;;21224:34;21274:19;;;21267:35;21318:19;;;21311:35;;;20978:19;;2660:79:23;;;;;;;;;;;;2650:90;;;;;;2629:111;;2751:12;2766:28;2783:10;2766:16;:28::i;:::-;2751:43;;2805:14;2822:39;2847:4;2853:1;2856;2859;2822:24;:39::i;:::-;2805:56;;2889:5;-1:-1:-1;;;;;2879:15:23;:6;-1:-1:-1;;;;;2879:15:23;;2871:58;;;;-1:-1:-1;;;2871:58:23;;21559:2:51;2871:58:23;;;21541:21:51;21598:2;21578:18;;;21571:30;21637:32;21617:18;;;21610:60;21687:18;;2871:58:23;21357:354:51;2871:58:23;2940:31;2949:5;2956:7;2965:5;2940:8;:31::i;:::-;2539:439;;;2341:637;;;;;;;:::o;1594:445:50:-;3279:19:20;3302:13;;;;;;3301:14;;3347:34;;;;-1:-1:-1;3365:12:20;;3380:1;3365:12;;;;:16;3347:34;3346:108;;;-1:-1:-1;3426:4:20;1702:19:43;:23;;;3387:66:20;;-1:-1:-1;3436:12:20;;;;;:17;3387:66;3325:201;;;;-1:-1:-1;;;3325:201:20;;21918:2:51;3325:201:20;;;21900:21:51;21957:2;21937:18;;;21930:30;21996:34;21976:18;;;21969:62;22067:16;22047:18;;;22040:44;22101:19;;3325:201:20;21716:410:51;3325:201:20;3536:12;:16;;-1:-1:-1;;3536:16:20;3551:1;3536:16;;;3562:65;;;;3596:13;:20;;-1:-1:-1;;3596:20:20;;;;;3562:65;1801:28:50::1;1814:5;1821:7;1801:12;:28::i;:::-;1839:25;1858:5;1839:18;:25::i;:::-;1874:19;:17;:19::i;:::-;1903:16;:14;:16::i;:::-;1929:67;1955:5;1962:25;1989:6;1929:25;:67::i;:::-;2006:26;2025:6;2006:18;:26::i;:::-;3651:14:20::0;3647:99;;;3697:5;3681:21;;-1:-1:-1;;3681:21:20;;;3721:14;;-1:-1:-1;2901:36:51;;3721:14:20;;2889:2:51;2874:18;3721:14:20;;;;;;;3647:99;3269:483;1594:445:50;;;;;:::o;2493:373:3:-;1355:13:15;:11;:13::i;:::-;2648:36:3;;::::1;2640:56;;;::::0;-1:-1:-1;;;2640:56:3;;22532:2:51;2640:56:3::1;::::0;::::1;22514:21:51::0;22571:1;22551:18;;;22544:29;22609:9;22589:18;;;22582:37;22636:18;;2640:56:3::1;22330:330:51::0;2640:56:3::1;2723:8:::0;2706:14:::1;2748:112;2772:6;2768:1;:10;2748:112;;;2802:47;2822:8;;2831:1;2822:11;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;2835:10;;2846:1;2835:13;;;;;;;:::i;:::-;;;;;;;2802:19;:47::i;:::-;2780:6;2785:1;2780:6:::0;::::1;:::i;:::-;;;2748:112;;1737:120:::0;1355:13:15;:11;:13::i;:::-;1820:30:3::1;1842:7;1820:21;:30::i;2707:148:24:-:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;2822:21:24;;;;;;:12;:21;;;;;:26;;;;;;;;;;;;:::i;:::-;;;;;;;;;;2815:33;;;;;;;;;2822:26;;2815:33;;;;;;;;;-1:-1:-1;;;;;2815:33:24;;;;;;;;;2707:148;-1:-1:-1;;;2707:148:24:o;1843:185:1:-;1958:63;;;;;;;;;1932:7;1958:63;;;2015:4;;1932:7;;1958:63;;1983:18;;1958:63;-1:-1:-1;;;;;2015:4:1;1958:24;:63::i;2335:198:15:-;1355:13;:11;:13::i;:::-;-1:-1:-1;;;;;2423:22:15;::::1;2415:73;;;::::0;-1:-1:-1;;;2415:73:15;;22867:2:51;2415:73:15::1;::::0;::::1;22849:21:51::0;22906:2;22886:18;;;22879:30;22945:34;22925:18;;;22918:62;23016:8;22996:18;;;22989:36;23042:19;;2415:73:15::1;22665:402:51::0;2415:73:15::1;2498:28;2517:8;2498:18;:28::i;10815:340:21:-:0;-1:-1:-1;;;;;10916:19:21;;10908:68;;;;-1:-1:-1;;;10908:68:21;;23274:2:51;10908:68:21;;;23256:21:51;23313:2;23293:18;;;23286:30;23352:34;23332:18;;;23325:62;-1:-1:-1;;;23403:18:51;;;23396:34;23447:19;;10908:68:21;23072:400:51;10908:68:21;-1:-1:-1;;;;;10994:21:21;;10986:68;;;;-1:-1:-1;;;10986:68:21;;23679:2:51;10986:68:21;;;23661:21:51;23718:2;23698:18;;;23691:30;23757:34;23737:18;;;23730:62;-1:-1:-1;;;23808:18:51;;;23801:32;23850:19;;10986:68:21;23477:398:51;10986:68:21;-1:-1:-1;;;;;11065:18:21;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;11116:32;;1805:25:51;;;11116:32:21;;1778:18:51;11116:32:21;;;;;;;10815:340;;;:::o;1620:130:15:-;1534:6;;-1:-1:-1;;;;;1534:6:15;965:10:28;1683:23:15;1675:68;;;;-1:-1:-1;;;1675:68:15;;24082:2:51;1675:68:15;;;24064:21:51;;;24101:18;;;24094:30;24160:34;24140:18;;;24133:62;24212:18;;1675:68:15;23880:356:51;11436:411:21;-1:-1:-1;;;;;4460:18:21;;;11536:24;4460:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;11602:37:21;;11598:243;;11683:6;11663:16;:26;;11655:68;;;;-1:-1:-1;;;11655:68:21;;24443:2:51;11655:68:21;;;24425:21:51;24482:2;24462:18;;;24455:30;24521:31;24501:18;;;24494:59;24570:18;;11655:68:21;24241:353:51;11655:68:21;11765:51;11774:5;11781:7;11809:6;11790:16;:25;11765:8;:51::i;7814:788::-;-1:-1:-1;;;;;7910:18:21;;7902:68;;;;-1:-1:-1;;;7902:68:21;;24801:2:51;7902:68:21;;;24783:21:51;24840:2;24820:18;;;24813:30;24879:34;24859:18;;;24852:62;24950:7;24930:18;;;24923:35;24975:19;;7902:68:21;24599:401:51;7902:68:21;-1:-1:-1;;;;;7988:16:21;;7980:64;;;;-1:-1:-1;;;7980:64:21;;25207:2:51;7980:64:21;;;25189:21:51;25246:2;25226:18;;;25219:30;25285:34;25265:18;;;25258:62;-1:-1:-1;;;25336:18:51;;;25329:33;25379:19;;7980:64:21;25005:399:51;7980:64:21;-1:-1:-1;;;;;8126:15:21;;8104:19;8126:15;;;:9;:15;;;;;;8159:21;;;;8151:72;;;;-1:-1:-1;;;8151:72:21;;25611:2:51;8151:72:21;;;25593:21:51;25650:2;25630:18;;;25623:30;25689:34;25669:18;;;25662:62;25760:8;25740:18;;;25733:36;25786:19;;8151:72:21;25409:402:51;8151:72:21;-1:-1:-1;;;;;8257:15:21;;;;;;;:9;:15;;;;;;8275:20;;;8257:38;;8472:13;;;;;;;;;;:23;;;;;;8521:26;;;;;;8289:6;1805:25:51;;1793:2;1778:18;;1659:177;8521:26:21;;;;;;;;8558:37;8578:4;8584:2;8588:6;8558:19;:37::i;1719:174:9:-;1823:4;;1855:31;:3;1881;1855:17;:31::i;:::-;1848:38;;;;1719:174;;;;;;:::o;3325:109:32:-;3378:7;3404:23;:21;:23::i;4639:1917:24:-;5850:12;;4736:7;;;5850:12;5943:1;5934:10;;5930:253;;;5960:11;5983:28;6004:6;5983:20;:28::i;:::-;5974:37;;:6;:37;:::i;:::-;11032:25;11092:21;;;11158:4;11145:18;;5960:51;;-1:-1:-1;6067:9:24;;11141:28;;6029:35;;;:47;6025:148;;;6103:3;6096:10;;6025:148;;;6151:7;:3;6157:1;6151:7;:::i;:::-;6145:13;;6025:148;5946:237;5930:253;6206:4;6200:3;:10;6193:253;;;6226:11;6240:34;6264:3;6269:4;6240:23;:34::i;:::-;11032:25;11092:21;;;11158:4;11145:18;;6226:48;;-1:-1:-1;6330:9:24;;11141:28;;6292:35;;;:47;6288:148;;;6366:3;6359:10;;6288:148;;;6414:7;:3;6420:1;6414:7;:::i;:::-;6408:13;;6288:148;6212:234;6193:253;;;6487:9;;:52;;11032:25;11092:21;;;11158:4;11145:18;;11141:28;;-1:-1:-1;;11141:28:24;6503:36;;;;-1:-1:-1;;;;;6503:36:24;6487:52;;;6499:1;6487:52;-1:-1:-1;;;;;6480:59:24;;4639:1917;-1:-1:-1;;;;;;4639:1917:24:o;3529:164:50:-;3663:23;3675:2;3679:6;3663:11;:23::i;1044:333:9:-;1131:21;1164:28;1195:9;1200:3;1195:4;:9::i;:::-;1164:40;;1235:11;:18;1222:32;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1222:32:9;;1214:40;;1269:9;1264:107;1288:11;:18;1284:1;:22;1264:107;;;1345:11;1357:1;1345:14;;;;;;;;:::i;:::-;;;;;;;1327:5;1333:1;1327:8;;;;;;;;:::i;:::-;:33;;;;:8;;;;;;;;;;;:33;1308:3;;1264:107;;;;1154:223;1044:333;;;:::o;2248:144:1:-;2323:22;;;;;;;:14;:22;;;;;;;;;:28;;;2366:19;;26121:42:51;;;26179:18;;26172:34;;;2366:19:1;;26094:18:51;2366:19:1;25949:263:51;2681:575:50;2916:17;2965:12;2949:28;;:12;:28;;;2945:75;;2986:34;;-1:-1:-1;;;2986:34:50;;;;;;;;;;;2945:75;3049:200;3088:12;3118:10;3146:11;3175:6;3199:13;3230:5;3049:21;:200::i;5295:280:3:-;5379:7;;;5434:24;:8;:24;;;;;:15;:24;:::i;:::-;5398:60;;;;5472:9;5468:54;;;5504:7;5295:280;-1:-1:-1;;;5295:280:3:o;5468:54::-;5538:29;5559:7;5538:20;:29::i;:::-;5531:37;;-1:-1:-1;;;5531:37:3;;;;;;;;:::i;5841:413:13:-;5974:17;5994:20;:8;;:18;:20::i;:::-;5974:40;;6024:14;6041:17;:8;;:15;:17::i;:::-;6024:34;;6068:23;;6094:19;:8;;:17;:19::i;:::-;6068:45;;;;6123:59;6135:28;:9;:26;:28::i;:::-;6165:6;6173:8;;6123:11;:59::i;:::-;6229:9;6220:7;6197:50;;;6240:6;6197:50;;;;1805:25:51;;1793:2;1778:18;;1659:177;6197:50:13;;;;;;;;5964:290;;;;5841:413;;;;:::o;8804:380:24:-;-1:-1:-1;;;;;3278:19:24;;;8888:23;3278:19;;;:10;:19;;;;;;;;;;8971:20;3278:19;8971:9;:20::i;:::-;-1:-1:-1;;;;;9001:21:24;;;;;;;:10;:21;;;;;;:33;;-1:-1:-1;;;;;;9001:33:24;;;;;;;;;;9050:54;;8944:47;;-1:-1:-1;9001:33:24;9050:54;;;;;;9001:21;9050:54;9115:62;9132:15;9149:9;9160:16;9115;:62::i;15275:187:34:-;15331:6;15366:16;15357:25;;;15349:76;;;;-1:-1:-1;;;15349:76:34;;26419:2:51;15349:76:34;;;26401:21:51;26458:2;26438:18;;;26431:30;26497:34;26477:18;;;26470:62;26568:8;26548:18;;;26541:36;26594:19;;15349:76:34;26217:402:51;15349:76:34;-1:-1:-1;15449:5:34;15275:187::o;2687::15:-;2779:6;;;-1:-1:-1;;;;;2795:17:15;;;-1:-1:-1;;;;;;2795:17:15;;;;;;;2827:40;;2779:6;;;2795:17;2779:6;;2827:40;;2760:16;;2827:40;2750:124;2687:187;:::o;4419:145:3:-;4501:24;:8;:24;;;;;:15;:24;:::i;:::-;4527:29;4548:7;4527:20;:29::i;:::-;4493:64;;;;;-1:-1:-1;;;4493:64:3;;;;;;;;:::i;3699:440:13:-;3858:17;3906:226;3939:12;3969:10;3997:11;4026:6;4050:37;4074:12;4050:23;:37::i;:::-;4113:4;;-1:-1:-1;;;;;4113:4:13;3906:15;:226::i;:::-;3887:245;3699:440;-1:-1:-1;;;;;3699:440:13:o;5606:98:32:-;5660:13;5692:5;5685:12;;;;;:::i;5931:104::-;5988:13;6020:8;6013:15;;;;;:::i;14251:187:34:-;14307:6;14342:16;14333:25;;;14325:76;;;;-1:-1:-1;;;14325:76:34;;26826:2:51;14325:76:34;;;26808:21:51;26865:2;26845:18;;;26838:30;26904:34;26884:18;;;26877:62;26975:8;26955:18;;;26948:36;27001:19;;14325:76:34;26624:402:51;4162:150:3;4274:31;:8;:31;;;;;4296:8;;4274:12;:31;:::i;4257:176:32:-;4334:7;4360:66;4393:20;:18;:20::i;:::-;4415:10;8569:4:31;8563:11;-1:-1:-1;;;8587:23:31;;8639:4;8630:14;;8623:39;;;;8691:4;8682:14;;8675:34;8745:4;8730:20;;;8369:397;6620:232;6705:7;6725:17;6744:18;6766:25;6777:4;6783:1;6786;6789;6766:10;:25::i;:::-;6724:67;;;;6801:18;6813:5;6801:11;:18::i;:::-;-1:-1:-1;6836:9:31;6620:232;-1:-1:-1;;;;;6620:232:31:o;3531:214:23:-;-1:-1:-1;;;;;3662:14:23;;3591:15;3662:14;;;:7;:14;;;;;929::29;;1061:1;1043:19;;;;929:14;3721:17:23;3608:137;3531:214;;;:::o;2139:147:21:-;5374:13:20;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:20;;27233:2:51;5366:69:20;;;27215:21:51;27272:2;27252:18;;;27245:30;27311:34;27291:18;;;27284:62;-1:-1:-1;;;27362:18:51;;;27355:41;27413:19;;5366:69:20;27031:407:51;5366:69:20;2241:38:21::1;2264:5;2271:7;2241:22;:38::i;2064:125:23:-:0;5374:13:20;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:20;;27233:2:51;5366:69:20;;;27215:21:51;27272:2;27252:18;;;27245:30;27311:34;27291:18;;;27284:62;-1:-1:-1;;;27362:18:51;;;27355:41;27413:19;;5366:69:20;27031:407:51;5366:69:20;2148:34:23::1;2172:4;2148:34;;;;;;;;;;;;;-1:-1:-1::0;;;2148:34:23::1;;::::0;:23:::1;:34::i;1852:62:24:-:0;5374:13:20;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:20;;27233:2:51;5366:69:20;;;27215:21:51;27272:2;27252:18;;;27245:30;27311:34;27291:18;;;27284:62;-1:-1:-1;;;27362:18:51;;;27355:41;27413:19;;5366:69:20;27031:407:51;1024:95:15;5374:13:20;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:20;;27233:2:51;5366:69:20;;;27215:21:51;27272:2;27252:18;;;27245:30;27311:34;27291:18;;;27284:62;-1:-1:-1;;;27362:18:51;;;27355:41;27413:19;;5366:69:20;27031:407:51;5366:69:20;1086:26:15::1;:24;:26::i;3036:314:2:-:0;5374:13:20;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:20;;27233:2:51;5366:69:20;;;27215:21:51;27272:2;27252:18;;;27245:30;27311:34;27291:18;;;27284:62;-1:-1:-1;;;27362:18:51;;;27355:41;27413:19;;5366:69:20;27031:407:51;5366:69:20;3203:16:2::1;:14;:16::i;:::-;3229:14;3237:5;3229:7;:14::i;:::-;3253:54;3281:25;3253:27;:54::i;:::-;3317:26;3336:6;3317:18;:26::i;2805:368:1:-:0;2955:7;2993:173;3032:12;3062;3092:37;3116:12;3092:23;:37::i;:::-;3147:5;2993:21;:173::i;3303:220:50:-;3473:43;3499:4;3505:2;3509:6;3473:25;:43::i;4166:298:48:-;4251:4;4292:16;;;:11;;;:16;;;;;;4251:4;;4292:16;4318:140;;4365:18;4374:3;4379;4365:8;:18::i;:::-;4357:39;-1:-1:-1;4393:1:48;;-1:-1:-1;4357:39:48;;-1:-1:-1;4357:39:48;4318:140;4435:4;;-1:-1:-1;4441:5:48;-1:-1:-1;4427:20:48;;3440:192:32;3495:7;1934:95;3554:17;:15;:17::i;:::-;3573:20;:18;:20::i;:::-;3531:93;;;;;;27702:25:51;;;;27743:18;;27736:34;;;;27786:18;;;27779:34;3595:13:32;27829:18:51;;;27822:34;3618:4:32;27872:19:51;;;27865:84;27674:19;;3531:93:32;;;;;;;;;;;;3521:104;;;;;;3514:111;;3440:192;:::o;6541:1642:33:-;6589:7;6612:1;6617;6612:6;6608:45;;-1:-1:-1;6641:1:33;;6541:1642;-1:-1:-1;6541:1642:33:o;6608:45::-;7332:14;7366:1;7355:7;7360:1;7355:4;:7::i;:::-;:12;;7349:1;:19;;7332:36;;7827:1;7816:6;7812:1;:10;;;;;:::i;:::-;;7803:6;:19;7802:26;;7793:35;;7876:1;7865:6;7861:1;:10;;;;;:::i;:::-;;7852:6;:19;7851:26;;7842:35;;7925:1;7914:6;7910:1;:10;;;;;:::i;:::-;;7901:6;:19;7900:26;;7891:35;;7974:1;7963:6;7959:1;:10;;;;;:::i;:::-;;7950:6;:19;7949:26;;7940:35;;8023:1;8012:6;8008:1;:10;;;;;:::i;:::-;;7999:6;:19;7998:26;;7989:35;;8072:1;8061:6;8057:1;:10;;;;;:::i;:::-;;8048:6;:19;8047:26;;8038:35;;8121:1;8110:6;8106:1;:10;;;;;:::i;:::-;;8097:6;:19;8096:26;;8087:35;;8143:23;8147:6;8159;8155:1;:10;;;;;:::i;:::-;;8143:3;:23::i;816:153::-;878:7;951:11;961:1;952:5;;;951:11;:::i;:::-;941:21;;942:5;;;941:21;:::i;7705:285:24:-;7789:28;7801:7;7810:6;7789:11;:28::i;:::-;3700:12:21;;-1:-1:-1;;;;;;7835:29:24;7827:90;;;;-1:-1:-1;;;7827:90:24;;28516:2:51;7827:90:24;;;28498:21:51;28555:2;28535:18;;;28528:30;28594:34;28574:18;;;28567:62;28665:18;28645;;;28638:46;28701:19;;7827:90:24;28314:412:51;7827:90:24;7928:55;7945:23;7970:4;7976:6;7928:16;:55::i;725:313:9:-;806:22;840:15;858:19;:3;:17;:19::i;:::-;840:37;;909:7;895:22;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;895:22:9;;887:30;;932:9;927:105;951:7;947:1;:11;927:105;;;998:22;:3;1018:1;998:19;:22::i;:::-;990:31;;979:5;985:1;979:8;;;;;;;;:::i;:::-;;;;;;;;;;:42;960:3;;927:105;;4145:710:13;4371:17;4400:27;4430:32;4450:11;4430:19;:32::i;:::-;4400:62;;4472:26;4501:106;4534:10;4558:11;4583:14;4501:19;:106::i;:::-;4472:135;;4630:145;4660:12;4686:6;4706:13;4733;4760:5;4630:16;:145::i;:::-;4618:157;;4824:10;4810:12;4791:57;;;4836:11;4791:57;;;;1805:25:51;;1793:2;1778:18;;1659:177;4791:57:13;;;;;;;;4390:465;;4145:710;;;;;;;;:::o;5581:248:3:-;5664:13;5790:18;:7;:16;;;:18::i;:::-;5708:114;;;;;;;;:::i;:::-;;;;;;;;;;;;;5689:133;;5581:248;;;:::o;321:121:12:-;387:7;421:13;431:2;387:7;421;;:13;:::i;:::-;413:22;;;:::i;448:128::-;511:7;553:14;564:2;561;553:7;;:14;:::i;724:131::-;803:14;;836:12;:7;844:2;836:7;;:12;:::i;298:263:11:-;361:7;-1:-1:-1;;;;;401:43:11;;;380:126;;;;-1:-1:-1;;;380:126:11;;29987:2:51;380:126:11;;;29969:21:51;30026:2;30006:18;;;29999:30;30065:34;30045:18;;;30038:62;-1:-1:-1;;;30116:18:51;;;30109:34;30160:19;;380:126:11;29785:400:51;2502:173:50;2642:26;2648:10;2660:7;2642:5;:26::i;9190:597:24:-;9287:3;-1:-1:-1;;;;;9280:10:24;:3;-1:-1:-1;;;;;9280:10:24;;;:24;;;;;9303:1;9294:6;:10;9280:24;9276:505;;;-1:-1:-1;;;;;9324:17:24;;;9320:221;;-1:-1:-1;;;;;9419:17:24;;9362;9419;;;:12;:17;;;;;9362;;9402:54;;9438:9;9449:6;9402:16;:54::i;:::-;9361:95;;;;9500:3;-1:-1:-1;;;;;9479:47:24;;9505:9;9516;9479:47;;;;;;30364:25:51;;;30420:2;30405:18;;30398:34;30352:2;30337:18;;30190:248;9479:47:24;;;;;;;;9343:198;;9320:221;-1:-1:-1;;;;;9559:17:24;;;9555:216;;-1:-1:-1;;;;;9654:17:24;;9597;9654;;;:12;:17;;;;;9597;;9637:49;;9673:4;9679:6;9637:16;:49::i;:::-;9596:90;;;;9730:3;-1:-1:-1;;;;;9709:47:24;;9735:9;9746;9709:47;;;;;;30364:25:51;;;30420:2;30405:18;;30398:34;30352:2;30337:18;;30190:248;9709:47:24;;;;;;;;9578:193;;9190:597;;;:::o;1899:160:9:-;1998:4;2021:31;:3;2047;2021:17;:31::i;2034:208:1:-;2206:28;;;;;;;:14;:28;;;;;;2125:12;;2168:67;;:37;:67::i;1383:162:9:-;1503:35;:3;1526;1532:5;1503:14;:35::i;5031:1456:31:-;5119:7;;6043:66;6030:79;;6026:161;;;-1:-1:-1;6141:1:31;;-1:-1:-1;6145:30:31;6125:51;;6026:161;6298:24;;;6281:14;6298:24;;;;;;;;;30670:25:51;;;30743:4;30731:17;;30711:18;;;30704:45;;;;30765:18;;;30758:34;;;30808:18;;;30801:34;;;6298:24:31;;30642:19:51;;6298:24:31;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;6298:24:31;;-1:-1:-1;;6298:24:31;;;-1:-1:-1;;;;;;;6336:20:31;;6332:101;;6388:1;6392:29;6372:50;;;;;;;6332:101;6451:6;-1:-1:-1;6459:20:31;;-1:-1:-1;5031:1456:31;;;;;;;;:::o;592:511::-;669:20;660:5;:29;;;;;;;;:::i;:::-;;656:441;;592:511;:::o;656:441::-;765:29;756:5;:38;;;;;;;;:::i;:::-;;752:345;;810:34;;-1:-1:-1;;;810:34:31;;31180:2:51;810:34:31;;;31162:21:51;31219:2;31199:18;;;31192:30;31258:26;31238:18;;;31231:54;31302:18;;810:34:31;30978:348:51;752:345:31;874:35;865:5;:44;;;;;;;;:::i;:::-;;861:236;;925:41;;-1:-1:-1;;;925:41:31;;31533:2:51;925:41:31;;;31515:21:51;31572:2;31552:18;;;31545:30;31611:33;31591:18;;;31584:61;31662:18;;925:41:31;31331:355:51;861:236:31;996:30;987:5;:39;;;;;;;;:::i;:::-;;983:114;;1042:44;;-1:-1:-1;;;1042:44:31;;31893:2:51;1042:44:31;;;31875:21:51;31932:2;31912:18;;;31905:30;31971:34;31951:18;;;31944:62;-1:-1:-1;;;32022:18:51;;;32015:32;32064:19;;1042:44:31;31691:398:51;2292:159:21;5374:13:20;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:20;;27233:2:51;5366:69:20;;;27215:21:51;27272:2;27252:18;;;27245:30;27311:34;27291:18;;;27284:62;-1:-1:-1;;;27362:18:51;;;27355:41;27413:19;;5366:69:20;27031:407:51;5366:69:20;2404:5:21::1;:13;2412:5:::0;2404;:13:::1;:::i;:::-;-1:-1:-1::0;2427:7:21::1;:17;2437:7:::0;2427;:17:::1;:::i;2972:267:32:-:0;5374:13:20;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:20;;27233:2:51;5366:69:20;;;27215:21:51;27272:2;27252:18;;;27245:30;27311:34;27291:18;;;27284:62;-1:-1:-1;;;27362:18:51;;;27355:41;27413:19;;5366:69:20;27031:407:51;5366:69:20;3084:5:32::1;:12;3092:4:::0;3084:5;:12:::1;:::i;:::-;-1:-1:-1::0;3106:8:32::1;:18;3117:7:::0;3106:8;:18:::1;:::i;:::-;-1:-1:-1::0;;3203:1:32::1;3189:11;:15:::0;;;3214:14:::1;:18:::0;-1:-1:-1;2972:267:32:o;1125:111:15:-;5374:13:20;;;;;;;5366:69;;;;-1:-1:-1;;;5366:69:20;;27233:2:51;5366:69:20;;;27215:21:51;27272:2;27252:18;;;27245:30;27311:34;27291:18;;;27284:62;-1:-1:-1;;;27362:18:51;;;27355:41;27413:19;;5366:69:20;27031:407:51;5366:69:20;1197:32:15::1;965:10:28::0;1197:18:15::1;:32::i;6835:502:3:-:0;7024:7;7043:15;7061:41;7083:18;7061:21;:41::i;:::-;7131:199;;-1:-1:-1;;;7131:199:3;;7043:59;;-1:-1:-1;;;;;;7131:7:3;:21;;;;:199;;7170:18;;7043:59;;7231:12;;7261:13;;7310:5;;7131:199;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7112:218;6835:502;-1:-1:-1;;;;;;6835:502:3:o;8409:224:24:-;-1:-1:-1;;;;;3278:19:24;;;3252:7;3278:19;;;:10;:19;;;;;;;;;;;;;;;8570:56;;3278:19;;;;;8619:6;8570:16;:56::i;3128:140:48:-;3215:4;3238:23;:3;3257;3238:18;:23::i;6250:630:32:-;6300:7;6319:18;6340:13;:11;:13::i;:::-;6367:18;;6319:34;;-1:-1:-1;6367:22:32;6363:511;;6412:22;;;;;;;;6250:630;-1:-1:-1;6250:630:32:o;6363:511::-;6709:11;;6738:15;;6734:130;;6780:10;6250:630;-1:-1:-1;;6250:630:32:o;6734:130::-;6836:13;6829:20;;;;6250:630;:::o;7101:666::-;7154:7;7173:21;7197:16;:14;:16::i;:::-;7227:21;;7173:40;;-1:-1:-1;7227:25:32;7223:538;;7275:25;;;;;;;;7101:666;-1:-1:-1;7101:666:32:o;7223:538::-;7587:14;;7619:18;;7615:136;;7664:13;7101:666;-1:-1:-1;;7101:666:32:o;8644:983:33:-;8696:7;;8780:3;8771:12;;;:16;8767:99;;8817:3;8807:13;;;;8838;8767:99;8892:2;8883:11;;;:15;8879:96;;8928:2;8918:12;;;;8948;8879:96;9001:2;8992:11;;;:15;8988:96;;9037:2;9027:12;;;;9057;8988:96;9110:2;9101:11;;;:15;9097:96;;9146:2;9136:12;;;;9166;9097:96;9219:1;9210:10;;;:14;9206:93;;9254:1;9244:11;;;;9273;9206:93;9325:1;9316:10;;;:14;9312:93;;9360:1;9350:11;;;;9379;9312:93;9431:1;9422:10;;;:14;9418:93;;9466:1;9456:11;;;;9485;9418:93;9537:1;9528:10;;;:14;9524:64;;9572:1;9562:11;9614:6;8644:983;-1:-1:-1;;8644:983:33:o;599:104::-;657:7;687:1;683;:5;:13;;695:1;683:13;;;-1:-1:-1;691:1:33;;599:104;-1:-1:-1;599:104:33:o;8878:535:21:-;-1:-1:-1;;;;;8961:21:21;;8953:65;;;;-1:-1:-1;;;8953:65:21;;35299:2:51;8953:65:21;;;35281:21:51;35338:2;35318:18;;;35311:30;35377:33;35357:18;;;35350:61;35428:18;;8953:65:21;35097:355:51;8953:65:21;9105:6;9089:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;9257:18:21;;;;;;:9;:18;;;;;;;;:28;;;;;;9310:37;1805:25:51;;;9310:37:21;;1778:18:51;9310:37:21;;;;;;;9358:48;9386:1;9390:7;9399:6;9358:19;:48::i;10600:96:24:-;10658:7;10684:5;10688:1;10684;:5;:::i;9793:801::-;10025:12;;9963:17;;;;;10100:8;;:59;;11032:25;11092:21;;;11158:4;11145:18;;11141:28;;-1:-1:-1;;11141:28:24;10100:59;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;10100:59:24;;;;;;;;10111:16;;;;;;;;;-1:-1:-1;10111:16:24;;;;;;;10100:59;10072:87;;10186:7;:13;;;-1:-1:-1;;;;;10174:25:24;;;10225:20;10228:9;10239:5;10225:2;:20;;:::i;:::-;10213:32;;10270:1;10264:3;:7;:39;;;;;10296:7;:5;:7::i;:::-;10275:28;;:7;:17;;;:28;;;10264:39;10260:318;;;10361:40;10391:9;10361:29;:40::i;:::-;11032:25;11092:21;;;11158:4;11145:18;;11141:28;;-1:-1:-1;;11141:28:24;10323:78;;-1:-1:-1;;;;;10323:78:24;;;;;;;;;;;;;;;;10260:318;;;10440:5;10451:111;;;;;;;;10474:37;10503:7;:5;:7::i;:::-;10474:37;;:28;:37::i;:::-;10451:111;;;;;;10520:40;10550:9;10520:29;:40::i;:::-;-1:-1:-1;;;;;10451:111:24;;;;;;10440:123;;;;;;;-1:-1:-1;10440:123:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10260:318;10048:540;10001:593;9793:801;;;;;;:::o;3358:123:48:-;3430:7;3456:18;:3;:16;:18::i;7096:129:49:-;7170:7;7196:22;7200:3;7212:5;7196:3;:22::i;2340:156:50:-;2413:12;2437:26;2443:10;2455:7;2437:5;:26::i;:::-;-1:-1:-1;;2480:9:50;;;;;;;;;-1:-1:-1;2480:9:50;;;2340:156::o;99:216:12:-;229:12;277:10;289:7;298:9;260:48;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;253:55;;99:216;;;;;:::o;5835:526:3:-;6038:7;6057:15;6075:41;6097:18;6075:21;:41::i;:::-;6057:59;;6145:7;-1:-1:-1;;;;;6145:16:3;;6169:6;6194:18;6230:7;6255:12;6285:13;6334:5;6145:209;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;447:696:45:-;503:13;552:14;569:17;580:5;569:10;:17::i;:::-;589:1;569:21;552:38;;604:20;638:6;627:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;627:18:45;-1:-1:-1;604:41:45;-1:-1:-1;765:28:45;;;781:2;765:28;820:280;-1:-1:-1;;851:5:45;990:8;985:2;974:14;;969:30;851:5;956:44;1044:2;1035:11;;;-1:-1:-1;1064:21:45;820:280;1064:21;-1:-1:-1;1120:6:45;447:696;-1:-1:-1;;;447:696:45:o;10702:101:24:-;10765:7;10791:5;10795:1;10791;:5;:::i;2885:164:48:-;2965:4;2988:16;;;:11;;;:16;;;;;2981:23;;;3021:21;2988:3;3000;3021:16;:21::i;4969:173:4:-;5051:12;5082:53;5105:1;5109:9;5120:10;5082:53;;;;;;;;;;;;:14;:53::i;2543:174:48:-;2635:4;2651:16;;;:11;;;:16;;;;;:24;;;2692:18;2651:3;2663;2692:13;:18::i;6420:138:49:-;6500:4;4351:19;;;:12;;;:19;;;;;;:24;;6523:28;4255:127;2847:192:34;2904:7;-1:-1:-1;;;;;2931:26:34;;;2923:78;;;;-1:-1:-1;;;2923:78:34;;36277:2:51;2923:78:34;;;36259:21:51;36316:2;36296:18;;;36289:30;36355:34;36335:18;;;36328:62;36426:9;36406:18;;;36399:37;36453:19;;2923:78:34;36075:403:51;6639:115:49;6702:7;6728:19;6736:3;4545:18;;4463:107;4912:118;4979:7;5005:3;:11;;5017:5;5005:18;;;;;;;;:::i;:::-;;;;;;;;;4998:25;;4912:118;;;;:::o;3699:174:50:-;3838:28;3850:7;3859:6;3838:11;:28::i;10139:916:46:-;10192:7;;10276:8;10267:17;;10263:103;;10313:8;10304:17;;;-1:-1:-1;10349:2:46;10339:12;10263:103;10392:8;10383:5;:17;10379:103;;10429:8;10420:17;;;-1:-1:-1;10465:2:46;10455:12;10379:103;10508:8;10499:5;:17;10495:103;;10545:8;10536:17;;;-1:-1:-1;10581:2:46;10571:12;10495:103;10624:7;10615:5;:16;10611:100;;10660:7;10651:16;;;-1:-1:-1;10695:1:46;10685:11;10611:100;10737:7;10728:5;:16;10724:100;;10773:7;10764:16;;;-1:-1:-1;10808:1:46;10798:11;10724:100;10850:7;10841:5;:16;10837:100;;10886:7;10877:16;;;-1:-1:-1;10921:1:46;10911:11;10837:100;10963:7;10954:5;:16;10950:66;;11000:1;10990:11;11042:6;10139:916;-1:-1:-1;;10139:916:46:o;6210:129:49:-;6283:4;6306:26;6314:3;6326:5;6306:7;:26::i;3957:401:4:-;4134:12;1025:1;4236:9;4263;4290:14;4322:15;4177:174;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4158:193;;3957:401;;;;;;:::o;5919:123:49:-;5989:4;6012:23;6017:3;6029:5;6012:4;:23::i;8079:190:24:-;8163:28;8175:7;8184:6;8163:11;:28::i;:::-;8202:60;8219:23;8244:9;8255:6;8202:16;:60::i;2786:1388:49:-;2852:4;2989:19;;;:12;;;:19;;;;;;3023:15;;3019:1149;;3392:21;3416:14;3429:1;3416:10;:14;:::i;:::-;3464:18;;3392:38;;-1:-1:-1;3444:17:49;;3464:22;;3485:1;;3464:22;:::i;:::-;3444:42;;3518:13;3505:9;:26;3501:398;;3551:17;3571:3;:11;;3583:9;3571:22;;;;;;;;:::i;:::-;;;;;;;;;3551:42;;3722:9;3693:3;:11;;3705:13;3693:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;3805:23;;;:12;;;:23;;;;;:36;;;3501:398;3977:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;4069:3;:12;;:19;4082:5;4069:19;;;;;;;;;;;4062:26;;;4110:4;4103:11;;;;;;;3019:1149;4152:5;4145:12;;;;;2214:404;2277:4;4351:19;;;:12;;;:19;;;;;;2293:319;;-1:-1:-1;2335:23:49;;;;;;;;:11;:23;;;;;;;;;;;;;2515:18;;2493:19;;;:12;;;:19;;;;;;:40;;;;2547:11;;2293:319;-1:-1:-1;2596:5:49;2589:12;;9733:659:21;-1:-1:-1;;;;;9816:21:21;;9808:67;;;;-1:-1:-1;;;9808:67:21;;37454:2:51;9808:67:21;;;37436:21:51;37493:2;37473:18;;;37466:30;37532:34;37512:18;;;37505:62;-1:-1:-1;;;37583:18:51;;;37576:31;37624:19;;9808:67:21;37252:397:51;9808:67:21;-1:-1:-1;;;;;9971:18:21;;9946:22;9971:18;;;:9;:18;;;;;;10007:24;;;;9999:71;;;;-1:-1:-1;;;9999:71:21;;37856:2:51;9999:71:21;;;37838:21:51;37895:2;37875:18;;;37868:30;37934:34;37914:18;;;37907:62;-1:-1:-1;;;37985:18:51;;;37978:32;38027:19;;9999:71:21;37654:398:51;9999:71:21;-1:-1:-1;;;;;10104:18:21;;;;;;:9;:18;;;;;;;;10125:23;;;10104:44;;10241:12;:22;;;;;;;10289:37;1805:25:51;;;10104:18:21;;;10289:37;;1778:18:51;10289:37:21;;;;;;;10337:48;10357:7;10374:1;10378:6;10337:19;:48::i;14:250:51:-;99:1;109:113;123:6;120:1;117:13;109:113;;;199:11;;;193:18;180:11;;;173:39;145:2;138:10;109:113;;;-1:-1:-1;;256:1:51;238:16;;231:27;14:250::o;269:271::-;311:3;349:5;343:12;376:6;371:3;364:19;392:76;461:6;454:4;449:3;445:14;438:4;431:5;427:16;392:76;:::i;:::-;522:2;501:15;-1:-1:-1;;497:29:51;488:39;;;;529:4;484:50;;269:271;-1:-1:-1;;269:271:51:o;545:220::-;694:2;683:9;676:21;657:4;714:45;755:2;744:9;740:18;732:6;714:45;:::i;770:196::-;838:20;;-1:-1:-1;;;;;887:54:51;;877:65;;867:93;;956:1;953;946:12;867:93;770:196;;;:::o;971:300::-;1039:6;1047;1100:2;1088:9;1079:7;1075:23;1071:32;1068:52;;;1116:1;1113;1106:12;1068:52;1139:29;1158:9;1139:29;:::i;:::-;1129:39;1237:2;1222:18;;;;1209:32;;-1:-1:-1;;;971:300:51:o;1468:186::-;1527:6;1580:2;1568:9;1559:7;1555:23;1551:32;1548:52;;;1596:1;1593;1586:12;1548:52;1619:29;1638:9;1619:29;:::i;1841:374::-;1918:6;1926;1934;1987:2;1975:9;1966:7;1962:23;1958:32;1955:52;;;2003:1;2000;1993:12;1955:52;2026:29;2045:9;2026:29;:::i;:::-;2016:39;;2074:38;2108:2;2097:9;2093:18;2074:38;:::i;:::-;1841:374;;2064:48;;-1:-1:-1;;;2181:2:51;2166:18;;;;2153:32;;1841:374::o;2220:163::-;2287:20;;2347:10;2336:22;;2326:33;;2316:61;;2373:1;2370;2363:12;2388:184;2446:6;2499:2;2487:9;2478:7;2474:23;2470:32;2467:52;;;2515:1;2512;2505:12;2467:52;2538:28;2556:9;2538:28;:::i;2948:626::-;3136:2;3148:21;;;3218:13;;3121:18;;;3240:22;;;3088:4;;3319:15;;;3293:2;3278:18;;;3088:4;3362:186;3376:6;3373:1;3370:13;3362:186;;;3441:13;;3456:10;3437:30;3425:43;;3497:2;3523:15;;;;3488:12;;;;3398:1;3391:9;3362:186;;;-1:-1:-1;3565:3:51;;2948:626;-1:-1:-1;;;;;2948:626:51:o;3579:298::-;3646:6;3654;3707:2;3695:9;3686:7;3682:23;3678:32;3675:52;;;3723:1;3720;3713:12;3675:52;3746:28;3764:9;3746:28;:::i;3882:347::-;3933:8;3943:6;3997:3;3990:4;3982:6;3978:17;3974:27;3964:55;;4015:1;4012;4005:12;3964:55;-1:-1:-1;4038:20:51;;4081:18;4070:30;;4067:50;;;4113:1;4110;4103:12;4067:50;4150:4;4142:6;4138:17;4126:29;;4202:3;4195:4;4186:6;4178;4174:19;4170:30;4167:39;4164:59;;;4219:1;4216;4209:12;4234:791;4339:6;4347;4355;4363;4371;4379;4432:3;4420:9;4411:7;4407:23;4403:33;4400:53;;;4449:1;4446;4439:12;4400:53;4472:28;4490:9;4472:28;:::i;:::-;4462:38;-1:-1:-1;4569:2:51;4554:18;;4541:32;;-1:-1:-1;4670:2:51;4655:18;;4642:32;;-1:-1:-1;4751:2:51;4736:18;;4723:32;4778:18;4767:30;;4764:50;;;4810:1;4807;4800:12;4764:50;4849:58;4899:7;4890:6;4879:9;4875:22;4849:58;:::i;:::-;4926:8;;-1:-1:-1;4823:84:51;-1:-1:-1;4980:39:51;;-1:-1:-1;5014:3:51;4999:19;;4980:39;:::i;:::-;4970:49;;4234:791;;;;;;;;:::o;5030:595::-;5117:6;5125;5133;5141;5194:2;5182:9;5173:7;5169:23;5165:32;5162:52;;;5210:1;5207;5200:12;5162:52;5233:28;5251:9;5233:28;:::i;:::-;5223:38;-1:-1:-1;5330:2:51;5315:18;;5302:32;;-1:-1:-1;5409:2:51;5394:18;;5381:32;5436:18;5425:30;;5422:50;;;5468:1;5465;5458:12;5422:50;5507:58;5557:7;5548:6;5537:9;5533:22;5507:58;:::i;:::-;5030:595;;;;-1:-1:-1;5584:8:51;-1:-1:-1;;;;5030:595:51:o;6058:366::-;6120:8;6130:6;6184:3;6177:4;6169:6;6165:17;6161:27;6151:55;;6202:1;6199;6192:12;6151:55;-1:-1:-1;6225:20:51;;6268:18;6257:30;;6254:50;;;6300:1;6297;6290:12;6254:50;6337:4;6329:6;6325:17;6313:29;;6397:3;6390:4;6380:6;6377:1;6373:14;6365:6;6361:27;6357:38;6354:47;6351:67;;;6414:1;6411;6404:12;6429:435;6514:6;6522;6575:2;6563:9;6554:7;6550:23;6546:32;6543:52;;;6591:1;6588;6581:12;6543:52;6631:9;6618:23;6664:18;6656:6;6653:30;6650:50;;;6696:1;6693;6686:12;6650:50;6735:69;6796:7;6787:6;6776:9;6772:22;6735:69;:::i;:::-;6823:8;;6709:95;;-1:-1:-1;6429:435:51;-1:-1:-1;;;;6429:435:51:o;7126:418::-;7202:6;7210;7218;7271:2;7259:9;7250:7;7246:23;7242:32;7239:52;;;7287:1;7284;7277:12;7239:52;7310:28;7328:9;7310:28;:::i;:::-;7300:38;7407:2;7392:18;;7379:32;;-1:-1:-1;7508:2:51;7493:18;;;7480:32;;7126:418;-1:-1:-1;;;7126:418:51:o;7549:1261::-;7955:3;7950;7946:13;7938:6;7934:26;7923:9;7916:45;7997:3;7992:2;7981:9;7977:18;7970:31;7897:4;8024:46;8065:3;8054:9;8050:19;8042:6;8024:46;:::i;:::-;8118:9;8110:6;8106:22;8101:2;8090:9;8086:18;8079:50;8152:33;8178:6;8170;8152:33;:::i;:::-;8216:2;8201:18;;8194:34;;;-1:-1:-1;;;;;8265:55:51;;8259:3;8244:19;;8237:84;8352:3;8337:19;;8330:35;;;8402:22;;;8396:3;8381:19;;8374:51;8474:13;;8496:22;;;8546:2;8572:15;;;;-1:-1:-1;8534:15:51;;;;-1:-1:-1;8615:169:51;8629:6;8626:1;8623:13;8615:169;;;8690:13;;8678:26;;8733:2;8759:15;;;;8724:12;;;;8651:1;8644:9;8615:169;;;-1:-1:-1;8801:3:51;;7549:1261;-1:-1:-1;;;;;;;;;;;7549:1261:51:o;8815:226::-;8874:6;8927:2;8915:9;8906:7;8902:23;8898:32;8895:52;;;8943:1;8940;8933:12;8895:52;-1:-1:-1;8988:23:51;;8815:226;-1:-1:-1;8815:226:51:o;9247:643::-;9366:6;9374;9427:2;9415:9;9406:7;9402:23;9398:32;9395:52;;;9443:1;9440;9433:12;9395:52;9483:9;9470:23;9516:18;9508:6;9505:30;9502:50;;;9548:1;9545;9538:12;9502:50;9571:22;;9624:4;9616:13;;9612:27;-1:-1:-1;9602:55:51;;9653:1;9650;9643:12;9602:55;9693:2;9680:16;9719:18;9711:6;9708:30;9705:50;;;9751:1;9748;9741:12;9705:50;9804:7;9799:2;9789:6;9786:1;9782:14;9778:2;9774:23;9770:32;9767:45;9764:65;;;9825:1;9822;9815:12;9764:65;9856:2;9848:11;;;;;9878:6;;-1:-1:-1;9247:643:51;-1:-1:-1;;;9247:643:51:o;10198:156::-;10264:20;;10324:4;10313:16;;10303:27;;10293:55;;10344:1;10341;10334:12;10359:733;10461:6;10469;10477;10485;10493;10501;10554:3;10542:9;10533:7;10529:23;10525:33;10522:53;;;10571:1;10568;10561:12;10522:53;10594:29;10613:9;10594:29;:::i;:::-;10584:39;-1:-1:-1;10692:2:51;10677:18;;10664:32;;-1:-1:-1;10793:2:51;10778:18;;10765:32;;-1:-1:-1;10842:36:51;10874:2;10859:18;;10842:36;:::i;:::-;10359:733;;;;-1:-1:-1;10359:733:51;;10951:3;10936:19;;10923:33;;11055:3;11040:19;;;11027:33;;-1:-1:-1;10359:733:51;-1:-1:-1;;10359:733:51:o;11097:808::-;11208:6;11216;11224;11232;11240;11248;11256;11309:3;11297:9;11288:7;11284:23;11280:33;11277:53;;;11326:1;11323;11316:12;11277:53;11349:29;11368:9;11349:29;:::i;:::-;11339:39;;11397:38;11431:2;11420:9;11416:18;11397:38;:::i;:::-;11387:48;-1:-1:-1;11504:2:51;11489:18;;11476:32;;-1:-1:-1;11605:2:51;11590:18;;11577:32;;-1:-1:-1;11654:37:51;11686:3;11671:19;;11654:37;:::i;:::-;11097:808;;;;-1:-1:-1;11097:808:51;;;;11644:47;11764:3;11749:19;;11736:33;;-1:-1:-1;11868:3:51;11853:19;;;11840:33;;11097:808;-1:-1:-1;;11097:808:51:o;12158:127::-;12219:10;12214:3;12210:20;12207:1;12200:31;12250:4;12247:1;12240:15;12274:4;12271:1;12264:15;12290:726;12333:5;12386:3;12379:4;12371:6;12367:17;12363:27;12353:55;;12404:1;12401;12394:12;12353:55;12444:6;12431:20;12474:18;12466:6;12463:30;12460:56;;;12496:18;;:::i;:::-;12545:2;12539:9;12637:2;12599:17;;-1:-1:-1;;12595:31:51;;;12628:2;12591:40;12587:54;12575:67;;12672:18;12657:34;;12693:22;;;12654:62;12651:88;;;12719:18;;:::i;:::-;12755:2;12748:22;12779;;;12820:19;;;12841:4;12816:30;12813:39;-1:-1:-1;12810:59:51;;;12865:1;12862;12855:12;12810:59;12929:6;12922:4;12914:6;12910:17;12903:4;12895:6;12891:17;12878:58;12984:1;12956:19;;;12977:4;12952:30;12945:41;;;;12960:6;12290:726;-1:-1:-1;;;12290:726:51:o;13021:762::-;13136:6;13144;13152;13160;13168;13221:3;13209:9;13200:7;13196:23;13192:33;13189:53;;;13238:1;13235;13228:12;13189:53;13278:9;13265:23;13311:18;13303:6;13300:30;13297:50;;;13343:1;13340;13333:12;13297:50;13366;13408:7;13399:6;13388:9;13384:22;13366:50;:::i;:::-;13356:60;;;13469:2;13458:9;13454:18;13441:32;13498:18;13488:8;13485:32;13482:52;;;13530:1;13527;13520:12;13482:52;13553;13597:7;13586:8;13575:9;13571:24;13553:52;:::i;:::-;13543:62;;;13624:38;13658:2;13647:9;13643:18;13624:38;:::i;:::-;13614:48;;13681:38;13715:2;13704:9;13700:18;13681:38;:::i;:::-;13671:48;;13738:39;13772:3;13761:9;13757:19;13738:39;:::i;:::-;13728:49;;13021:762;;;;;;;;:::o;13788:260::-;13856:6;13864;13917:2;13905:9;13896:7;13892:23;13888:32;13885:52;;;13933:1;13930;13923:12;13885:52;13956:29;13975:9;13956:29;:::i;:::-;13946:39;;14004:38;14038:2;14027:9;14023:18;14004:38;:::i;:::-;13994:48;;13788:260;;;;;:::o;14318:765::-;14439:6;14447;14455;14463;14516:2;14504:9;14495:7;14491:23;14487:32;14484:52;;;14532:1;14529;14522:12;14484:52;14572:9;14559:23;14605:18;14597:6;14594:30;14591:50;;;14637:1;14634;14627:12;14591:50;14676:69;14737:7;14728:6;14717:9;14713:22;14676:69;:::i;:::-;14764:8;;-1:-1:-1;14650:95:51;-1:-1:-1;;14852:2:51;14837:18;;14824:32;14881:18;14868:32;;14865:52;;;14913:1;14910;14903:12;14865:52;14952:71;15015:7;15004:8;14993:9;14989:24;14952:71;:::i;15088:258::-;15155:6;15163;15216:2;15204:9;15195:7;15191:23;15187:32;15184:52;;;15232:1;15229;15222:12;15184:52;15255:29;15274:9;15255:29;:::i;:::-;15245:39;;15303:37;15336:2;15325:9;15321:18;15303:37;:::i;15741:380::-;15820:1;15816:12;;;;15863;;;15884:61;;15938:4;15930:6;15926:17;15916:27;;15884:61;15991:2;15983:6;15980:14;15960:18;15957:38;15954:161;;16037:10;16032:3;16028:20;16025:1;16018:31;16072:4;16069:1;16062:15;16100:4;16097:1;16090:15;16534:127;16595:10;16590:3;16586:20;16583:1;16576:31;16626:4;16623:1;16616:15;16650:4;16647:1;16640:15;16666:125;16731:9;;;16752:10;;;16749:36;;;16765:18;;:::i;18316:127::-;18377:10;18372:3;18368:20;18365:1;18358:31;18408:4;18405:1;18398:15;18432:4;18429:1;18422:15;25816:128;25883:9;;;25904:11;;;25901:37;;;25918:18;;:::i;27960:127::-;28021:10;28016:3;28012:20;28009:1;28002:31;28052:4;28049:1;28042:15;28076:4;28073:1;28066:15;28092:217;28132:1;28158;28148:132;;28202:10;28197:3;28193:20;28190:1;28183:31;28237:4;28234:1;28227:15;28265:4;28262:1;28255:15;28148:132;-1:-1:-1;28294:9:51;;28092:217::o;28731:453::-;28983:33;28978:3;28971:46;28953:3;29046:6;29040:13;29062:75;29130:6;29125:2;29120:3;29116:12;29109:4;29101:6;29097:17;29062:75;:::i;:::-;29157:16;;;;29175:2;29153:25;;28731:453;-1:-1:-1;;28731:453:51:o;29189:331::-;29294:9;29305;29347:8;29335:10;29332:24;29329:44;;;29369:1;29366;29359:12;29329:44;29398:6;29388:8;29385:20;29382:40;;;29418:1;29415;29408:12;29382:40;-1:-1:-1;;29444:23:51;;;29489:25;;;;;-1:-1:-1;29189:331:51:o;29525:255::-;29645:19;;29684:2;29676:11;;29673:101;;;-1:-1:-1;;29745:2:51;29741:12;;;29738:1;29734:20;29730:33;29719:45;29525:255;;;;:::o;30846:127::-;30907:10;30902:3;30898:20;30895:1;30888:31;30938:4;30935:1;30928:15;30962:4;30959:1;30952:15;32220:518;32322:2;32317:3;32314:11;32311:421;;;32358:5;32355:1;32348:16;32402:4;32399:1;32389:18;32472:2;32460:10;32456:19;32453:1;32449:27;32443:4;32439:38;32508:4;32496:10;32493:20;32490:47;;;-1:-1:-1;32531:4:51;32490:47;32586:2;32581:3;32577:12;32574:1;32570:20;32564:4;32560:31;32550:41;;32641:81;32659:2;32652:5;32649:13;32641:81;;;32718:1;32704:16;;32685:1;32674:13;32641:81;;32914:1299;33040:3;33034:10;33067:18;33059:6;33056:30;33053:56;;;33089:18;;:::i;:::-;33118:97;33208:6;33168:38;33200:4;33194:11;33168:38;:::i;:::-;33162:4;33118:97;:::i;:::-;33264:4;33295:2;33284:14;;33312:1;33307:649;;;;34000:1;34017:6;34014:89;;;-1:-1:-1;34069:19:51;;;34063:26;34014:89;-1:-1:-1;;32871:1:51;32867:11;;;32863:24;32859:29;32849:40;32895:1;32891:11;;;32846:57;34116:81;;33277:930;;33307:649;32167:1;32160:14;;;32204:4;32191:18;;-1:-1:-1;;33343:20:51;;;33461:222;33475:7;33472:1;33469:14;33461:222;;;33557:19;;;33551:26;33536:42;;33664:4;33649:20;;;;33617:1;33605:14;;;;33491:12;33461:222;;;33465:3;33711:6;33702:7;33699:19;33696:201;;;33772:19;;;33766:26;-1:-1:-1;;33855:1:51;33851:14;;;33867:3;33847:24;33843:37;33839:42;33824:58;33809:74;;33696:201;-1:-1:-1;;;;33943:1:51;33927:14;;;33923:22;33910:36;;-1:-1:-1;32914:1299:51:o;34218:685::-;34531:10;34523:6;34519:23;34508:9;34501:42;34579:6;34574:2;34563:9;34559:18;34552:34;34622:3;34617:2;34606:9;34602:18;34595:31;34482:4;34649:46;34690:3;34679:9;34675:19;34667:6;34649:46;:::i;:::-;34743:9;34735:6;34731:22;34726:2;34715:9;34711:18;34704:50;34771:33;34797:6;34789;34771:33;:::i;:::-;34763:41;;;-1:-1:-1;;;;;34845:6:51;34841:55;34835:3;34824:9;34820:19;34813:84;34218:685;;;;;;;;:::o;34908:184::-;34978:6;35031:2;35019:9;35010:7;35006:23;35002:32;34999:52;;;35047:1;35044;35037:12;34999:52;-1:-1:-1;35070:16:51;;34908:184;-1:-1:-1;34908:184:51:o;35457:424::-;35672:6;35667:3;35660:19;35709:6;35704:2;35699:3;35695:12;35688:28;35642:3;35745:6;35739:13;35761:73;35827:6;35822:2;35817:3;35813:12;35808:2;35800:6;35796:15;35761:73;:::i;:::-;35854:16;;;;35872:2;35850:25;;35457:424;-1:-1:-1;;;;35457:424:51:o;36483:632::-;36783:5;36778:3;36774:15;36765:6;36760:3;36756:16;36752:38;36747:3;36740:51;36820:6;36816:1;36811:3;36807:11;36800:27;36857:6;36852:2;36847:3;36843:12;36836:28;36919:26;36915:31;36906:6;36902:2;36898:15;36894:53;36889:2;36884:3;36880:12;36873:75;36722:3;36977:6;36971:13;36993:75;37061:6;37056:2;37051:3;37047:12;37040:4;37032:6;37028:17;36993:75;:::i;:::-;37088:16;;;;37106:2;37084:25;;36483:632;-1:-1:-1;;;;;;36483:632:51:o;37120:127::-;37181:10;37176:3;37172:20;37169:1;37162:31;37212:4;37209:1;37202:15;37236:4;37233:1;37226:15
Swarm Source
ipfs://59457c6da227c99c5ce23bb2213bfb1ec033f78595b7e08a626010ac94f869e6
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.