Contract Overview
Balance:
0 FTM
FTM Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0xe09b9382e829a0562810271d1a7275d57228ce907fa4666d9af14ae3adda4aad | 0x60a06040 | 31782715 | 399 days 8 hrs ago | 0x4b2f59151d4bb1692439226f872ae7d8b93a9b11 | IN | Create: FrockTokenV1 | 0 FTM | 14.85084 |
[ Download CSV Export ]
Latest 1 internal transaction
Parent Txn Hash | Block | From | To | Value | |||
---|---|---|---|---|---|---|---|
0xe09b9382e829a0562810271d1a7275d57228ce907fa4666d9af14ae3adda4aad | 31782715 | 399 days 8 hrs ago | 0x4b2f59151d4bb1692439226f872ae7d8b93a9b11 | Contract Creation | 0 FTM |
[ Download CSV Export ]
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:
FrockTokenV1
Compiler Version
v0.8.5+commit.a4f2e591
Contract Source Code (Solidity)
/** *Submitted for verification at FtmScan.com on 2022-02-23 */ pragma solidity 0.8.5; // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.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 a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } } // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) /** * @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); } // OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol) /** * @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) { assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { assembly { r.slot := slot } } } // OpenZeppelin Contracts v4.4.1 (proxy/ERC1967/ERC1967Upgrade.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 { __ERC1967Upgrade_init_unchained(); } 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 _upgradeToAndCallSecure( address newImplementation, bytes memory data, bool forceCall ) internal { address oldImplementation = _getImplementation(); // Initial upgrade and setup call _setImplementation(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } // Perform rollback test if not already in progress StorageSlotUpgradeable.BooleanSlot storage rollbackTesting = StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT); if (!rollbackTesting.value) { // Trigger rollback using upgradeTo from the new implementation rollbackTesting.value = true; _functionDelegateCall( newImplementation, abi.encodeWithSignature("upgradeTo(address)", oldImplementation) ); rollbackTesting.value = false; // Check rollback was effective require(oldImplementation == _getImplementation(), "ERC1967Upgrade: upgrade breaks further upgrades"); // Finally reset to the new implementation and log the upgrade _upgradeTo(newImplementation); } } /** * @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"); } uint256[50] private __gap; } // OpenZeppelin Contracts v4.4.1 (proxy/utils/UUPSUpgradeable.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, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { __ERC1967Upgrade_init_unchained(); __UUPSUpgradeable_init_unchained(); } 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 Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallSecure(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); _upgradeToAndCallSecure(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; uint256[50] private __gap; } // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { __Context_init_unchained(); } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; } // OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol) /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} uint256[45] private __gap; } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Capped.sol) /** * @dev Extension of {ERC20} that adds a cap to the supply of tokens. */ abstract contract ERC20CappedUpgradeable is Initializable, ERC20Upgradeable { uint256 private _cap; /** * @dev Sets the value of the `cap`. This value is immutable, it can only be * set once during construction. */ function __ERC20Capped_init(uint256 cap_) internal onlyInitializing { __Context_init_unchained(); __ERC20Capped_init_unchained(cap_); } function __ERC20Capped_init_unchained(uint256 cap_) internal onlyInitializing { require(cap_ > 0, "ERC20Capped: cap is 0"); _cap = cap_; } /** * @dev Returns the cap on the token's total supply. */ function cap() public view virtual returns (uint256) { return _cap; } /** * @dev See {ERC20-_mint}. */ function _mint(address account, uint256 amount) internal virtual override { require(ERC20Upgradeable.totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded"); super._mint(account, amount); } uint256[50] private __gap; } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Burnable.sol) /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20BurnableUpgradeable is Initializable, ContextUpgradeable, ERC20Upgradeable { function __ERC20Burnable_init() internal onlyInitializing { __Context_init_unchained(); __ERC20Burnable_init_unchained(); } function __ERC20Burnable_init_unchained() internal onlyInitializing { } /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { uint256 currentAllowance = allowance(account, _msgSender()); require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance"); unchecked { _approve(account, _msgSender(), currentAllowance - amount); } _burn(account, amount); } uint256[50] private __gap; } // OpenZeppelin Contracts v4.4.1 (utils/math/Math.sol) /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } } // OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol) /** * @dev Collection of functions related to array types. */ library ArraysUpgradeable { /** * @dev Searches a sorted `array` and returns the first index that contains * a value greater or equal to `element`. If no such index exists (i.e. all * values in the array are strictly less than `element`), the array length is * returned. Time complexity O(log n). * * `array` is expected to be sorted in ascending order, and to contain no * repeated elements. */ function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { if (array.length == 0) { return 0; } uint256 low = 0; uint256 high = array.length; while (low < high) { uint256 mid = MathUpgradeable.average(low, high); // Note that mid will always be strictly less than high (i.e. it will be a valid array index) // because Math.average rounds down (it does integer division with truncation). if (array[mid] > element) { high = mid; } else { low = mid + 1; } } // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. if (low > 0 && array[low - 1] == element) { return low - 1; } else { return low; } } } // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library CountersUpgradeable { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Snapshot.sol) /** * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and * total supply at the time are recorded for later access. * * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting. * In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be * used to create an efficient ERC20 forking mechanism. * * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id * and the account address. * * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it * return `block.number` will trigger the creation of snapshot at the begining of each new block. When overridding this * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract. * * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient * alternative consider {ERC20Votes}. * * ==== Gas Costs * * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much * smaller since identical balances in subsequent snapshots are stored as a single entry. * * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent * transfers will have normal cost until the next snapshot, and so on. */ abstract contract ERC20SnapshotUpgradeable is Initializable, ERC20Upgradeable { function __ERC20Snapshot_init() internal onlyInitializing { __Context_init_unchained(); __ERC20Snapshot_init_unchained(); } function __ERC20Snapshot_init_unchained() internal onlyInitializing { } // Inspired by Jordi Baylina's MiniMeToken to record historical balances: // https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol using ArraysUpgradeable for uint256[]; using CountersUpgradeable for CountersUpgradeable.Counter; // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a // Snapshot struct, but that would impede usage of functions that work on an array. struct Snapshots { uint256[] ids; uint256[] values; } mapping(address => Snapshots) private _accountBalanceSnapshots; Snapshots private _totalSupplySnapshots; // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid. CountersUpgradeable.Counter private _currentSnapshotId; /** * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created. */ event Snapshot(uint256 id); /** * @dev Creates a new snapshot and returns its snapshot id. * * Emits a {Snapshot} event that contains the same id. * * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a * set of accounts, for example using {AccessControl}, or it may be open to the public. * * [WARNING] * ==== * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking, * you must consider that it can potentially be used by attackers in two ways. * * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs * section above. * * We haven't measured the actual numbers; if this is something you're interested in please reach out to us. * ==== */ function _snapshot() internal virtual returns (uint256) { _currentSnapshotId.increment(); uint256 currentId = _getCurrentSnapshotId(); emit Snapshot(currentId); return currentId; } /** * @dev Get the current snapshotId */ function _getCurrentSnapshotId() internal view virtual returns (uint256) { return _currentSnapshotId.current(); } /** * @dev Retrieves the balance of `account` at the time `snapshotId` was created. */ function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) { (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]); return snapshotted ? value : balanceOf(account); } /** * @dev Retrieves the total supply at the time `snapshotId` was created. */ function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) { (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots); return snapshotted ? value : totalSupply(); } // Update balance and/or total supply snapshots before the values are modified. This is implemented // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations. function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); if (from == address(0)) { // mint _updateAccountSnapshot(to); _updateTotalSupplySnapshot(); } else if (to == address(0)) { // burn _updateAccountSnapshot(from); _updateTotalSupplySnapshot(); } else { // transfer _updateAccountSnapshot(from); _updateAccountSnapshot(to); } } function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) { require(snapshotId > 0, "ERC20Snapshot: id is 0"); require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id"); // When a valid snapshot is queried, there are three possibilities: // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds // to this id is the current one. // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the // requested id, and its value is the one to return. // c) More snapshots were created after the requested one, and the queried value was later modified. There will be // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is // larger than the requested one. // // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does // exactly this. uint256 index = snapshots.ids.findUpperBound(snapshotId); if (index == snapshots.ids.length) { return (false, 0); } else { return (true, snapshots.values[index]); } } function _updateAccountSnapshot(address account) private { _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account)); } function _updateTotalSupplySnapshot() private { _updateSnapshot(_totalSupplySnapshots, totalSupply()); } function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private { uint256 currentId = _getCurrentSnapshotId(); if (_lastSnapshotId(snapshots.ids) < currentId) { snapshots.ids.push(currentId); snapshots.values.push(currentValue); } } function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) { if (ids.length == 0) { return 0; } else { return ids[ids.length - 1]; } } uint256[46] private __gap; } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) /** * @dev String operations. */ library StringsUpgradeable { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } // OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol) /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSAUpgradeable { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 27) } return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", StringsUpgradeable.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol) /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ abstract contract EIP712Upgradeable is Initializable { /* solhint-disable var-name-mixedcase */ bytes32 private _HASHED_NAME; bytes32 private _HASHED_VERSION; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ function __EIP712_init(string memory name, string memory version) internal onlyInitializing { __EIP712_init_unchained(name, version); } function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash()); } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev The hash of the name parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712NameHash() internal virtual view returns (bytes32) { return _HASHED_NAME; } /** * @dev The hash of the version parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712VersionHash() internal virtual view returns (bytes32) { return _HASHED_VERSION; } uint256[50] private __gap; } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol) /** * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * _Available since v3.4._ */ abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable { using CountersUpgradeable for CountersUpgradeable.Counter; mapping(address => CountersUpgradeable.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private _PERMIT_TYPEHASH; /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ function __ERC20Permit_init(string memory name) internal onlyInitializing { __Context_init_unchained(); __EIP712_init_unchained(name, "1"); __ERC20Permit_init_unchained(name); } function __ERC20Permit_init_unchained(string memory name) internal onlyInitializing { _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");} /** * @dev See {IERC20Permit-permit}. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSAUpgradeable.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @dev See {IERC20Permit-nonces}. */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. * * _Available since v4.1._ */ function _useNonce(address owner) internal virtual returns (uint256 current) { CountersUpgradeable.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } uint256[49] private __gap; } // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControlUpgradeable { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; } // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing { __ERC165_init_unchained(); } function __ERC165_init_unchained() internal onlyInitializing { } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } uint256[50] private __gap; } // OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol) /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControlUpgradeable, ERC165Upgradeable { function __AccessControl_init() internal onlyInitializing { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); } function __AccessControl_init_unchained() internal onlyInitializing { } struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", StringsUpgradeable.toHexString(uint160(account), 20), " is missing role ", StringsUpgradeable.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } uint256[49] private __gap; } // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Context_init_unchained(); __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[49] private __gap; } /** * @title IERC1363 Interface * @author Vittorio Minacori (https://github.com/vittominacori) * @dev Interface for a Payable Token contract as defined in * https://eips.ethereum.org/EIPS/eip-1363 */ interface IERC1363Upgradeable is IERC20Upgradeable, IERC165Upgradeable { /** * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver * @param recipient address The address which you want to transfer to * @param amount uint256 The amount of tokens to be transferred * @return true unless throwing */ function transferAndCall(address recipient, uint256 amount) external returns (bool); /** * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver * @param recipient address The address which you want to transfer to * @param amount uint256 The amount of tokens to be transferred * @param data bytes Additional data with no specified format, sent in call to `recipient` * @return true unless throwing */ function transferAndCall( address recipient, uint256 amount, bytes calldata data ) external returns (bool); /** * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver * @param sender address The address which you want to send tokens from * @param recipient address The address which you want to transfer to * @param amount uint256 The amount of tokens to be transferred * @return true unless throwing */ function transferFromAndCall( address sender, address recipient, uint256 amount ) external returns (bool); /** * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver * @param sender address The address which you want to send tokens from * @param recipient address The address which you want to transfer to * @param amount uint256 The amount of tokens to be transferred * @param data bytes Additional data with no specified format, sent in call to `recipient` * @return true unless throwing */ function transferFromAndCall( address sender, address recipient, uint256 amount, bytes calldata data ) external returns (bool); /** * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender * and then call `onApprovalReceived` on spender. * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param spender address The address which will spend the funds * @param amount uint256 The amount of tokens to be spent */ function approveAndCall(address spender, uint256 amount) external returns (bool); /** * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender * and then call `onApprovalReceived` on spender. * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param spender address The address which will spend the funds * @param amount uint256 The amount of tokens to be spent * @param data bytes Additional data with no specified format, sent in call to `spender` */ function approveAndCall( address spender, uint256 amount, bytes calldata data ) external returns (bool); } /** * @title IERC1363Receiver Interface * @author Vittorio Minacori (https://github.com/vittominacori) * @dev Interface for any contract that wants to support transferAndCall or transferFromAndCall * from ERC1363 token contracts as defined in * https://eips.ethereum.org/EIPS/eip-1363 */ interface IERC1363Receiver { /** * @notice Handle the receipt of ERC1363 tokens * @dev Any ERC1363 smart contract calls this function on the recipient * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the * transfer. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the token contract address is always the message sender. * @param operator address The address which called `transferAndCall` or `transferFromAndCall` function * @param sender address The address which are token transferred from * @param amount uint256 The amount of tokens transferred * @param data bytes Additional data with no specified format * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` unless throwing */ function onTransferReceived( address operator, address sender, uint256 amount, bytes calldata data ) external returns (bytes4); } /** * @title IERC1363Spender Interface * @author Vittorio Minacori (https://github.com/vittominacori) * @dev Interface for any contract that wants to support approveAndCall * from ERC1363 token contracts as defined in * https://eips.ethereum.org/EIPS/eip-1363 */ interface IERC1363Spender { /** * @notice Handle the approval of ERC1363 tokens * @dev Any ERC1363 smart contract calls this function on the recipient * after an `approve`. This function MAY throw to revert and reject the * approval. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the token contract address is always the message sender. * @param sender address The address which called `approveAndCall` function * @param amount uint256 The amount of tokens to be spent * @param data bytes Additional data with no specified format * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` unless throwing */ function onApprovalReceived( address sender, uint256 amount, bytes calldata data ) external returns (bytes4); } /** * @title ERC1363 * @author Vittorio Minacori (https://github.com/vittominacori) * @dev Implementation of an ERC1363 interface */ abstract contract ERC1363Upgradeable is Initializable, ERC20Upgradeable, IERC1363Upgradeable, ERC165Upgradeable { using AddressUpgradeable for address; // solhint-disable-next-line func-name-mixedcase function __ERC1363_init(string memory name, string memory symbol) internal initializer { __ERC20_init_unchained(name, symbol); __ERC165_init_unchained(); __ERC1363_init_unchained(); } // solhint-disable-next-line func-name-mixedcase, no-empty-blocks function __ERC1363_init_unchained() internal initializer {} /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC1363Upgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Transfer tokens to a specified address and then execute a callback on recipient. * @param recipient The address to transfer to. * @param amount The amount to be transferred. * @return A boolean that indicates if the operation was successful. */ function transferAndCall(address recipient, uint256 amount) public virtual override returns (bool) { return transferAndCall(recipient, amount, ""); } /** * @dev Transfer tokens to a specified address and then execute a callback on recipient. * @param recipient The address to transfer to * @param amount The amount to be transferred * @param data Additional data with no specified format * @return A boolean that indicates if the operation was successful. */ function transferAndCall( address recipient, uint256 amount, bytes memory data ) public virtual override returns (bool) { transfer(recipient, amount); require( _checkAndCallTransfer(_msgSender(), recipient, amount, data), "ERC1363: _checkAndCallTransfer reverts" ); return true; } /** * @dev Transfer tokens from one address to another and then execute a callback on recipient. * @param sender The address which you want to send tokens from * @param recipient The address which you want to transfer to * @param amount The amount of tokens to be transferred * @return A boolean that indicates if the operation was successful. */ function transferFromAndCall( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { return transferFromAndCall(sender, recipient, amount, ""); } /** * @dev Transfer tokens from one address to another and then execute a callback on recipient. * @param sender The address which you want to send tokens from * @param recipient The address which you want to transfer to * @param amount The amount of tokens to be transferred * @param data Additional data with no specified format * @return A boolean that indicates if the operation was successful. */ function transferFromAndCall( address sender, address recipient, uint256 amount, bytes memory data ) public virtual override returns (bool) { transferFrom(sender, recipient, amount); require( _checkAndCallTransfer(sender, recipient, amount, data), "ERC1363: _checkAndCallTransfer reverts" ); return true; } /** * @dev Approve spender to transfer tokens and then execute a callback on recipient. * @param spender The address allowed to transfer to * @param amount The amount allowed to be transferred * @return A boolean that indicates if the operation was successful. */ function approveAndCall(address spender, uint256 amount) public virtual override returns (bool) { return approveAndCall(spender, amount, ""); } /** * @dev Approve spender to transfer tokens and then execute a callback on recipient. * @param spender The address allowed to transfer to. * @param amount The amount allowed to be transferred. * @param data Additional data with no specified format. * @return A boolean that indicates if the operation was successful. */ function approveAndCall( address spender, uint256 amount, bytes memory data ) public virtual override returns (bool) { approve(spender, amount); require( _checkAndCallApprove(spender, amount, data), "ERC1363: _checkAndCallApprove reverts" ); return true; } /** * @dev Internal function to invoke `onTransferReceived` on a target address * The call is not executed if the target address is not a contract * @param sender address Representing the previous owner of the given token value * @param recipient address Target address that will receive the tokens * @param amount uint256 The amount mount of tokens to be transferred * @param data bytes Optional data to send along with the call * @return whether the call correctly returned the expected magic value */ function _checkAndCallTransfer( address sender, address recipient, uint256 amount, bytes memory data ) internal virtual returns (bool) { if (!recipient.isContract()) { return false; } bytes4 retval = IERC1363Receiver(recipient).onTransferReceived( _msgSender(), sender, amount, data ); return (retval == IERC1363Receiver(recipient).onTransferReceived.selector); } /** * @dev Internal function to invoke `onApprovalReceived` on a target address * The call is not executed if the target address is not a contract * @param spender address The address which will spend the funds * @param amount uint256 The amount of tokens to be spent * @param data bytes Optional data to send along with the call * @return whether the call correctly returned the expected magic value */ function _checkAndCallApprove( address spender, uint256 amount, bytes memory data ) internal virtual returns (bool) { if (!spender.isContract()) { return false; } bytes4 retval = IERC1363Spender(spender).onApprovalReceived( _msgSender(), amount, data ); return (retval == IERC1363Spender(spender).onApprovalReceived.selector); } uint256[50] private __gap; } // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using AddressUpgradeable for address; function safeTransfer( IERC20Upgradeable token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20Upgradeable token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20Upgradeable token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } /** * @title SafeTokenRecover * @author Vittorio Minacori (https://github.com/vittominacori) * @dev Allow to recover any ERC20 sent into the contract for error */ contract SafeTokenRecoverUpgradeable is Initializable, AccessControlUpgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; bytes32 public constant RESCUER_ROLE = keccak256("RESCUER_ROLE"); // solhint-disable-next-line func-name-mixedcase function __SafeTokenRecover_init() internal initializer { __Context_init_unchained(); __ERC165_init_unchained(); __AccessControl_init_unchained(); __SafeTokenRecover_init_unchained(); } // solhint-disable-next-line func-name-mixedcase, no-empty-blocks function __SafeTokenRecover_init_unchained() internal initializer { _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); } /** * @notice Recover ERC20 tokens locked up in this contract. * @param tokenAddress ERC20 token contract address * @param tokenAmount Amount to recover */ function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyRole(RESCUER_ROLE) { IERC20Upgradeable(tokenAddress).safeTransfer(_msgSender(), tokenAmount); } /** * @notice Rescue ERC20 tokens locked up in this contract. * @param tokenContract ERC20 token contract address * @param to Recipient address * @param amount Amount to rescue */ function rescueERC20( IERC20Upgradeable tokenContract, address to, uint256 amount ) external onlyRole(RESCUER_ROLE) { tokenContract.safeTransfer(to, amount); } uint256[50] private __gap; } contract TokenBasic is Initializable, UUPSUpgradeable, ERC20CappedUpgradeable, ERC20BurnableUpgradeable, ERC20PermitUpgradeable, ERC1363Upgradeable, AccessControlUpgradeable, SafeTokenRecoverUpgradeable, PausableUpgradeable, ERC20SnapshotUpgradeable { bytes32 public constant SNAPSHOTER = keccak256("SNAPSHOTER"); mapping (address => bool) public isExcludedFromFees; mapping(address => bool) public isBlacklisted; event ExcludeFromFees(address indexed account, bool isExcluded); event Blacklisted(address indexed account, bool blacklisted); function initialize( string memory name, string memory symbol, uint256 cap ) public initializer { __Context_init_unchained(); __ERC20_init_unchained(name, symbol); __EIP712_init_unchained(name, "1"); __ERC20Permit_init_unchained(name); __ERC165_init_unchained(); __AccessControl_init_unchained(); __ERC20Capped_init_unchained(cap); __ERC20Burnable_init_unchained(); __ERC20Snapshot_init_unchained(); __ERC1363_init_unchained(); __SafeTokenRecover_init_unchained(); __Pausable_init_unchained(); // Setup deployer as Admin when construction _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); // Minting _mint(_msgSender(), cap); // Exclude From Fee isExcludedFromFees[msg.sender] = true; } function excludeFromFees(address account, bool excluded) external onlyRole(DEFAULT_ADMIN_ROLE) { require(isExcludedFromFees[account] != excluded, "Account is already the value of 'excluded'"); isExcludedFromFees[account] = excluded; emit ExcludeFromFees(account, excluded); } function setBlacklist(address account, bool blacklisted) external onlyRole(DEFAULT_ADMIN_ROLE) { require(isBlacklisted[account] != blacklisted, "Account is already the value of 'blacklisted'"); isBlacklisted[account] = blacklisted; emit Blacklisted(account, blacklisted); } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 9; } /** * Function that should revert when msg.sender is not authorized to upgrade * the contract. * * Called by upgradeTo and upgradeToAndCall. */ function _authorizeUpgrade(address newImplementation) internal override { require(_msgSender() == _getAdmin(), "Not the Owner of Contract"); } // solhint-disable-line no-empty-blocks /** * @dev Function to mint tokens. * * @param account The address that will receive the minted tokens * @param amount The amount of tokens to mint */ function _mint(address account, uint256 amount) internal virtual override(ERC20CappedUpgradeable, ERC20Upgradeable) { ERC20CappedUpgradeable._mint(account, amount); } function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override(ERC20SnapshotUpgradeable, ERC20Upgradeable) { require(!PausableUpgradeable.paused(), "ERC20Pausable: token transfer while paused"); require(!isBlacklisted[from] && !isBlacklisted[to], "Blacklisted: user blacklisted"); ERC20SnapshotUpgradeable._beforeTokenTransfer(from, to, amount); } function pause() external onlyRole(DEFAULT_ADMIN_ROLE) { PausableUpgradeable._pause(); } function unpause() external onlyRole(DEFAULT_ADMIN_ROLE) { PausableUpgradeable._unpause(); } function paused() public view override virtual returns (bool) { return PausableUpgradeable.paused(); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1363Upgradeable, AccessControlUpgradeable) returns (bool) { return ERC1363Upgradeable.supportsInterface(interfaceId) || AccessControlUpgradeable.supportsInterface(interfaceId); } function snapshot() external onlyRole(SNAPSHOTER) returns (uint256) { return super._snapshot(); } function lastSnapshotId() external view returns (uint256) { return super._getCurrentSnapshotId(); } } // solhint-disable-next-line no-empty-blocks contract FrockTokenV1 is TokenBasic { bool public isAddressSetted; address public reflection; address public treasury; address public marketing; uint256 public reflectionPercentage; // Using 2 decimals uint256 public treasuryPercentage; // Using 2 decimals uint256 public marketingPercentage; // Using 2 decimals uint256 public totalTax; event ReflectionUpdated(address newReflectionAddress); event TreasuryUpdated(address newTreasuryAddress); event MarketingUpdated(address newMarketingAddress); event PercentageUpdated(uint256 reflectionPercentage, uint256 treasuryPercentage, uint256 marketingPercentage); function setReflection(address newAddress) external onlyRole(DEFAULT_ADMIN_ROLE) { reflection = newAddress; _setIsAddressSetted(); emit ReflectionUpdated(newAddress); } function setTreasury(address newAddress) external onlyRole(DEFAULT_ADMIN_ROLE) { treasury = newAddress; _setIsAddressSetted(); emit TreasuryUpdated(newAddress); } function setMarketing(address newAddress) external onlyRole(DEFAULT_ADMIN_ROLE) { marketing = newAddress; _setIsAddressSetted(); emit MarketingUpdated(newAddress); } function _setIsAddressSetted() private { isAddressSetted = (reflection != address(0) && treasury != address(0) && marketing != address(0)); } function setPercentage(uint256 reflectionPrctg, uint256 treasuryPrctg, uint256 marketingPrctg) external onlyRole(DEFAULT_ADMIN_ROLE) { require(reflectionPrctg + treasuryPrctg + marketingPrctg <= 22_00, "Tax: Maximal Tax is 22%"); reflectionPercentage = reflectionPrctg; treasuryPercentage = treasuryPrctg; marketingPercentage = marketingPrctg; totalTax = reflectionPrctg + treasuryPrctg + marketingPrctg; emit PercentageUpdated(reflectionPrctg, treasuryPrctg, marketingPercentage); } /** * @dev Override transfer function to apply tax deduction */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { super._transfer(_msgSender(), recipient, amount); _taxDeduction(_msgSender(), recipient, amount); return true; } /** * @dev Override transferFrom function to apply tax deduction */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { super.transferFrom(sender, recipient, amount); _taxDeduction(sender, recipient, amount); return true; } function _taxDeduction(address sender, address recipient, uint256 amount) internal virtual { if(!(isExcludedFromFees[sender] || isExcludedFromFees[recipient])) { require(isAddressSetted, "Tax : Address not set correctly"); require(totalTax > 0, "Tax : Percentage not set correctly"); // Calculate amount uint256 reflectionAmount = reflectionPercentage * amount / 100_00; uint256 treasuryAmount = treasuryPercentage * amount / 100_00; uint256 marketingAmount = marketingPercentage * amount / 100_00; // Transfer token _transfer(recipient, reflection, reflectionAmount); _transfer(recipient, treasury, treasuryAmount); _transfer(recipient, marketing, marketingAmount); } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"blacklisted","type":"bool"}],"name":"Blacklisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludeFromFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newMarketingAddress","type":"address"}],"name":"MarketingUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reflectionPercentage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"treasuryPercentage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"marketingPercentage","type":"uint256"}],"name":"PercentageUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newReflectionAddress","type":"address"}],"name":"ReflectionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Snapshot","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":"address","name":"newTreasuryAddress","type":"address"}],"name":"TreasuryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESCUER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SNAPSHOTER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approveAndCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"approveAndCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"snapshotId","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"excludeFromFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"cap","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isAddressSetted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isExcludedFromFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastSnapshotId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketing","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reflection","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reflectionPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"tokenContract","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"blacklisted","type":"bool"}],"name":"setBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setMarketing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"reflectionPrctg","type":"uint256"},{"internalType":"uint256","name":"treasuryPrctg","type":"uint256"},{"internalType":"uint256","name":"marketingPrctg","type":"uint256"}],"name":"setPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setReflection","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"snapshot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"uint256","name":"snapshotId","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferAndCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"transferAndCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"transferFromAndCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFromAndCall","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","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
60a06040523060601b60805234801561001757600080fd5b5060805160601c61423761004b60003960008181610e3501528181610e7501528181610fe7015261102701526142376000f3fe6080604052600436106103975760003560e01c80637ab56083116101dc578063b2118a8d11610102578063d8fbe994116100a0578063f0f442601161006f578063f0f4426014610ac6578063fce69f9814610ae6578063fe575a8714610b06578063fe85b42b14610b3757600080fd5b8063d8fbe99414610a15578063dd62ed3e14610a35578063de20308a14610a7b578063eb1e63ec14610a9257600080fd5b8063cae9ca51116100dc578063cae9ca511461099a578063cb2bb732146109ba578063d505accf146109d5578063d547741f146109f557600080fd5b8063b2118a8d1461093a578063c02466681461095a578063c1d34b891461097a57600080fd5b806391d148541161017a578063a217fddf11610149578063a217fddf146108c5578063a457c2d7146108da578063a9059cbb146108fa578063b119490e1461091a57600080fd5b806391d148541461085b57806395d89b411461087b5780639711715a14610890578063981b24d0146108a557600080fd5b8063837afbc0116101b6578063837afbc0146107f15780638456cb59146108065780638980f11f1461081b5780638b0414d51461083b57600080fd5b80637ab560831461079a5780637b1ad1d7146107b15780637ecebe00146107d157600080fd5b80633644e515116102c15780634ee2cd7e1161025f57806361d027b31161022e57806361d027b3146106ef57806370a0823114610710578063713725441461074657806379cc67901461077a57600080fd5b80634ee2cd7e146106765780634f1ef286146106965780634fbee193146106a95780635c975abb146106da57600080fd5b8063395093511161029b57806339509351146106015780633f4ba83a146106215780634000aea01461063657806342966c681461065657600080fd5b80633644e515146105ac57806336568abe146105c15780633659cfe6146105e157600080fd5b806323b872dd116103395780632f2ff15d116103085780632f2ff15d1461053b578063313ce5671461055b5780633177029f14610577578063355274ea1461059757600080fd5b806323b872dd1461048b578063248a9ca3146104ab578063268f8f77146104dc5780632d3e474a1461051a57600080fd5b80631296ee62116103755780631296ee6214610413578063153b0d1e1461043357806318160ddd146104555780631d1fb0c91461047457600080fd5b806301ffc9a71461039c57806306fdde03146103d1578063095ea7b3146103f3575b600080fd5b3480156103a857600080fd5b506103bc6103b7366004613ce3565b610b4e565b60405190151581526020015b60405180910390f35b3480156103dd57600080fd5b506103e6610b6e565b6040516103c89190613ed7565b3480156103ff57600080fd5b506103bc61040e366004613c03565b610c00565b34801561041f57600080fd5b506103bc61042e366004613c03565b610c16565b34801561043f57600080fd5b5061045361044e366004613b85565b610c39565b005b34801561046157600080fd5b506099545b6040519081526020016103c8565b34801561048057600080fd5b506104666102c65481565b34801561049757600080fd5b506103bc6104a6366004613a61565b610d32565b3480156104b757600080fd5b506104666104c6366004613ca5565b60009081526101f9602052604090206001015490565b3480156104e857600080fd5b506102c3546105029061010090046001600160a01b031681565b6040516001600160a01b0390911681526020016103c8565b34801561052657600080fd5b506102c554610502906001600160a01b031681565b34801561054757600080fd5b50610453610556366004613cbe565b610d55565b34801561056757600080fd5b50604051600981526020016103c8565b34801561058357600080fd5b506103bc610592366004613c03565b610d81565b3480156105a357600080fd5b5060c954610466565b3480156105b857600080fd5b50610466610d9d565b3480156105cd57600080fd5b506104536105dc366004613cbe565b610dac565b3480156105ed57600080fd5b506104536105fc366004613a0b565b610e2a565b34801561060d57600080fd5b506103bc61061c366004613c03565b610ef3565b34801561062d57600080fd5b50610453610f2f565b34801561064257600080fd5b506103bc610651366004613c2f565b610f43565b34801561066257600080fd5b50610453610671366004613ca5565b610f78565b34801561068257600080fd5b50610466610691366004613c03565b610f82565b6104536106a4366004613bb3565b610fdc565b3480156106b557600080fd5b506103bc6106c4366004613a0b565b6102c16020526000908152604090205460ff1681565b3480156106e657600080fd5b506103bc611092565b3480156106fb57600080fd5b506102c454610502906001600160a01b031681565b34801561071c57600080fd5b5061046661072b366004613a0b565b6001600160a01b031660009081526097602052604090205490565b34801561075257600080fd5b506104667fcf6f9f892731e14b8859835f2ff35575f447fb501f46243c4eb8bac19e31a05081565b34801561078657600080fd5b50610453610795366004613c03565b6110a1565b3480156107a657600080fd5b506104666102c75481565b3480156107bd57600080fd5b506104536107cc366004613a0b565b611122565b3480156107dd57600080fd5b506104666107ec366004613a0b565b611198565b3480156107fd57600080fd5b506104666111b7565b34801561081257600080fd5b506104536111c1565b34801561082757600080fd5b50610453610836366004613c03565b6111d5565b34801561084757600080fd5b50610453610856366004613a0b565b611214565b34801561086757600080fd5b506103bc610876366004613cbe565b61127d565b34801561088757600080fd5b506103e66112a9565b34801561089c57600080fd5b506104666112b8565b3480156108b157600080fd5b506104666108c0366004613ca5565b6112f4565b3480156108d157600080fd5b50610466600081565b3480156108e657600080fd5b506103bc6108f5366004613c03565b611320565b34801561090657600080fd5b506103bc610915366004613c03565b6113af565b34801561092657600080fd5b50610453610935366004613d1d565b6113c7565b34801561094657600080fd5b50610453610955366004613a61565b6114eb565b34801561096657600080fd5b50610453610975366004613b85565b61152a565b34801561098657600080fd5b506103bc610995366004613aa2565b611612565b3480156109a657600080fd5b506103bc6109b5366004613c2f565b611653565b3480156109c657600080fd5b506102c3546103bc9060ff1681565b3480156109e157600080fd5b506104536109f0366004613b0e565b6116c5565b348015610a0157600080fd5b50610453610a10366004613cbe565b61180c565b348015610a2157600080fd5b506103bc610a30366004613a61565b611833565b348015610a4157600080fd5b50610466610a50366004613a28565b6001600160a01b03918216600090815260986020908152604080832093909416825291909152205490565b348015610a8757600080fd5b506104666102c85481565b348015610a9e57600080fd5b506104667f5ab148f1d1bd666625ce84879016e3e7882fae77985c6c4f676e3383c230d06981565b348015610ad257600080fd5b50610453610ae1366004613a0b565b611850565b348015610af257600080fd5b50610453610b01366004613d8a565b6118b9565b348015610b1257600080fd5b506103bc610b21366004613a0b565b6102c26020526000908152604090205460ff1681565b348015610b4357600080fd5b506104666102c95481565b6000610b59826119a0565b80610b685750610b68826119d5565b92915050565b6060609a8054610b7d90614114565b80601f0160208091040260200160405190810160405280929190818152602001828054610ba990614114565b8015610bf65780601f10610bcb57610100808354040283529160200191610bf6565b820191906000526020600020905b815481529060010190602001808311610bd957829003601f168201915b5050505050905090565b6000610c0d3384846119fa565b50600192915050565b6000610c32838360405180602001604052806000815250610f43565b9392505050565b6000610c458133611b1e565b6001600160a01b03831660009081526102c2602052604090205460ff1615158215151415610cd05760405162461bcd60e51b815260206004820152602d60248201527f4163636f756e7420697320616c7265616479207468652076616c7565206f662060448201526c27626c61636b6c69737465642760981b60648201526084015b60405180910390fd5b6001600160a01b03831660008181526102c26020908152604091829020805460ff191686151590811790915591519182527fcf3473b85df1594d47b6958f29a32bea0abff9dd68296f7bf33443646793cfd891015b60405180910390a2505050565b6000610d3f848484611b82565b50610d4b848484611c21565b5060019392505050565b60008281526101f96020526040902060010154610d728133611b1e565b610d7c8383611dd2565b505050565b6000610c32838360405180602001604052806000815250611653565b6000610da7611e59565b905090565b6001600160a01b0381163314610e1c5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610cc7565b610e268282611ed6565b5050565b306001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161415610e735760405162461bcd60e51b8152600401610cc790613eea565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610ea5611f3e565b6001600160a01b031614610ecb5760405162461bcd60e51b8152600401610cc790613f36565b610ed481611f71565b60408051600080825260208201909252610ef091839190611fd9565b50565b3360008181526098602090815260408083206001600160a01b03871684529091528120549091610c0d918590610f2a908690614061565b6119fa565b6000610f3b8133611b1e565b610ef0612124565b6000610f4f84846113af565b50610f5c338585856121ba565b610d4b5760405162461bcd60e51b8152600401610cc790613f82565b610ef03382612278565b6001600160a01b038216600090815261028f6020526040812081908190610faa9085906123d2565b9150915081610fd1576001600160a01b038516600090815260976020526040902054610fd3565b805b95945050505050565b306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614156110255760405162461bcd60e51b8152600401610cc790613eea565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611057611f3e565b6001600160a01b03161461107d5760405162461bcd60e51b8152600401610cc790613f36565b61108682611f71565b610e2682826001611fd9565b6000610da761025d5460ff1690565b60006110ad8333610a50565b90508181101561110b5760405162461bcd60e51b8152602060048201526024808201527f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f77604482015263616e636560e01b6064820152608401610cc7565b61111883338484036119fa565b610d7c8383612278565b600061112e8133611b1e565b6102c38054610100600160a81b0319166101006001600160a01b038516021790556111576124c9565b6040516001600160a01b03831681527fb17b1085c482e9242145d9abbf42d7effa094c0a4573e624845ff23840fbaf49906020015b60405180910390a15050565b6001600160a01b03811660009081526101626020526040812054610b68565b6000610da761251f565b60006111cd8133611b1e565b610ef061252b565b7fcf6f9f892731e14b8859835f2ff35575f447fb501f46243c4eb8bac19e31a0506112008133611b1e565b610d7c6001600160a01b03841633846125a9565b60006112208133611b1e565b6102c580546001600160a01b0319166001600160a01b0384161790556112446124c9565b6040516001600160a01b03831681527feaf8ef35e433762aa696ae9447608369d638cec1961bd2317c4349bb5be9ee789060200161118c565b60009182526101f9602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060609b8054610b7d90614114565b60007f5ab148f1d1bd666625ce84879016e3e7882fae77985c6c4f676e3383c230d0696112e58133611b1e565b6112ed6125fb565b91505b5090565b6000806000611305846102906123d2565b915091508161131657609954611318565b805b949350505050565b3360009081526098602090815260408083206001600160a01b0386168452909152812054828110156113a25760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b6064820152608401610cc7565b610d4b33858584036119fa565b60006113bc338484612656565b610c0d338484611c21565b600054610100900460ff166113e25760005460ff16156113e6565b303b155b6114025760405162461bcd60e51b8152600401610cc790613fc8565b600054610100900460ff16158015611424576000805461ffff19166101011790555b61142c61282f565b6114368484612858565b61145984604051806040016040528060018152602001603160f81b8152506128a6565b611462846128e9565b61146a61282f565b61147261282f565b61147b82612938565b61148361282f565b61148b61282f565b6114936129ac565b61149b612a1d565b6114a3612a85565b6114ae600033612ab9565b6114b83383612ac3565b3360009081526102c160205260409020805460ff1916600117905580156114e5576000805461ff00191690555b50505050565b7fcf6f9f892731e14b8859835f2ff35575f447fb501f46243c4eb8bac19e31a0506115168133611b1e565b6114e56001600160a01b03851684846125a9565b60006115368133611b1e565b6001600160a01b03831660009081526102c1602052604090205460ff16151582151514156115b95760405162461bcd60e51b815260206004820152602a60248201527f4163636f756e7420697320616c7265616479207468652076616c7565206f6620604482015269276578636c756465642760b01b6064820152608401610cc7565b6001600160a01b03831660008181526102c16020908152604091829020805460ff191686151590811790915591519182527f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df79101610d25565b600061161f858585610d32565b5061162c858585856121ba565b6116485760405162461bcd60e51b8152600401610cc790613f82565b506001949350505050565b600061165f8484610c00565b5061166b848484612acd565b610d4b5760405162461bcd60e51b815260206004820152602560248201527f455243313336333a205f636865636b416e6443616c6c417070726f7665207265604482015264766572747360d81b6064820152608401610cc7565b834211156117155760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610cc7565b6000610163548888886117278c612b88565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061178282612bb1565b9050600061179282878787612bff565b9050896001600160a01b0316816001600160a01b0316146117f55760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610cc7565b6118008a8a8a6119fa565b50505050505050505050565b60008281526101f960205260409020600101546118298133611b1e565b610d7c8383611ed6565b600061131884848460405180602001604052806000815250611612565b600061185c8133611b1e565b6102c480546001600160a01b0319166001600160a01b0384161790556118806124c9565b6040516001600160a01b03831681527f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d19060200161118c565b60006118c58133611b1e565b610898826118d38587614061565b6118dd9190614061565b111561192b5760405162461bcd60e51b815260206004820152601760248201527f5461783a204d6178696d616c20546178206973203232250000000000000000006044820152606401610cc7565b6102c68490556102c78390556102c8829055816119488486614061565b6119529190614061565b6102c9556102c854604080518681526020810186905280820192909252517fdc5a6ff43d4bc77d157a8548d030d365d5e905062832400752bbf235de1bd2a19181900360600190a150505050565b60006001600160e01b0319821663b0202a1160e01b1480610b6857506301ffc9a760e01b6001600160e01b0319831614610b68565b60006001600160e01b03198216637965db0b60e01b1480610b685750610b68826119a0565b6001600160a01b038316611a5c5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610cc7565b6001600160a01b038216611abd5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610cc7565b6001600160a01b0383811660008181526098602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b611b28828261127d565b610e2657611b40816001600160a01b03166014612c27565b611b4b836020612c27565b604051602001611b5c929190613dfe565b60408051601f198184030181529082905262461bcd60e51b8252610cc791600401613ed7565b6000611b8f848484612656565b6001600160a01b038416600090815260986020908152604080832033845290915290205482811015611c145760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b6064820152608401610cc7565b61164885338584036119fa565b6001600160a01b03831660009081526102c1602052604090205460ff1680611c6257506001600160a01b03821660009081526102c1602052604090205460ff165b610d7c576102c35460ff16611cb95760405162461bcd60e51b815260206004820152601f60248201527f546178203a2041646472657373206e6f742073657420636f72726563746c79006044820152606401610cc7565b60006102c95411611d175760405162461bcd60e51b815260206004820152602260248201527f546178203a2050657263656e74616765206e6f742073657420636f72726563746044820152616c7960f01b6064820152608401610cc7565b6000612710826102c654611d2b919061409b565b611d359190614079565b90506000612710836102c754611d4b919061409b565b611d559190614079565b90506000612710846102c854611d6b919061409b565b611d759190614079565b9050611d98856102c360019054906101000a90046001600160a01b031685612656565b6102c454611db19086906001600160a01b031684612656565b6102c554611dca9086906001600160a01b031683612656565b505050505050565b611ddc828261127d565b610e265760008281526101f9602090815260408083206001600160a01b03851684529091529020805460ff19166001179055611e153390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000610da77f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611e8961012e5490565b61012f546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b611ee0828261127d565b15610e265760008281526101f9602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b546001600160a01b0316919050565b611f79612dc3565b6001600160a01b0316336001600160a01b031614610ef05760405162461bcd60e51b815260206004820152601960248201527f4e6f7420746865204f776e6572206f6620436f6e7472616374000000000000006044820152606401610cc7565b6000611fe3611f3e565b9050611fee84612deb565b600083511180611ffb5750815b1561200c5761200a8484612e90565b505b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143805460ff1661211d57805460ff191660011781556040516001600160a01b038316602482015261208b90869060440160408051601f198184030181529190526020810180516001600160e01b0316631b2ce7f360e11b179052612e90565b50805460ff1916815561209c611f3e565b6001600160a01b0316826001600160a01b0316146121145760405162461bcd60e51b815260206004820152602f60248201527f45524331393637557067726164653a207570677261646520627265616b73206660448201526e75727468657220757067726164657360881b6064820152608401610cc7565b61211d85612f72565b5050505050565b61212c611092565b61216f5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610cc7565b61025d805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60006001600160a01b0384163b6121d357506000611318565b604051632229f29760e21b81526000906001600160a01b038616906388a7ca5c906122089033908a9089908990600401613e73565b602060405180830381600087803b15801561222257600080fd5b505af1158015612236573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061225a9190613d00565b6001600160e01b031916632229f29760e21b14915050949350505050565b6001600160a01b0382166122d85760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610cc7565b6122e482600083612fb2565b6001600160a01b038216600090815260976020526040902054818110156123585760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610cc7565b6001600160a01b03831660009081526097602052604081208383039055609980548492906123879084906140ba565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b6000806000841161241e5760405162461bcd60e51b815260206004820152601660248201527504552433230536e617073686f743a20696420697320360541b6044820152606401610cc7565b61242661251f565b8411156124755760405162461bcd60e51b815260206004820152601d60248201527f4552433230536e617073686f743a206e6f6e6578697374656e742069640000006044820152606401610cc7565b600061248184866130b4565b845490915081141561249a5760008092509250506124c2565b60018460010182815481106124b1576124b1614175565b906000526020600020015492509250505b9250929050565b6102c35461010090046001600160a01b0316158015906124f457506102c4546001600160a01b031615155b801561250b57506102c5546001600160a01b031615155b6102c3805460ff1916911515919091179055565b6000610da76102925490565b612533611092565b156125735760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610cc7565b61025d805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861219d3390565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610d7c908490613177565b600061260c61029280546001019055565b600061261661251f565b90507f8030e83b04d87bef53480e26263266d6ca66863aa8506aca6f2559d18aa1cb678160405161264991815260200190565b60405180910390a1919050565b6001600160a01b0383166126ba5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610cc7565b6001600160a01b03821661271c5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610cc7565b612727838383612fb2565b6001600160a01b0383166000908152609760205260409020548181101561279f5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b6064820152608401610cc7565b6001600160a01b038085166000908152609760205260408082208585039055918516815290812080548492906127d6908490614061565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161282291815260200190565b60405180910390a36114e5565b600054610100900460ff166128565760405162461bcd60e51b8152600401610cc790614016565b565b600054610100900460ff1661287f5760405162461bcd60e51b8152600401610cc790614016565b815161289290609a9060208501906138ee565b508051610d7c90609b9060208401906138ee565b600054610100900460ff166128cd5760405162461bcd60e51b8152600401610cc790614016565b81516020928301208151919092012061012e9190915561012f55565b600054610100900460ff166129105760405162461bcd60e51b8152600401610cc790614016565b507f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c961016355565b600054610100900460ff1661295f5760405162461bcd60e51b8152600401610cc790614016565b600081116129a75760405162461bcd60e51b8152602060048201526015602482015274045524332304361707065643a20636170206973203605c1b6044820152606401610cc7565b60c955565b600054610100900460ff166129c75760005460ff16156129cb565b303b155b6129e75760405162461bcd60e51b8152600401610cc790613fc8565b600054610100900460ff16158015612a09576000805461ffff19166101011790555b8015610ef0576000805461ff001916905550565b600054610100900460ff16612a385760005460ff1615612a3c565b303b155b612a585760405162461bcd60e51b8152600401610cc790613fc8565b600054610100900460ff16158015612a7a576000805461ffff19166101011790555b612a09600033612ab9565b600054610100900460ff16612aac5760405162461bcd60e51b8152600401610cc790614016565b61025d805460ff19169055565b610e268282611dd2565b610e268282613249565b60006001600160a01b0384163b612ae657506000610c32565b6040516307b04a2d60e41b81526000906001600160a01b03861690637b04a2d090612b1990339088908890600401613eb0565b602060405180830381600087803b158015612b3357600080fd5b505af1158015612b47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b6b9190613d00565b6001600160e01b0319166307b04a2d60e41b149150509392505050565b6001600160a01b0381166000908152610162602052604090208054600181018255905b50919050565b6000610b68612bbe611e59565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000806000612c10878787876132b8565b91509150612c1d816133a5565b5095945050505050565b60606000612c3683600261409b565b612c41906002614061565b67ffffffffffffffff811115612c5957612c5961418b565b6040519080825280601f01601f191660200182016040528015612c83576020820181803683370190505b509050600360fc1b81600081518110612c9e57612c9e614175565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612ccd57612ccd614175565b60200101906001600160f81b031916908160001a9053506000612cf184600261409b565b612cfc906001614061565b90505b6001811115612d74576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612d3057612d30614175565b1a60f81b828281518110612d4657612d46614175565b60200101906001600160f81b031916908160001a90535060049490941c93612d6d816140fd565b9050612cff565b508315610c325760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610cc7565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103611f62565b803b612e4f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610cc7565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0392909216919091179055565b6060823b612eef5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610cc7565b600080846001600160a01b031684604051612f0a9190613de2565b600060405180830381855af49150503d8060008114612f45576040519150601f19603f3d011682016040523d82523d6000602084013e612f4a565b606091505b5091509150610fd382826040518060600160405280602781526020016141db60279139613560565b612f7b81612deb565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b61025d5460ff16156130195760405162461bcd60e51b815260206004820152602a60248201527f45524332305061757361626c653a20746f6b656e207472616e736665722077686044820152691a5b19481c185d5cd95960b21b6064820152608401610cc7565b6001600160a01b03831660009081526102c2602052604090205460ff1615801561305d57506001600160a01b03821660009081526102c2602052604090205460ff16155b6130a95760405162461bcd60e51b815260206004820152601d60248201527f426c61636b6c69737465643a207573657220626c61636b6c69737465640000006044820152606401610cc7565b610d7c838383613599565b81546000906130c557506000610b68565b82546000905b808210156131215760006130df83836135e1565b9050848682815481106130f4576130f4614175565b9060005260206000200154111561310d5780915061311b565b613118816001614061565b92505b506130cb565b600082118015613156575083856131396001856140ba565b8154811061314957613149614175565b9060005260206000200154145b1561316f576131666001836140ba565b92505050610b68565b509050610b68565b60006131cc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166135fc9092919063ffffffff16565b805190915015610d7c57808060200190518101906131ea9190613c88565b610d7c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610cc7565b60c9548161325660995490565b6132609190614061565b11156132ae5760405162461bcd60e51b815260206004820152601960248201527f45524332304361707065643a20636170206578636565646564000000000000006044820152606401610cc7565b610e26828261360b565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156132ef575060009050600361339c565b8460ff16601b1415801561330757508460ff16601c14155b15613318575060009050600461339c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561336c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166133955760006001925092505061339c565b9150600090505b94509492505050565b60008160048111156133b9576133b961415f565b14156133c25750565b60018160048111156133d6576133d661415f565b14156134245760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610cc7565b60028160048111156134385761343861415f565b14156134865760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610cc7565b600381600481111561349a5761349a61415f565b14156134f35760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610cc7565b60048160048111156135075761350761415f565b1415610ef05760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610cc7565b6060831561356f575081610c32565b82511561357f5782518084602001fd5b8160405162461bcd60e51b8152600401610cc79190613ed7565b6001600160a01b0383166135b8576135b0826136f6565b610d7c61372a565b6001600160a01b0382166135cf576135b0836136f6565b6135d8836136f6565b610d7c826136f6565b60006135f06002848418614079565b610c3290848416614061565b60606113188484600085613739565b6001600160a01b0382166136615760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610cc7565b61366d60008383612fb2565b806099600082825461367f9190614061565b90915550506001600160a01b038216600090815260976020526040812080548392906136ac908490614061565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b038116600090815261028f60209081526040808320609790925290912054610ef09190613861565b613861565b61285661029061372560995490565b60608247101561379a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610cc7565b843b6137e85760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cc7565b600080866001600160a01b031685876040516138049190613de2565b60006040518083038185875af1925050503d8060008114613841576040519150601f19603f3d011682016040523d82523d6000602084013e613846565b606091505b5091509150613856828286613560565b979650505050505050565b600061386b61251f565b905080613877846138ab565b1015610d7c578254600180820185556000858152602080822090930193909355938401805494850181558252902090910155565b80546000906138bc57506000919050565b815482906138cc906001906140ba565b815481106138dc576138dc614175565b90600052602060002001549050919050565b8280546138fa90614114565b90600052602060002090601f01602090048101928261391c5760008555613962565b82601f1061393557805160ff1916838001178555613962565b82800160010185558215613962579182015b82811115613962578251825591602001919060010190613947565b506112f09291505b808211156112f0576000815560010161396a565b600082601f83011261398f57600080fd5b813567ffffffffffffffff808211156139aa576139aa61418b565b604051601f8301601f19908116603f011681019082821181831017156139d2576139d261418b565b816040528381528660208588010111156139eb57600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060208284031215613a1d57600080fd5b8135610c32816141a1565b60008060408385031215613a3b57600080fd5b8235613a46816141a1565b91506020830135613a56816141a1565b809150509250929050565b600080600060608486031215613a7657600080fd5b8335613a81816141a1565b92506020840135613a91816141a1565b929592945050506040919091013590565b60008060008060808587031215613ab857600080fd5b8435613ac3816141a1565b93506020850135613ad3816141a1565b925060408501359150606085013567ffffffffffffffff811115613af657600080fd5b613b028782880161397e565b91505092959194509250565b600080600080600080600060e0888a031215613b2957600080fd5b8735613b34816141a1565b96506020880135613b44816141a1565b95506040880135945060608801359350608088013560ff81168114613b6857600080fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215613b9857600080fd5b8235613ba3816141a1565b91506020830135613a56816141b6565b60008060408385031215613bc657600080fd5b8235613bd1816141a1565b9150602083013567ffffffffffffffff811115613bed57600080fd5b613bf98582860161397e565b9150509250929050565b60008060408385031215613c1657600080fd5b8235613c21816141a1565b946020939093013593505050565b600080600060608486031215613c4457600080fd5b8335613c4f816141a1565b925060208401359150604084013567ffffffffffffffff811115613c7257600080fd5b613c7e8682870161397e565b9150509250925092565b600060208284031215613c9a57600080fd5b8151610c32816141b6565b600060208284031215613cb757600080fd5b5035919050565b60008060408385031215613cd157600080fd5b823591506020830135613a56816141a1565b600060208284031215613cf557600080fd5b8135610c32816141c4565b600060208284031215613d1257600080fd5b8151610c32816141c4565b600080600060608486031215613d3257600080fd5b833567ffffffffffffffff80821115613d4a57600080fd5b613d568783880161397e565b94506020860135915080821115613d6c57600080fd5b50613d798682870161397e565b925050604084013590509250925092565b600080600060608486031215613d9f57600080fd5b505081359360208301359350604090920135919050565b60008151808452613dce8160208601602086016140d1565b601f01601f19169290920160200192915050565b60008251613df48184602087016140d1565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613e368160178501602088016140d1565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613e678160288401602088016140d1565b01602801949350505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613ea690830184613db6565b9695505050505050565b60018060a01b0384168152826020820152606060408201526000610fd36060830184613db6565b602081526000610c326020830184613db6565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b60208082526026908201527f455243313336333a205f636865636b416e6443616c6c5472616e73666572207260408201526565766572747360d01b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6000821982111561407457614074614149565b500190565b60008261409657634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156140b5576140b5614149565b500290565b6000828210156140cc576140cc614149565b500390565b60005b838110156140ec5781810151838201526020016140d4565b838111156114e55750506000910152565b60008161410c5761410c614149565b506000190190565b600181811c9082168061412857607f821691505b60208210811415612bab57634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610ef057600080fd5b8015158114610ef057600080fd5b6001600160e01b031981168114610ef057600080fdfe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220c5d1e83442084c341119aa2dc27dc40129e307a344d5cb52339521f846674c8c64736f6c63430008050033
Deployed ByteCode Sourcemap
119376:3726:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;118726:355;;;;;;;;;;-1:-1:-1;118726:355:0;;;;;:::i;:::-;;:::i;:::-;;;11171:14:1;;11164:22;11146:41;;11134:2;11119:18;118726:355:0;;;;;;;;31220:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;33387:169::-;;;;;;;;;;-1:-1:-1;33387:169:0;;;;;:::i;:::-;;:::i;102512:204::-;;;;;;;;;;-1:-1:-1;102512:204:0;;;;;:::i;:::-;;:::i;115972:305::-;;;;;;;;;;-1:-1:-1;115972:305:0;;;;;:::i;:::-;;:::i;:::-;;32340:108;;;;;;;;;;-1:-1:-1;32428:12:0;;32340:108;;;11344:25:1;;;11332:2;11317:18;32340:108:0;11299:76:1;119550:35:0;;;;;;;;;;;;;;;;121875:296;;;;;;;;;;-1:-1:-1;121875:296:0;;;;;:::i;:::-;;:::i;88225:123::-;;;;;;;;;;-1:-1:-1;88225:123:0;;;;;:::i;:::-;88291:7;88318:12;;;:6;:12;;;;;:22;;;;88225:123;119455:25;;;;;;;;;;-1:-1:-1;119455:25:0;;;;;;;-1:-1:-1;;;;;119455:25:0;;;;;;-1:-1:-1;;;;;9800:32:1;;;9782:51;;9770:2;9755:18;119455:25:0;9737:102:1;119517:24:0;;;;;;;;;;-1:-1:-1;119517:24:0;;;;-1:-1:-1;;;;;119517:24:0;;;88610:147;;;;;;;;;;-1:-1:-1;88610:147:0;;;;;:::i;:::-;;:::i;116916:92::-;;;;;;;;;;-1:-1:-1;116916:92:0;;116999:1;31217:36:1;;31205:2;31190:18;116916:92:0;31172:87:1;105256:198:0;;;;;;;;;;-1:-1:-1;105256:198:0;;;;;:::i;:::-;;:::i;42032:83::-;;;;;;;;;;-1:-1:-1;42103:4:0;;42032:83;;78481:115;;;;;;;;;;;;;:::i;89658:218::-;;;;;;;;;;-1:-1:-1;89658:218:0;;;;;:::i;:::-;;:::i;23147:202::-;;;;;;;;;;-1:-1:-1;23147:202:0;;;;;:::i;:::-;;:::i;34939:215::-;;;;;;;;;;-1:-1:-1;34939:215:0;;;;;:::i;:::-;;:::i;118419:106::-;;;;;;;;;;;;;:::i;103074:379::-;;;;;;;;;;-1:-1:-1;103074:379:0;;;;;:::i;:::-;;:::i;43172:91::-;;;;;;;;;;-1:-1:-1;43172:91:0;;;;;:::i;:::-;;:::i;53342:266::-;;;;;;;;;;-1:-1:-1;53342:266:0;;;;;:::i;:::-;;:::i;23608:227::-;;;;;;:::i;:::-;;:::i;114395:51::-;;;;;;;;;;-1:-1:-1;114395:51:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;118533:116;;;;;;;;;;;;;:::i;119487:23::-;;;;;;;;;;-1:-1:-1;119487:23:0;;;;-1:-1:-1;;;;;119487:23:0;;;32511:127;;;;;;;;;;-1:-1:-1;32511:127:0;;;;;:::i;:::-;-1:-1:-1;;;;;32612:18:0;32585:7;32612:18;;;:9;:18;;;;;;;32511:127;112550:64;;;;;;;;;;;;112589:25;112550:64;;43582:368;;;;;;;;;;-1:-1:-1;43582:368:0;;;;;:::i;:::-;;:::i;119612:33::-;;;;;;;;;;;;;;;;120063:208;;;;;;;;;;-1:-1:-1;120063:208:0;;;;;:::i;:::-;;:::i;78223:128::-;;;;;;;;;;-1:-1:-1;78223:128:0;;;;;:::i;:::-;;:::i;119208:113::-;;;;;;;;;;;;;:::i;118309:102::-;;;;;;;;;;;;;:::i;113306:210::-;;;;;;;;;;-1:-1:-1;113306:210:0;;;;;:::i;:::-;;:::i;120481:197::-;;;;;;;;;;-1:-1:-1;120481:197:0;;;;;:::i;:::-;;:::i;87088:139::-;;;;;;;;;;-1:-1:-1;87088:139:0;;;;;:::i;:::-;;:::i;31439:104::-;;;;;;;;;;;;;:::i;119089:111::-;;;;;;;;;;;;;:::i;53712:234::-;;;;;;;;;;-1:-1:-1;53712:234:0;;;;;:::i;:::-;;:::i;86168:49::-;;;;;;;;;;-1:-1:-1;86168:49:0;86213:4;86168:49;;35657:413;;;;;;;;;;-1:-1:-1;35657:413:0;;;;;:::i;:::-;;:::i;121516:266::-;;;;;;;;;;-1:-1:-1;121516:266:0;;;;;:::i;:::-;;:::i;114653:994::-;;;;;;;;;;-1:-1:-1;114653:994:0;;;;;:::i;:::-;;:::i;113749:205::-;;;;;;;;;;-1:-1:-1;113749:205:0;;;;;:::i;:::-;;:::i;115657:307::-;;;;;;;;;;-1:-1:-1;115657:307:0;;;;;:::i;:::-;;:::i;104535:414::-;;;;;;;;;;-1:-1:-1;104535:414:0;;;;;:::i;:::-;;:::i;105825:355::-;;;;;;;;;;-1:-1:-1;105825:355:0;;;;;:::i;:::-;;:::i;119421:27::-;;;;;;;;;;-1:-1:-1;119421:27:0;;;;;;;;77501:656;;;;;;;;;;-1:-1:-1;77501:656:0;;;;;:::i;:::-;;:::i;89002:149::-;;;;;;;;;;-1:-1:-1;89002:149:0;;;;;:::i;:::-;;:::i;103849:229::-;;;;;;;;;;-1:-1:-1;103849:229:0;;;;;:::i;:::-;;:::i;33089:151::-;;;;;;;;;;-1:-1:-1;33089:151:0;;;;;:::i;:::-;-1:-1:-1;;;;;33205:18:0;;;33178:7;33205:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;33089:151;119672:34;;;;;;;;;;;;;;;;114326:60;;;;;;;;;;;;114363:23;114326:60;;120279:194;;;;;;;;;;-1:-1:-1;120279:194:0;;;;;:::i;:::-;;:::i;120850:577::-;;;;;;;;;;-1:-1:-1;120850:577:0;;;;;:::i;:::-;;:::i;114457:45::-;;;;;;;;;;-1:-1:-1;114457:45:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;119737:23;;;;;;;;;;;;;;;;118726:355;118902:4;118952:49;118989:11;118952:36;:49::i;:::-;:121;;;;119018:55;119061:11;119018:42;:55::i;:::-;118932:141;118726:355;-1:-1:-1;;118726:355:0:o;31220:100::-;31274:13;31307:5;31300:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31220:100;:::o;33387:169::-;33470:4;33487:39;28717:10;33510:7;33519:6;33487:8;:39::i;:::-;-1:-1:-1;33544:4:0;33387:169;;;;:::o;102512:204::-;102641:4;102670:38;102686:9;102697:6;102670:38;;;;;;;;;;;;:15;:38::i;:::-;102663:45;102512:204;-1:-1:-1;;;102512:204:0:o;115972:305::-;86213:4;86659:30;86213:4;28717:10;86659;:30::i;:::-;-1:-1:-1;;;;;116086:22:0;::::1;;::::0;;;:13:::1;:22;::::0;;;;;::::1;;:37;;::::0;::::1;;;;116078:95;;;::::0;-1:-1:-1;;;116078:95:0;;20221:2:1;116078:95:0::1;::::0;::::1;20203:21:1::0;20260:2;20240:18;;;20233:30;20299:34;20279:18;;;20272:62;-1:-1:-1;;;20350:18:1;;;20343:43;20403:19;;116078:95:0::1;;;;;;;;;-1:-1:-1::0;;;;;116184:22:0;::::1;;::::0;;;:13:::1;:22;::::0;;;;;;;;:36;;-1:-1:-1;;116184:36:0::1;::::0;::::1;;::::0;;::::1;::::0;;;116236:33;;11146:41:1;;;116236:33:0::1;::::0;11119:18:1;116236:33:0::1;;;;;;;;115972:305:::0;;;:::o;121875:296::-;122015:4;122032:45;122051:6;122059:9;122070:6;122032:18;:45::i;:::-;;122090:40;122104:6;122112:9;122123:6;122090:13;:40::i;:::-;-1:-1:-1;122159:4:0;121875:296;;;;;:::o;88610:147::-;88291:7;88318:12;;;:6;:12;;;;;:22;;;86659:30;86670:4;28717:10;86659;:30::i;:::-;88724:25:::1;88735:4;88741:7;88724:10;:25::i;:::-;88610:147:::0;;;:::o;105256:198::-;105382:4;105411:35;105426:7;105435:6;105411:35;;;;;;;;;;;;:14;:35::i;78481:115::-;78541:7;78568:20;:18;:20::i;:::-;78561:27;;78481:115;:::o;89658:218::-;-1:-1:-1;;;;;89754:23:0;;28717:10;89754:23;89746:83;;;;-1:-1:-1;;;89746:83:0;;29584:2:1;89746:83:0;;;29566:21:1;29623:2;29603:18;;;29596:30;29662:34;29642:18;;;29635:62;-1:-1:-1;;;29713:18:1;;;29706:45;29768:19;;89746:83:0;29556:237:1;89746:83:0;89842:26;89854:4;89860:7;89842:11;:26::i;:::-;89658:218;;:::o;23147:202::-;22776:4;-1:-1:-1;;;;;22785:6:0;22768:23;;;22760:80;;;;-1:-1:-1;;;22760:80:0;;;;;;;:::i;:::-;22883:6;-1:-1:-1;;;;;22859:30:0;:20;:18;:20::i;:::-;-1:-1:-1;;;;;22859:30:0;;22851:87;;;;-1:-1:-1;;;22851:87:0;;;;;;;:::i;:::-;23231:36:::1;23249:17;23231;:36::i;:::-;23321:12;::::0;;23331:1:::1;23321:12:::0;;;::::1;::::0;::::1;::::0;;;23278:63:::1;::::0;23302:17;;23321:12;23278:23:::1;:63::i;:::-;23147:202:::0;:::o;34939:215::-;28717:10;35027:4;35076:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;35076:34:0;;;;;;;;;;35027:4;;35044:80;;35067:7;;35076:47;;35113:10;;35076:47;:::i;:::-;35044:8;:80::i;118419:106::-;86213:4;86659:30;86213:4;28717:10;86659;:30::i;:::-;118487::::1;:28;:30::i;103074:379::-:0;103220:4;103237:27;103246:9;103257:6;103237:8;:27::i;:::-;-1:-1:-1;103297:60:0;28717:10;103333:9;103344:6;103352:4;103297:21;:60::i;:::-;103275:148;;;;-1:-1:-1;;;103275:148:0;;;;;;;:::i;43172:91::-;43228:27;28717:10;43248:6;43228:5;:27::i;53342:266::-;-1:-1:-1;;;;;53506:33:0;;53429:7;53506:33;;;:24;:33;;;;;53429:7;;;;53485:55;;53494:10;;53485:8;:55::i;:::-;53449:91;;;;53560:11;:40;;-1:-1:-1;;;;;32612:18:0;;32585:7;32612:18;;;:9;:18;;;;;;53560:40;;;53574:5;53560:40;53553:47;53342:266;-1:-1:-1;;;;;53342:266:0:o;23608:227::-;22776:4;-1:-1:-1;;;;;22785:6:0;22768:23;;;22760:80;;;;-1:-1:-1;;;22760:80:0;;;;;;;:::i;:::-;22883:6;-1:-1:-1;;;;;22859:30:0;:20;:18;:20::i;:::-;-1:-1:-1;;;;;22859:30:0;;22851:87;;;;-1:-1:-1;;;22851:87:0;;;;;;;:::i;:::-;23726:36:::1;23744:17;23726;:36::i;:::-;23773:54;23797:17;23816:4;23822;23773:23;:54::i;118533:116::-:0;118589:4;118613:28;93151:7;;;;;93080:86;43582:368;43659:24;43686:32;43696:7;28717:10;33089:151;:::i;43686:32::-;43659:59;;43757:6;43737:16;:26;;43729:75;;;;-1:-1:-1;;;43729:75:0;;24150:2:1;43729:75:0;;;24132:21:1;24189:2;24169:18;;;24162:30;24228:34;24208:18;;;24201:62;-1:-1:-1;;;24279:18:1;;;24272:34;24323:19;;43729:75:0;24122:226:1;43729:75:0;43840:58;43849:7;28717:10;43891:6;43872:16;:25;43840:8;:58::i;:::-;43920:22;43926:7;43935:6;43920:5;:22::i;120063:208::-;86213:4;86659:30;86213:4;28717:10;86659;:30::i;:::-;120155:10:::1;:23:::0;;-1:-1:-1;;;;;;120155:23:0::1;;-1:-1:-1::0;;;;;120155:23:0;::::1;;;::::0;;120193:21:::1;:19;:21::i;:::-;120234:29;::::0;-1:-1:-1;;;;;9800:32:1;;9782:51;;120234:29:0::1;::::0;9770:2:1;9755:18;120234:29:0::1;;;;;;;;120063:208:::0;;:::o;78223:128::-;-1:-1:-1;;;;;78319:14:0;;78292:7;78319:14;;;:7;:14;;;;;47600;78319:24;47508:114;119208:113;119257:7;119284:29;:27;:29::i;118309:102::-;86213:4;86659:30;86213:4;28717:10;86659;:30::i;:::-;118375:28:::1;:26;:28::i;113306:210::-:0;112589:25;86659:30;112589:25;28717:10;86659;:30::i;:::-;113437:71:::1;-1:-1:-1::0;;;;;113437:44:0;::::1;28717:10:::0;113496:11;113437:44:::1;:71::i;120481:197::-:0;86213:4;86659:30;86213:4;28717:10;86659;:30::i;:::-;120572:9:::1;:22:::0;;-1:-1:-1;;;;;;120572:22:0::1;-1:-1:-1::0;;;;;120572:22:0;::::1;;::::0;;120605:21:::1;:19;:21::i;:::-;120642:28;::::0;-1:-1:-1;;;;;9800:32:1;;9782:51;;120642:28:0::1;::::0;9770:2:1;9755:18;120642:28:0::1;9737:102:1::0;87088:139:0;87166:4;87190:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;87190:29:0;;;;;;;;;;;;;;;87088:139::o;31439:104::-;31495:13;31528:7;31521:14;;;;;:::i;119089:111::-;119148:7;114363:23;86659:30;114363:23;28717:10;86659;:30::i;:::-;119175:17:::1;:15;:17::i;:::-;119168:24;;86700:1;119089:111:::0;;:::o;53712:234::-;53784:7;53805:16;53823:13;53840:43;53849:10;53861:21;53840:8;:43::i;:::-;53804:79;;;;53903:11;:35;;32428:12;;53903:35;;;53917:5;53903:35;53896:42;53712:234;-1:-1:-1;;;;53712:234:0:o;35657:413::-;28717:10;35750:4;35794:25;;;:11;:25;;;;;;;;-1:-1:-1;;;;;35794:34:0;;;;;;;;;;35847:35;;;;35839:85;;;;-1:-1:-1;;;35839:85:0;;29178:2:1;35839:85:0;;;29160:21:1;29217:2;29197:18;;;29190:30;29256:34;29236:18;;;29229:62;-1:-1:-1;;;29307:18:1;;;29300:35;29352:19;;35839:85:0;29150:227:1;35839:85:0;35960:67;28717:10;35983:7;36011:15;35992:16;:34;35960:8;:67::i;121516:266::-;121602:4;121619:48;28717:10;121649:9;121660:6;121619:15;:48::i;:::-;121680:46;28717:10;121708:9;121719:6;121680:13;:46::i;114653:994::-;9452:13;;;;;;;:48;;9488:12;;;;9487:13;9452:48;;;10255:4;1130:20;1178:8;9468:16;9444:107;;;;-1:-1:-1;;;9444:107:0;;;;;;;:::i;:::-;9564:19;9587:13;;;;;;9586:14;9611:101;;;;9646:13;:20;;-1:-1:-1;;9681:19:0;;;;;9611:101;114800:26:::1;:24;:26::i;:::-;114855:36;114878:4;114884:6;114855:22;:36::i;:::-;114902:34;114926:4;114902:34;;;;;;;;;;;;;-1:-1:-1::0;;;114902:34:0::1;;::::0;:23:::1;:34::i;:::-;114947;114976:4;114947:28;:34::i;:::-;115000:25;:23;:25::i;:::-;115036:32;:30;:32::i;:::-;115095:33;115124:3;115095:28;:33::i;:::-;115139:32;:30;:32::i;:::-;115187;:30;:32::i;:::-;115241:26;:24;:26::i;:::-;115286:35;:33;:35::i;:::-;115340:27;:25;:27::i;:::-;115434:44;86213:4;28717:10:::0;115434::::1;:44::i;:::-;115511:24;28717:10:::0;115531:3:::1;115511:5;:24::i;:::-;115619:10;115600:30;::::0;;;:18:::1;:30;::::0;;;;:37;;-1:-1:-1;;115600:37:0::1;115633:4;115600:37;::::0;;9738:68;;;;9789:5;9773:21;;-1:-1:-1;;9773:21:0;;;9738:68;9159:654;114653:994;;;:::o;113749:205::-;112589:25;86659:30;112589:25;28717:10;86659;:30::i;:::-;113908:38:::1;-1:-1:-1::0;;;;;113908:26:0;::::1;113935:2:::0;113939:6;113908:26:::1;:38::i;115657:307::-:0;86213:4;86659:30;86213:4;28717:10;86659;:30::i;:::-;-1:-1:-1;;;;;115771:27:0;::::1;;::::0;;;:18:::1;:27;::::0;;;;;::::1;;:39;;::::0;::::1;;;;115763:94;;;::::0;-1:-1:-1;;;115763:94:0;;28002:2:1;115763:94:0::1;::::0;::::1;27984:21:1::0;28041:2;28021:18;;;28014:30;28080:34;28060:18;;;28053:62;-1:-1:-1;;;28131:18:1;;;28124:40;28181:19;;115763:94:0::1;27974:232:1::0;115763:94:0::1;-1:-1:-1::0;;;;;115868:27:0;::::1;;::::0;;;:18:::1;:27;::::0;;;;;;;;:38;;-1:-1:-1;;115868:38:0::1;::::0;::::1;;::::0;;::::1;::::0;;;115922:34;;11146:41:1;;;115922:34:0::1;::::0;11119:18:1;115922:34:0::1;11101:92:1::0;104535:414:0;104710:4;104727:39;104740:6;104748:9;104759:6;104727:12;:39::i;:::-;;104799:54;104821:6;104829:9;104840:6;104848:4;104799:21;:54::i;:::-;104777:142;;;;-1:-1:-1;;;104777:142:0;;;;;;;:::i;:::-;-1:-1:-1;104937:4:0;104535:414;;;;;;:::o;105825:355::-;105968:4;105985:24;105993:7;106002:6;105985:7;:24::i;:::-;;106042:43;106063:7;106072:6;106080:4;106042:20;:43::i;:::-;106020:130;;;;-1:-1:-1;;;106020:130:0;;17056:2:1;106020:130:0;;;17038:21:1;17095:2;17075:18;;;17068:30;17134:34;17114:18;;;17107:62;-1:-1:-1;;;17185:18:1;;;17178:35;17230:19;;106020:130:0;17028:227:1;77501:656:0;77745:8;77726:15;:27;;77718:69;;;;-1:-1:-1;;;77718:69:0;;18233:2:1;77718:69:0;;;18215:21:1;18272:2;18252:18;;;18245:30;18311:31;18291:18;;;18284:59;18360:18;;77718:69:0;18205:179:1;77718:69:0;77800:18;77842:16;;77860:5;77867:7;77876:5;77883:16;77893:5;77883:9;:16::i;:::-;77831:79;;;;;;11667:25:1;;;;-1:-1:-1;;;;;11766:15:1;;;11746:18;;;11739:43;11818:15;;;;11798:18;;;11791:43;11850:18;;;11843:34;11893:19;;;11886:35;11937:19;;;11930:35;;;11639:19;;77831:79:0;;;;;;;;;;;;77821:90;;;;;;77800:111;;77924:12;77939:28;77956:10;77939:16;:28::i;:::-;77924:43;;77980:14;77997:39;78022:4;78028:1;78031;78034;77997:24;:39::i;:::-;77980:56;;78065:5;-1:-1:-1;;;;;78055:15:0;:6;-1:-1:-1;;;;;78055:15:0;;78047:58;;;;-1:-1:-1;;;78047:58:0;;22565:2:1;78047:58:0;;;22547:21:1;22604:2;22584:18;;;22577:30;22643:32;22623:18;;;22616:60;22693:18;;78047:58:0;22537:180:1;78047:58:0;78118:31;78127:5;78134:7;78143:5;78118:8;:31::i;:::-;77707:450;;;77501:656;;;;;;;:::o;89002:149::-;88291:7;88318:12;;;:6;:12;;;;;:22;;;86659:30;86670:4;28717:10;86659;:30::i;:::-;89117:26:::1;89129:4;89135:7;89117:11;:26::i;103849:229::-:0;103996:4;104020:50;104040:6;104048:9;104059:6;104020:50;;;;;;;;;;;;:19;:50::i;120279:194::-;86213:4;86659:30;86213:4;28717:10;86659;:30::i;:::-;120369:8:::1;:21:::0;;-1:-1:-1;;;;;;120369:21:0::1;-1:-1:-1::0;;;;;120369:21:0;::::1;;::::0;;120401::::1;:19;:21::i;:::-;120438:27;::::0;-1:-1:-1;;;;;9800:32:1;;9782:51;;120438:27:0::1;::::0;9770:2:1;9755:18;120438:27:0::1;9737:102:1::0;120850:577:0;86213:4;86659:30;86213:4;28717:10;86659;:30::i;:::-;121075:5:::1;121057:14:::0;121023:31:::1;121041:13:::0;121023:15;:31:::1;:::i;:::-;:48;;;;:::i;:::-;:57;;121015:93;;;::::0;-1:-1:-1;;;121015:93:0;;24957:2:1;121015:93:0::1;::::0;::::1;24939:21:1::0;24996:2;24976:18;;;24969:30;25035:25;25015:18;;;25008:53;25078:18;;121015:93:0::1;24929:173:1::0;121015:93:0::1;121119:20;:38:::0;;;121168:18:::1;:34:::0;;;121213:19:::1;:36:::0;;;121235:14;121273:31:::1;121189:13:::0;121142:15;121273:31:::1;:::i;:::-;:48;;;;:::i;:::-;121262:8;:59:::0;121399:19:::1;::::0;121349:70:::1;::::0;;30953:25:1;;;31009:2;30994:18;;30987:34;;;31037:18;;;31030:34;;;;121349:70:0;::::1;::::0;;;;30941:2:1;121349:70:0;;::::1;120850:577:::0;;;;:::o;101889:324::-;102058:4;-1:-1:-1;;;;;;102100:52:0;;-1:-1:-1;;;102100:52:0;;:105;;-1:-1:-1;;;;;;;;;;83874:51:0;;;102169:36;83765:168;86781:215;86866:4;-1:-1:-1;;;;;;86890:58:0;;-1:-1:-1;;;86890:58:0;;:98;;;86952:36;86976:11;86952:23;:36::i;39341:380::-;-1:-1:-1;;;;;39477:19:0;;39469:68;;;;-1:-1:-1;;;39469:68:0;;26476:2:1;39469:68:0;;;26458:21:1;26515:2;26495:18;;;26488:30;26554:34;26534:18;;;26527:62;-1:-1:-1;;;26605:18:1;;;26598:34;26649:19;;39469:68:0;26448:226:1;39469:68:0;-1:-1:-1;;;;;39556:21:0;;39548:68;;;;-1:-1:-1;;;39548:68:0;;16653:2:1;39548:68:0;;;16635:21:1;16692:2;16672:18;;;16665:30;16731:34;16711:18;;;16704:62;-1:-1:-1;;;16782:18:1;;;16775:32;16824:19;;39548:68:0;16625:224:1;39548:68:0;-1:-1:-1;;;;;39629:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;39681:32;;11344:25:1;;;39681:32:0;;11317:18:1;39681:32:0;;;;;;;39341:380;;;:::o;87517:519::-;87598:22;87606:4;87612:7;87598;:22::i;:::-;87593:436;;87786:52;87825:7;-1:-1:-1;;;;;87786:52:0;87835:2;87786:30;:52::i;:::-;87911:49;87950:4;87957:2;87911:30;:49::i;:::-;87691:292;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;87691:292:0;;;;;;;;;;-1:-1:-1;;;87637:380:0;;;;;;;:::i;34038:492::-;34178:4;34195:36;34205:6;34213:9;34224:6;34195:9;:36::i;:::-;-1:-1:-1;;;;;34271:19:0;;34244:24;34271:19;;;:11;:19;;;;;;;;28717:10;34271:33;;;;;;;;34323:26;;;;34315:79;;;;-1:-1:-1;;;34315:79:0;;23741:2:1;34315:79:0;;;23723:21:1;23780:2;23760:18;;;23753:30;23819:34;23799:18;;;23792:62;-1:-1:-1;;;23870:18:1;;;23863:38;23918:19;;34315:79:0;23713:230:1;34315:79:0;34430:57;34439:6;28717:10;34480:6;34461:16;:25;34430:8;:57::i;122179:916::-;-1:-1:-1;;;;;122286:26:0;;;;;;:18;:26;;;;;;;;;:59;;-1:-1:-1;;;;;;122316:29:0;;;;;;:18;:29;;;;;;;;122286:59;122281:769;;122376:15;;;;122368:59;;;;-1:-1:-1;;;122368:59:0;;20980:2:1;122368:59:0;;;20962:21:1;21019:2;20999:18;;;20992:30;21058:33;21038:18;;;21031:61;21109:18;;122368:59:0;20952:181:1;122368:59:0;122461:1;122450:8;;:12;122442:59;;;;-1:-1:-1;;;122442:59:0;;22924:2:1;122442:59:0;;;22906:21:1;22963:2;22943:18;;;22936:30;23002:34;22982:18;;;22975:62;-1:-1:-1;;;23053:18:1;;;23046:32;23095:19;;122442:59:0;22896:224:1;122442:59:0;122577:24;122636:6;122627;122604:20;;:29;;;;:::i;:::-;:38;;;;:::i;:::-;122577:65;;122657:22;122712:6;122703;122682:18;;:27;;;;:::i;:::-;:36;;;;:::i;:::-;122657:61;;122733:23;122790:6;122781;122759:19;;:28;;;;:::i;:::-;:37;;;;:::i;:::-;122733:63;;122852:50;122862:9;122873:10;;;;;;;;;-1:-1:-1;;;;;122873:10:0;122885:16;122852:9;:50::i;:::-;122938:8;;122917:46;;122927:9;;-1:-1:-1;;;;;122938:8:0;122948:14;122917:9;:46::i;:::-;122999:9;;122978:48;;122988:9;;-1:-1:-1;;;;;122999:9:0;123010:15;122978:9;:48::i;:::-;122348:702;;;122179:916;;;:::o;91159:238::-;91243:22;91251:4;91257:7;91243;:22::i;:::-;91238:152;;91282:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;91282:29:0;;;;;;;;;:36;;-1:-1:-1;;91282:36:0;91314:4;91282:36;;;91365:12;28717:10;;28637:98;91365:12;-1:-1:-1;;;;;91338:40:0;91356:7;-1:-1:-1;;;;;91338:40:0;91350:4;91338:40;;;;;;;;;;91159:238;;:::o;73808:162::-;73861:7;73888:74;72531:95;73922:17;75390:12;;;75305:105;73922:17;75745:15;;74159:73;;;;;;12235:25:1;;;12276:18;;;12269:34;;;12319:18;;;12312:34;;;74203:13:0;12362:18:1;;;12355:34;74226:4:0;12405:19:1;;;12398:61;74122:7:0;;12207:19:1;;74159:73:0;;;;;;;;;;;;74149:84;;;;;;74142:91;;73978:263;;;;;;91529:239;91613:22;91621:4;91627:7;91613;:22::i;:::-;91609:152;;;91684:5;91652:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;91652:29:0;;;;;;;;;;:37;;-1:-1:-1;;91652:37:0;;;91709:40;28717:10;;91652:12;;91709:40;;91684:5;91709:40;91529:239;;:::o;14553:153::-;14606:7;14272:66;14633:59;:65;-1:-1:-1;;;;;14633:65:0;;14553:153;-1:-1:-1;14553:153:0:o;117195:187::-;117333:11;:9;:11::i;:::-;-1:-1:-1;;;;;117317:27:0;28717:10;-1:-1:-1;;;;;117317:27:0;;117309:65;;;;-1:-1:-1;;;117309:65:0;;28824:2:1;117309:65:0;;;28806:21:1;28863:2;28843:18;;;28836:30;28902:27;28882:18;;;28875:55;28947:18;;117309:65:0;28796:175:1;15971:1268:0;16120:25;16148:20;:18;:20::i;:::-;16120:48;;16224:37;16243:17;16224:18;:37::i;:::-;16290:1;16276:4;:11;:15;:28;;;;16295:9;16276:28;16272:107;;;16321:46;16343:17;16362:4;16321:21;:46::i;:::-;;16272:107;13924:66;16582:21;;;;16577:655;;16697:28;;-1:-1:-1;;16697:28:0;16721:4;16697:28;;;16816:64;;-1:-1:-1;;;;;9800:32:1;;16816:64:0;;;9782:51:1;16740:155:0;;16780:17;;9755:18:1;;16816:64:0;;;-1:-1:-1;;16816:64:0;;;;;;;;;;;;;;-1:-1:-1;;;;;16816:64:0;-1:-1:-1;;;16816:64:0;;;16740:21;:155::i;:::-;-1:-1:-1;16910:29:0;;-1:-1:-1;;16910:29:0;;;17028:20;:18;:20::i;:::-;-1:-1:-1;;;;;17007:41:0;:17;-1:-1:-1;;;;;17007:41:0;;16999:101;;;;-1:-1:-1;;;16999:101:0;;16237:2:1;16999:101:0;;;16219:21:1;16276:2;16256:18;;;16249:30;16315:34;16295:18;;;16288:62;-1:-1:-1;;;16366:18:1;;;16359:45;16421:19;;16999:101:0;16209:237:1;16999:101:0;17191:29;17202:17;17191:10;:29::i;:::-;16109:1130;;15971:1268;;;:::o;94139:120::-;93683:8;:6;:8::i;:::-;93675:41;;;;-1:-1:-1;;;93675:41:0;;15125:2:1;93675:41:0;;;15107:21:1;15164:2;15144:18;;;15137:30;-1:-1:-1;;;15183:18:1;;;15176:50;15243:18;;93675:41:0;15097:170:1;93675:41:0;94198:7:::1;:15:::0;;-1:-1:-1;;94198:15:0::1;::::0;;94229:22:::1;28717:10:::0;94238:12:::1;94229:22;::::0;-1:-1:-1;;;;;9800:32:1;;;9782:51;;9770:2;9755:18;94229:22:0::1;;;;;;;94139:120::o:0;106746:532::-;106916:4;-1:-1:-1;;;;;106938:20:0;;1130;106933:68;;-1:-1:-1;106984:5:0;106977:12;;106933:68;107027:145;;-1:-1:-1;;;107027:145:0;;107011:13;;-1:-1:-1;;;;;107027:46:0;;;;;:145;;28717:10;;107115:6;;107136;;107157:4;;107027:145;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;107191:78:0;-1:-1:-1;;;107191:78:0;;-1:-1:-1;;106746:532:0;;;;;;:::o;38312:591::-;-1:-1:-1;;;;;38396:21:0;;38388:67;;;;-1:-1:-1;;;38388:67:0;;24555:2:1;38388:67:0;;;24537:21:1;24594:2;24574:18;;;24567:30;24633:34;24613:18;;;24606:62;-1:-1:-1;;;24684:18:1;;;24677:31;24725:19;;38388:67:0;24527:223:1;38388:67:0;38468:49;38489:7;38506:1;38510:6;38468:20;:49::i;:::-;-1:-1:-1;;;;;38555:18:0;;38530:22;38555:18;;;:9;:18;;;;;;38592:24;;;;38584:71;;;;-1:-1:-1;;;38584:71:0;;15474:2:1;38584:71:0;;;15456:21:1;15513:2;15493:18;;;15486:30;15552:34;15532:18;;;15525:62;-1:-1:-1;;;15603:18:1;;;15596:32;15645:19;;38584:71:0;15446:224:1;38584:71:0;-1:-1:-1;;;;;38691:18:0;;;;;;:9;:18;;;;;38712:23;;;38691:44;;38757:12;:22;;38729:6;;38691:18;38757:22;;38729:6;;38757:22;:::i;:::-;;;;-1:-1:-1;;38797:37:0;;11344:25:1;;;38823:1:0;;-1:-1:-1;;;;;38797:37:0;;;;;11332:2:1;11317:18;38797:37:0;;;;;;;88610:147;;;:::o;54793:1619::-;54882:4;54888:7;54929:1;54916:10;:14;54908:49;;;;-1:-1:-1;;;54908:49:0;;27651:2:1;54908:49:0;;;27633:21:1;27690:2;27670:18;;;27663:30;-1:-1:-1;;;27709:18:1;;;27702:52;27771:18;;54908:49:0;27623:172:1;54908:49:0;54990:23;:21;:23::i;:::-;54976:10;:37;;54968:79;;;;-1:-1:-1;;;54968:79:0;;13652:2:1;54968:79:0;;;13634:21:1;13691:2;13671:18;;;13664:30;13730:31;13710:18;;;13703:59;13779:18;;54968:79:0;13624:179:1;54968:79:0;56186:13;56202:40;:9;56231:10;56202:28;:40::i;:::-;56268:20;;56186:56;;-1:-1:-1;56259:29:0;;56255:150;;;56313:5;56320:1;56305:17;;;;;;;56255:150;56363:4;56369:9;:16;;56386:5;56369:23;;;;;;;;:::i;:::-;;;;;;;;;56355:38;;;;;54793:1619;;;;;;:::o;120686:155::-;120755:10;;;;;-1:-1:-1;;;;;120755:10:0;:24;;;;:50;;-1:-1:-1;120783:8:0;;-1:-1:-1;;;;;120783:8:0;:22;;120755:50;:77;;;;-1:-1:-1;120809:9:0;;-1:-1:-1;;;;;120809:9:0;:23;;120755:77;120736:15;:97;;-1:-1:-1;;120736:97:0;;;;;;;;;;120686:155::o;53103:127::-;53167:7;53194:28;:18;47600:14;;47508:114;93880:118;93406:8;:6;:8::i;:::-;93405:9;93397:38;;;;-1:-1:-1;;;93397:38:0;;20635:2:1;93397:38:0;;;20617:21:1;20674:2;20654:18;;;20647:30;-1:-1:-1;;;20693:18:1;;;20686:46;20749:18;;93397:38:0;20607:166:1;93397:38:0;93940:7:::1;:14:::0;;-1:-1:-1;;93940:14:0::1;93950:4;93940:14;::::0;;93970:20:::1;93977:12;28717:10:::0;;28637:98;108859:222;109014:58;;;-1:-1:-1;;;;;10529:32:1;;109014:58:0;;;10511:51:1;10578:18;;;;10571:34;;;109014:58:0;;;;;;;;;;10484:18:1;;;;109014:58:0;;;;;;;;-1:-1:-1;;;;;109014:58:0;-1:-1:-1;;;109014:58:0;;;108987:86;;109007:5;;108987:19;:86::i;52814:223::-;52861:7;52881:30;:18;47719:19;;47737:1;47719:19;;;47630:127;52881:30;52924:17;52944:23;:21;:23::i;:::-;52924:43;;52983:19;52992:9;52983:19;;;;11344:25:1;;11332:2;11317:18;;11299:76;52983:19:0;;;;;;;;53020:9;52814:223;-1:-1:-1;52814:223:0:o;36560:733::-;-1:-1:-1;;;;;36700:20:0;;36692:70;;;;-1:-1:-1;;;36692:70:0;;25716:2:1;36692:70:0;;;25698:21:1;25755:2;25735:18;;;25728:30;25794:34;25774:18;;;25767:62;-1:-1:-1;;;25845:18:1;;;25838:35;25890:19;;36692:70:0;25688:227:1;36692:70:0;-1:-1:-1;;;;;36781:23:0;;36773:71;;;;-1:-1:-1;;;36773:71:0;;14371:2:1;36773:71:0;;;14353:21:1;14410:2;14390:18;;;14383:30;14449:34;14429:18;;;14422:62;-1:-1:-1;;;14500:18:1;;;14493:33;14543:19;;36773:71:0;14343:225:1;36773:71:0;36857:47;36878:6;36886:9;36897:6;36857:20;:47::i;:::-;-1:-1:-1;;;;;36941:17:0;;36917:21;36941:17;;;:9;:17;;;;;;36977:23;;;;36969:74;;;;-1:-1:-1;;;36969:74:0;;18591:2:1;36969:74:0;;;18573:21:1;18630:2;18610:18;;;18603:30;18669:34;18649:18;;;18642:62;-1:-1:-1;;;18720:18:1;;;18713:36;18766:19;;36969:74:0;18563:228:1;36969:74:0;-1:-1:-1;;;;;37079:17:0;;;;;;;:9;:17;;;;;;37099:22;;;37079:42;;37143:20;;;;;;;;:30;;37115:6;;37079:17;37143:30;;37115:6;;37143:30;:::i;:::-;;;;;;;;37208:9;-1:-1:-1;;;;;37191:35:0;37200:6;-1:-1:-1;;;;;37191:35:0;;37219:6;37191:35;;;;11344:25:1;;11332:2;11317:18;;11299:76;37191:35:0;;;;;;;;37239:46;88610:147;28561:70;10055:13;;;;;;;10047:69;;;;-1:-1:-1;;;10047:69:0;;;;;;;:::i;:::-;28561:70::o;30988:162::-;10055:13;;;;;;;10047:69;;;;-1:-1:-1;;;10047:69:0;;;;;;;:::i;:::-;31101:13;;::::1;::::0;:5:::1;::::0;:13:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;31125:17:0;;::::1;::::0;:7:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;73415:302::-:0;10055:13;;;;;;;10047:69;;;;-1:-1:-1;;;10047:69:0;;;;;;;:::i;:::-;73549:22;;::::1;::::0;;::::1;::::0;73606:25;;;;;::::1;::::0;73642:12:::1;:25:::0;;;;73678:15:::1;:31:::0;73415:302::o;77224:211::-;10055:13;;;;;;;10047:69;;;;-1:-1:-1;;;10047:69:0;;;;;;;:::i;:::-;-1:-1:-1;77338:95:0::1;77319:16;:114:::0;77224:211::o;41787:161::-;10055:13;;;;;;;10047:69;;;;-1:-1:-1;;;10047:69:0;;;;;;;:::i;:::-;41891:1:::1;41884:4;:8;41876:42;;;::::0;-1:-1:-1;;;41876:42:0;;14775:2:1;41876:42:0::1;::::0;::::1;14757:21:1::0;14814:2;14794:18;;;14787:30;-1:-1:-1;;;14833:18:1;;;14826:51;14894:18;;41876:42:0::1;14747:171:1::0;41876:42:0::1;41929:4;:11:::0;41787:161::o;101758:59::-;9452:13;;;;;;;:48;;9488:12;;;;9487:13;9452:48;;;10255:4;1130:20;1178:8;9468:16;9444:107;;;;-1:-1:-1;;;9444:107:0;;;;;;;:::i;:::-;9564:19;9587:13;;;;;;9586:14;9611:101;;;;9646:13;:20;;-1:-1:-1;;9681:19:0;;;;;9611:101;9742:14;9738:68;;;9789:5;9773:21;;-1:-1:-1;;9773:21:0;;;9159:654;101758:59::o;112984:129::-;9452:13;;;;;;;:48;;9488:12;;;;9487:13;9452:48;;;10255:4;1130:20;1178:8;9468:16;9444:107;;;;-1:-1:-1;;;9444:107:0;;;;;;;:::i;:::-;9564:19;9587:13;;;;;;9586:14;9611:101;;;;9646:13;:20;;-1:-1:-1;;9681:19:0;;;;;9611:101;113061:44:::1;86213:4;28717:10:::0;115434::::1;:44::i;92883:97::-:0;10055:13;;;;;;;10047:69;;;;-1:-1:-1;;;10047:69:0;;;;;;;:::i;:::-;92957:7:::1;:15:::0;;-1:-1:-1;;92957:15:0::1;::::0;;92883:97::o;90535:112::-;90614:25;90625:4;90631:7;90614:10;:25::i;117617:212::-;117776:45;117805:7;117814:6;117776:28;:45::i;107738:462::-;107880:4;-1:-1:-1;;;;;107902:18:0;;1130:20;107897:66;;-1:-1:-1;107946:5:0;107939:12;;107897:66;107989:121;;-1:-1:-1;;;107989:121:0;;107973:13;;-1:-1:-1;;;;;107989:43:0;;;;;:121;;28717:10;;108074:6;;108095:4;;107989:121;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;108129:62:0;-1:-1:-1;;;108129:62:0;;-1:-1:-1;;107738:462:0;;;;;:::o;78734:218::-;-1:-1:-1;;;;;78866:14:0;;78794:15;78866:14;;;:7;:14;;;;;47600;;47737:1;47719:19;;;;47600:14;78927:17;78811:141;78734:218;;;:::o;74883:178::-;74960:7;74987:66;75020:20;:18;:20::i;:::-;75042:10;71005:57;;-1:-1:-1;;;71005:57:0;;;8706:27:1;8749:11;;;8742:27;;;8785:12;;;8778:28;;;70968:7:0;;8822:12:1;;71005:57:0;;;;;;;;;;;;70995:68;;;;;;70988:75;;70875:196;;;;;69173:279;69301:7;69322:17;69341:18;69363:25;69374:4;69380:1;69383;69386;69363:10;:25::i;:::-;69321:67;;;;69399:18;69411:5;69399:11;:18::i;:::-;-1:-1:-1;69435:9:0;69173:279;-1:-1:-1;;;;;69173:279:0:o;61128:451::-;61203:13;61229:19;61261:10;61265:6;61261:1;:10;:::i;:::-;:14;;61274:1;61261:14;:::i;:::-;61251:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61251:25:0;;61229:47;;-1:-1:-1;;;61287:6:0;61294:1;61287:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;61287:15:0;;;;;;;;;-1:-1:-1;;;61313:6:0;61320:1;61313:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;61313:15:0;;;;;;;;-1:-1:-1;61344:9:0;61356:10;61360:6;61356:1;:10;:::i;:::-;:14;;61369:1;61356:14;:::i;:::-;61344:26;;61339:135;61376:1;61372;:5;61339:135;;;-1:-1:-1;;;61424:5:0;61432:3;61424:11;61411:25;;;;;;;:::i;:::-;;;;61399:6;61406:1;61399:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;61399:37:0;;;;;;;;-1:-1:-1;61461:1:0;61451:11;;;;;61379:3;;;:::i;:::-;;;61339:135;;;-1:-1:-1;61492:10:0;;61484:55;;;;-1:-1:-1;;;61484:55:0;;14010:2:1;61484:55:0;;;13992:21:1;;;14029:18;;;14022:30;14088:34;14068:18;;;14061:62;14140:18;;61484:55:0;13982:182:1;17762:135:0;17806:7;17486:66;17833:50;12296:151;14802:284;1130:20;;14876:106;;;;-1:-1:-1;;;14876:106:0;;23327:2:1;14876:106:0;;;23309:21:1;23366:2;23346:18;;;23339:30;23405:34;23385:18;;;23378:62;-1:-1:-1;;;23456:18:1;;;23449:43;23509:19;;14876:106:0;23299:235:1;14876:106:0;14272:66;14993:85;;-1:-1:-1;;;;;;14993:85:0;-1:-1:-1;;;;;14993:85:0;;;;;;;;;;14802:284::o;20508:461::-;20591:12;1130:20;;20616:88;;;;-1:-1:-1;;;20616:88:0;;25309:2:1;20616:88:0;;;25291:21:1;25348:2;25328:18;;;25321:30;25387:34;25367:18;;;25360:62;-1:-1:-1;;;25438:18:1;;;25431:36;25484:19;;20616:88:0;25281:228:1;20616:88:0;20778:12;20792:23;20819:6;-1:-1:-1;;;;;20819:19:0;20839:4;20819:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20777:67;;;;20862:99;20898:7;20907:10;20862:99;;;;;;;;;;;;;;;;;:35;:99::i;15199:155::-;15266:37;15285:17;15266:18;:37::i;:::-;15319:27;;-1:-1:-1;;;;;15319:27:0;;;;;;;;15199:155;:::o;117837:464::-;93151:7;;;;118032:29;118024:84;;;;-1:-1:-1;;;118024:84:0;;30360:2:1;118024:84:0;;;30342:21:1;30399:2;30379:18;;;30372:30;30438:34;30418:18;;;30411:62;-1:-1:-1;;;30489:18:1;;;30482:40;30539:19;;118024:84:0;30332:232:1;118024:84:0;-1:-1:-1;;;;;118128:19:0;;;;;;:13;:19;;;;;;;;118127:20;:42;;;;-1:-1:-1;;;;;;118152:17:0;;;;;;:13;:17;;;;;;;;118151:18;118127:42;118119:84;;;;-1:-1:-1;;;118119:84:0;;17462:2:1;118119:84:0;;;17444:21:1;17501:2;17481:18;;;17474:30;17540:31;17520:18;;;17513:59;17589:18;;118119:84:0;17434:179:1;118119:84:0;118214:63;118260:4;118266:2;118270:6;118214:45;:63::i;45773:929::-;45886:12;;45862:7;;45882:58;;-1:-1:-1;45927:1:0;45920:8;;45882:58;45993:12;;45952:11;;46018:435;46031:4;46025:3;:10;46018:435;;;46052:11;46066:34;46090:3;46095:4;46066:23;:34::i;:::-;46052:48;;46334:7;46321:5;46327:3;46321:10;;;;;;;;:::i;:::-;;;;;;;;;:20;46317:125;;;46369:3;46362:10;;46317:125;;;46419:7;:3;46425:1;46419:7;:::i;:::-;46413:13;;46317:125;46037:416;46018:435;;;46579:1;46573:3;:7;:36;;;;-1:-1:-1;46602:7:0;46584:5;46590:7;46596:1;46590:3;:7;:::i;:::-;46584:14;;;;;;;;:::i;:::-;;;;;;;;;:25;46573:36;46569:126;;;46633:7;46639:1;46633:3;:7;:::i;:::-;46626:14;;;;;;46569:126;-1:-1:-1;46680:3:0;-1:-1:-1;46673:10:0;;111487:727;111922:23;111948:69;111976:4;111948:69;;;;;;;;;;;;;;;;;111956:5;-1:-1:-1;;;;;111948:27:0;;;:69;;;;;:::i;:::-;112032:17;;111922:95;;-1:-1:-1;112032:21:0;112028:179;;112129:10;112118:30;;;;;;;;;;;;:::i;:::-;112110:85;;;;-1:-1:-1;;;112110:85:0;;28413:2:1;112110:85:0;;;28395:21:1;28452:2;28432:18;;;28425:30;28491:34;28471:18;;;28464:62;-1:-1:-1;;;28542:18:1;;;28535:40;28592:19;;112110:85:0;28385:232:1;42173:218:0;42103:4;;42299:6;42266:30;32428:12;;;32340:108;42266:30;:39;;;;:::i;:::-;:48;;42258:86;;;;-1:-1:-1;;;42258:86:0;;26122:2:1;42258:86:0;;;26104:21:1;26161:2;26141:18;;;26134:30;26200:27;26180:18;;;26173:55;26245:18;;42258:86:0;26094:175:1;42258:86:0;42355:28;42367:7;42376:6;42355:11;:28::i;67402:1632::-;67533:7;;68467:66;68454:79;;68450:163;;;-1:-1:-1;68566:1:0;;-1:-1:-1;68570:30:0;68550:51;;68450:163;68627:1;:7;;68632:2;68627:7;;:18;;;;;68638:1;:7;;68643:2;68638:7;;68627:18;68623:102;;;-1:-1:-1;68678:1:0;;-1:-1:-1;68682:30:0;68662:51;;68623:102;68839:24;;;68822:14;68839:24;;;;;;;;;12697:25:1;;;12770:4;12758:17;;12738:18;;;12731:45;;;;12792:18;;;12785:34;;;12835:18;;;12828:34;;;68839:24:0;;12669:19:1;;68839:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;68839:24:0;;-1:-1:-1;;68839:24:0;;;-1:-1:-1;;;;;;;68878:20:0;;68874:103;;68931:1;68935:29;68915:50;;;;;;;68874:103;68997:6;-1:-1:-1;69005:20:0;;-1:-1:-1;67402:1632:0;;;;;;;;:::o;62064:643::-;62142:20;62133:5;:29;;;;;;;;:::i;:::-;;62129:571;;;62064:643;:::o;62129:571::-;62240:29;62231:5;:38;;;;;;;;:::i;:::-;;62227:473;;;62286:34;;-1:-1:-1;;;62286:34:0;;13299:2:1;62286:34:0;;;13281:21:1;13338:2;13318:18;;;13311:30;13377:26;13357:18;;;13350:54;13421:18;;62286:34:0;13271:174:1;62227:473:0;62351:35;62342:5;:44;;;;;;;;:::i;:::-;;62338:362;;;62403:41;;-1:-1:-1;;;62403:41:0;;15877:2:1;62403:41:0;;;15859:21:1;15916:2;15896:18;;;15889:30;15955:33;15935:18;;;15928:61;16006:18;;62403:41:0;15849:181:1;62338:362:0;62475:30;62466:5;:39;;;;;;;;:::i;:::-;;62462:238;;;62522:44;;-1:-1:-1;;;62522:44:0;;18998:2:1;62522:44:0;;;18980:21:1;19037:2;19017:18;;;19010:30;19076:34;19056:18;;;19049:62;-1:-1:-1;;;19127:18:1;;;19120:32;19169:19;;62522:44:0;18970:224:1;62462:238:0;62597:30;62588:5;:39;;;;;;;;:::i;:::-;;62584:116;;;62644:44;;-1:-1:-1;;;62644:44:0;;22162:2:1;62644:44:0;;;22144:21:1;22201:2;22181:18;;;22174:30;22240:34;22220:18;;;22213:62;-1:-1:-1;;;22291:18:1;;;22284:32;22333:19;;62644:44:0;22134:224:1;6442:712:0;6592:12;6621:7;6617:530;;;-1:-1:-1;6652:10:0;6645:17;;6617:530;6766:17;;:21;6762:374;;6964:10;6958:17;7025:15;7012:10;7008:2;7004:19;6997:44;6762:374;7107:12;7100:20;;-1:-1:-1;;;7100:20:0;;;;;;;;:::i;54163:622::-;-1:-1:-1;;;;;54367:18:0;;54363:415;;54423:26;54446:2;54423:22;:26::i;:::-;54464:28;:26;:28::i;54363:415::-;-1:-1:-1;;;;;54514:16:0;;54510:268;;54568:28;54591:4;54568:22;:28::i;54510:268::-;54697:28;54720:4;54697:22;:28::i;:::-;54740:26;54763:2;54740:22;:26::i;44630:156::-;44692:7;44767:11;44777:1;44768:5;;;44767:11;:::i;:::-;44757:21;;44758:5;;;44757:21;:::i;3613:229::-;3750:12;3782:52;3804:6;3812:4;3818:1;3821:12;3782:21;:52::i;37580:399::-;-1:-1:-1;;;;;37664:21:0;;37656:65;;;;-1:-1:-1;;;37656:65:0;;30000:2:1;37656:65:0;;;29982:21:1;30039:2;30019:18;;;30012:30;30078:33;30058:18;;;30051:61;30129:18;;37656:65:0;29972:181:1;37656:65:0;37734:49;37763:1;37767:7;37776:6;37734:20;:49::i;:::-;37812:6;37796:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;37829:18:0;;;;;;:9;:18;;;;;:28;;37851:6;;37829:18;:28;;37851:6;;37829:28;:::i;:::-;;;;-1:-1:-1;;37873:37:0;;11344:25:1;;;-1:-1:-1;;;;;37873:37:0;;;37890:1;;37873:37;;11332:2:1;11317:18;37873:37:0;;;;;;;89658:218;;:::o;56420:146::-;-1:-1:-1;;;;;56504:33:0;;;;;;:24;:33;;;;;;;;32612:9;:18;;;;;;;56488:70;;56504:33;56488:15;:70::i;56539:18::-;56488:15;:70::i;56574:118::-;56631:53;56647:21;56670:13;32428:12;;;32340:108;4733:510;4903:12;4961:5;4936:21;:30;;4928:81;;;;-1:-1:-1;;;4928:81:0;;19814:2:1;4928:81:0;;;19796:21:1;19853:2;19833:18;;;19826:30;19892:34;19872:18;;;19865:62;-1:-1:-1;;;19943:18:1;;;19936:36;19989:19;;4928:81:0;19786:228:1;4928:81:0;1130:20;;5020:60;;;;-1:-1:-1;;;5020:60:0;;26881:2:1;5020:60:0;;;26863:21:1;26920:2;26900:18;;;26893:30;26959:31;26939:18;;;26932:59;27008:18;;5020:60:0;26853:179:1;5020:60:0;5094:12;5108:23;5135:6;-1:-1:-1;;;;;5135:11:0;5154:5;5161:4;5135:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5093:73;;;;5184:51;5201:7;5210:10;5222:12;5184:16;:51::i;:::-;5177:58;4733:510;-1:-1:-1;;;;;;;4733:510:0:o;56700:310::-;56795:17;56815:23;:21;:23::i;:::-;56795:43;-1:-1:-1;56795:43:0;56853:30;56869:9;56853:15;:30::i;:::-;:42;56849:154;;;56912:29;;;;;;;;-1:-1:-1;56912:29:0;;;;;;;;;;;;;;56956:16;;;:35;;;;;;;;;;;;;;;56700:310::o;57018:212::-;57112:10;;57088:7;;57108:115;;-1:-1:-1;57151:1:0;;57018:212;-1:-1:-1;57018:212:0:o;57108:115::-;57196:10;;57192:3;;57196:14;;57209:1;;57196:14;:::i;:::-;57192:19;;;;;;;;:::i;:::-;;;;;;;;;57185:26;;57018:212;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:718:1;56:5;109:3;102:4;94:6;90:17;86:27;76:2;;127:1;124;117:12;76:2;163:6;150:20;189:18;226:2;222;219:10;216:2;;;232:18;;:::i;:::-;307:2;301:9;275:2;361:13;;-1:-1:-1;;357:22:1;;;381:2;353:31;349:40;337:53;;;405:18;;;425:22;;;402:46;399:2;;;451:18;;:::i;:::-;491:10;487:2;480:22;526:2;518:6;511:18;572:3;565:4;560:2;552:6;548:15;544:26;541:35;538:2;;;589:1;586;579:12;538:2;653;646:4;638:6;634:17;627:4;619:6;615:17;602:54;700:1;693:4;688:2;680:6;676:15;672:26;665:37;720:6;711:15;;;;;;66:666;;;;:::o;737:247::-;796:6;849:2;837:9;828:7;824:23;820:32;817:2;;;865:1;862;855:12;817:2;904:9;891:23;923:31;948:5;923:31;:::i;989:388::-;1057:6;1065;1118:2;1106:9;1097:7;1093:23;1089:32;1086:2;;;1134:1;1131;1124:12;1086:2;1173:9;1160:23;1192:31;1217:5;1192:31;:::i;:::-;1242:5;-1:-1:-1;1299:2:1;1284:18;;1271:32;1312:33;1271:32;1312:33;:::i;:::-;1364:7;1354:17;;;1076:301;;;;;:::o;1382:456::-;1459:6;1467;1475;1528:2;1516:9;1507:7;1503:23;1499:32;1496:2;;;1544:1;1541;1534:12;1496:2;1583:9;1570:23;1602:31;1627:5;1602:31;:::i;:::-;1652:5;-1:-1:-1;1709:2:1;1694:18;;1681:32;1722:33;1681:32;1722:33;:::i;:::-;1486:352;;1774:7;;-1:-1:-1;;;1828:2:1;1813:18;;;;1800:32;;1486:352::o;1843:665::-;1938:6;1946;1954;1962;2015:3;2003:9;1994:7;1990:23;1986:33;1983:2;;;2032:1;2029;2022:12;1983:2;2071:9;2058:23;2090:31;2115:5;2090:31;:::i;:::-;2140:5;-1:-1:-1;2197:2:1;2182:18;;2169:32;2210:33;2169:32;2210:33;:::i;:::-;2262:7;-1:-1:-1;2316:2:1;2301:18;;2288:32;;-1:-1:-1;2371:2:1;2356:18;;2343:32;2398:18;2387:30;;2384:2;;;2430:1;2427;2420:12;2384:2;2453:49;2494:7;2485:6;2474:9;2470:22;2453:49;:::i;:::-;2443:59;;;1973:535;;;;;;;:::o;2513:829::-;2624:6;2632;2640;2648;2656;2664;2672;2725:3;2713:9;2704:7;2700:23;2696:33;2693:2;;;2742:1;2739;2732:12;2693:2;2781:9;2768:23;2800:31;2825:5;2800:31;:::i;:::-;2850:5;-1:-1:-1;2907:2:1;2892:18;;2879:32;2920:33;2879:32;2920:33;:::i;:::-;2972:7;-1:-1:-1;3026:2:1;3011:18;;2998:32;;-1:-1:-1;3077:2:1;3062:18;;3049:32;;-1:-1:-1;3133:3:1;3118:19;;3105:33;3182:4;3169:18;;3157:31;;3147:2;;3202:1;3199;3192:12;3147:2;2683:659;;;;-1:-1:-1;2683:659:1;;;;3225:7;3279:3;3264:19;;3251:33;;-1:-1:-1;3331:3:1;3316:19;;;3303:33;;2683:659;-1:-1:-1;;2683:659:1:o;3347:382::-;3412:6;3420;3473:2;3461:9;3452:7;3448:23;3444:32;3441:2;;;3489:1;3486;3479:12;3441:2;3528:9;3515:23;3547:31;3572:5;3547:31;:::i;:::-;3597:5;-1:-1:-1;3654:2:1;3639:18;;3626:32;3667:30;3626:32;3667:30;:::i;3734:455::-;3811:6;3819;3872:2;3860:9;3851:7;3847:23;3843:32;3840:2;;;3888:1;3885;3878:12;3840:2;3927:9;3914:23;3946:31;3971:5;3946:31;:::i;:::-;3996:5;-1:-1:-1;4052:2:1;4037:18;;4024:32;4079:18;4068:30;;4065:2;;;4111:1;4108;4101:12;4065:2;4134:49;4175:7;4166:6;4155:9;4151:22;4134:49;:::i;:::-;4124:59;;;3830:359;;;;;:::o;4194:315::-;4262:6;4270;4323:2;4311:9;4302:7;4298:23;4294:32;4291:2;;;4339:1;4336;4329:12;4291:2;4378:9;4365:23;4397:31;4422:5;4397:31;:::i;:::-;4447:5;4499:2;4484:18;;;;4471:32;;-1:-1:-1;;;4281:228:1:o;4514:523::-;4600:6;4608;4616;4669:2;4657:9;4648:7;4644:23;4640:32;4637:2;;;4685:1;4682;4675:12;4637:2;4724:9;4711:23;4743:31;4768:5;4743:31;:::i;:::-;4793:5;-1:-1:-1;4845:2:1;4830:18;;4817:32;;-1:-1:-1;4900:2:1;4885:18;;4872:32;4927:18;4916:30;;4913:2;;;4959:1;4956;4949:12;4913:2;4982:49;5023:7;5014:6;5003:9;4999:22;4982:49;:::i;:::-;4972:59;;;4627:410;;;;;:::o;5042:245::-;5109:6;5162:2;5150:9;5141:7;5137:23;5133:32;5130:2;;;5178:1;5175;5168:12;5130:2;5210:9;5204:16;5229:28;5251:5;5229:28;:::i;5292:180::-;5351:6;5404:2;5392:9;5383:7;5379:23;5375:32;5372:2;;;5420:1;5417;5410:12;5372:2;-1:-1:-1;5443:23:1;;5362:110;-1:-1:-1;5362:110:1:o;5477:315::-;5545:6;5553;5606:2;5594:9;5585:7;5581:23;5577:32;5574:2;;;5622:1;5619;5612:12;5574:2;5658:9;5645:23;5635:33;;5718:2;5707:9;5703:18;5690:32;5731:31;5756:5;5731:31;:::i;5797:245::-;5855:6;5908:2;5896:9;5887:7;5883:23;5879:32;5876:2;;;5924:1;5921;5914:12;5876:2;5963:9;5950:23;5982:30;6006:5;5982:30;:::i;6047:249::-;6116:6;6169:2;6157:9;6148:7;6144:23;6140:32;6137:2;;;6185:1;6182;6175:12;6137:2;6217:9;6211:16;6236:30;6260:5;6236:30;:::i;6787:609::-;6884:6;6892;6900;6953:2;6941:9;6932:7;6928:23;6924:32;6921:2;;;6969:1;6966;6959:12;6921:2;7009:9;6996:23;7038:18;7079:2;7071:6;7068:14;7065:2;;;7095:1;7092;7085:12;7065:2;7118:49;7159:7;7150:6;7139:9;7135:22;7118:49;:::i;:::-;7108:59;;7220:2;7209:9;7205:18;7192:32;7176:48;;7249:2;7239:8;7236:16;7233:2;;;7265:1;7262;7255:12;7233:2;;7288:51;7331:7;7320:8;7309:9;7305:24;7288:51;:::i;:::-;7278:61;;;7386:2;7375:9;7371:18;7358:32;7348:42;;6911:485;;;;;:::o;7586:316::-;7663:6;7671;7679;7732:2;7720:9;7711:7;7707:23;7703:32;7700:2;;;7748:1;7745;7738:12;7700:2;-1:-1:-1;;7771:23:1;;;7841:2;7826:18;;7813:32;;-1:-1:-1;7892:2:1;7877:18;;;7864:32;;7690:212;-1:-1:-1;7690:212:1:o;7907:257::-;7948:3;7986:5;7980:12;8013:6;8008:3;8001:19;8029:63;8085:6;8078:4;8073:3;8069:14;8062:4;8055:5;8051:16;8029:63;:::i;:::-;8146:2;8125:15;-1:-1:-1;;8121:29:1;8112:39;;;;8153:4;8108:50;;7956:208;-1:-1:-1;;7956:208:1:o;8169:274::-;8298:3;8336:6;8330:13;8352:53;8398:6;8393:3;8386:4;8378:6;8374:17;8352:53;:::i;:::-;8421:16;;;;;8306:137;-1:-1:-1;;8306:137:1:o;8845:786::-;9256:25;9251:3;9244:38;9226:3;9311:6;9305:13;9327:62;9382:6;9377:2;9372:3;9368:12;9361:4;9353:6;9349:17;9327:62;:::i;:::-;-1:-1:-1;;;9448:2:1;9408:16;;;9440:11;;;9433:40;9498:13;;9520:63;9498:13;9569:2;9561:11;;9554:4;9542:17;;9520:63;:::i;:::-;9603:17;9622:2;9599:26;;9234:397;-1:-1:-1;;;;9234:397:1:o;9844:488::-;-1:-1:-1;;;;;10113:15:1;;;10095:34;;10165:15;;10160:2;10145:18;;10138:43;10212:2;10197:18;;10190:34;;;10260:3;10255:2;10240:18;;10233:31;;;10038:4;;10281:45;;10306:19;;10298:6;10281:45;:::i;:::-;10273:53;10047:285;-1:-1:-1;;;;;;10047:285:1:o;10616:385::-;10848:1;10844;10839:3;10835:11;10831:19;10823:6;10819:32;10808:9;10801:51;10888:6;10883:2;10872:9;10868:18;10861:34;10931:2;10926;10915:9;10911:18;10904:30;10782:4;10951:44;10991:2;10980:9;10976:18;10968:6;10951:44;:::i;12873:219::-;13022:2;13011:9;13004:21;12985:4;13042:44;13082:2;13071:9;13067:18;13059:6;13042:44;:::i;17618:408::-;17820:2;17802:21;;;17859:2;17839:18;;;17832:30;17898:34;17893:2;17878:18;;17871:62;-1:-1:-1;;;17964:2:1;17949:18;;17942:42;18016:3;18001:19;;17792:234::o;19199:408::-;19401:2;19383:21;;;19440:2;19420:18;;;19413:30;19479:34;19474:2;19459:18;;19452:62;-1:-1:-1;;;19545:2:1;19530:18;;19523:42;19597:3;19582:19;;19373:234::o;21138:402::-;21340:2;21322:21;;;21379:2;21359:18;;;21352:30;21418:34;21413:2;21398:18;;21391:62;-1:-1:-1;;;21484:2:1;21469:18;;21462:36;21530:3;21515:19;;21312:228::o;21545:410::-;21747:2;21729:21;;;21786:2;21766:18;;;21759:30;21825:34;21820:2;21805:18;;21798:62;-1:-1:-1;;;21891:2:1;21876:18;;21869:44;21945:3;21930:19;;21719:236::o;27037:407::-;27239:2;27221:21;;;27278:2;27258:18;;;27251:30;27317:34;27312:2;27297:18;;27290:62;-1:-1:-1;;;27383:2:1;27368:18;;27361:41;27434:3;27419:19;;27211:233::o;31264:128::-;31304:3;31335:1;31331:6;31328:1;31325:13;31322:2;;;31341:18;;:::i;:::-;-1:-1:-1;31377:9:1;;31312:80::o;31397:217::-;31437:1;31463;31453:2;;31507:10;31502:3;31498:20;31495:1;31488:31;31542:4;31539:1;31532:15;31570:4;31567:1;31560:15;31453:2;-1:-1:-1;31599:9:1;;31443:171::o;31619:168::-;31659:7;31725:1;31721;31717:6;31713:14;31710:1;31707:21;31702:1;31695:9;31688:17;31684:45;31681:2;;;31732:18;;:::i;:::-;-1:-1:-1;31772:9:1;;31671:116::o;31792:125::-;31832:4;31860:1;31857;31854:8;31851:2;;;31865:18;;:::i;:::-;-1:-1:-1;31902:9:1;;31841:76::o;31922:258::-;31994:1;32004:113;32018:6;32015:1;32012:13;32004:113;;;32094:11;;;32088:18;32075:11;;;32068:39;32040:2;32033:10;32004:113;;;32135:6;32132:1;32129:13;32126:2;;;-1:-1:-1;;32170:1:1;32152:16;;32145:27;31975:205::o;32185:136::-;32224:3;32252:5;32242:2;;32261:18;;:::i;:::-;-1:-1:-1;;;32297:18:1;;32232:89::o;32326:380::-;32405:1;32401:12;;;;32448;;;32469:2;;32523:4;32515:6;32511:17;32501:27;;32469:2;32576;32568:6;32565:14;32545:18;32542:38;32539:2;;;32622:10;32617:3;32613:20;32610:1;32603:31;32657:4;32654:1;32647:15;32685:4;32682:1;32675:15;32711:127;32772:10;32767:3;32763:20;32760:1;32753:31;32803:4;32800:1;32793:15;32827:4;32824:1;32817:15;32843:127;32904:10;32899:3;32895:20;32892:1;32885:31;32935:4;32932:1;32925:15;32959:4;32956:1;32949:15;32975:127;33036:10;33031:3;33027:20;33024:1;33017:31;33067:4;33064:1;33057:15;33091:4;33088:1;33081:15;33107:127;33168:10;33163:3;33159:20;33156:1;33149:31;33199:4;33196:1;33189:15;33223:4;33220:1;33213:15;33239:131;-1:-1:-1;;;;;33314:31:1;;33304:42;;33294:2;;33360:1;33357;33350:12;33375:118;33461:5;33454:13;33447:21;33440:5;33437:32;33427:2;;33483:1;33480;33473:12;33498:131;-1:-1:-1;;;;;;33572:32:1;;33562:43;;33552:2;;33619:1;33616;33609:12
Swarm Source
ipfs://c5d1e83442084c341119aa2dc27dc40129e307a344d5cb52339521f846674c8c
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Validator ID :
0 FTM
Amount Staked
0
Amount Delegated
0
Staking Total
0
Staking Start Epoch
0
Staking Start Time
0
Proof of Importance
0
Origination Score
0
Validation Score
0
Active
0
Online
0
Downtime
0 s
Address | Amount | claimed Rewards | Created On Epoch | Created On |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.