Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
MCLBv2
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: $MCLB ERC-20 in EIP 1822 format * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./Max-20-Burnable-UUPS-LZv2.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./lib/Lists.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; contract MCLBv2 is Initializable , Max20BurnUUPSLZv2 , UUPSUpgradeable { using Lib20 for Lib20.Token; using Safe20 for IERC20; using Lists for Lists.Access; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize( string memory _name , string memory _symbol , address _admin , address _dev , address _owner ) initializer public { __Max20_init(_name, _symbol, 18, _admin, _dev, _owner); __UUPSUpgradeable_init(); } function _authorizeUpgrade(address newImplementation) internal onlyRole(ADMIN) override {} function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { if (denyList[_to] || denyList[msg.sender]) { revert MaxSplaining({ reason: "Max20: blacklisted" }); } uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { if (denyList[_to] || denyList[_from]) { revert MaxSplaining({ reason: "Max20: blacklisted" }); } uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: insufficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @notice This function transfers the ft from your address on the /// source chain to the same address on the destination chain /// @param _chainId: the uint16 of desination chain (see LZ docs) /// @param _amount: amount to be sent function traverseChains( uint16 _chainId , uint256 _amount ) public virtual payable { if (denyList[msg.sender]) { revert MaxSplaining({ reason: "Max20: blacklisted" }); } uint256 userBal = token20.getBalanceOf(msg.sender); if (_amount > userBal) { revert Unauthorized(); } if (trustedRemoteLookup[_chainId].length == 0) { revert MaxSplaining({ reason: "Token: TR not set" }); } // burn FT, eliminating it from circulation on src chain token20.burn(msg.sender, _amount); emit Transfer(address(0), msg.sender, _amount); // abi.encode() the payload with the values to send bytes memory payload = abi.encode( msg.sender , _amount); // encode adapterParams to specify more gas for the destination uint16 version = 1; bytes memory adapterParams = abi.encodePacked( version , gasForDestinationLzReceive); // get the fees we need to pay to LayerZero + Relayer to cover message delivery // you will be refunded for extra gas paid (uint messageFee, ) = endpoint.estimateFees( _chainId , address(this) , payload , false , adapterParams); // revert this transaction if the fees are not met if (messageFee > msg.value) { revert MaxSplaining({ reason: "Token: message fee low" }); } // send the transaction to the endpoint endpoint.send{value: msg.value}( _chainId, // destination chainId trustedRemoteLookup[_chainId], // destination address of nft contract payload, // abi.encoded()'ed bytes payable(msg.sender), // refund address address(0x0), // 'zroPaymentAddress' unused for this adapterParams // txParameters ); } // @notice just in case this fixed variable limits us from future integrations // @param newVal: new value for gas amount function setGasForDestinationLzReceive( uint newVal ) external onlyDev() { gasForDestinationLzReceive = newVal; } /// @notice internal function to mint FT from migration /// @param _srcChainId - the source endpoint identifier /// @param _srcAddress - the source sending contract address from the source chain /// @param _nonce - the ordered message nonce /// @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) override internal { // decode (address toAddr, uint256 amount) = abi.decode(_payload, (address, uint256)); // mint the tokens back into existence on destination chain token20.mint(toAddr, amount); emit Transfer(address(0), toAddr, amount); } // @notice will return gas value for LZ // @return: uint for gas value function currentLZGas() external view returns (uint256) { return gasForDestinationLzReceive; } }
// 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 IERC1822ProxiableUpgradeable { /** * @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.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.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._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // 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 Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.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) { _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 (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(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 Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.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"); StorageSlotUpgradeable.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 Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.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) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @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) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @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 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @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/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] * ``` * 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. Equivalent to `reinitializer(1)`. */ 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. * * `initializer` is equivalent to `reinitializer(1)`, so 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. * * 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. */ 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. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * 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. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) 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[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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.7.0) (utils/StorageSlot.sol) 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: * ``` * 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`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 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 } } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZv2 is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin , address _dev , address _owner ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _dev); contractRoles.setDeveloper(_dev); contractRoles.add(OWNERS, _owner); contractRoles.setOwner(_owner); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { return token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal { revert MaxSplaining({ reason: "Max20: not enabled" }); } // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } mapping(address => bool) public denyList; event DenyEntry(address _user, bool _status); function addDeny( address _new ) external onlyDev() { denyList[_new] = true; emit DenyEntry(_new, true); } function removeDeny( address _new ) external onlyDev() { denyList[_new] = false; emit DenyEntry(_new, false); } function addDenyBatch( address[] memory newAddresses ) external virtual onlyDev() { uint len = newAddresses.length; for (uint i = 0; i < len;) { denyList[newAddresses[i]] = true; emit DenyEntry(newAddresses[i], true); unchecked { ++i; } } } function removeDenyBatch( address[] memory newAddresses ) external virtual onlyDev() { uint len = newAddresses.length; for (uint i = 0; i < len;) { denyList[newAddresses[i]] = false; emit DenyEntry(newAddresses[i], false); unchecked { ++i; } } } uint256[38] private __gap; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @notice Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @notice The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard, extension * @author: Unknown * @notice n/a * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external returns (bool success); /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: CountersV2.sol * @author Matt Condon (@shrugs) rewritten by Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice Provides counters that can only be incremented, decremented, reset or set. * This can be used e.g. to track the number of elements in a mapping, issuing ERC721 ids * or counting request ids. * * Edited by @MaxFlowO2 for more NFT functionality on 13 Jan 2022 * added .set(uint) so if projects need to start at say 1 or some random number they can * and an event log for numbers being reset or set. * * Include with `using CountersV2 for CountersV2.Counter;` */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library CountersV2 { // @dev: this is MaxSplaining(), giving you a reason, aka require(param, "reason") // @param reason: Use the "Contract name: error" // @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); event CounterNumberChangedTo(uint _number); 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; } } function decrement( Counter storage counter ) internal { uint256 value = counter._value; if (value == 0) { revert MaxSplaining({ reason : "CV2:1" }); } unchecked { --counter._value; } } function reset( Counter storage counter ) internal { counter._value = 0; emit CounterNumberChangedTo(counter._value); } function set( Counter storage counter , uint number ) internal { counter._value = number; emit CounterNumberChangedTo(counter._value); } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Access lists * @author: @MaxFlowO2 on bird app/GitHub * @notice Formerly whitelists, now allowlist, or whatever it's called. * @custom:change-log removed end variable/functions (un-needed) * @custom:change-log variables renamed from lib whitelist * @custom:change-log internal -> internal * @custom:error-code Lists:1 "(user) is already whitelisted." * @custom:error-code Lists:2 "(user) is not whitelisted." * @custom:error-code Lists:3 "Whitelist already enabled." * @custom:error-code Lists:4 "Whitelist already disabled." * @custom:change-log added custom error codes * @custom:change-log removed import "./Strings.sol"; (un-needed) * * Include with 'using Lists for Lists.Access;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./CountersV2.sol"; library Lists { using CountersV2 for CountersV2.Counter; event ListChanged(bool _old, bool _new, address _address); event ListStatus(bool _old, bool _new); error MaxSplaining(string reason); struct Access { bool _status; CountersV2.Counter added; CountersV2.Counter removed; mapping(address => bool) allowed; } function add( Access storage list , address user ) internal { if (list.allowed[user]) { revert MaxSplaining({ reason : "Lists:1" }); } // since now all previous values are false no need for another variable // and add them to the list! list.allowed[user] = true; // increment counter list.added.increment(); // emit event emit ListChanged(false, list.allowed[user], user); } function remove( Access storage list , address user ) internal { if (!list.allowed[user]) { revert MaxSplaining({ reason : "Lists:2" }); } // since now all previous values are true no need for another variable // and remove them from the list! list.allowed[user] = false; // increment counter list.removed.increment(); // emit event emit ListChanged(true, list.allowed[user], user); } function enable( Access storage list ) internal { if (list._status) { revert MaxSplaining({ reason : "Lists:3" }); } list._status = true; emit ListStatus(false, list._status); } function disable( Access storage list ) internal { if (!list._status) { revert MaxSplaining({ reason : "Lists:4" }); } list._status = false; emit ListStatus(true, list._status); } function status( Access storage list ) internal view returns (bool) { return list._status; } function totalAdded( Access storage list ) internal view returns (uint) { return list.added.current(); } function totalRemoved( Access storage list ) internal view returns (uint) { return list.removed.current(); } function onList( Access storage list , address user ) internal view returns (bool) { return list.allowed[user]; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @notice Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 10000 }, "evmVersion": "london", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"uint256","name":"yourTime","type":"uint256"},{"internalType":"uint256","name":"hitTime","type":"uint256"}],"name":"TooLateBoomer","type":"error"},{"inputs":[{"internalType":"uint256","name":"yourTime","type":"uint256"},{"internalType":"uint256","name":"hitTime","type":"uint256"}],"name":"TooSoonJunior","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"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":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_user","type":"address"},{"indexed":false,"internalType":"bool","name":"_status","type":"bool"}],"name":"DenyEntry","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_endpoint","type":"address"}],"name":"EndpointSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"MessageFailed","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":"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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_chainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_trustedRemote","type":"bytes"}],"name":"TrustedRemoteSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"acceptDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"addDeny","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"newAddresses","type":"address[]"}],"name":"addDenyBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"remaining","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"burn","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"burnFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentLZGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"declineDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"declineOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"denyList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"developer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"failedMessages","outputs":[{"internalType":"uint256","name":"payloadLength","type":"uint256"},{"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_dev","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"onLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newDeveloper","type":"address"}],"name":"pushDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"pushOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_new","type":"address"}],"name":"removeDeny","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"newAddresses","type":"address[]"}],"name":"removeDenyBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newEndpoint","type":"address"}],"name":"setEndPoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVal","type":"uint256"}],"name":"setGasForDestinationLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"bytes","name":"_trustedRemote","type":"bytes"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"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":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDeveloper","type":"address"}],"name":"transferDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"traverseChains","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161496762000120600039600081816114a90152818161153f0152818161184b015281816118e101526119dc01526149676000f3fe6080604052600436106103125760003560e01c806366278a6c1161019a578063a9059cbb116100e1578063d39ce77c1161008a578063de02cde711610064578063de02cde7146108ea578063eb8d72b71461090a578063f2fde38b1461092a57600080fd5b8063d39ce77c1461088a578063db0ed6a0146108aa578063dd62ed3e146108ca57600080fd5b8063cb40cb49116100bb578063cb40cb4914610844578063cf89fa0314610864578063d1deba1f1461087757600080fd5b8063a9059cbb146107f1578063ad6d9c1714610811578063ca4b208b1461082657600080fd5b80638da5cb5b1161014357806395d89b411161011d57806395d89b41146107a75780639c0ae0a2146107bc578063a86ff960146107dc57600080fd5b80638da5cb5b146106ea5780638ee749121461071c578063943fb8721461078757600080fd5b80637533d788116101745780637533d7881461069557806379ba5097146106b557806379cc6790146106ca57600080fd5b806366278a6c1461064057806370a0823114610660578063715018a61461068057600080fd5b806331e26cfd1161025e5780634f1ef286116102075780635d7875d4116101e15780635d7875d4146105e05780636149d8711461060057806364cb4edb1461062057600080fd5b80634f1ef2861461056057806352d1902d146105735780635ba5e9f01461058857600080fd5b806342966c681161023857806342966c681461050b57806344faded01461052b578063475de12e1461054b57600080fd5b806331e26cfd146104a65780633659cfe6146104bb57806340682152146104db57600080fd5b80631c37a822116102c05780632bfcf0f21161029a5780632bfcf0f21461044f5780632fb623c514610464578063313ce5671461048457600080fd5b80631c37a822146103ef57806323b872dd1461040f5780632ab0b0a41461042f57600080fd5b8063095ea7b3116102f1578063095ea7b31461039057806310ab9432146103b057806318160ddd146103d057600080fd5b80621d35671461031757806301ffc9a71461033957806306fdde031461036e575b600080fd5b34801561032357600080fd5b50610337610332366004613d59565b61094a565b005b34801561034557600080fd5b50610359610354366004613e0e565b610b88565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610d51565b6040516103659190613e79565b34801561039c57600080fd5b506103596103ab366004613ea1565b610d62565b3480156103bc57600080fd5b506103596103cb366004613ecd565b610dc4565b3480156103dc57600080fd5b506003545b604051908152602001610365565b3480156103fb57600080fd5b5061033761040a366004613d59565b610dd9565b34801561041b57600080fd5b5061035961042a366004613f04565b610e35565b34801561043b57600080fd5b5061033761044a366004613f45565b6111f2565b34801561045b57600080fd5b50610337611319565b34801561047057600080fd5b5061033761047f366004613ff7565b6113ae565b34801561049057600080fd5b5060045460405160ff9091168152602001610365565b3480156104b257600080fd5b50610337611428565b3480156104c757600080fd5b506103376104d6366004613ff7565b61149f565b3480156104e757600080fd5b506103596104f6366004613ff7565b600f6020526000908152604090205460ff1681565b34801561051757600080fd5b50610359610526366004614014565b611639565b34801561053757600080fd5b50610337610546366004613ecd565b611758565b34801561055757600080fd5b50600e546103e1565b61033761056e36600461402d565b611841565b34801561057f57600080fd5b506103e16119cf565b34801561059457600080fd5b506105af6105a3366004613e0e565b506303e1469160e61b90565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610365565b3480156105ec57600080fd5b506103376105fb366004613f45565b611a94565b34801561060c57600080fd5b5061033761061b366004613ff7565b611b81565b34801561062c57600080fd5b5061033761063b366004613ff7565b611bdf565b34801561064c57600080fd5b5061033761065b366004613e0e565b611c42565b34801561066c57600080fd5b506103e161067b366004613ff7565b611c79565b34801561068c57600080fd5b50610337611c97565b3480156106a157600080fd5b506103836106b036600461407d565b611d1a565b3480156106c157600080fd5b50610337611db4565b3480156106d657600080fd5b506103596106e5366004613ea1565b611e62565b3480156106f657600080fd5b506008546001600160a01b03165b6040516001600160a01b039091168152602001610365565b34801561072857600080fd5b50610772610737366004614098565b600c60209081526000938452604080852084518086018401805192815290840195840195909520945292905282529020805460019091015482565b60408051928352602083019190915201610365565b34801561079357600080fd5b506103376107a2366004614014565b612146565b3480156107b357600080fd5b50610383612163565b3480156107c857600080fd5b506103376107d7366004613ff7565b61216f565b3480156107e857600080fd5b506103376121de565b3480156107fd57600080fd5b5061035961080c366004613ea1565b612255565b34801561081d57600080fd5b50610337612461565b34801561083257600080fd5b506009546001600160a01b0316610704565b34801561085057600080fd5b5061033761085f366004613ff7565b6124b2565b6103376108723660046140ef565b61252c565b610337610885366004614154565b612876565b34801561089657600080fd5b506103376108a5366004613ff7565b612a12565b3480156108b657600080fd5b506103376108c53660046141e0565b612a89565b3480156108d657600080fd5b506103e16108e536600461427e565b612bf7565b3480156108f657600080fd5b50610337610905366004613ecd565b612c24565b34801561091657600080fd5b5061033761092536600461429c565b612d23565b34801561093657600080fd5b50610337610945366004613ff7565b612d9a565b600b546001600160a01b031633146109aa57604051630330dbc960e11b815260206004820152600560248201527f4e42523a3100000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61ffff84166000908152600d6020526040902080546109c8906142ef565b90508351141580610a08575061ffff84166000908152600d60205260409081902090516109f5919061433c565b6040518091039020838051906020012014155b15610a5657604051630330dbc960e11b815260206004820152600560248201527f4e42523a3200000000000000000000000000000000000000000000000000000060448201526064016109a1565b6040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a82290610a989087908790879087906004016143b2565b600060405180830381600087803b158015610ab257600080fd5b505af1925050508015610ac3575060015b610b82576040518060400160405280825181526020018280519060200120815250600c60008661ffff1661ffff16815260200190815260200160002084604051610b0d91906143fc565b90815260408051918290036020908101832067ffffffffffffffff8716600090815290825291909120835181559201516001909201919091557fe6f254030bcb01ffd20558175c13fcaed6d1520be7becee4c961b65f79243b0d90610b799086908690869086906143b2565b60405180910390a15b50505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7f5828d0000000000000000000000000000000000000000000000000000000001480610c1b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f7319562d00000000000000000000000000000000000000000000000000000000145b80610c6757507fffffffff0000000000000000000000000000000000000000000000000000000082167f78bab63900000000000000000000000000000000000000000000000000000000145b80610cb357507fffffffff0000000000000000000000000000000000000000000000000000000082167fb7d1e49900000000000000000000000000000000000000000000000000000000145b80610cff57507fffffffff0000000000000000000000000000000000000000000000000000000082167f3b5a0bf800000000000000000000000000000000000000000000000000000000145b80610d4b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f942e8b2200000000000000000000000000000000000000000000000000000000145b92915050565b6060610d5d6001612e48565b905090565b3360008181526002602090815260408083206001600160a01b0387168085529083529281902085905551848152600193917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a392915050565b6000610dd260078484612ede565b9392505050565b333014610e2957604051630330dbc960e11b815260206004820152600560248201527f4e42523a3300000000000000000000000000000000000000000000000000000060448201526064016109a1565b610b8284848484612f6d565b6001600160a01b0382166000908152600f602052604081205460ff1680610e7457506001600160a01b0384166000908152600f602052604090205460ff165b15610ec257604051630330dbc960e11b815260206004820152601260248201527f4d617832303a20626c61636b6c6973746564000000000000000000000000000060448201526064016109a1565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260009030906370a0823190602401602060405180830381865afa158015610f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f469190614418565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b0387166004820152336024820152909150600090309063dd62ed3e90604401602060405180830381865afa158015610faf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd39190614418565b90506001600160a01b0386161580610ff257506001600160a01b038516155b1561104057604051630330dbc960e11b815260206004820152601960248201527f4d617832303a20746f2f66726f6d20616464726573732830290000000000000060448201526064016109a1565b8184111561109157604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016109a1565b8084111561110857604051630330dbc960e11b815260206004820152602360248201527f4d617832303a206e6f7420617070726f76656420746f207370656e64205f766160448201527f6c7565000000000000000000000000000000000000000000000000000000000060648201526084016109a1565b6111156001878787612fde565b9250846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8660405161115c91815260200190565b60405180910390a36111a186336111738785614460565b6001600160a01b03928316600090815260026020908152604080832095909416825293909352912055600190565b50336001600160a01b0387167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256111d88785614460565b60405190815260200160405180910390a350509392505050565b611205600763ca4b208b60e01b33612ede565b156112e457805160005b818110156112df576000600f600085848151811061122f5761122f614473565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055507f0f67744da620d6c14d9467e3c6548012659cce57a9ab6e1711b8b0857de20a2c8382815181106112a1576112a1614473565b602002602001015160006040516112cf9291906001600160a01b039290921682521515602082015260400190565b60405180910390a160010161120f565b505050565b6040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b7fca4b208a0000000000000000000000000000000000000000000000000000000061134660078233612ede565b8061135f575061135f60076303e1469160e61b33612ede565b156112e457611377600763ca4b208b60e01b33613081565b6113826007336131ab565b61131660077fca4b208a00000000000000000000000000000000000000000000000000000000336132aa565b6113c1600763ca4b208b60e01b33612ede565b156112e4576001600160a01b0381166000818152600f6020908152604091829020805460ff191660019081179091558251938452908301527f0f67744da620d6c14d9467e3c6548012659cce57a9ab6e1711b8b0857de20a2c91015b60405180910390a150565b7fca4b208a0000000000000000000000000000000000000000000000000000000061145560078233612ede565b8061146e575061146e60076303e1469160e61b33612ede565b156112e45761131660077fca4b208a00000000000000000000000000000000000000000000000000000000336132aa565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361153d5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084016109a1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166115987f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146116145760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f7879000000000000000000000000000000000000000060648201526084016109a1565b61161d816133c9565b604080516000808252602082019092526113169183919061342c565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819030906370a0823190602401602060405180830381865afa158015611692573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b69190614418565b90508083111561170957604051630330dbc960e11b815260206004820152601b60248201527f4d617832303a20696e73756666696369656e742062616c616e6365000000000060448201526064016109a1565b611715600133856135cc565b6040518381526001925060009033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35b50919050565b8161176560078233612ede565b8061177e575061177e60076303e1469160e61b33612ede565b156112e4577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a00000000000000000000000000000000000000000000000000000000148061181457507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b1561183557336001600160a01b038316036112e4576112df600784846132aa565b6112df600784846132aa565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036118df5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084016109a1565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661193a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146119b65760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f7879000000000000000000000000000000000000000060648201526084016109a1565b6119bf826133c9565b6119cb8282600161342c565b5050565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a6f5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016109a1565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b611aa7600763ca4b208b60e01b33612ede565b156112e457805160005b818110156112df576001600f6000858481518110611ad157611ad1614473565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055507f0f67744da620d6c14d9467e3c6548012659cce57a9ab6e1711b8b0857de20a2c838281518110611b4357611b43614473565b60200260200101516001604051611b719291906001600160a01b039290921682521515602082015260400190565b60405180910390a1600101611ab1565b63ca4b208b60e01b611b9560078233612ede565b80611bae5750611bae60076303e1469160e61b33612ede565b156112e4576119cb60077fca4b208a0000000000000000000000000000000000000000000000000000000084613081565b63ca4b208b60e01b611bf360078233612ede565b80611c0c5750611c0c60076303e1469160e61b33612ede565b156112e457611c24600763ca4b208b60e01b84613081565b611c2f6007836131ab565b6119cb600763ca4b208b60e01b336132aa565b80611c4f60078233612ede565b80611c685750611c6860076303e1469160e61b33612ede565b156112e4576119cb600783336132aa565b6001600160a01b038116600090815260016020526040812054610d4b565b7f8da5cb5b00000000000000000000000000000000000000000000000000000000611cc460078233612ede565b80611cdd5750611cdd60076303e1469160e61b33612ede565b156112e457611cee60076000613665565b61131660077f8da5cb5b00000000000000000000000000000000000000000000000000000000336132aa565b600d6020526000908152604090208054611d33906142ef565b80601f0160208091040260200160405190810160405280929190818152602001828054611d5f906142ef565b8015611dac5780601f10611d8157610100808354040283529160200191611dac565b820191906000526020600020905b815481529060010190602001808311611d8f57829003601f168201915b505050505081565b7f8da5cb5a00000000000000000000000000000000000000000000000000000000611de160078233612ede565b80611dfa5750611dfa60076303e1469160e61b33612ede565b156112e457611e2b60077f8da5cb5b0000000000000000000000000000000000000000000000000000000033613081565b611e36600733613665565b61131660077f8da5cb5a00000000000000000000000000000000000000000000000000000000336132aa565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152600090819030906370a0823190602401602060405180830381865afa158015611ec4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee89190614418565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152336024820152909150600090309063dd62ed3e90604401602060405180830381865afa158015611f51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f759190614418565b90506001600160a01b038516611fce57604051630330dbc960e11b815260206004820152601660248201527f4d617832303a2066726f6d20616464726573732830290000000000000000000060448201526064016109a1565b8184111561201f57604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016109a1565b8084111561209657604051630330dbc960e11b815260206004820152602360248201527f4d617832303a206e6f7420617070726f76656420746f207370656e64205f766160448201527f6c7565000000000000000000000000000000000000000000000000000000000060648201526084016109a1565b6120a2600186866135cc565b604051848152600193506000906001600160a01b038716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a36120f685336111738785614460565b50336001600160a01b0386167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92561212d8785614460565b60405190815260200160405180910390a3505092915050565b612159600763ca4b208b60e01b33612ede565b156112e457600e55565b6060610d5d6001613702565b612182600763ca4b208b60e01b33612ede565b156112e4576001600160a01b0381166000818152600f60209081526040808320805460ff191690558051938452908301919091527f0f67744da620d6c14d9467e3c6548012659cce57a9ab6e1711b8b0857de20a2c910161141d565b7f8da5cb5a0000000000000000000000000000000000000000000000000000000061220b60078233612ede565b80612224575061222460076303e1469160e61b33612ede565b156112e45761131660077f8da5cb5a00000000000000000000000000000000000000000000000000000000336132aa565b6001600160a01b0382166000908152600f602052604081205460ff168061228b5750336000908152600f602052604090205460ff165b156122d957604051630330dbc960e11b815260206004820152601260248201527f4d617832303a20626c61636b6c6973746564000000000000000000000000000060448201526064016109a1565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015260009030906370a0823190602401602060405180830381865afa158015612330573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123549190614418565b90506001600160a01b0384166123ad57604051630330dbc960e11b815260206004820152601460248201527f4d617832303a20746f206164647265737328302900000000000000000000000060448201526064016109a1565b808311156123fe57604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016109a1565b61240b6001338686612fde565b9150836001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161245291815260200190565b60405180910390a35092915050565b63ca4b208b60e01b61247560078233612ede565b8061248e575061248e60076303e1469160e61b33612ede565b156112e45761249f600760006131ab565b611316600763ca4b208b60e01b336132aa565b6124c5600763ca4b208b60e01b33612ede565b156112e457600b80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f87bf030d6c6aa55db1e81d52f84962fc04ce1d477e64e50d57d3a91c52296f9390600090a250565b336000908152600f602052604090205460ff161561258d57604051630330dbc960e11b815260206004820152601260248201527f4d617832303a20626c61636b6c6973746564000000000000000000000000000060448201526064016109a1565b33600090815260016020526040902054808211156125d7576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61ffff83166000908152600d6020526040902080546125f5906142ef565b905060000361264757604051630330dbc960e11b815260206004820152601160248201527f546f6b656e3a205452206e6f742073657400000000000000000000000000000060448201526064016109a1565b612653600133846135cc565b60405182815233906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a360408051336020820152808201849052815180820383018152606082018352600e547e0100000000000000000000000000000000000000000000000000000000000060808401526082808401919091528351808403909101815260a2830193849052600b547f40a7bb100000000000000000000000000000000000000000000000000000000090945290926001926000916001600160a01b0316906340a7bb1090612742908a90309089908790899060a6016144a2565b6040805180830381865afa15801561275e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278291906144e8565b509050348111156127d657604051630330dbc960e11b815260206004820152601660248201527f546f6b656e3a206d65737361676520666565206c6f770000000000000000000060448201526064016109a1565b600b5461ffff88166000908152600d602052604080822090517fc58031000000000000000000000000000000000000000000000000000000000081526001600160a01b039093169263c580310092349261283b928d928b913391908b9060040161450c565b6000604051808303818588803b15801561285457600080fd5b505af1158015612868573d6000803e3d6000fd5b505050505050505050505050565b61ffff85166000908152600c602052604080822090516128979087906143fc565b908152604080516020928190038301902067ffffffffffffffff8716600090815292529020600181015490915061291157604051630330dbc960e11b815260206004820152600560248201527f4e42523a3400000000000000000000000000000000000000000000000000000060448201526064016109a1565b80548214158061293c5750806001015483836040516129319291906145f1565b604051809103902014155b1561298a57604051630330dbc960e11b815260206004820152600560248201527f4e42523a3500000000000000000000000000000000000000000000000000000060448201526064016109a1565b600080825560018201556040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a822906129d8908990899089908990899060040161462c565b600060405180830381600087803b1580156129f257600080fd5b505af1158015612a06573d6000803e3d6000fd5b50505050505050505050565b7f8da5cb5b00000000000000000000000000000000000000000000000000000000612a3f60078233612ede565b80612a585750612a5860076303e1469160e61b33612ede565b156112e4576119cb60077f8da5cb5a0000000000000000000000000000000000000000000000000000000084613081565b600054610100900460ff1615808015612aa95750600054600160ff909116105b80612ac35750303b158015612ac3575060005460ff166001145b612b355760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016109a1565b6000805460ff191660011790558015612b7557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b612b8486866012878787613713565b612b8c613828565b8015612bef57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6001600160a01b038083166000908152600260209081526040808320938516835292905290812054610dd2565b81612c3160078233612ede565b80612c4a5750612c4a60076303e1469160e61b33612ede565b156112e4577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a000000000000000000000000000000000000000000000000000000001480612ce057507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b15612d17576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112df60078484613081565b612d36600763ca4b208b60e01b33612ede565b156112e45761ffff83166000908152600d60205260409020612d598284836146b2565b507f93c35c217d799290d33244ef8905b63167d13758ab18343cd8055ed1b8056748838383604051612d8d939291906147af565b60405180910390a1505050565b7f8da5cb5b00000000000000000000000000000000000000000000000000000000612dc760078233612ede565b80612de05750612de060076303e1469160e61b33612ede565b156112e457612e1160077f8da5cb5b0000000000000000000000000000000000000000000000000000000084613081565b612e1c600783613665565b6119cb60077f8da5cb5b00000000000000000000000000000000000000000000000000000000336132aa565b6060816004018054612e59906142ef565b80601f0160208091040260200160405190810160405280929190818152602001828054612e85906142ef565b8015612ed25780601f10612ea757610100808354040283529160200191612ed2565b820191906000526020600020905b815481529060010190602001808311612eb557829003601f168201915b50505050509050919050565b60006001600160a01b038216612f20576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082207fffffffff000000000000000000000000000000000000000000000000000000009390931682529190925290205460ff1690565b60008082806020019051810190612f8491906147cd565b9092509050612f95600183836138a7565b6040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050505050565b6001600160a01b0383166000908152602085905260408120548083111561304857604051630330dbc960e11b815260206004820152600760248201527f4d617832303a310000000000000000000000000000000000000000000000000060448201526064016109a1565b50506001600160a01b03808416600090815260208690526040808220805485900390559184168152208054820190556001949350505050565b6001600160a01b0381166130c1576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130cc838383612ede565b1561311a57604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a310000000000000000000000000000000000000000000000000060448201526064016109a1565b6001600160a01b0381166000818152602085815260408083207fffffffff00000000000000000000000000000000000000000000000000000000871680855290835292819020805460ff19166001908117909155815193845291830193909352918101919091527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f790606001612d8d565b6131bd8263ca4b208b60e01b83612ede565b1561322f576002820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f2cfca82ac51c2fc6b6db547820d28d526a505e12d230afb8bf112a5aeefa9a4c90600090a3505050565b6001600160a01b0381166112e4576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6001600160a01b0381166132ea576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6132f5838383612ede565b61334257604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a320000000000000000000000000000000000000000000000000060448201526064016109a1565b6001600160a01b0381166000818152602085815260408083207fffffffff000000000000000000000000000000000000000000000000000000008716808552908352818420805460ff19169055815190815291820193909352918201527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f790606001612d8d565b6303e1469160e61b6133dd60078233612ede565b806133f657506133f660076303e1469160e61b33612ede565b6119cb576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561345f576112df8361393b565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156134b9575060408051601f3d908101601f191682019092526134b691810190614418565b60015b61352b5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f74205555505300000000000000000000000000000000000060648201526084016109a1565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81146135c05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c6555554944000000000000000000000000000000000000000000000060648201526084016109a1565b506112df838383613a11565b6001600160a01b0382166000908152602084905260409020548082111561363657604051630330dbc960e11b815260206004820152600760248201527f4d617832303a310000000000000000000000000000000000000000000000000060448201526064016109a1565b6001600160a01b0390921660009081526020849052604090209181900390915560029091018054919091039055565b613690827f8da5cb5b0000000000000000000000000000000000000000000000000000000083612ede565b1561322f576001820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6060816005018054612e59906142ef565b600054610100900460ff166137905760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a1565b61379b600187613a36565b6137a6600186613a44565b6004805460ff191660ff86161790556137c860076303e1469160e61b85613081565b6137d3600784613a52565b6137e6600763ca4b208b60e01b84613081565b6137f16007836131ab565b61381d60077f8da5cb5b0000000000000000000000000000000000000000000000000000000083613081565b612bef600782613665565b600054610100900460ff166138a55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a1565b565b6001600160a01b0382166138fe57604051630330dbc960e11b815260206004820152600760248201527f4d617832303a320000000000000000000000000000000000000000000000000060448201526064016109a1565b8083600201600082825461391291906147fb565b90915550506001600160a01b039091166000908152602092909252604090912080549091019055565b6001600160a01b0381163b6139b85760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016109a1565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b613a1a83613ad6565b600082511180613a275750805b156112df57610b828383613b16565b600482016112df828261480e565b600582016112df828261480e565b613a64826303e1469160e61b83612ede565b1561322f576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b613adf8161393b565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613b955760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016109a1565b600080846001600160a01b031684604051613bb091906143fc565b600060405180830381855af49150503d8060008114613beb576040519150601f19603f3d011682016040523d82523d6000602084013e613bf0565b606091505b5091509150613c18828260405180606001604052806027815260200161490b60279139613c21565b95945050505050565b60608315613c30575081610dd2565b825115613c405782518084602001fd5b8160405162461bcd60e51b81526004016109a19190613e79565b803561ffff81168114613c6c57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613cc957613cc9613c71565b604052919050565b600082601f830112613ce257600080fd5b813567ffffffffffffffff811115613cfc57613cfc613c71565b613d0f6020601f19601f84011601613ca0565b818152846020838601011115613d2457600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff81168114613c6c57600080fd5b60008060008060808587031215613d6f57600080fd5b613d7885613c5a565b9350602085013567ffffffffffffffff80821115613d9557600080fd5b613da188838901613cd1565b9450613daf60408801613d41565b93506060870135915080821115613dc557600080fd5b50613dd287828801613cd1565b91505092959194509250565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114613c6c57600080fd5b600060208284031215613e2057600080fd5b610dd282613dde565b60005b83811015613e44578181015183820152602001613e2c565b50506000910152565b60008151808452613e65816020860160208601613e29565b601f01601f19169290920160200192915050565b602081526000610dd26020830184613e4d565b6001600160a01b038116811461131657600080fd5b60008060408385031215613eb457600080fd5b8235613ebf81613e8c565b946020939093013593505050565b60008060408385031215613ee057600080fd5b613ee983613dde565b91506020830135613ef981613e8c565b809150509250929050565b600080600060608486031215613f1957600080fd5b8335613f2481613e8c565b92506020840135613f3481613e8c565b929592945050506040919091013590565b60006020808385031215613f5857600080fd5b823567ffffffffffffffff80821115613f7057600080fd5b818501915085601f830112613f8457600080fd5b813581811115613f9657613f96613c71565b8060051b9150613fa7848301613ca0565b8181529183018401918481019088841115613fc157600080fd5b938501935b83851015613feb5784359250613fdb83613e8c565b8282529385019390850190613fc6565b98975050505050505050565b60006020828403121561400957600080fd5b8135610dd281613e8c565b60006020828403121561402657600080fd5b5035919050565b6000806040838503121561404057600080fd5b823561404b81613e8c565b9150602083013567ffffffffffffffff81111561406757600080fd5b61407385828601613cd1565b9150509250929050565b60006020828403121561408f57600080fd5b610dd282613c5a565b6000806000606084860312156140ad57600080fd5b6140b684613c5a565b9250602084013567ffffffffffffffff8111156140d257600080fd5b6140de86828701613cd1565b925050604084013590509250925092565b6000806040838503121561410257600080fd5b613ebf83613c5a565b60008083601f84011261411d57600080fd5b50813567ffffffffffffffff81111561413557600080fd5b60208301915083602082850101111561414d57600080fd5b9250929050565b60008060008060006080868803121561416c57600080fd5b61417586613c5a565b9450602086013567ffffffffffffffff8082111561419257600080fd5b61419e89838a01613cd1565b95506141ac60408901613d41565b945060608801359150808211156141c257600080fd5b506141cf8882890161410b565b969995985093965092949392505050565b600080600080600060a086880312156141f857600080fd5b853567ffffffffffffffff8082111561421057600080fd5b61421c89838a01613cd1565b9650602088013591508082111561423257600080fd5b5061423f88828901613cd1565b945050604086013561425081613e8c565b9250606086013561426081613e8c565b9150608086013561427081613e8c565b809150509295509295909350565b6000806040838503121561429157600080fd5b8235613ee981613e8c565b6000806000604084860312156142b157600080fd5b6142ba84613c5a565b9250602084013567ffffffffffffffff8111156142d657600080fd5b6142e28682870161410b565b9497909650939450505050565b600181811c9082168061430357607f821691505b602082108103611752577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080835461434a816142ef565b600182811680156143625760018114614377576143a6565b60ff19841687528215158302870194506143a6565b8760005260208060002060005b8581101561439d5781548a820152908401908201614384565b50505082870194505b50929695505050505050565b61ffff851681526080602082015260006143cf6080830186613e4d565b67ffffffffffffffff8516604084015282810360608401526143f18185613e4d565b979650505050505050565b6000825161440e818460208701613e29565b9190910192915050565b60006020828403121561442a57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d4b57610d4b614431565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff861681526001600160a01b038516602082015260a0604082015260006144ce60a0830186613e4d565b84151560608401528281036080840152613feb8185613e4d565b600080604083850312156144fb57600080fd5b505080516020909101519092909150565b61ffff871681526000602060c0818401526000885461452a816142ef565b8060c087015260e060018084166000811461454c576001811461456657614594565b60ff198516838a01528284151560051b8a01019550614594565b8d6000528660002060005b8581101561458c5781548b8201860152908301908801614571565b8a0184019650505b505050505083810360408501526145ab8189613e4d565b9150506145c360608401876001600160a01b03169052565b6001600160a01b038516608084015282810360a08401526145e48185613e4d565b9998505050505050505050565b8183823760009101908152919050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b61ffff861681526080602082015260006146496080830187613e4d565b67ffffffffffffffff861660408401528281036060840152613feb818587614601565b601f8211156112df57600081815260208120601f850160051c810160208610156146935750805b601f850160051c820191505b81811015612bef5782815560010161469f565b67ffffffffffffffff8311156146ca576146ca613c71565b6146de836146d883546142ef565b8361466c565b6000601f84116001811461473057600085156146fa5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556147a8565b600083815260209020601f19861690835b828110156147615786850135825560209485019460019092019101614741565b508682101561479c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff84168152604060208201526000613c18604083018486614601565b600080604083850312156147e057600080fd5b82516147eb81613e8c565b6020939093015192949293505050565b80820180821115610d4b57610d4b614431565b815167ffffffffffffffff81111561482857614828613c71565b61483c8161483684546142ef565b8461466c565b602080601f83116001811461488f57600084156148595750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612bef565b600085815260208120601f198616915b828110156148be5788860151825594840194600190910190840161489f565b50858210156148fa57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b9e70586c31c5bd08b0b28b651559911f4644cded53f06dca8fda3a21c1fb4b664736f6c63430008110033
Deployed Bytecode
0x6080604052600436106103125760003560e01c806366278a6c1161019a578063a9059cbb116100e1578063d39ce77c1161008a578063de02cde711610064578063de02cde7146108ea578063eb8d72b71461090a578063f2fde38b1461092a57600080fd5b8063d39ce77c1461088a578063db0ed6a0146108aa578063dd62ed3e146108ca57600080fd5b8063cb40cb49116100bb578063cb40cb4914610844578063cf89fa0314610864578063d1deba1f1461087757600080fd5b8063a9059cbb146107f1578063ad6d9c1714610811578063ca4b208b1461082657600080fd5b80638da5cb5b1161014357806395d89b411161011d57806395d89b41146107a75780639c0ae0a2146107bc578063a86ff960146107dc57600080fd5b80638da5cb5b146106ea5780638ee749121461071c578063943fb8721461078757600080fd5b80637533d788116101745780637533d7881461069557806379ba5097146106b557806379cc6790146106ca57600080fd5b806366278a6c1461064057806370a0823114610660578063715018a61461068057600080fd5b806331e26cfd1161025e5780634f1ef286116102075780635d7875d4116101e15780635d7875d4146105e05780636149d8711461060057806364cb4edb1461062057600080fd5b80634f1ef2861461056057806352d1902d146105735780635ba5e9f01461058857600080fd5b806342966c681161023857806342966c681461050b57806344faded01461052b578063475de12e1461054b57600080fd5b806331e26cfd146104a65780633659cfe6146104bb57806340682152146104db57600080fd5b80631c37a822116102c05780632bfcf0f21161029a5780632bfcf0f21461044f5780632fb623c514610464578063313ce5671461048457600080fd5b80631c37a822146103ef57806323b872dd1461040f5780632ab0b0a41461042f57600080fd5b8063095ea7b3116102f1578063095ea7b31461039057806310ab9432146103b057806318160ddd146103d057600080fd5b80621d35671461031757806301ffc9a71461033957806306fdde031461036e575b600080fd5b34801561032357600080fd5b50610337610332366004613d59565b61094a565b005b34801561034557600080fd5b50610359610354366004613e0e565b610b88565b60405190151581526020015b60405180910390f35b34801561037a57600080fd5b50610383610d51565b6040516103659190613e79565b34801561039c57600080fd5b506103596103ab366004613ea1565b610d62565b3480156103bc57600080fd5b506103596103cb366004613ecd565b610dc4565b3480156103dc57600080fd5b506003545b604051908152602001610365565b3480156103fb57600080fd5b5061033761040a366004613d59565b610dd9565b34801561041b57600080fd5b5061035961042a366004613f04565b610e35565b34801561043b57600080fd5b5061033761044a366004613f45565b6111f2565b34801561045b57600080fd5b50610337611319565b34801561047057600080fd5b5061033761047f366004613ff7565b6113ae565b34801561049057600080fd5b5060045460405160ff9091168152602001610365565b3480156104b257600080fd5b50610337611428565b3480156104c757600080fd5b506103376104d6366004613ff7565b61149f565b3480156104e757600080fd5b506103596104f6366004613ff7565b600f6020526000908152604090205460ff1681565b34801561051757600080fd5b50610359610526366004614014565b611639565b34801561053757600080fd5b50610337610546366004613ecd565b611758565b34801561055757600080fd5b50600e546103e1565b61033761056e36600461402d565b611841565b34801561057f57600080fd5b506103e16119cf565b34801561059457600080fd5b506105af6105a3366004613e0e565b506303e1469160e61b90565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610365565b3480156105ec57600080fd5b506103376105fb366004613f45565b611a94565b34801561060c57600080fd5b5061033761061b366004613ff7565b611b81565b34801561062c57600080fd5b5061033761063b366004613ff7565b611bdf565b34801561064c57600080fd5b5061033761065b366004613e0e565b611c42565b34801561066c57600080fd5b506103e161067b366004613ff7565b611c79565b34801561068c57600080fd5b50610337611c97565b3480156106a157600080fd5b506103836106b036600461407d565b611d1a565b3480156106c157600080fd5b50610337611db4565b3480156106d657600080fd5b506103596106e5366004613ea1565b611e62565b3480156106f657600080fd5b506008546001600160a01b03165b6040516001600160a01b039091168152602001610365565b34801561072857600080fd5b50610772610737366004614098565b600c60209081526000938452604080852084518086018401805192815290840195840195909520945292905282529020805460019091015482565b60408051928352602083019190915201610365565b34801561079357600080fd5b506103376107a2366004614014565b612146565b3480156107b357600080fd5b50610383612163565b3480156107c857600080fd5b506103376107d7366004613ff7565b61216f565b3480156107e857600080fd5b506103376121de565b3480156107fd57600080fd5b5061035961080c366004613ea1565b612255565b34801561081d57600080fd5b50610337612461565b34801561083257600080fd5b506009546001600160a01b0316610704565b34801561085057600080fd5b5061033761085f366004613ff7565b6124b2565b6103376108723660046140ef565b61252c565b610337610885366004614154565b612876565b34801561089657600080fd5b506103376108a5366004613ff7565b612a12565b3480156108b657600080fd5b506103376108c53660046141e0565b612a89565b3480156108d657600080fd5b506103e16108e536600461427e565b612bf7565b3480156108f657600080fd5b50610337610905366004613ecd565b612c24565b34801561091657600080fd5b5061033761092536600461429c565b612d23565b34801561093657600080fd5b50610337610945366004613ff7565b612d9a565b600b546001600160a01b031633146109aa57604051630330dbc960e11b815260206004820152600560248201527f4e42523a3100000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61ffff84166000908152600d6020526040902080546109c8906142ef565b90508351141580610a08575061ffff84166000908152600d60205260409081902090516109f5919061433c565b6040518091039020838051906020012014155b15610a5657604051630330dbc960e11b815260206004820152600560248201527f4e42523a3200000000000000000000000000000000000000000000000000000060448201526064016109a1565b6040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a82290610a989087908790879087906004016143b2565b600060405180830381600087803b158015610ab257600080fd5b505af1925050508015610ac3575060015b610b82576040518060400160405280825181526020018280519060200120815250600c60008661ffff1661ffff16815260200190815260200160002084604051610b0d91906143fc565b90815260408051918290036020908101832067ffffffffffffffff8716600090815290825291909120835181559201516001909201919091557fe6f254030bcb01ffd20558175c13fcaed6d1520be7becee4c961b65f79243b0d90610b799086908690869086906143b2565b60405180910390a15b50505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7f5828d0000000000000000000000000000000000000000000000000000000001480610c1b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f7319562d00000000000000000000000000000000000000000000000000000000145b80610c6757507fffffffff0000000000000000000000000000000000000000000000000000000082167f78bab63900000000000000000000000000000000000000000000000000000000145b80610cb357507fffffffff0000000000000000000000000000000000000000000000000000000082167fb7d1e49900000000000000000000000000000000000000000000000000000000145b80610cff57507fffffffff0000000000000000000000000000000000000000000000000000000082167f3b5a0bf800000000000000000000000000000000000000000000000000000000145b80610d4b57507fffffffff0000000000000000000000000000000000000000000000000000000082167f942e8b2200000000000000000000000000000000000000000000000000000000145b92915050565b6060610d5d6001612e48565b905090565b3360008181526002602090815260408083206001600160a01b0387168085529083529281902085905551848152600193917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a392915050565b6000610dd260078484612ede565b9392505050565b333014610e2957604051630330dbc960e11b815260206004820152600560248201527f4e42523a3300000000000000000000000000000000000000000000000000000060448201526064016109a1565b610b8284848484612f6d565b6001600160a01b0382166000908152600f602052604081205460ff1680610e7457506001600160a01b0384166000908152600f602052604090205460ff165b15610ec257604051630330dbc960e11b815260206004820152601260248201527f4d617832303a20626c61636b6c6973746564000000000000000000000000000060448201526064016109a1565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038516600482015260009030906370a0823190602401602060405180830381865afa158015610f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f469190614418565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b0387166004820152336024820152909150600090309063dd62ed3e90604401602060405180830381865afa158015610faf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd39190614418565b90506001600160a01b0386161580610ff257506001600160a01b038516155b1561104057604051630330dbc960e11b815260206004820152601960248201527f4d617832303a20746f2f66726f6d20616464726573732830290000000000000060448201526064016109a1565b8184111561109157604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016109a1565b8084111561110857604051630330dbc960e11b815260206004820152602360248201527f4d617832303a206e6f7420617070726f76656420746f207370656e64205f766160448201527f6c7565000000000000000000000000000000000000000000000000000000000060648201526084016109a1565b6111156001878787612fde565b9250846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8660405161115c91815260200190565b60405180910390a36111a186336111738785614460565b6001600160a01b03928316600090815260026020908152604080832095909416825293909352912055600190565b50336001600160a01b0387167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256111d88785614460565b60405190815260200160405180910390a350509392505050565b611205600763ca4b208b60e01b33612ede565b156112e457805160005b818110156112df576000600f600085848151811061122f5761122f614473565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055507f0f67744da620d6c14d9467e3c6548012659cce57a9ab6e1711b8b0857de20a2c8382815181106112a1576112a1614473565b602002602001015160006040516112cf9291906001600160a01b039290921682521515602082015260400190565b60405180910390a160010161120f565b505050565b6040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b7fca4b208a0000000000000000000000000000000000000000000000000000000061134660078233612ede565b8061135f575061135f60076303e1469160e61b33612ede565b156112e457611377600763ca4b208b60e01b33613081565b6113826007336131ab565b61131660077fca4b208a00000000000000000000000000000000000000000000000000000000336132aa565b6113c1600763ca4b208b60e01b33612ede565b156112e4576001600160a01b0381166000818152600f6020908152604091829020805460ff191660019081179091558251938452908301527f0f67744da620d6c14d9467e3c6548012659cce57a9ab6e1711b8b0857de20a2c91015b60405180910390a150565b7fca4b208a0000000000000000000000000000000000000000000000000000000061145560078233612ede565b8061146e575061146e60076303e1469160e61b33612ede565b156112e45761131660077fca4b208a00000000000000000000000000000000000000000000000000000000336132aa565b6001600160a01b037f00000000000000000000000024e7a666d8a2eec1c26931ecd643a4e42b3a6c1116300361153d5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084016109a1565b7f00000000000000000000000024e7a666d8a2eec1c26931ecd643a4e42b3a6c116001600160a01b03166115987f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146116145760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f7879000000000000000000000000000000000000000060648201526084016109a1565b61161d816133c9565b604080516000808252602082019092526113169183919061342c565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819030906370a0823190602401602060405180830381865afa158015611692573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b69190614418565b90508083111561170957604051630330dbc960e11b815260206004820152601b60248201527f4d617832303a20696e73756666696369656e742062616c616e6365000000000060448201526064016109a1565b611715600133856135cc565b6040518381526001925060009033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35b50919050565b8161176560078233612ede565b8061177e575061177e60076303e1469160e61b33612ede565b156112e4577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a00000000000000000000000000000000000000000000000000000000148061181457507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b1561183557336001600160a01b038316036112e4576112df600784846132aa565b6112df600784846132aa565b6001600160a01b037f00000000000000000000000024e7a666d8a2eec1c26931ecd643a4e42b3a6c111630036118df5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084016109a1565b7f00000000000000000000000024e7a666d8a2eec1c26931ecd643a4e42b3a6c116001600160a01b031661193a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146119b65760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f7879000000000000000000000000000000000000000060648201526084016109a1565b6119bf826133c9565b6119cb8282600161342c565b5050565b6000306001600160a01b037f00000000000000000000000024e7a666d8a2eec1c26931ecd643a4e42b3a6c111614611a6f5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016109a1565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b611aa7600763ca4b208b60e01b33612ede565b156112e457805160005b818110156112df576001600f6000858481518110611ad157611ad1614473565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055507f0f67744da620d6c14d9467e3c6548012659cce57a9ab6e1711b8b0857de20a2c838281518110611b4357611b43614473565b60200260200101516001604051611b719291906001600160a01b039290921682521515602082015260400190565b60405180910390a1600101611ab1565b63ca4b208b60e01b611b9560078233612ede565b80611bae5750611bae60076303e1469160e61b33612ede565b156112e4576119cb60077fca4b208a0000000000000000000000000000000000000000000000000000000084613081565b63ca4b208b60e01b611bf360078233612ede565b80611c0c5750611c0c60076303e1469160e61b33612ede565b156112e457611c24600763ca4b208b60e01b84613081565b611c2f6007836131ab565b6119cb600763ca4b208b60e01b336132aa565b80611c4f60078233612ede565b80611c685750611c6860076303e1469160e61b33612ede565b156112e4576119cb600783336132aa565b6001600160a01b038116600090815260016020526040812054610d4b565b7f8da5cb5b00000000000000000000000000000000000000000000000000000000611cc460078233612ede565b80611cdd5750611cdd60076303e1469160e61b33612ede565b156112e457611cee60076000613665565b61131660077f8da5cb5b00000000000000000000000000000000000000000000000000000000336132aa565b600d6020526000908152604090208054611d33906142ef565b80601f0160208091040260200160405190810160405280929190818152602001828054611d5f906142ef565b8015611dac5780601f10611d8157610100808354040283529160200191611dac565b820191906000526020600020905b815481529060010190602001808311611d8f57829003601f168201915b505050505081565b7f8da5cb5a00000000000000000000000000000000000000000000000000000000611de160078233612ede565b80611dfa5750611dfa60076303e1469160e61b33612ede565b156112e457611e2b60077f8da5cb5b0000000000000000000000000000000000000000000000000000000033613081565b611e36600733613665565b61131660077f8da5cb5a00000000000000000000000000000000000000000000000000000000336132aa565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152600090819030906370a0823190602401602060405180830381865afa158015611ec4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee89190614418565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152336024820152909150600090309063dd62ed3e90604401602060405180830381865afa158015611f51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f759190614418565b90506001600160a01b038516611fce57604051630330dbc960e11b815260206004820152601660248201527f4d617832303a2066726f6d20616464726573732830290000000000000000000060448201526064016109a1565b8184111561201f57604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016109a1565b8084111561209657604051630330dbc960e11b815260206004820152602360248201527f4d617832303a206e6f7420617070726f76656420746f207370656e64205f766160448201527f6c7565000000000000000000000000000000000000000000000000000000000060648201526084016109a1565b6120a2600186866135cc565b604051848152600193506000906001600160a01b038716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a36120f685336111738785614460565b50336001600160a01b0386167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92561212d8785614460565b60405190815260200160405180910390a3505092915050565b612159600763ca4b208b60e01b33612ede565b156112e457600e55565b6060610d5d6001613702565b612182600763ca4b208b60e01b33612ede565b156112e4576001600160a01b0381166000818152600f60209081526040808320805460ff191690558051938452908301919091527f0f67744da620d6c14d9467e3c6548012659cce57a9ab6e1711b8b0857de20a2c910161141d565b7f8da5cb5a0000000000000000000000000000000000000000000000000000000061220b60078233612ede565b80612224575061222460076303e1469160e61b33612ede565b156112e45761131660077f8da5cb5a00000000000000000000000000000000000000000000000000000000336132aa565b6001600160a01b0382166000908152600f602052604081205460ff168061228b5750336000908152600f602052604090205460ff165b156122d957604051630330dbc960e11b815260206004820152601260248201527f4d617832303a20626c61636b6c6973746564000000000000000000000000000060448201526064016109a1565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015260009030906370a0823190602401602060405180830381865afa158015612330573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123549190614418565b90506001600160a01b0384166123ad57604051630330dbc960e11b815260206004820152601460248201527f4d617832303a20746f206164647265737328302900000000000000000000000060448201526064016109a1565b808311156123fe57604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016109a1565b61240b6001338686612fde565b9150836001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161245291815260200190565b60405180910390a35092915050565b63ca4b208b60e01b61247560078233612ede565b8061248e575061248e60076303e1469160e61b33612ede565b156112e45761249f600760006131ab565b611316600763ca4b208b60e01b336132aa565b6124c5600763ca4b208b60e01b33612ede565b156112e457600b80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f87bf030d6c6aa55db1e81d52f84962fc04ce1d477e64e50d57d3a91c52296f9390600090a250565b336000908152600f602052604090205460ff161561258d57604051630330dbc960e11b815260206004820152601260248201527f4d617832303a20626c61636b6c6973746564000000000000000000000000000060448201526064016109a1565b33600090815260016020526040902054808211156125d7576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61ffff83166000908152600d6020526040902080546125f5906142ef565b905060000361264757604051630330dbc960e11b815260206004820152601160248201527f546f6b656e3a205452206e6f742073657400000000000000000000000000000060448201526064016109a1565b612653600133846135cc565b60405182815233906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a360408051336020820152808201849052815180820383018152606082018352600e547e0100000000000000000000000000000000000000000000000000000000000060808401526082808401919091528351808403909101815260a2830193849052600b547f40a7bb100000000000000000000000000000000000000000000000000000000090945290926001926000916001600160a01b0316906340a7bb1090612742908a90309089908790899060a6016144a2565b6040805180830381865afa15801561275e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278291906144e8565b509050348111156127d657604051630330dbc960e11b815260206004820152601660248201527f546f6b656e3a206d65737361676520666565206c6f770000000000000000000060448201526064016109a1565b600b5461ffff88166000908152600d602052604080822090517fc58031000000000000000000000000000000000000000000000000000000000081526001600160a01b039093169263c580310092349261283b928d928b913391908b9060040161450c565b6000604051808303818588803b15801561285457600080fd5b505af1158015612868573d6000803e3d6000fd5b505050505050505050505050565b61ffff85166000908152600c602052604080822090516128979087906143fc565b908152604080516020928190038301902067ffffffffffffffff8716600090815292529020600181015490915061291157604051630330dbc960e11b815260206004820152600560248201527f4e42523a3400000000000000000000000000000000000000000000000000000060448201526064016109a1565b80548214158061293c5750806001015483836040516129319291906145f1565b604051809103902014155b1561298a57604051630330dbc960e11b815260206004820152600560248201527f4e42523a3500000000000000000000000000000000000000000000000000000060448201526064016109a1565b600080825560018201556040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a822906129d8908990899089908990899060040161462c565b600060405180830381600087803b1580156129f257600080fd5b505af1158015612a06573d6000803e3d6000fd5b50505050505050505050565b7f8da5cb5b00000000000000000000000000000000000000000000000000000000612a3f60078233612ede565b80612a585750612a5860076303e1469160e61b33612ede565b156112e4576119cb60077f8da5cb5a0000000000000000000000000000000000000000000000000000000084613081565b600054610100900460ff1615808015612aa95750600054600160ff909116105b80612ac35750303b158015612ac3575060005460ff166001145b612b355760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016109a1565b6000805460ff191660011790558015612b7557600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b612b8486866012878787613713565b612b8c613828565b8015612bef57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6001600160a01b038083166000908152600260209081526040808320938516835292905290812054610dd2565b81612c3160078233612ede565b80612c4a5750612c4a60076303e1469160e61b33612ede565b156112e4577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a000000000000000000000000000000000000000000000000000000001480612ce057507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b15612d17576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6112df60078484613081565b612d36600763ca4b208b60e01b33612ede565b156112e45761ffff83166000908152600d60205260409020612d598284836146b2565b507f93c35c217d799290d33244ef8905b63167d13758ab18343cd8055ed1b8056748838383604051612d8d939291906147af565b60405180910390a1505050565b7f8da5cb5b00000000000000000000000000000000000000000000000000000000612dc760078233612ede565b80612de05750612de060076303e1469160e61b33612ede565b156112e457612e1160077f8da5cb5b0000000000000000000000000000000000000000000000000000000084613081565b612e1c600783613665565b6119cb60077f8da5cb5b00000000000000000000000000000000000000000000000000000000336132aa565b6060816004018054612e59906142ef565b80601f0160208091040260200160405190810160405280929190818152602001828054612e85906142ef565b8015612ed25780601f10612ea757610100808354040283529160200191612ed2565b820191906000526020600020905b815481529060010190602001808311612eb557829003601f168201915b50505050509050919050565b60006001600160a01b038216612f20576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082207fffffffff000000000000000000000000000000000000000000000000000000009390931682529190925290205460ff1690565b60008082806020019051810190612f8491906147cd565b9092509050612f95600183836138a7565b6040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050505050565b6001600160a01b0383166000908152602085905260408120548083111561304857604051630330dbc960e11b815260206004820152600760248201527f4d617832303a310000000000000000000000000000000000000000000000000060448201526064016109a1565b50506001600160a01b03808416600090815260208690526040808220805485900390559184168152208054820190556001949350505050565b6001600160a01b0381166130c1576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130cc838383612ede565b1561311a57604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a310000000000000000000000000000000000000000000000000060448201526064016109a1565b6001600160a01b0381166000818152602085815260408083207fffffffff00000000000000000000000000000000000000000000000000000000871680855290835292819020805460ff19166001908117909155815193845291830193909352918101919091527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f790606001612d8d565b6131bd8263ca4b208b60e01b83612ede565b1561322f576002820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f2cfca82ac51c2fc6b6db547820d28d526a505e12d230afb8bf112a5aeefa9a4c90600090a3505050565b6001600160a01b0381166112e4576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6001600160a01b0381166132ea576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6132f5838383612ede565b61334257604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a320000000000000000000000000000000000000000000000000060448201526064016109a1565b6001600160a01b0381166000818152602085815260408083207fffffffff000000000000000000000000000000000000000000000000000000008716808552908352818420805460ff19169055815190815291820193909352918201527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f790606001612d8d565b6303e1469160e61b6133dd60078233612ede565b806133f657506133f660076303e1469160e61b33612ede565b6119cb576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561345f576112df8361393b565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156134b9575060408051601f3d908101601f191682019092526134b691810190614418565b60015b61352b5760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f74205555505300000000000000000000000000000000000060648201526084016109a1565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81146135c05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c6555554944000000000000000000000000000000000000000000000060648201526084016109a1565b506112df838383613a11565b6001600160a01b0382166000908152602084905260409020548082111561363657604051630330dbc960e11b815260206004820152600760248201527f4d617832303a310000000000000000000000000000000000000000000000000060448201526064016109a1565b6001600160a01b0390921660009081526020849052604090209181900390915560029091018054919091039055565b613690827f8da5cb5b0000000000000000000000000000000000000000000000000000000083612ede565b1561322f576001820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6060816005018054612e59906142ef565b600054610100900460ff166137905760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a1565b61379b600187613a36565b6137a6600186613a44565b6004805460ff191660ff86161790556137c860076303e1469160e61b85613081565b6137d3600784613a52565b6137e6600763ca4b208b60e01b84613081565b6137f16007836131ab565b61381d60077f8da5cb5b0000000000000000000000000000000000000000000000000000000083613081565b612bef600782613665565b600054610100900460ff166138a55760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016109a1565b565b6001600160a01b0382166138fe57604051630330dbc960e11b815260206004820152600760248201527f4d617832303a320000000000000000000000000000000000000000000000000060448201526064016109a1565b8083600201600082825461391291906147fb565b90915550506001600160a01b039091166000908152602092909252604090912080549091019055565b6001600160a01b0381163b6139b85760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016109a1565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b613a1a83613ad6565b600082511180613a275750805b156112df57610b828383613b16565b600482016112df828261480e565b600582016112df828261480e565b613a64826303e1469160e61b83612ede565b1561322f576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b613adf8161393b565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613b955760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016109a1565b600080846001600160a01b031684604051613bb091906143fc565b600060405180830381855af49150503d8060008114613beb576040519150601f19603f3d011682016040523d82523d6000602084013e613bf0565b606091505b5091509150613c18828260405180606001604052806027815260200161490b60279139613c21565b95945050505050565b60608315613c30575081610dd2565b825115613c405782518084602001fd5b8160405162461bcd60e51b81526004016109a19190613e79565b803561ffff81168114613c6c57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613cc957613cc9613c71565b604052919050565b600082601f830112613ce257600080fd5b813567ffffffffffffffff811115613cfc57613cfc613c71565b613d0f6020601f19601f84011601613ca0565b818152846020838601011115613d2457600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff81168114613c6c57600080fd5b60008060008060808587031215613d6f57600080fd5b613d7885613c5a565b9350602085013567ffffffffffffffff80821115613d9557600080fd5b613da188838901613cd1565b9450613daf60408801613d41565b93506060870135915080821115613dc557600080fd5b50613dd287828801613cd1565b91505092959194509250565b80357fffffffff0000000000000000000000000000000000000000000000000000000081168114613c6c57600080fd5b600060208284031215613e2057600080fd5b610dd282613dde565b60005b83811015613e44578181015183820152602001613e2c565b50506000910152565b60008151808452613e65816020860160208601613e29565b601f01601f19169290920160200192915050565b602081526000610dd26020830184613e4d565b6001600160a01b038116811461131657600080fd5b60008060408385031215613eb457600080fd5b8235613ebf81613e8c565b946020939093013593505050565b60008060408385031215613ee057600080fd5b613ee983613dde565b91506020830135613ef981613e8c565b809150509250929050565b600080600060608486031215613f1957600080fd5b8335613f2481613e8c565b92506020840135613f3481613e8c565b929592945050506040919091013590565b60006020808385031215613f5857600080fd5b823567ffffffffffffffff80821115613f7057600080fd5b818501915085601f830112613f8457600080fd5b813581811115613f9657613f96613c71565b8060051b9150613fa7848301613ca0565b8181529183018401918481019088841115613fc157600080fd5b938501935b83851015613feb5784359250613fdb83613e8c565b8282529385019390850190613fc6565b98975050505050505050565b60006020828403121561400957600080fd5b8135610dd281613e8c565b60006020828403121561402657600080fd5b5035919050565b6000806040838503121561404057600080fd5b823561404b81613e8c565b9150602083013567ffffffffffffffff81111561406757600080fd5b61407385828601613cd1565b9150509250929050565b60006020828403121561408f57600080fd5b610dd282613c5a565b6000806000606084860312156140ad57600080fd5b6140b684613c5a565b9250602084013567ffffffffffffffff8111156140d257600080fd5b6140de86828701613cd1565b925050604084013590509250925092565b6000806040838503121561410257600080fd5b613ebf83613c5a565b60008083601f84011261411d57600080fd5b50813567ffffffffffffffff81111561413557600080fd5b60208301915083602082850101111561414d57600080fd5b9250929050565b60008060008060006080868803121561416c57600080fd5b61417586613c5a565b9450602086013567ffffffffffffffff8082111561419257600080fd5b61419e89838a01613cd1565b95506141ac60408901613d41565b945060608801359150808211156141c257600080fd5b506141cf8882890161410b565b969995985093965092949392505050565b600080600080600060a086880312156141f857600080fd5b853567ffffffffffffffff8082111561421057600080fd5b61421c89838a01613cd1565b9650602088013591508082111561423257600080fd5b5061423f88828901613cd1565b945050604086013561425081613e8c565b9250606086013561426081613e8c565b9150608086013561427081613e8c565b809150509295509295909350565b6000806040838503121561429157600080fd5b8235613ee981613e8c565b6000806000604084860312156142b157600080fd5b6142ba84613c5a565b9250602084013567ffffffffffffffff8111156142d657600080fd5b6142e28682870161410b565b9497909650939450505050565b600181811c9082168061430357607f821691505b602082108103611752577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080835461434a816142ef565b600182811680156143625760018114614377576143a6565b60ff19841687528215158302870194506143a6565b8760005260208060002060005b8581101561439d5781548a820152908401908201614384565b50505082870194505b50929695505050505050565b61ffff851681526080602082015260006143cf6080830186613e4d565b67ffffffffffffffff8516604084015282810360608401526143f18185613e4d565b979650505050505050565b6000825161440e818460208701613e29565b9190910192915050565b60006020828403121561442a57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610d4b57610d4b614431565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61ffff861681526001600160a01b038516602082015260a0604082015260006144ce60a0830186613e4d565b84151560608401528281036080840152613feb8185613e4d565b600080604083850312156144fb57600080fd5b505080516020909101519092909150565b61ffff871681526000602060c0818401526000885461452a816142ef565b8060c087015260e060018084166000811461454c576001811461456657614594565b60ff198516838a01528284151560051b8a01019550614594565b8d6000528660002060005b8581101561458c5781548b8201860152908301908801614571565b8a0184019650505b505050505083810360408501526145ab8189613e4d565b9150506145c360608401876001600160a01b03169052565b6001600160a01b038516608084015282810360a08401526145e48185613e4d565b9998505050505050505050565b8183823760009101908152919050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b61ffff861681526080602082015260006146496080830187613e4d565b67ffffffffffffffff861660408401528281036060840152613feb818587614601565b601f8211156112df57600081815260208120601f850160051c810160208610156146935750805b601f850160051c820191505b81811015612bef5782815560010161469f565b67ffffffffffffffff8311156146ca576146ca613c71565b6146de836146d883546142ef565b8361466c565b6000601f84116001811461473057600085156146fa5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556147a8565b600083815260209020601f19861690835b828110156147615786850135825560209485019460019092019101614741565b508682101561479c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff84168152604060208201526000613c18604083018486614601565b600080604083850312156147e057600080fd5b82516147eb81613e8c565b6020939093015192949293505050565b80820180821115610d4b57610d4b614431565b815167ffffffffffffffff81111561482857614828613c71565b61483c8161483684546142ef565b8461466c565b602080601f83116001811461488f57600084156148595750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612bef565b600085815260208120601f198616915b828110156148be5788860151825594840194600190910190840161489f565b50858210156148fa57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b9e70586c31c5bd08b0b28b651559911f4644cded53f06dca8fda3a21c1fb4b664736f6c63430008110033
Deployed Bytecode Sourcemap
2404:6664:7:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12675:913:8;;;;;;;;;;-1:-1:-1;12675:913:8;;;;;:::i;:::-;;:::i;:::-;;23501:452;;;;;;;;;;-1:-1:-1;23501:452:8;;;;;:::i;:::-;;:::i;:::-;;;2743:14:26;;2736:22;2718:41;;2706:2;2691:18;23501:452:8;;;;;;;;5555:126;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;10076:241::-;;;;;;;;;;-1:-1:-1;10076:241:8;;;;;:::i;:::-;;:::i;21582:145::-;;;;;;;;;;-1:-1:-1;21582:145:8;;;;;:::i;:::-;;:::i;6587:134::-;;;;;;;;;;-1:-1:-1;3351:17:14;;6587:134:8;;;4534:25:26;;;4522:2;4507:18;6587:134:8;4388:177:26;13927:368:8;;;;;;;;;;-1:-1:-1;13927:368:8;;;;;:::i;:::-;;:::i;3740:1009:7:-;;;;;;;;;;-1:-1:-1;3740:1009:7;;;;;:::i;:::-;;:::i;24605:291:8:-;;;;;;;;;;-1:-1:-1;24605:291:8;;;;;:::i;:::-;;:::i;20595:209::-;;;;;;;;;;;;;:::i;24050:126::-;;;;;;;;;;-1:-1:-1;24050:126:8;;;;;:::i;:::-;;:::i;6380:::-;;;;;;;;;;-1:-1:-1;3222:14:14;;6380:126:8;;3222:14:14;;;;6451:36:26;;6439:2;6424:18;6380:126:8;6309:184:26;20867:125:8;;;;;;;;;;;;;:::i;3315:197:4:-;;;;;;;;;;-1:-1:-1;3315:197:4;;;;;:::i;:::-;;:::i;23957:40:8:-;;;;;;;;;;-1:-1:-1;23957:40:8;;;;;:::i;:::-;;;;;;;;;;;;;;;;5132:408:7;;;;;;;;;;-1:-1:-1;5132:408:7;;;;;:::i;:::-;;:::i;22444:348:8:-;;;;;;;;;;-1:-1:-1;22444:348:8;;;;;:::i;:::-;;:::i;8954:112:7:-;;;;;;;;;;-1:-1:-1;9035:26:7;;8954:112;;3761:222:4;;;;;;:::i;:::-;;:::i;3004:131::-;;;;;;;;;;;;;:::i;21844:106:8:-;;;;;;;;;;-1:-1:-1;21844:106:8;;;;;:::i;:::-;-1:-1:-1;;;;21940:5:8;21844:106;;;;7499:66:26;7487:79;;;7469:98;;7457:2;7442:18;21844:106:8;7325:248:26;24315:286:8;;;;;;;;;;-1:-1:-1;24315:286:8;;;;;:::i;:::-;;:::i;21117:137::-;;;;;;;;;;-1:-1:-1;21117:137:8;;;;;:::i;:::-;;:::i;20310:223::-;;;;;;;;;;-1:-1:-1;20310:223:8;;;;;:::i;:::-;;:::i;22875:120::-;;;;;;;;;;-1:-1:-1;22875:120:8;;;;;:::i;:::-;;:::i;6836:165::-;;;;;;;;;;-1:-1:-1;6836:165:8;;;;;:::i;:::-;;:::i;18767:155::-;;;;;;;;;;;;;:::i;3813:51::-;;;;;;;;;;-1:-1:-1;3813:51:8;;;;;:::i;:::-;;:::i;18986:211::-;;;;;;;;;;;;;:::i;11388:848::-;;;;;;;;;;-1:-1:-1;11388:848:8;;;;;:::i;:::-;;:::i;17962:102::-;;;;;;;;;;-1:-1:-1;5748:10:17;;-1:-1:-1;;;;;5748:10:17;17962:102:8;;;-1:-1:-1;;;;;8286:55:26;;;8268:74;;8256:2;8241:18;17962:102:8;8122:226:26;3719:90:8;;;;;;;;;;-1:-1:-1;3719:90:8;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8992:25:26;;;9048:2;9033:18;;9026:34;;;;8965:18;3719:90:8;8818:248:26;8026:125:7;;;;;;;;;;-1:-1:-1;8026:125:7;;;;;:::i;:::-;;:::i;5920:130:8:-;;;;;;;;;;;;;:::i;24180:131::-;;;;;;;;;;-1:-1:-1;24180:131:8;;;;;:::i;:::-;;:::i;19262:129::-;;;;;;;;;;;;;:::i;3074:662:7:-;;;;;;;;;;-1:-1:-1;3074:662:7;;;;;:::i;:::-;;:::i;20041:154:8:-;;;;;;;;;;;;;:::i;19877:111::-;;;;;;;;;;-1:-1:-1;5627:14:17;;-1:-1:-1;;;;;5627:14:17;19877:111:8;5555:126;17578:161;;;;;;;;;;-1:-1:-1;17578:161:8;;;;;:::i;:::-;;:::i;5795:2101:7:-;;;;;;:::i;:::-;;:::i;16196:809:8:-;;;;;;:::i;:::-;;:::i;19510:133::-;;;;;;;;;;-1:-1:-1;19510:133:8;;;;;:::i;:::-;;:::i;2707:253:7:-;;;;;;;;;;-1:-1:-1;2707:253:7;;;;;:::i;:::-;;:::i;10487:195:8:-;;;;;;;;;;-1:-1:-1;10487:195:8;;;;;:::i;:::-;;:::i;22074:239::-;;;;;;;;;;-1:-1:-1;22074:239:8;;;;;:::i;:::-;;:::i;17183:218::-;;;;;;;;;;-1:-1:-1;17183:218:8;;;;;:::i;:::-;;:::i;18270:216::-;;;;;;;;;;-1:-1:-1;18270:216:8;;;;;:::i;:::-;;:::i;12675:913::-;12849:8;;-1:-1:-1;;;;;12849:8:8;12827:10;:31;12823:106;;12875:47;;-1:-1:-1;;;12875:47:8;;12504:2:26;12875:47:8;;;12486:21:26;12543:1;12523:18;;;12516:29;12581:7;12561:18;;;12554:35;12606:18;;12875:47:8;;;;;;;;12823:106;12968:32;;;;;;;:19;:32;;;;;:39;;;;;:::i;:::-;;;12946:11;:18;:61;;:140;;;-1:-1:-1;13053:32:8;;;;;;;:19;:32;;;;;;;13043:43;;;;13053:32;13043:43;:::i;:::-;;;;;;;;13027:11;13017:22;;;;;;:69;;12946:140;12935:227;;;13108:47;;-1:-1:-1;;;13108:47:8;;14307:2:26;13108:47:8;;;14289:21:26;14346:1;14326:18;;;14319:29;14384:7;14364:18;;;14357:35;14409:18;;13108:47:8;14105:328:26;12935:227:8;13273:60;;;;;:4;;:16;;:60;;13290:11;;13303;;13316:6;;13324:8;;13273:60;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13269:315;;13455:52;;;;;;;;13470:8;:15;13455:52;;;;13497:8;13487:19;;;;;;13455:52;;;13404:14;:27;13419:11;13404:27;;;;;;;;;;;;;;;13432:11;13404:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;:48;;;;;;;;;;;;;;:103;;;;;;;;;;;;;;;13520:57;;;;13534:11;;13547;;13445:6;;13568:8;;13520:57;:::i;:::-;;;;;;;;13269:315;12675:913;;;;:::o;23501:452::-;23612:4;23639:40;;;23654:25;23639:40;;:91;;-1:-1:-1;23690:40:8;;;23705:25;23690:40;23639:91;:142;;;-1:-1:-1;23741:40:8;;;23756:25;23741:40;23639:142;:192;;;-1:-1:-1;23792:39:8;;;23807:24;23792:39;23639:192;:250;;;-1:-1:-1;23842:47:8;;;23857:32;23842:47;23639:250;:300;;;-1:-1:-1;23900:39:8;;;23915:24;23900:39;23639:300;23624:324;23501:452;-1:-1:-1;;23501:452:8:o;5555:126::-;5631:13;5659:17;:7;:15;:17::i;:::-;5652:24;;5555:126;:::o;10076:241::-;10234:10;10185:12;4255:23:14;;;:16;:23;;;;;;;;-1:-1:-1;;;;;4255:32:14;;;;;;;;;;;;:41;;;10274:38:8;4534:25:26;;;10215:7:8;;10234:10;10274:38;;4507:18:26;10274:38:8;;;;;;;10076:241;;;;:::o;21582:145::-;21671:4;21690:32;:13;21708:4;21714:7;21690:17;:32::i;:::-;21683:39;21582:145;-1:-1:-1;;;21582:145:8:o;13927:368::-;14100:10;14122:4;14100:27;14096:102;;14144:47;;-1:-1:-1;;;14144:47:8;;15494:2:26;14144:47:8;;;15476:21:26;15533:1;15513:18;;;15506:29;15571:7;15551:18;;;15544:35;15596:18;;14144:47:8;15292:328:26;14096:102:8;14235:55;14247:11;14260;14273:6;14281:8;14235:10;:55::i;3740:1009:7:-;-1:-1:-1;;;;;3891:13:7;;3867:12;3891:13;;;:8;:13;;;;;;;;;:32;;-1:-1:-1;;;;;;3908:15:7;;;;;;:8;:15;;;;;;;;3891:32;3887:120;;;3940:60;;-1:-1:-1;;;3940:60:7;;15827:2:26;3940:60:7;;;15809:21:26;15866:2;15846:18;;;15839:30;15905:20;15885:18;;;15878:48;15943:18;;3940:60:7;15625:342:26;3887:120:7;4034:21;;;;;-1:-1:-1;;;;;8286:55:26;;4034:21:7;;;8268:74:26;4012:19:7;;4034:4;;:14;;8241:18:26;;4034:21:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4082:33;;;;;-1:-1:-1;;;;;16414:15:26;;4082:33:7;;;16396:34:26;4104:10:7;16446:18:26;;;16439:43;4012::7;;-1:-1:-1;4061:18:7;;4082:4;;:14;;16308:18:26;;4082:33:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4061:54;-1:-1:-1;;;;;;4125:19:7;;;;:40;;-1:-1:-1;;;;;;4148:17:7;;;4125:40;4121:624;;;4182:67;;-1:-1:-1;;;4182:67:7;;16695:2:26;4182:67:7;;;16677:21:26;16734:2;16714:18;;;16707:30;16773:27;16753:18;;;16746:55;16818:18;;4182:67:7;16493:349:26;4121:624:7;4275:11;4266:6;:20;4262:483;;;4303:68;;-1:-1:-1;;;4303:68:7;;17049:2:26;4303:68:7;;;17031:21:26;17088:2;17068:18;;;17061:30;17127:28;17107:18;;;17100:56;17173:18;;4303:68:7;16847:350:26;4262:483:7;4397:10;4388:6;:19;4384:361;;;4424:77;;-1:-1:-1;;;4424:77:7;;17404:2:26;4424:77:7;;;17386:21:26;17443:2;17423:18;;;17416:30;17482:34;17462:18;;;17455:62;17553:5;17533:18;;;17526:33;17576:19;;4424:77:7;17202:399:26;4384:361:7;4532:38;:7;4551:5;4558:3;4563:6;4532:18;:38::i;:::-;4522:48;;4599:3;-1:-1:-1;;;;;4583:28:7;4592:5;-1:-1:-1;;;;;4583:28:7;;4604:6;4583:28;;;;4534:25:26;;4522:2;4507:18;;4388:177;4583:28:7;;;;;;;;4619:58;4638:5;4645:10;4657:19;4670:6;4657:10;:19;:::i;:::-;-1:-1:-1;;;;;4255:23:14;;;4243:4;4255:23;;;:16;:23;;;;;;;;:32;;;;;;;;;;;;:41;4619:7:7;;4114:204:14;4619:58:7;-1:-1:-1;4706:10:7;-1:-1:-1;;;;;4690:48:7;;;4718:19;4731:6;4718:10;:19;:::i;:::-;4690:48;;4534:25:26;;;4522:2;4507:18;4690:48:7;;;;;;;3881:868;;3740:1009;;;;;:::o;24605:291:8:-;4544:35;:13;-1:-1:-1;;;4568:10:8;4544:17;:35::i;:::-;4540:97;;;24721:19;;24710:8:::1;24746:146;24767:3;24763:1;:7;24746:146;;;24809:5;24781:8;:25;24790:12;24803:1;24790:15;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;24781:25:8::1;-1:-1:-1::0;;;;;24781:25:8::1;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;24827;24837:12;24850:1;24837:15;;;;;;;;:::i;:::-;;;;;;;24854:5;24827:33;;;;;;-1:-1:-1::0;;;;;18303:55:26;;;;18285:74;;18402:14;18395:22;18390:2;18375:18;;18368:50;18273:2;18258:18;;18117:307;24827:33:8::1;;;;;;;;24880:3;;24746:146;;;;24704:192;24605:291:::0;:::o;4540:97::-;4616:14;;;;;;;;;;;;;;4540:97;24605:291;:::o;20595:209::-;20648:12;4240:35;:13;20648:12;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;20668:35:::1;:13;-1:-1:-1::0;;;20692:10:8::1;20668:17;:35::i;:::-;20709:38;:13;20736:10;20709:26;:38::i;:::-;20753:46;:13;20774:12:::0;20788:10:::1;20753:20;:46::i;24050:126::-:0;4544:35;:13;-1:-1:-1;;;4568:10:8;4544:17;:35::i;:::-;4540:97;;;-1:-1:-1;;;;;24118:14:8;::::1;;::::0;;;:8:::1;:14;::::0;;;;;;;;:21;;-1:-1:-1;;24118:21:8::1;24135:4;24118:21:::0;;::::1;::::0;;;24150;;18285:74:26;;;18375:18;;;18368:50;24150:21:8::1;::::0;18258:18:26;24150:21:8::1;;;;;;;;24605:291:::0;:::o;20867:125::-;20921:12;4240:35;:13;20921:12;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;20941:46:::1;:13;20962:12:::0;20976:10:::1;20941:20;:46::i;3315:197:4:-:0;-1:-1:-1;;;;;1898:6:4;1881:23;1889:4;1881:23;1873:80;;;;-1:-1:-1;;;1873:80:4;;18631:2:26;1873:80:4;;;18613:21:26;18670:2;18650:18;;;18643:30;18709:34;18689:18;;;18682:62;18780:14;18760:18;;;18753:42;18812:19;;1873:80:4;18429:408:26;1873:80:4;1995:6;-1:-1:-1;;;;;1971:30:4;:20;1292:66:1;1642:65;-1:-1:-1;;;;;1642:65:1;;1563:151;1971:20:4;-1:-1:-1;;;;;1971:30:4;;1963:87;;;;-1:-1:-1;;;1963:87:4;;19044:2:26;1963:87:4;;;19026:21:26;19083:2;19063:18;;;19056:30;19122:34;19102:18;;;19095:62;19193:14;19173:18;;;19166:42;19225:19;;1963:87:4;18842:408:26;1963:87:4;3398:36:::1;3416:17;3398;:36::i;:::-;3485:12;::::0;;3495:1:::1;3485:12:::0;;;::::1;::::0;::::1;::::0;;;3444:61:::1;::::0;3466:17;;3485:12;3444:21:::1;:61::i;5132:408:7:-:0;5259:26;;;;;5274:10;5259:26;;;8268:74:26;5217:12:7;;;;5259:4;;:14;;8241:18:26;;5259:26:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5237:48;;5304:11;5295:6;:20;5291:245;;;5332:69;;-1:-1:-1;;;5332:69:7;;19457:2:26;5332:69:7;;;19439:21:26;19496:2;19476:18;;;19469:30;19535:29;19515:18;;;19508:57;19582:18;;5332:69:7;19255:351:26;5291:245:7;5422:32;:7;5435:10;5447:6;5422:12;:32::i;:::-;5489:40;;4534:25:26;;;5472:4:7;;-1:-1:-1;5518:1:7;;5498:10;;5489:40;;4522:2:26;4507:18;5489:40:7;;;;;;;5291:245;5231:309;5132:408;;;:::o;22444:348:8:-;22527:4;4240:35;:13;22527:4;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;22543:20;;::::1;22551:12:::0;22543:20:::1;::::0;:46:::1;;-1:-1:-1::0;22567:22:8;;::::1;22575:14:::0;22567:22:::1;22543:46;22539:249;;;22614:10;-1:-1:-1::0;;;;;22603:21:8;::::1;::::0;22599:127:::1;;22636:35;:13;22657:4:::0;22663:7;22636:20:::1;:35::i;22539:249::-;22746:35;:13;22767:4:::0;22773:7;22746:20:::1;:35::i;3761:222:4:-:0;-1:-1:-1;;;;;1898:6:4;1881:23;1889:4;1881:23;1873:80;;;;-1:-1:-1;;;1873:80:4;;18631:2:26;1873:80:4;;;18613:21:26;18670:2;18650:18;;;18643:30;18709:34;18689:18;;;18682:62;18780:14;18760:18;;;18753:42;18812:19;;1873:80:4;18429:408:26;1873:80:4;1995:6;-1:-1:-1;;;;;1971:30:4;:20;1292:66:1;1642:65;-1:-1:-1;;;;;1642:65:1;;1563:151;1971:20:4;-1:-1:-1;;;;;1971:30:4;;1963:87;;;;-1:-1:-1;;;1963:87:4;;19044:2:26;1963:87:4;;;19026:21:26;19083:2;19063:18;;;19056:30;19122:34;19102:18;;;19095:62;19193:14;19173:18;;;19166:42;19225:19;;1963:87:4;18842:408:26;1963:87:4;3878:36:::1;3896:17;3878;:36::i;:::-;3924:52;3946:17;3965:4;3971;3924:21;:52::i;:::-;3761:222:::0;;:::o;3004:131::-;3082:7;2324:4;-1:-1:-1;;;;;2333:6:4;2316:23;;2308:92;;;;-1:-1:-1;;;2308:92:4;;19813:2:26;2308:92:4;;;19795:21:26;19852:2;19832:18;;;19825:30;19891:34;19871:18;;;19864:62;19962:26;19942:18;;;19935:54;20006:19;;2308:92:4;19611:420:26;2308:92:4;-1:-1:-1;1292:66:1::1;3004:131:4::0;:::o;24315:286:8:-;4544:35;:13;-1:-1:-1;;;4568:10:8;4544:17;:35::i;:::-;4540:97;;;24428:19;;24417:8:::1;24453:144;24474:3;24470:1;:7;24453:144;;;24516:4;24488:8;:25;24497:12;24510:1;24497:15;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1::0;;;;;24488:25:8::1;-1:-1:-1::0;;;;;24488:25:8::1;;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;24533;24543:12;24556:1;24543:15;;;;;;;;:::i;:::-;;;;;;;24560:4;24533:32;;;;;;-1:-1:-1::0;;;;;18303:55:26;;;;18285:74;;18402:14;18395:22;18390:2;18375:18;;18368:50;18273:2;18258:18;;18117:307;24533:32:8::1;;;;;;;;24585:3;;24453:144;;21117:137:::0;-1:-1:-1;;;4240:35:8;:13;21192:4;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;21204:45:::1;:13;21222:12:::0;21236;21204:17:::1;:45::i;20310:223::-:0;-1:-1:-1;;;4240:35:8;:13;20389:4;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;20401:37:::1;:13;-1:-1:-1::0;;;20425:12:8;20401:17:::1;:37::i;:::-;20444:40;:13;20471:12:::0;20444:26:::1;:40::i;:::-;20490:38;:13;-1:-1:-1::0;;;20517:10:8::1;20490:20;:38::i;22875:120::-:0;22940:4;4240:35;:13;22940:4;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;22952:38:::1;:13;22973:4:::0;22979:10:::1;22952:20;:38::i;6836:165::-:0;-1:-1:-1;;;;;3499:21:14;;6935:15:8;3499:21:14;;;6968:7:8;3499:21:14;;;;;;6968:28:8;3377:148:14;18767:155:8;18823:6;4240:35;:13;18823:6;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;18837:34:::1;:13;18868:1;18837:22;:34::i;:::-;18877:40;:13;18898:6:::0;18906:10:::1;18877:20;:40::i;3813:51::-:0;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;18986:211::-;19039:14;4240:35;:13;19039:14;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;19061:37:::1;:13;19079:6:::0;19087:10:::1;19061:17;:37::i;:::-;19104:34;:13;19127:10;19104:22;:34::i;:::-;19144:48;:13;19165:14:::0;19181:10:::1;19144:20;:48::i;11388:848::-:0;11537:21;;;;;-1:-1:-1;;;;;8286:55:26;;11537:21:8;;;8268:74:26;11495:12:8;;;;11537:4;;:14;;8241:18:26;;11537:21:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11585:33;;;;;-1:-1:-1;;;;;16414:15:26;;11585:33:8;;;16396:34:26;11607:10:8;16446:18:26;;;16439:43;11515::8;;-1:-1:-1;11564:18:8;;11585:4;;:14;;16308:18:26;;11585:33:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11564:54;-1:-1:-1;;;;;;11628:19:8;;11624:608;;11664:64;;-1:-1:-1;;;11664:64:8;;20238:2:26;11664:64:8;;;20220:21:26;20277:2;20257:18;;;20250:30;20316:24;20296:18;;;20289:52;20358:18;;11664:64:8;20036:346:26;11624:608:8;11754:11;11745:6;:20;11741:491;;;11782:68;;-1:-1:-1;;;11782:68:8;;17049:2:26;11782:68:8;;;17031:21:26;17088:2;17068:18;;;17061:30;17127:28;17107:18;;;17100:56;17173:18;;11782:68:8;16847:350:26;11741:491:8;11876:10;11867:6;:19;11863:369;;;11903:77;;-1:-1:-1;;;11903:77:8;;17404:2:26;11903:77:8;;;17386:21:26;17443:2;17423:18;;;17416:30;17482:34;17462:18;;;17455:62;17553:5;17533:18;;;17526:33;17576:19;;11903:77:8;17202:399:26;11863:369:8;12001:27;:7;12014:5;12021:6;12001:12;:27::i;:::-;12063:35;;4534:25:26;;;12046:4:8;;-1:-1:-1;12087:1:8;;-1:-1:-1;;;;;12063:35:8;;;;;4522:2:26;4507:18;12063:35:8;;;;;;;12106:58;12125:5;12132:10;12144:19;12157:6;12144:10;:19;:::i;12106:58::-;-1:-1:-1;12193:10:8;-1:-1:-1;;;;;12177:48:8;;;12205:19;12218:6;12205:10;:19;:::i;:::-;12177:48;;4534:25:26;;;4522:2;4507:18;12177:48:8;;;;;;;11509:727;;11388:848;;;;:::o;8026:125:7:-;4544:35:8;:13;-1:-1:-1;;;4568:10:8;4544:17;:35::i;:::-;4540:97;;;8111:26:7::1;:35:::0;24605:291:8:o;5920:130::-;5998:13;6026:19;:7;:17;:19::i;24180:131::-;4544:35;:13;-1:-1:-1;;;4568:10:8;4544:17;:35::i;:::-;4540:97;;;-1:-1:-1;;;;;24251:14:8;::::1;24268:5;24251:14:::0;;;:8:::1;:14;::::0;;;;;;;:22;;-1:-1:-1;;24251:22:8::1;::::0;;24284;;18285:74:26;;;18375:18;;;18368:50;;;;24284:22:8::1;::::0;18258:18:26;24284:22:8::1;18117:307:26::0;19262:129:8;19316:14;4240:35;:13;19316:14;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;19338:48:::1;:13;19359:14:::0;19375:10:::1;19338:20;:48::i;3074:662:7:-:0;-1:-1:-1;;;;;3203:13:7;;3179:12;3203:13;;;:8;:13;;;;;;;;;:37;;-1:-1:-1;3229:10:7;3220:20;;;;:8;:20;;;;;;;;3203:37;3199:125;;;3257:60;;-1:-1:-1;;;3257:60:7;;15827:2:26;3257:60:7;;;15809:21:26;15866:2;15846:18;;;15839:30;15905:20;15885:18;;;15878:48;15943:18;;3257:60:7;15625:342:26;3199:125:7;3351:26;;;;;3366:10;3351:26;;;8268:74:26;3329:19:7;;3351:4;;:14;;8241:18:26;;3351:26:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3329:48;-1:-1:-1;;;;;;3387:17:7;;3383:349;;3421:62;;-1:-1:-1;;;3421:62:7;;20589:2:26;3421:62:7;;;20571:21:26;20628:2;20608:18;;;20601:30;20667:22;20647:18;;;20640:50;20707:18;;3421:62:7;20387:344:26;3383:349:7;3509:11;3500:6;:20;3496:236;;;3537:68;;-1:-1:-1;;;3537:68:7;;17049:2:26;3537:68:7;;;17031:21:26;17088:2;17068:18;;;17061:30;17127:28;17107:18;;;17100:56;17173:18;;3537:68:7;16847:350:26;3496:236:7;3636:43;:7;3655:10;3667:3;3672:6;3636:18;:43::i;:::-;3626:53;;3713:3;-1:-1:-1;;;;;3692:33:7;3701:10;-1:-1:-1;;;;;3692:33:7;;3718:6;3692:33;;;;4534:25:26;;4522:2;4507:18;;4388:177;3692:33:7;;;;;;;;3193:543;3074:662;;;;:::o;20041:154:8:-;-1:-1:-1;;;4240:35:8;:13;20096:4;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;20108:38:::1;:13;20143:1;20108:26;:38::i;:::-;20152;:13;-1:-1:-1::0;;;20179:10:8::1;20152:20;:38::i;17578:161::-:0;4544:35;:13;-1:-1:-1;;;4568:10:8;4544:17;:35::i;:::-;4540:97;;;17657:8:::1;:42:::0;;;::::1;-1:-1:-1::0;;;;;17657:42:8;::::1;::::0;;::::1;::::0;;;17710:24:::1;::::0;::::1;::::0;-1:-1:-1;;17710:24:8::1;24605:291:::0;:::o;5795:2101:7:-;5914:10;5905:20;;;;:8;:20;;;;;;;;5901:108;;;5942:60;;-1:-1:-1;;;5942:60:7;;15827:2:26;5942:60:7;;;15809:21:26;15866:2;15846:18;;;15839:30;15905:20;15885:18;;;15878:48;15943:18;;5942:60:7;15625:342:26;5901:108:7;6053:10;6014:15;3499:21:14;;;6032:7:7;3499:21:14;;;;;;6074:17:7;;;6070:59;;;6108:14;;;;;;;;;;;;;;6070:59;6138:29;;;;;;;:19;:29;;;;;:36;;;;;:::i;:::-;;;6178:1;6138:41;6134:128;;6196:59;;-1:-1:-1;;;6196:59:7;;20938:2:26;6196:59:7;;;20920:21:26;20977:2;20957:18;;;20950:30;21016:19;20996:18;;;20989:47;21053:18;;6196:59:7;20736:341:26;6134:128:7;6329:33;:7;6342:10;6354:7;6329:12;:33::i;:::-;6373:41;;4534:25:26;;;6394:10:7;;6390:1;;6373:41;;4522:2:26;4507:18;6373:41:7;;;;;;;6500:89;;;6541:10;6500:89;;;21256:74:26;21346:18;;;21339:34;;;6500:89:7;;;;;;;;;21229:18:26;;;6500:89:7;;6813:26;;21555:16:26;6717:123:7;;;21539:102:26;21657:11;;;;21650:27;;;;6717:123:7;;;;;;;;;;21693:12:26;;;6717:123:7;;;;7000:8;;:214;;;;6500:89;;6681:1;;-1:-1:-1;;;;;;;7000:8:7;;:21;;:214;;7051:8;;7096:4;;6500:89;;-1:-1:-1;;6717:123:7;;7000:214;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6978:236;;;7293:9;7280:10;:22;7276:114;;;7319:64;;-1:-1:-1;;;7319:64:7;;22838:2:26;7319:64:7;;;22820:21:26;22877:2;22857:18;;;22850:30;22916:24;22896:18;;;22889:52;22958:18;;7319:64:7;22636:346:26;7276:114:7;7440:8;;7544:29;;;7440:8;7544:29;;;:19;:29;;;;;;7440:451;;;;;-1:-1:-1;;;;;7440:8:7;;;;:13;;7461:9;;7440:451;;7479:8;;7625:7;;7701:10;;7440:8;7834:13;;7440:451;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5895:2001;;;;;5795:2101;;:::o;16196:809:8:-;16423:27;;;16388:32;16423:27;;;:14;:27;;;;;;:40;;;;16451:11;;16423:40;:::i;:::-;;;;;;;;;;;;;;;;:48;;;;;;;;;;;16481:21;;;;16423:48;;-1:-1:-1;16477:110:8;;16533:47;;-1:-1:-1;;;16533:47:8;;24772:2:26;16533:47:8;;;24754:21:26;24811:1;24791:18;;;24784:29;24849:7;24829:18;;;24822:35;24874:18;;16533:47:8;24570:328:26;16477:110:8;16622:23;;16603:42;;;;:96;;;16678:9;:21;;;16665:8;;16655:19;;;;;;;:::i;:::-;;;;;;;;:44;;16603:96;16592:183;;;16721:47;;-1:-1:-1;;;16721:47:8;;25381:2:26;16721:47:8;;;25363:21:26;25420:1;25400:18;;;25393:29;25458:7;25438:18;;;25431:35;25483:18;;16721:47:8;25179:328:26;16592:183:8;16839:1;16813:27;;;16846:21;;;:34;16940:60;;;;;:4;;:16;;:60;;16957:11;;16970;;16983:6;;16991:8;;;;16940:60;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16342:663;16196:809;;;;;:::o;19510:133::-;19581:6;4240:35;:13;19581:6;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;19595:43:::1;:13;19613:14:::0;19629:8;19595:17:::1;:43::i;2707:253:7:-:0;3111:19:3;3134:13;;;;;;3133:14;;3179:34;;;;-1:-1:-1;3197:12:3;;3212:1;3197:12;;;;:16;3179:34;3178:108;;;-1:-1:-1;3258:4:3;1476:19:5;:23;;;3219:66:3;;-1:-1:-1;3268:12:3;;;;;:17;3219:66;3157:201;;;;-1:-1:-1;;;3157:201:3;;26632:2:26;3157:201:3;;;26614:21:26;26671:2;26651:18;;;26644:30;26710:34;26690:18;;;26683:62;26781:16;26761:18;;;26754:44;26815:19;;3157:201:3;26430:410:26;3157:201:3;3368:12;:16;;-1:-1:-1;;3368:16:3;3383:1;3368:16;;;3394:65;;;;3428:13;:20;;;;;;;;3394:65;2868:55:7::1;2881:5;2888:7;2897:2;2902:6;2910:4;2916:6;2868:12;:55::i;:::-;2931:24;:22;:24::i;:::-;3483:14:3::0;3479:99;;;3529:5;3513:21;;;;;;3553:14;;-1:-1:-1;6451:36:26;;3553:14:3;;6439:2:26;6424:18;3553:14:3;;;;;;;3479:99;3101:483;2707:253:7;;;;;:::o;10487:195:8:-;-1:-1:-1;;;;;4073:23:14;;;10607:17:8;4073:23:14;;;:16;:23;;;;;;;;:32;;;;;;;;;;;;10639:38:8;3930:180:14;22074:239:8;22156:4;4240:35;:13;22156:4;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;22172:20;;::::1;22180:12:::0;22172:20:::1;::::0;:46:::1;;-1:-1:-1::0;22196:22:8;;::::1;22204:14:::0;22196:22:::1;22172:46;22168:141;;;22235:14;;;;;;;;;;;;;;22168:141;22270:32;:13;22288:4:::0;22294:7;22270:17:::1;:32::i;17183:218::-:0;4544:35;:13;-1:-1:-1;;;4568:10:8;4544:17;:35::i;:::-;4540:97;;;17297:29:::1;::::0;::::1;;::::0;;;:19:::1;:29;::::0;;;;:46:::1;17329:14:::0;;17297:29;:46:::1;:::i;:::-;;17354:42;17371:8;17381:14;;17354:42;;;;;;;;:::i;:::-;;;;;;;;22444:348:::0;;;:::o;18270:216::-;18346:6;4240:35;:13;18346:6;4264:10;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;;18360:36:::1;:13;18378:6:::0;18386:9;18360:17:::1;:36::i;:::-;18402:33;:13;18425:9:::0;18402:22:::1;:33::i;:::-;18441:40;:13;18462:6:::0;18470:10:::1;18441:20;:40::i;2621:120:14:-:0;2698:13;2726:5;:10;;2719:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2621:120;;;:::o;3885:234:17:-;3997:4;-1:-1:-1;;;;;4013:21:17;;4009:63;;4051:14;;;;;;;;;;;;;;4009:63;-1:-1:-1;;;;;;4084:20:17;:11;:20;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;3885:234::o;8486:389:7:-;8650:14;8666;8695:8;8684:40;;;;;;;;;;;;:::i;:::-;8649:75;;-1:-1:-1;8649:75:7;-1:-1:-1;8795:28:7;:7;8649:75;;8795:12;:28::i;:::-;8834:36;;4534:25:26;;;-1:-1:-1;;;;;8834:36:7;;;8851:1;;8834:36;;4522:2:26;4507:18;8834:36:7;;;;;;;8629:246;;8486:389;;;;:::o;3529:397:14:-;-1:-1:-1;;;;;3499:21:14;;3650:12;3499:21;;;;;;;;;;;3731:7;3723:5;:15;3719:92;;;3755:49;;-1:-1:-1;;;3755:49:14;;30008:2:26;3755:49:14;;;29990:21:26;30047:1;30027:18;;;30020:29;30085:9;30065:18;;;30058:37;30112:18;;3755:49:14;29806:330:26;3719:92:14;-1:-1:-1;;;;;;;3834:20:14;;;:14;:20;;;;;;;;;;;:29;;;;;;;3871:18;;;;;;:27;;;;;;-1:-1:-1;3529:397:14;;;;;;:::o;3145:363:17:-;-1:-1:-1;;;;;3244:21:17;;3240:174;;3282:14;;;;;;;;;;;;;;3240:174;3313:28;3317:4;3323:8;3333:7;3313:3;:28::i;:::-;3309:105;;;3358:49;;-1:-1:-1;;;3358:49:17;;30343:2:26;3358:49:17;;;30325:21:26;30382:1;30362:18;;;30355:29;30420:9;30400:18;;;30393:37;30447:18;;3358:49:17;30141:330:26;3309:105:17;-1:-1:-1;;;;;3419:20:17;;:11;:20;;;;;;;;;;;:30;;;;;;;;;;;;;:37;;-1:-1:-1;;3419:37:17;3452:4;3419:37;;;;;;3467:36;;30670:98:26;;;30784:18;;;30777:83;;;;30876:18;;;30869:50;;;;3467:36:17;;30658:2:26;30643:18;3467:36:17;30476:449:26;4543:435:17;4631:24;4635:4;-1:-1:-1;;;4647:7:17;4631:3;:24::i;:::-;4627:347;;;4679:14;;;;;-1:-1:-1;;;;;4701:24:17;;;;;;;;;;;4738:41;;4679:14;;;4701:24;4679:14;;4738:41;;4665:11;;4738:41;4657:129;3761:222:4;;:::o;4627:347:17:-;-1:-1:-1;;;;;4796:21:17;;4792:182;;4841:10;;;;;-1:-1:-1;;;;;4859:20:17;;;;;;;;;;;4892:33;;4841:10;;;4859:20;4841:10;;4892:33;;4827:11;;4892:33;4819:113;3761:222:4;;:::o;3512:369:17:-;-1:-1:-1;;;;;3614:21:17;;3610:175;;3652:14;;;;;;;;;;;;;;3610:175;3684:28;3688:4;3694:8;3704:7;3684:3;:28::i;:::-;3679:106;;3729:49;;-1:-1:-1;;;3729:49:17;;31132:2:26;3729:49:17;;;31114:21:26;31171:1;31151:18;;;31144:29;31209:9;31189:18;;;31182:37;31236:18;;3729:49:17;30930:330:26;3679:106:17;-1:-1:-1;;;;;3790:20:17;;3823:5;3790:20;;;;;;;;;;;:30;;;;;;;;;;;;:38;;-1:-1:-1;;3790:38:17;;;3839:37;;30670:98:26;;;30784:18;;;30777:83;;;;30876:18;;;30869:50;3839:37:17;;30658:2:26;30643:18;3839:37:17;30476:449:26;2964:106:7;-1:-1:-1;;;4240:35:8;:13;3044:5:7;4264:10:8;4240:17;:35::i;:::-;:75;;;-1:-1:-1;4279:36:8;:13;-1:-1:-1;;;4304:10:8;4279:17;:36::i;:::-;4236:137;;4352:14;;;;;;;;;;;;;;2938:974:1;951:66;3384:59;;;3380:526;;;3459:37;3478:17;3459:18;:37::i;3380:526::-;3560:17;-1:-1:-1;;;;;3531:61:1;;:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3531:63:1;;;;;;;;-1:-1:-1;;3531:63:1;;;;;;;;;;;;:::i;:::-;;;3527:302;;3758:56;;-1:-1:-1;;;3758:56:1;;31656:2:26;3758:56:1;;;31638:21:26;31695:2;31675:18;;;31668:30;31734:34;31714:18;;;31707:62;31805:16;31785:18;;;31778:44;31839:19;;3758:56:1;31454:410:26;3527:302:1;1292:66;3644:28;;3636:82;;;;-1:-1:-1;;;3636:82:1;;32071:2:26;3636:82:1;;;32053:21:26;32110:2;32090:18;;;32083:30;32149:34;32129:18;;;32122:62;32220:11;32200:18;;;32193:39;32249:19;;3636:82:1;31869:405:26;3636:82:1;3595:138;3842:53;3860:17;3879:4;3885:9;3842:17;:53::i;4621:362:14:-;-1:-1:-1;;;;;3499:21:14;;4718:18;3499:21;;;;;;;;;;;4777:19;;;4773:96;;;4813:49;;-1:-1:-1;;;4813:49:14;;30008:2:26;4813:49:14;;;29990:21:26;30047:1;30027:18;;;30020:29;30085:9;30065:18;;;30058:37;30112:18;;4813:49:14;29806:330:26;4773:96:14;-1:-1:-1;;;;;4892:23:14;;;:14;:23;;;;;;;;;;4918:19;;;;4892:45;;;4945:17;;;;:27;;;;;;;;4621:362::o;4982:421:17:-;5066:26;5070:4;5076:6;5084:7;5066:3;:26::i;:::-;5062:337;;;5116:10;;;;;-1:-1:-1;;;;;5134:20:17;;;;;;;;;;;5167:37;;5116:10;;;5134:20;5116:10;;5167:37;;5102:11;;5167:37;5094:117;3761:222:4;;:::o;2869:124:14:-;2948:13;2976:5;:12;;2969:19;;;;;:::i;4722:508:8:-;4910:13:3;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:3;;32481:2:26;4902:69:3;;;32463:21:26;32520:2;32500:18;;;32493:30;32559:34;32539:18;;;32532:62;32630:13;32610:18;;;32603:41;32661:19;;4902:69:3;32279:407:26;4902:69:3;4913:22:8::1;:7;4929:5:::0;4913:15:::1;:22::i;:::-;4941:26;:7;4959::::0;4941:17:::1;:26::i;:::-;3084:14:14::0;:28;;-1:-1:-1;;3084:28:14;;;;;;;5009:32:8::1;:13;-1:-1:-1::0;;;5034:6:8;5009:17:::1;:32::i;:::-;5047:30;:13;5070:6:::0;5047:22:::1;:30::i;:::-;5083:29;:13;-1:-1:-1::0;;;5107:4:8;5083:17:::1;:29::i;:::-;5118:32;:13;5145:4:::0;5118:26:::1;:32::i;:::-;5156:33;:13;5174:6:::0;5182;5156:17:::1;:33::i;:::-;5195:30;:13;5218:6:::0;5195:22:::1;:30::i;1042:67:4:-:0;4910:13:3;;;;;;;4902:69;;;;-1:-1:-1;;;4902:69:3;;32481:2:26;4902:69:3;;;32463:21:26;32520:2;32500:18;;;32493:30;32559:34;32539:18;;;32532:62;32630:13;32610:18;;;32603:41;32661:19;;4902:69:3;32279:407:26;4902:69:3;1042:67:4:o;4322:295:14:-;-1:-1:-1;;;;;4423:21:14;;4419:98;;4461:49;;-1:-1:-1;;;4461:49:14;;32893:2:26;4461:49:14;;;32875:21:26;32932:1;32912:18;;;32905:29;32970:9;32950:18;;;32943:37;32997:18;;4461:49:14;32691:330:26;4419:98:14;4543:6;4522:5;:17;;;:27;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;4573:23:14;;;:14;:23;;;;;;;;;;;;:33;;;;;;;4322:295::o;1805:281:1:-;-1:-1:-1;;;;;1476:19:5;;;1878:106:1;;;;-1:-1:-1;;;1878:106:1;;33358:2:26;1878:106:1;;;33340:21:26;33397:2;33377:18;;;33370:30;33436:34;33416:18;;;33409:62;33507:15;33487:18;;;33480:43;33540:19;;1878:106:1;33156:409:26;1878:106:1;1292:66;1994:85;;;;-1:-1:-1;;;;;1994:85:1;;;;;;;;;;1805:281::o;2478:288::-;2616:29;2627:17;2616:10;:29::i;:::-;2673:1;2659:4;:11;:15;:28;;;;2678:9;2659:28;2655:105;;;2703:46;2725:17;2744:4;2703:21;:46::i;2505:112:14:-;2592:10;;;:20;2605:7;2592:10;:20;:::i;2745:120::-;2836:12;;;:24;2851:9;2836:12;:24;:::i;4123:416:17:-;4207:25;4211:4;-1:-1:-1;;;4224:7:17;4207:3;:25::i;:::-;4203:332;;;4256:10;;;;;-1:-1:-1;;;;;4274:20:17;;;;;;;;;;;4307:33;;4256:10;;;4274:20;4256:10;;4307:33;;4242:11;;4307:33;4234:113;3761:222:4;;:::o;2192:152:1:-;2258:37;2277:17;2258:18;:37::i;:::-;2310:27;;-1:-1:-1;;;;;2310:27:1;;;;;;;;2192:152;:::o;7088:455::-;7171:12;-1:-1:-1;;;;;1476:19:5;;;7195:88:1;;;;-1:-1:-1;;;7195:88:1;;35246:2:26;7195:88:1;;;35228:21:26;35285:2;35265:18;;;35258:30;35324:34;35304:18;;;35297:62;35395:8;35375:18;;;35368:36;35421:19;;7195:88:1;35044:402:26;7195:88:1;7354:12;7368:23;7395:6;-1:-1:-1;;;;;7395:19:1;7415:4;7395:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7353:67;;;;7437:99;7473:7;7482:10;7437:99;;;;;;;;;;;;;;;;;:35;:99::i;:::-;7430:106;7088:455;-1:-1:-1;;;;;7088:455:1:o;6622:742:5:-;6768:12;6796:7;6792:566;;;-1:-1:-1;6826:10:5;6819:17;;6792:566;6937:17;;:21;6933:415;;7181:10;7175:17;7241:15;7228:10;7224:2;7220:19;7213:44;6933:415;7320:12;7313:20;;-1:-1:-1;;;7313:20:5;;;;;;;;:::i;14:159:26:-;81:20;;141:6;130:18;;120:29;;110:57;;163:1;160;153:12;110:57;14:159;;;:::o;178:184::-;230:77;227:1;220:88;327:4;324:1;317:15;351:4;348:1;341:15;367:334;438:2;432:9;494:2;484:13;;-1:-1:-1;;480:86:26;468:99;;597:18;582:34;;618:22;;;579:62;576:88;;;644:18;;:::i;:::-;680:2;673:22;367:334;;-1:-1:-1;367:334:26:o;706:589::-;748:5;801:3;794:4;786:6;782:17;778:27;768:55;;819:1;816;809:12;768:55;855:6;842:20;881:18;877:2;874:26;871:52;;;903:18;;:::i;:::-;947:114;1055:4;-1:-1:-1;;979:4:26;975:2;971:13;967:86;963:97;947:114;:::i;:::-;1086:2;1077:7;1070:19;1132:3;1125:4;1120:2;1112:6;1108:15;1104:26;1101:35;1098:55;;;1149:1;1146;1139:12;1098:55;1214:2;1207:4;1199:6;1195:17;1188:4;1179:7;1175:18;1162:55;1262:1;1237:16;;;1255:4;1233:27;1226:38;;;;1241:7;706:589;-1:-1:-1;;;706:589:26:o;1300:171::-;1367:20;;1427:18;1416:30;;1406:41;;1396:69;;1461:1;1458;1451:12;1476:684;1578:6;1586;1594;1602;1655:3;1643:9;1634:7;1630:23;1626:33;1623:53;;;1672:1;1669;1662:12;1623:53;1695:28;1713:9;1695:28;:::i;:::-;1685:38;;1774:2;1763:9;1759:18;1746:32;1797:18;1838:2;1830:6;1827:14;1824:34;;;1854:1;1851;1844:12;1824:34;1877:49;1918:7;1909:6;1898:9;1894:22;1877:49;:::i;:::-;1867:59;;1945:37;1978:2;1967:9;1963:18;1945:37;:::i;:::-;1935:47;;2035:2;2024:9;2020:18;2007:32;1991:48;;2064:2;2054:8;2051:16;2048:36;;;2080:1;2077;2070:12;2048:36;;2103:51;2146:7;2135:8;2124:9;2120:24;2103:51;:::i;:::-;2093:61;;;1476:684;;;;;;;:::o;2165:219::-;2232:20;;2292:66;2281:78;;2271:89;;2261:117;;2374:1;2371;2364:12;2389:184;2447:6;2500:2;2488:9;2479:7;2475:23;2471:32;2468:52;;;2516:1;2513;2506:12;2468:52;2539:28;2557:9;2539:28;:::i;2770:250::-;2855:1;2865:113;2879:6;2876:1;2873:13;2865:113;;;2955:11;;;2949:18;2936:11;;;2929:39;2901:2;2894:10;2865:113;;;-1:-1:-1;;3012:1:26;2994:16;;2987:27;2770:250::o;3025:330::-;3067:3;3105:5;3099:12;3132:6;3127:3;3120:19;3148:76;3217:6;3210:4;3205:3;3201:14;3194:4;3187:5;3183:16;3148:76;:::i;:::-;3269:2;3257:15;-1:-1:-1;;3253:88:26;3244:98;;;;3344:4;3240:109;;3025:330;-1:-1:-1;;3025:330:26:o;3360:220::-;3509:2;3498:9;3491:21;3472:4;3529:45;3570:2;3559:9;3555:18;3547:6;3529:45;:::i;3585:154::-;-1:-1:-1;;;;;3664:5:26;3660:54;3653:5;3650:65;3640:93;;3729:1;3726;3719:12;3744:315;3812:6;3820;3873:2;3861:9;3852:7;3848:23;3844:32;3841:52;;;3889:1;3886;3879:12;3841:52;3928:9;3915:23;3947:31;3972:5;3947:31;:::i;:::-;3997:5;4049:2;4034:18;;;;4021:32;;-1:-1:-1;;;3744:315:26:o;4064:319::-;4131:6;4139;4192:2;4180:9;4171:7;4167:23;4163:32;4160:52;;;4208:1;4205;4198:12;4160:52;4231:28;4249:9;4231:28;:::i;:::-;4221:38;;4309:2;4298:9;4294:18;4281:32;4322:31;4347:5;4322:31;:::i;:::-;4372:5;4362:15;;;4064:319;;;;;:::o;4570:456::-;4647:6;4655;4663;4716:2;4704:9;4695:7;4691:23;4687:32;4684:52;;;4732:1;4729;4722:12;4684:52;4771:9;4758:23;4790:31;4815:5;4790:31;:::i;:::-;4840:5;-1:-1:-1;4897:2:26;4882:18;;4869:32;4910:33;4869:32;4910:33;:::i;:::-;4570:456;;4962:7;;-1:-1:-1;;;5016:2:26;5001:18;;;;4988:32;;4570:456::o;5031:1021::-;5115:6;5146:2;5189;5177:9;5168:7;5164:23;5160:32;5157:52;;;5205:1;5202;5195:12;5157:52;5245:9;5232:23;5274:18;5315:2;5307:6;5304:14;5301:34;;;5331:1;5328;5321:12;5301:34;5369:6;5358:9;5354:22;5344:32;;5414:7;5407:4;5403:2;5399:13;5395:27;5385:55;;5436:1;5433;5426:12;5385:55;5472:2;5459:16;5494:2;5490;5487:10;5484:36;;;5500:18;;:::i;:::-;5546:2;5543:1;5539:10;5529:20;;5569:28;5593:2;5589;5585:11;5569:28;:::i;:::-;5631:15;;;5701:11;;;5697:20;;;5662:12;;;;5729:19;;;5726:39;;;5761:1;5758;5751:12;5726:39;5785:11;;;;5805:217;5821:6;5816:3;5813:15;5805:217;;;5901:3;5888:17;5875:30;;5918:31;5943:5;5918:31;:::i;:::-;5962:18;;;5838:12;;;;6000;;;;5805:217;;;6041:5;5031:1021;-1:-1:-1;;;;;;;;5031:1021:26:o;6057:247::-;6116:6;6169:2;6157:9;6148:7;6144:23;6140:32;6137:52;;;6185:1;6182;6175:12;6137:52;6224:9;6211:23;6243:31;6268:5;6243:31;:::i;6498:180::-;6557:6;6610:2;6598:9;6589:7;6585:23;6581:32;6578:52;;;6626:1;6623;6616:12;6578:52;-1:-1:-1;6649:23:26;;6498:180;-1:-1:-1;6498:180:26:o;6683:455::-;6760:6;6768;6821:2;6809:9;6800:7;6796:23;6792:32;6789:52;;;6837:1;6834;6827:12;6789:52;6876:9;6863:23;6895:31;6920:5;6895:31;:::i;:::-;6945:5;-1:-1:-1;7001:2:26;6986:18;;6973:32;7028:18;7017:30;;7014:50;;;7060:1;7057;7050:12;7014:50;7083:49;7124:7;7115:6;7104:9;7100:22;7083:49;:::i;:::-;7073:59;;;6683:455;;;;;:::o;7578:184::-;7636:6;7689:2;7677:9;7668:7;7664:23;7660:32;7657:52;;;7705:1;7702;7695:12;7657:52;7728:28;7746:9;7728:28;:::i;8353:460::-;8438:6;8446;8454;8507:2;8495:9;8486:7;8482:23;8478:32;8475:52;;;8523:1;8520;8513:12;8475:52;8546:28;8564:9;8546:28;:::i;:::-;8536:38;;8625:2;8614:9;8610:18;8597:32;8652:18;8644:6;8641:30;8638:50;;;8684:1;8681;8674:12;8638:50;8707:49;8748:7;8739:6;8728:9;8724:22;8707:49;:::i;:::-;8697:59;;;8803:2;8792:9;8788:18;8775:32;8765:42;;8353:460;;;;;:::o;9071:252::-;9138:6;9146;9199:2;9187:9;9178:7;9174:23;9170:32;9167:52;;;9215:1;9212;9205:12;9167:52;9238:28;9256:9;9238:28;:::i;9328:347::-;9379:8;9389:6;9443:3;9436:4;9428:6;9424:17;9420:27;9410:55;;9461:1;9458;9451:12;9410:55;-1:-1:-1;9484:20:26;;9527:18;9516:30;;9513:50;;;9559:1;9556;9549:12;9513:50;9596:4;9588:6;9584:17;9572:29;;9648:3;9641:4;9632:6;9624;9620:19;9616:30;9613:39;9610:59;;;9665:1;9662;9655:12;9610:59;9328:347;;;;;:::o;9680:773::-;9784:6;9792;9800;9808;9816;9869:3;9857:9;9848:7;9844:23;9840:33;9837:53;;;9886:1;9883;9876:12;9837:53;9909:28;9927:9;9909:28;:::i;:::-;9899:38;;9988:2;9977:9;9973:18;9960:32;10011:18;10052:2;10044:6;10041:14;10038:34;;;10068:1;10065;10058:12;10038:34;10091:49;10132:7;10123:6;10112:9;10108:22;10091:49;:::i;:::-;10081:59;;10159:37;10192:2;10181:9;10177:18;10159:37;:::i;:::-;10149:47;;10249:2;10238:9;10234:18;10221:32;10205:48;;10278:2;10268:8;10265:16;10262:36;;;10294:1;10291;10284:12;10262:36;;10333:60;10385:7;10374:8;10363:9;10359:24;10333:60;:::i;:::-;9680:773;;;;-1:-1:-1;9680:773:26;;-1:-1:-1;10412:8:26;;10307:86;9680:773;-1:-1:-1;;;9680:773:26:o;10458:960::-;10573:6;10581;10589;10597;10605;10658:3;10646:9;10637:7;10633:23;10629:33;10626:53;;;10675:1;10672;10665:12;10626:53;10715:9;10702:23;10744:18;10785:2;10777:6;10774:14;10771:34;;;10801:1;10798;10791:12;10771:34;10824:49;10865:7;10856:6;10845:9;10841:22;10824:49;:::i;:::-;10814:59;;10926:2;10915:9;10911:18;10898:32;10882:48;;10955:2;10945:8;10942:16;10939:36;;;10971:1;10968;10961:12;10939:36;;10994:51;11037:7;11026:8;11015:9;11011:24;10994:51;:::i;:::-;10984:61;;;11095:2;11084:9;11080:18;11067:32;11108:31;11133:5;11108:31;:::i;:::-;11158:5;-1:-1:-1;11215:2:26;11200:18;;11187:32;11228:33;11187:32;11228:33;:::i;:::-;11280:7;-1:-1:-1;11339:3:26;11324:19;;11311:33;11353;11311;11353;:::i;:::-;11405:7;11395:17;;;10458:960;;;;;;;;:::o;11423:388::-;11491:6;11499;11552:2;11540:9;11531:7;11527:23;11523:32;11520:52;;;11568:1;11565;11558:12;11520:52;11607:9;11594:23;11626:31;11651:5;11626:31;:::i;11816:481::-;11894:6;11902;11910;11963:2;11951:9;11942:7;11938:23;11934:32;11931:52;;;11979:1;11976;11969:12;11931:52;12002:28;12020:9;12002:28;:::i;:::-;11992:38;;12081:2;12070:9;12066:18;12053:32;12108:18;12100:6;12097:30;12094:50;;;12140:1;12137;12130:12;12094:50;12179:58;12229:7;12220:6;12209:9;12205:22;12179:58;:::i;:::-;11816:481;;12256:8;;-1:-1:-1;12153:84:26;;-1:-1:-1;;;;11816:481:26:o;12635:437::-;12714:1;12710:12;;;;12757;;;12778:61;;12832:4;12824:6;12820:17;12810:27;;12778:61;12885:2;12877:6;12874:14;12854:18;12851:38;12848:218;;12922:77;12919:1;12912:88;13023:4;13020:1;13013:15;13051:4;13048:1;13041:15;13202:898;13328:3;13357:1;13390:6;13384:13;13420:36;13446:9;13420:36;:::i;:::-;13475:1;13492:18;;;13519:191;;;;13724:1;13719:356;;;;13485:590;;13519:191;-1:-1:-1;;13556:9:26;13552:82;13547:3;13540:95;13690:6;13683:14;13676:22;13668:6;13664:35;13659:3;13655:45;13648:52;;13519:191;;13719:356;13750:6;13747:1;13740:17;13780:4;13825:2;13822:1;13812:16;13850:1;13864:165;13878:6;13875:1;13872:13;13864:165;;;13956:14;;13943:11;;;13936:35;13999:16;;;;13893:10;;13864:165;;;13868:3;;;14058:6;14053:3;14049:16;14042:23;;13485:590;-1:-1:-1;14091:3:26;;13202:898;-1:-1:-1;;;;;;13202:898:26:o;14438:557::-;14695:6;14687;14683:19;14672:9;14665:38;14739:3;14734:2;14723:9;14719:18;14712:31;14646:4;14766:46;14807:3;14796:9;14792:19;14784:6;14766:46;:::i;:::-;14860:18;14852:6;14848:31;14843:2;14832:9;14828:18;14821:59;14928:9;14920:6;14916:22;14911:2;14900:9;14896:18;14889:50;14956:33;14982:6;14974;14956:33;:::i;:::-;14948:41;14438:557;-1:-1:-1;;;;;;;14438:557:26:o;15000:287::-;15129:3;15167:6;15161:13;15183:66;15242:6;15237:3;15230:4;15222:6;15218:17;15183:66;:::i;:::-;15265:16;;;;;15000:287;-1:-1:-1;;15000:287:26:o;15972:184::-;16042:6;16095:2;16083:9;16074:7;16070:23;16066:32;16063:52;;;16111:1;16108;16101:12;16063:52;-1:-1:-1;16134:16:26;;15972:184;-1:-1:-1;15972:184:26:o;17606:::-;17658:77;17655:1;17648:88;17755:4;17752:1;17745:15;17779:4;17776:1;17769:15;17795:128;17862:9;;;17883:11;;;17880:37;;;17897:18;;:::i;17928:184::-;17980:77;17977:1;17970:88;18077:4;18074:1;18067:15;18101:4;18098:1;18091:15;21716:665;21997:6;21989;21985:19;21974:9;21967:38;-1:-1:-1;;;;;22045:6:26;22041:55;22036:2;22025:9;22021:18;22014:83;22133:3;22128:2;22117:9;22113:18;22106:31;21948:4;22160:46;22201:3;22190:9;22186:19;22178:6;22160:46;:::i;:::-;22256:6;22249:14;22242:22;22237:2;22226:9;22222:18;22215:50;22314:9;22306:6;22302:22;22296:3;22285:9;22281:19;22274:51;22342:33;22368:6;22360;22342:33;:::i;22386:245::-;22465:6;22473;22526:2;22514:9;22505:7;22501:23;22497:32;22494:52;;;22542:1;22539;22532:12;22494:52;-1:-1:-1;;22565:16:26;;22621:2;22606:18;;;22600:25;22565:16;;22600:25;;-1:-1:-1;22386:245:26:o;22987:1578::-;23333:6;23325;23321:19;23310:9;23303:38;23284:4;23360:2;23398:3;23393:2;23382:9;23378:18;23371:31;23422:1;23455:6;23449:13;23485:36;23511:9;23485:36;:::i;:::-;23558:6;23552:3;23541:9;23537:19;23530:35;23584:3;23606:1;23638:2;23627:9;23623:18;23655:1;23650:216;;;;23880:1;23875:354;;;;23616:613;;23650:216;-1:-1:-1;;23702:9:26;23698:82;23693:2;23682:9;23678:18;23671:110;23853:2;23841:6;23834:14;23827:22;23824:1;23820:30;23809:9;23805:46;23801:55;23794:62;;23650:216;;23875:354;23906:6;23903:1;23896:17;23954:2;23951:1;23941:16;23979:1;23993:180;24007:6;24004:1;24001:13;23993:180;;;24100:14;;24076:17;;;24072:26;;24065:50;24143:16;;;;24022:10;;23993:180;;;24197:17;;24193:26;;;-1:-1:-1;;23616:613:26;;;;;;24274:9;24269:3;24265:19;24260:2;24249:9;24245:18;24238:47;24308:30;24334:3;24326:6;24308:30;:::i;:::-;24294:44;;;24347:46;24389:2;24378:9;24374:18;24366:6;-1:-1:-1;;;;;8056:54:26;8044:67;;7990:127;24347:46;-1:-1:-1;;;;;8056:54:26;;24444:3;24429:19;;8044:67;24498:9;24490:6;24486:22;24480:3;24469:9;24465:19;24458:51;24526:33;24552:6;24544;24526:33;:::i;:::-;24518:41;22987:1578;-1:-1:-1;;;;;;;;;22987:1578:26:o;24903:271::-;25086:6;25078;25073:3;25060:33;25042:3;25112:16;;25137:13;;;25112:16;24903:271;-1:-1:-1;24903:271:26:o;25512:325::-;25600:6;25595:3;25588:19;25652:6;25645:5;25638:4;25633:3;25629:14;25616:43;;25704:1;25697:4;25688:6;25683:3;25679:16;25675:27;25668:38;25570:3;25826:4;-1:-1:-1;;25751:2:26;25743:6;25739:15;25735:88;25730:3;25726:98;25722:109;25715:116;;25512:325;;;;:::o;25842:583::-;26109:6;26101;26097:19;26086:9;26079:38;26153:3;26148:2;26137:9;26133:18;26126:31;26060:4;26180:46;26221:3;26210:9;26206:19;26198:6;26180:46;:::i;:::-;26274:18;26266:6;26262:31;26257:2;26246:9;26242:18;26235:59;26342:9;26334:6;26330:22;26325:2;26314:9;26310:18;26303:50;26370:49;26412:6;26404;26396;26370:49;:::i;27044:544::-;27145:2;27140:3;27137:11;27134:448;;;27181:1;27206:5;27202:2;27195:17;27251:4;27247:2;27237:19;27321:2;27309:10;27305:19;27302:1;27298:27;27292:4;27288:38;27357:4;27345:10;27342:20;27339:47;;;-1:-1:-1;27380:4:26;27339:47;27435:2;27430:3;27426:12;27423:1;27419:20;27413:4;27409:31;27399:41;;27490:82;27508:2;27501:5;27498:13;27490:82;;;27553:17;;;27534:1;27523:13;27490:82;;27824:1321;27946:18;27941:3;27938:27;27935:53;;;27968:18;;:::i;:::-;27997:93;28086:3;28046:38;28078:4;28072:11;28046:38;:::i;:::-;28040:4;27997:93;:::i;:::-;28116:1;28141:2;28136:3;28133:11;28158:1;28153:734;;;;28931:1;28948:3;28945:93;;;-1:-1:-1;29004:19:26;;;28991:33;28945:93;27730:66;27721:1;27717:11;;;27713:84;27709:89;27699:100;27805:1;27801:11;;;27696:117;29051:78;;28126:1013;;28153:734;13149:1;13142:14;;;13186:4;13173:18;;-1:-1:-1;;28189:76:26;;;28348:9;28370:229;28384:7;28381:1;28378:14;28370:229;;;28473:19;;;28460:33;28445:49;;28580:4;28565:20;;;;28533:1;28521:14;;;;28400:12;28370:229;;;28374:3;28627;28618:7;28615:16;28612:219;;;28747:66;28741:3;28735;28732:1;28728:11;28724:21;28720:94;28716:99;28703:9;28698:3;28694:19;28681:33;28677:139;28669:6;28662:155;28612:219;;;28874:1;28868:3;28865:1;28861:11;28857:19;28851:4;28844:33;28126:1013;;;27824:1321;;;:::o;29150:326::-;29345:6;29337;29333:19;29322:9;29315:38;29389:2;29384;29373:9;29369:18;29362:30;29296:4;29409:61;29466:2;29455:9;29451:18;29443:6;29435;29409:61;:::i;29481:320::-;29568:6;29576;29629:2;29617:9;29608:7;29604:23;29600:32;29597:52;;;29645:1;29642;29635:12;29597:52;29677:9;29671:16;29696:31;29721:5;29696:31;:::i;:::-;29791:2;29776:18;;;;29770:25;29746:5;;29770:25;;-1:-1:-1;;;29481:320:26:o;33026:125::-;33091:9;;;33112:10;;;33109:36;;;33125:18;;:::i;33570:1469::-;33696:3;33690:10;33723:18;33715:6;33712:30;33709:56;;;33745:18;;:::i;:::-;33774:96;33863:6;33823:38;33855:4;33849:11;33823:38;:::i;:::-;33817:4;33774:96;:::i;:::-;33925:4;;33989:2;33978:14;;34006:1;34001:781;;;;34826:1;34843:6;34840:89;;;-1:-1:-1;34895:19:26;;;34889:26;34840:89;27730:66;27721:1;27717:11;;;27713:84;27709:89;27699:100;27805:1;27801:11;;;27696:117;34942:81;;33971:1062;;34001:781;13149:1;13142:14;;;13186:4;13173:18;;-1:-1:-1;;34037:79:26;;;34213:236;34227:7;34224:1;34221:14;34213:236;;;34316:19;;;34310:26;34295:42;;34408:27;;;;34376:1;34364:14;;;;34243:19;;34213:236;;;34217:3;34477:6;34468:7;34465:19;34462:261;;;34538:19;;;34532:26;34639:66;34621:1;34617:14;;;34633:3;34613:24;34609:97;34605:102;34590:118;34575:134;;34462:261;-1:-1:-1;;;;;34769:1:26;34753:14;;;34749:22;34736:36;;-1:-1:-1;33570:1469:26:o
Swarm Source
ipfs://b9e70586c31c5bd08b0b28b651559911f4644cded53f06dca8fda3a21c1fb4b6
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.